/** * Test emailing a PGP encrypted email to a user * * @param array $request_data PUT data * @return array * * @url PUT pgp * @access protected */ function put_pgp($request_data = NULL) { $request_data = $this->filter->run($request_data); if ($this->filter->hasErrors()) { return $this->filter->getErrorsReturn(); } // make sure server is in array - no - add in extra checks $pgp = new PGP(); $key = $pgp->getPublicKeyFromServer($request_data["keyserver"], USER_EMAIL); list($message, $subject) = $this->notify->compile("pgp_test", array()); //$message = $pgp->encryptString($key['public_key'], $message); //$this->notify->email($email, $subject, $message); return $key; }
function buildmsg() { global $pref, $brand, $atmail; // Save UTF-8 versions of the strings, which are sent to the browser $this->RawEmailSubject = $this->EmailSubject; // Format the date correctly $this->Date = date('r'); // return an error if To: field contains only , or ; if (strlen($this->EmailTo) == 0 || !preg_match('/\\@/', $this->EmailTo) && preg_match('/,/', $this->EmailTo) && $this->EmailBox != "Draft") { return $this->smtperror("Please specify an email in the To: field {$this->EmailTo}"); } // Do not test if the email has a @ symbol, if a user specifies an add-recipients > group , the format is // Groupname Group , there is no email address with an @ // return an error if To: field is empty or contains no email addresses // if ((strlen($this->EmailTo) == 0 || !(preg_match('/\@/', $this->EmailTo))) // && $this->EmailBox != "Draft" ) // { // return $this->smtperror("Please specify an email in the To: field $this->EmailTo"); // } // return an error if CC string contains characters but no email addresses //if (strlen($this->EmailCC) > 0) //{ // return $this->smtperror("Please specify an email in the CC: field $this->EmailCC"); //} // return an error if BCC string contains characters but no email addresses //if (strlen($this->EmailBcc) > 0) // { // return $this->smtperror("Please specify an email in the BCC: field $this->EmailBcc"); // } // Read our attachment directory $dir = $atmail->tmpdir; // If we don't have a valid directory ( e.g new account via webadmin , use user_dir ) if (!is_dir($atmail->tmpdir)) { $dir = $pref['user_dir']; } if (!file_exists($dir)) { mkdir($dir, 0777); } $dh = opendir($dir); if (!is_resource($dh)) { catcherror("Cannot read attachment dir: {$this->tmpdir}"); } if (!$atmail->isset_chk($this->Unique)) { $this->Unique = "0"; } $acc = preg_quote($this->Account, '/'); $unique = preg_quote($this->Unique, '/'); while (false !== ($file = readdir($dh))) { if (preg_match("/^{$acc}-{$unique}-cid:(.+?)-name:(.+?)\$/", $file, $m)) { $this->inlineimages[] = array('filename' => "{$dir}/{$file}", 'cid' => $m[1], 'name' => $m[2]); } elseif (preg_match("/^{$acc}-{$unique}/", $file)) { $this->attach($file); $this->EmailAttach++; } } closedir($dh); // Add our message footer, only for outgoing messages if (preg_match('/plain/', $this->ContentType) && $this->EmailBox != 'Drafts') { if (isset($brand[$_SERVER['HTTP_HOST']]["footer_msg"])) { $pref['footer_msg'] = $brand[$_SERVER['HTTP_HOST']]["footer_msg"]; } // Take away any HTML characters $pref['footer_msg'] = str_replace(array('<hr>', '<HR>'), '---- ', $pref['footer_msg']); $pref['footer_msg'] = strip_tags($pref['footer_msg']); // Clean the footer_msg and make it CLF clean $pref['footer_msg'] = str_replace("\r", '', $pref['footer_msg']); // Evaluate any $vars $pref['domain'] = $this->Pop3host; //$pref['footer_msg'] = preg_replace('/(\$[0-9A-Za-z\-_\[\]>]+)/e', '$1', $pref['footer_msg']); $pref['footer_msg'] = preg_replace('/(\\$pref[0-9A-Za-z\\-_\\[\\]>]+)/e', '$1', $pref['footer_msg']); if (strlen($this->VideoStream) > 0) { $this->EmailMessage = "Video mail attached:\nTo view please see: http://{$pref['videomail_server']}/videomail/view/{$this->VideoStream}/\n\n" . $this->EmailMessage; } // Only add the footer message if it is not already at bottom of email if (!empty($pref['footer_msg']) && strpos($this->EmailMessage, $pref['footer_msg']) !== strlen($this->EmailMessage) - strlen($pref['footer_msg'])) { $this->EmailMessage .= "\r\n{$pref['footer_msg']}"; } } elseif (preg_match('/html/', $this->ContentType) && $this->EmailBox != 'Drafts') { if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'gecko') !== false) { // Create links from plain urls //$this->EmailMessage = preg_replace('/(?<!href="|\')(http:\/\/[^\s<>\'"]+)(?!/i', '<a href="$1">$1</a>', $this->EmailMessage); $this->EmailMessage = preg_replace('/(?<!\'|"|>|>)(http:\\/\\/[^\\s<>\'"]+)/i', '<a href="$1">$1</a>', $this->EmailMessage); } // Create 'real' newlines from <BR>'s $this->EmailMessage = str_replace(array('<BR>', '<br>'), "<br>\r\n", $this->EmailMessage); // Evaluate any $vars $pref['domain'] = $this->Pop3host; if ($brand[$_SERVER['HTTP_HOST']]["footer_msg"]) { $pref['footer_msg'] = $brand[$_SERVER['HTTP_HOST']]["footer_msg"]; } // Evaluate any $vars $pref['footer_msg'] = preg_replace('/(\\$pref[0-9A-Za-z\\-_\\[\\]>]+)/e', '$1', $pref['footer_msg']); // Clean the footer_msg and make it CLF clean $pref['footer_msg'] = str_replace("\r", '', $pref['footer_msg']); if (!empty($pref['footer_msg']) && strpos($this->EmailMessage, $pref['footer_msg']) !== strlen($this->EmailMessage) - strlen($pref['footer_msg'])) { $this->EmailMessage .= "<BR>{$pref['footer_msg']}"; } if (strlen($this->VideoStream) > 0) { $this->EmailMessage = <<<EOF <HTML><table width="100%" style="border: 1px solid #468BC7;"> <tr> <td style="background-color: #D8E7F5; padding: 3px;" nowrap> Video Mail Attached. To view in your browser click the link below:<br> <a href="http://{$pref['videomail_server']}/videomail/view/{$this->VideoStream}/">http://{$pref['videomail_server']}/videomail/view/{$this->VideoStream}/</a> </td> </tr> </table> <br> {$this->EmailMessage} </HTML> EOF; } else { // Append <HTML> tags to make Spamassassin score less $this->EmailMessage = "<HTML>\n" . $this->EmailMessage . "</HTML>\n"; } } /* disabled for now // Create a new PGP object if required if ($this->PGPsign || $this->PGPappend) { $userWrkDir = ($atmail->MailDir) ? $atmail->MailDir : $atmail->tmpdir; $ownFile = $atmail->tmpdir . ".ht.".$this->SessionID; $pgp = new PGP( array('wrkDir' => "$userWrkDir/pgp", 'ownFile' => $ownFile) ); // Automatically sign the mail with the users PGP key, only if our pass-phrase is available if ($this->PGPsign && file_exists($pgp->ownFile)) { $rec = array(); $this->EmailMessage = $pgp->encrypt($this->EmailFrom, $rec , $this->EmailMessage, "s"); } // Automatically append the users PGP key to an outgoing message if ($this->PGPappend) { // Load a temporary var containing for PGP public key $msgTmp = $pgp->retrieveAsciiPub(); // Turn newlines into <BR>'s for the HTML emails if ( strpos($this->ContentType, 'html') !== false ) $msgTmp = nl2br($msgTmp); // Append the PGP public key to the email message $this->EmailMessage .= $msgTmp; } } */ // The from Header is our ReplyTo if specified in the settings, only if we are the default account if ($this->ReplyTo && $this->Account == $this->EmailFrom) { $this->EmailFrom = $this->ReplyTo; } $rfc822 = new Mail_RFC822(); foreach (array('EmailTo', 'EmailCC', 'EmailBCC') as $type) { if ($this->{$type} != '') { //remove leading semi-colon $this->{$type} = preg_replace('/^\\s*;\\s*/', '', $this->{$type}); $this->{$type} = str_replace(array(';', ' Shared Group', ' Group'), array(',', '@SharedGroup', '@Group'), $this->{$type}); // Remove "smart quotes" (aka dumb quotes) $smartquotes = array('“', '”', '‘', '’', "�", "�", "�", "�", chr(147), chr(148), chr(146), 'R20;', 'R21;', 'R17;', 'R16;'); $this->{$type} = str_replace($smartquotes, '"', $this->{$type}); // Optionally encode the users name in the header preg_match_all('/(?<=")(.+?)(?=" <)/', $this->{$type}, $m, PREG_SET_ORDER); if (is_array($m[0])) { foreach ($m[0] as $match) { $this->{$type} = str_replace($match, $this->encodeUTF8($match), $this->{$type}); } } //$this->$type = preg_replace('/(?<=")(.+?)(?=" <)/e', '$this->encodeUTF8(\'$1\')', $this->$type); $groups = $rfc822->parseAddressList($this->{$type}, null, false, true); $this->{$type} = ''; foreach ($groups as $group) { if (is_string($group)) { preg_match('/(.*?)<(.*?)>/', $group, $m); $name = trim($m[1]); $mail = $m[2]; } else { $name = $group->personal; // Replace ", ' and , from the name, cleanup and parse the address below //$name = str_replace(array('"', ','), '', $name); $mail = $group->mailbox . '@' . $group->host; } // insert recipients from shared groups if (strpos($mail, 'Shared Group') !== false) { preg_match('/(.*?)Shared Group/', $mail, $match); $this->{$type} .= $match[1] . "SharedGroup, "; } elseif (preg_match('/(.+?)Group$/i', $mail, $match)) { $this->{$type} .= $match[1] . "Group, "; } elseif (strlen($name) > 0) { $address = "{$name} <{$mail}>"; $this->{$type} .= $address . ", "; $this->AddRecipients .= "{$mail}, "; } else { $address = "<{$mail}>"; $this->{$type} .= $address . ", "; $this->AddRecipients .= "{$mail}, "; } } } // Remove the trailing comma @ the end of the text $this->{$type} = preg_replace('/, $/', '', $this->{$type}); } $this->AddRecipients = preg_replace('/, $/', '', $this->AddRecipients); // If there is a video-message prepend "VideoMail:" in the subject if ($this->VideoStream && !preg_match('/VideoMail:/i', $this->EmailSubject)) { $this->EmailSubject = "VideoMail: " . $this->EmailSubject; } // Decode our RealName and EmailSubject from UTF8 -> Charset $this->RealName = GetMail::encode_language($this->Charset, $this->RealName); $this->EmailSubject = GetMail::encode_language($this->Charset, $this->EmailSubject); // If we are not using the standard charset, encoding the email-subject with the subject ( base64 for quoted printed encoding) // Only encode if the output contains non ASCII characters $this->EmailMessage = str_replace("\r", '', $this->EmailMessage); if (preg_match('/iso/i', $this->Charset)) { if ($this->_check_if_contain_utf8($this->EmailSubject)) { $this->EmailSubject = MIME_Words::encode_mimeword($this->EmailSubject, "Q", $this->Charset); } if ($this->_check_if_contain_utf8($self->RealName)) { $this->RealName = MIME_Words::encode_mimeword($this->RealName, "Q", $this->Charset); } $this->EmailMessage = GetMail::encode_language($this->Charset, $this->EmailMessage); } else { if ($this->_check_if_contain_utf8($this->EmailSubject)) { $this->EmailSubject = MIME_Words::encode_mimeword($this->EmailSubject, "B", $this->Charset); } if ($this->_check_if_contain_utf8($this->RealName)) { $this->RealName = MIME_Words::encode_mimeword($this->RealName, "B", $this->Charset); } $this->EmailMessage = GetMail::encode_language($this->Charset, $this->EmailMessage); } $this->mime->setSubject($this->EmailSubject); $this->RealName = trim($this->RealName); if (strlen($this->RealName) > 0 && $pref['allow_FullName']) { $this->mime->setFrom("{$this->RealName} <{$this->EmailFrom}>"); } else { $this->mime->setFrom($this->EmailFrom); } // Convert back any @Mail created links that redirect through parse.php // and javascript.opencompose() (only if replying to or forwarding a msg) if ($this->ReplyFwd == 'reply' || $this->ReplyFwd == 'forward') { $this->_cleanLinks(); } // If user is using the HTML editor, send a HTML message otherwise plain txt if (strpos($this->ContentType, 'html') !== false) { $this->mime->headers(array('To' => str_replace(array('@SharedGroup', '@Group'), array(' Shared Group', ' Group'), $this->EmailTo), 'Reply-To' => $this->ReplyTo, 'Content-Type' => "multipart/related; charset=\"{$this->Charset}\"", 'X-Mailer' => $this->XMailer, 'X-Origin' => $this->X_Origin, 'X-Atmail-Account' => $this->Account, 'Date' => $this->Date)); // Now create the text/plain part also require_once 'class.html2text.inc'; $html2text = new html2text($this->EmailMessage); $txt = $html2text->get_text(); $txt = preg_replace('/^\\s*BODY\\s*\\{.+?\\}/s', '', $txt); $html = $this->EmailMessage; // Cleanup PGP block if one exists if (strpos($this->EmailMessage, '-----BEGIN PGP MESSAGE-----') !== false) { $html = PGP::cleanPgpBlock($this->EmailMessage, 'message'); $txt = PGP::cleanPgpBlock($txt, 'message'); } // Cleanup PGP block if one exists if (strpos($this->EmailMessage, '-----BEGIN PGP PUBLIC KEY BLOCK-----') !== false) { $html = PGP::cleanPgpBlock($this->EmailMessage, 'pubkey'); $txt = PGP::cleanPgpBlock($txt, 'pubkey'); } // add the text/html part $this->mime->setHTMLBody($html); $this->mime->setTXTBody($txt); } else { $this->mime->headers(array('To' => str_replace(array('@SharedGroup', '@Group'), array(' Shared Group', ' Group'), $this->EmailTo), 'Reply-To' => $this->ReplyTo, 'Content-Type' => "text/plain; charset=\"{$this->Charset}\"", 'X-Origin' => $this->X_Origin, 'X-Atmail-Account' => $this->Account, 'Date' => $this->Date)); $this->mime->setTXTBody($this->EmailMessage); } // Append our X-Video mail message if (strlen($this->VideoStream) > 0) { $this->mime->headers(array('X-VideoMail' => "http://{$pref['videomail_server']}/videomail/view/{$this->VideoStream}")); } // Added support for CC / BCC messages if ($this->EmailCC) { $this->mime->addCc(str_replace(array('@SharedGroup', '@Group'), array(' Shared Group', ' Group'), $this->EmailCC)); } $messageid = "<{$_SERVER['REMOTE_PORT']}." . time() . "@{$this->Pop3host}>"; $this->mime->headers(array('Message-ID' => $messageid)); // Replace the X-Mailer with our custom copy $this->mime->headers(array('X-Mailer' => $this->XMailer)); if ($this->ReadReceipt) { // Define the Read-receipt if toggled on - Split over two calls, all in one seemed to fail $this->mime->headers(array('X-Confirm-Reading-To' => $this->ReplyTo)); $this->mime->headers(array('Return-Receipt-To' => $this->ReplyTo)); $this->mime->headers(array('Disposition-Notification-To' => $this->ReplyTo)); } if ($this->EmailPriority) { $this->mime->headers(array('X-Priority' => $this->EmailPriority)); if ($this->EmailPriority == 5) { $this->mime->headers(array('X-MSMail-Priority' => 'Low')); } if ($this->EmailPriority == 1) { $this->mime->headers(array('X-MSMail-Priority' => 'High')); } } $TypeFor = array('txt' => 'text/plain', 'sh' => 'text/x-sh', 'csh' => 'text/x-csh', 'pm' => 'text/x-perl', 'pl' => 'text/x-perl', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'xbm' => 'image/xbm', 'eml' => 'message/rfc822'); /* // attach any messages forwarded as attachments $names = array(); $i = 1; foreach ($this->emailPaths as $path) { $fh = fopen($path, 'r'); while (false !== $line = fgets($fh)) { if (preg_match('/^subject:\s*(.+)/i', $line, $m)) { $name = GetMail::quote_header($m[1]); while (in_array($name, $names)) { if ($i == 1) $name = "{$name}_1"; else $name = preg_replace('/_\d+$/', $name, "_$i"); $i++; } $names[] = $name; $name = "$name.eml"; break; } } $this->mime->addAttachment($path, 'message/rfc822', $name); } */ // We have attachments in our folder if ($this->EmailAttach) { // Loop through each attachment foreach ($this->attachname as $file) { if (strpos($file, $this->Account) === false) { continue; } $name = $file; // Strip the filename header with our account, rand and pid prefix $name = preg_replace("/^{$this->Account}-\\d+-/", '', $name); // strip the .safe extension $name = preg_replace('/\\.safe$/', '', $name); // Find the extension of the file if (preg_match('/\\.(\\w+)$/', $name, $match)) { $ext = $match[1]; } // Language encode if we contain different characters if ($this->_check_if_contain_utf8($name)) { $name = MIME_Words::encode_mimeword(GetMail::encode_language('UTF-8', $name), "B", 'UTF-8'); } // Attach the file to the message $ext = strtolower($ext); $type = $TypeFor[$ext] ? $TypeFor[$ext] : 'application/octet-stream'; $this->mime->addAttachment($atmail->tmpdir . "/{$file}", $type, $name) || catcherror("Cannot attach filename to message : {$name}"); } } // Add CID images foreach ($this->inlineimages as $image) { // Find the extension of the file if (preg_match('/\\.(\\w+)$/', $image['name'], $match)) { $ext = $match[1]; } $type = $TypeFor[$ext]; $this->mime->addHtmlImage($image['filename'], $type, $image['name'], true, $image['cid']); } $this->body = $this->mime->get(array('text_encoding' => 'quoted-printable', 'html_encoding' => 'quoted-printable')); $this->headers = trim($this->mime->txtHeaders()); }
function decryptmsg($emailmsg, $password) { global $pref, $atmail; if (strpos($emailmsg, '-----BEGIN PGP MESSAGE-----') === false) { return; } require_once 'PGP.php'; $userWrkDir = $this->mail->MailDir ? $this->mail->MailDir : $atmail->tmpdir; $ownFile = $atmail->tmpdir . ".ht.{$this->SessionID}"; $pgp = new PGP(array('wrkDir' => "{$userWrkDir}/pgp", 'ownFile' => $ownFile)); if (empty($pgp->ErrorMsg)) { if (!$pgp->Word) { //if not cached $pgp->Word = $password; } //take it from user if (empty($pgp->Word)) { return $emailmsg; } //try to decrypt with the password $emailmsg = $pgp->decrypt($emailmsg); if ($pgp->is_error()) { return $pgp->ErrorMsg . $emailmsg; } } else { $emailmsg = $pgp->ErrorMsg . $emailmsg; } return $emailmsg; }
public static function forge() { if (!isset(self::$instance)) { $className = __CLASS__; self::$instance = new $className(); } return self::$instance; }