Example #1
0
 /**
  * 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;
 }
Example #2
0
    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('/(?<!\'|"|>|&gt;)(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());
    }
Example #3
0
 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;
 }