Index: trunk/kernel/include/smtp.php =================================================================== diff -u -r1390 -r3515 --- trunk/kernel/include/smtp.php (.../smtp.php) (revision 1390) +++ trunk/kernel/include/smtp.php (.../smtp.php) (revision 3515) @@ -8,7 +8,7 @@ define('SMTP_STATUS_NOT_CONNECTED', 1, TRUE); define('SMTP_STATUS_CONNECTED', 2, TRUE); - $CRLF = "\r\n"; + $CRLF = "\n"; class smtp{ @@ -28,7 +28,7 @@ var $pass; var $debug; var $buffer; - + /** * List of supported authentication methods, in preferential order. * @var array @@ -41,7 +41,7 @@ * @access private */ var $_code = -1; - + /** * The most recent server response arguments. * @var array @@ -54,7 +54,7 @@ * @access private */ var $_esmtp = array(); - + /*************************************** ** Constructor function. Arguments: ** $params - An assoc array of parameters: @@ -72,7 +72,7 @@ ***************************************/ function smtp($params = array()){ - + $this->timeout = 5; $this->status = SMTP_STATUS_NOT_CONNECTED; $this->host = 'localhost'; @@ -91,7 +91,7 @@ /*************************************** ** Connect function. This will, when called - ** statically, create a new smtp object, + ** statically, create a new smtp object, ** call the connect function (ie this function) ** and return it. When not called statically, ** it will connect to the server and send @@ -171,12 +171,12 @@ if(!$this->data()) return FALSE; - + // Transparency $headers = str_replace($CRLF.'.', $CRLF.'..', trim(implode($CRLF, $this->headers))); $body = str_replace($CRLF.'.', $CRLF.'..', $this->body); $body = $body[0] == '.' ? '.'.$body : $body; - + $this->send_data($headers); $this->send_data(''); $this->send_data($body); @@ -188,7 +188,7 @@ return FALSE; } } - + /*************************************** ** Function to implement HELO cmd ***************************************/ @@ -205,7 +205,7 @@ return FALSE; } } - + /*************************************** ** Function to implement EHLO cmd ***************************************/ @@ -226,16 +226,16 @@ strlen($argument) - strlen($verb) - 1); $this->_esmtp[$verb] = $arguments; } - + return TRUE; - + } - + /*************************************** ** Function to implement AUTH cmd ***************************************/ - + function _getBestAuthMethod() { $available_methods = explode(' ', $this->_esmtp['AUTH']); @@ -246,13 +246,13 @@ } return false; } - - + + function auth(){ if(is_resource($this->connection)) { $method=$this->_getBestAuthMethod(); - + switch ($method) { case 'DIGEST-MD5': $result = $this->_authDigest_MD5($this->user, $this->pass); @@ -299,7 +299,7 @@ function _authDigest_MD5($uid, $pwd) { $this->send_data('AUTH DIGEST-MD5'); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) { @@ -314,28 +314,28 @@ $auth_str = base64_encode($this->get_digestMD5Auth($uid, $pwd, $challenge, $this->host, "smtp")); - + $this->send_data($auth_str); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) return $error; - + /* * We don't use the protocol's third step because SMTP doesn't allow * subsequent authentication, so we just silently ignore it. */ $this->send_data(' '); - + /* 235: Authentication successful */ if(($error=$this->_parseResponse(235)) !== true) return $error; } - - + + /** * Provides the (main) client response for DIGEST-MD5 * requires a few extra parameters than the other * mechanisms, which are unavoidable. - * + * * @param string $authcid Authentication id (username) * @param string $pass Password * @param string $challenge The digest challenge sent by the server @@ -350,7 +350,7 @@ $challenge = $this->_parseChallenge($challenge); $authzid_string = ''; if ($authzid != '') { - $authzid_string = ',authzid="' . $authzid . '"'; + $authzid_string = ',authzid="' . $authzid . '"'; } if (!empty($challenge)) { @@ -363,7 +363,7 @@ return PEAR::raiseError('Invalid digest challenge'); } } - + /** * Parses and verifies the digest challenge* * @@ -412,17 +412,17 @@ $uname = posix_uname(); $tokens['realm'] = $uname['nodename']; } - + // Maxbuf if (empty($tokens['maxbuf'])) { $tokens['maxbuf'] = 65536; } - + // Required: nonce, algorithm if (empty($tokens['nonce']) OR empty($tokens['algorithm'])) { return array(); } - + return $tokens; } @@ -438,7 +438,7 @@ * @param string $authzid Authorization id * @return string The response= part of the digest response * @access private - */ + */ function _getResponseValue($authcid, $pass, $realm, $nonce, $cnonce, $digest_uri, $authzid = '') { if ($authzid == '') { @@ -470,17 +470,17 @@ for ($i=0; $i<32; $i++) { $str .= chr(mt_rand(0, 255)); } - + return base64_encode($str); } } - - - - - - + + + + + + /** * Authenticates the user using the CRAM-MD5 method. * @@ -495,7 +495,7 @@ function _authCRAM_MD5($uid, $pwd) { $this->send_data('AUTH CRAM-MD5'); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) { @@ -508,7 +508,7 @@ $challenge = base64_decode($this->_arguments[0]); $auth_str = base64_encode($uid . ' ' . $this->_HMAC_MD5($pwd, $challenge)); - + $this->send_data($auth_str); /* 235: Authentication successful */ @@ -531,7 +531,7 @@ function _authLogin($uid, $pwd) { $this->send_data('AUTH LOGIN'); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) { @@ -541,12 +541,12 @@ } return $error; } - + $this->send_data( base64_encode($uid) ); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) return $error; - + $this->send_data( base64_encode($pwd) ); /* 235: Authentication successful */ @@ -569,7 +569,7 @@ function _authPlain($uid, $pwd) { $this->send_data('AUTH PLAIN'); - + /* 334: Continue authentication request */ if(($error=$this->_parseResponse(334)) !== true) { @@ -602,22 +602,22 @@ if (strlen($key) > 64) { $key = pack('H32', md5($key)); } - + if (strlen($key) < 64) { $key = str_pad($key, 64, chr(0)); } - + $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); - + $inner = pack('H32', md5($k_ipad . $data)); $digest = md5($k_opad . $inner); - + return $digest; } - + /** * Read a reply from the SMTP server. The reply consists of a response * code and a response message. @@ -639,43 +639,43 @@ global $CRLF; $this->_code = -1; $this->_arguments = array(); - + if(!is_resource($this->connection)) return false; - + while ($line = fgets($this->connection, 512)) { if ($this->debug) { echo "DEBUG: Recv: $line
\n"; } - + /* If we receive an empty line, the connection has been closed. */ if (empty($line)) { $this->disconnect(); return 'Connection was unexpectedly closed'; } - + /* Read the code and store the rest in the arguments array. */ $code = substr($line, 0, 3); $this->_arguments[] = trim(substr($line, 4)); - + /* Check the syntax of the response code. */ if (is_numeric($code)) { $this->_code = (int)$code; } else { $this->_code = -1; break; } - + /* If this is not a multiline response, we're done. */ if (substr($line, 3, 1) != '-') { break; } } - + /* Compare the server's response code with the valid code. */ if (is_int($valid) && ($this->_code === $valid)) { return true; } - + /* If we were given an array of valid response codes, check each one. */ if (is_array($valid)) { foreach ($valid as $valid_code) { @@ -684,15 +684,15 @@ } } } - + return 'Invalid response code received from server'; } - + /*************************************** ** Function that handles the MAIL FROM: cmd ***************************************/ - + function mail($from){ if($this->is_connected() @@ -708,7 +708,7 @@ /*************************************** ** Function that handles the RCPT TO: cmd ***************************************/ - + function rcpt($to){ if($this->is_connected() @@ -732,7 +732,7 @@ if($this->is_connected() AND $this->send_data('DATA') AND substr(trim($error = $this->get_data()), 0, 3) === '354' ){ - + return TRUE; }else{ @@ -767,12 +767,12 @@ return FALSE; } - function bytes_left($fp) - { + function bytes_left($fp) + { $status = socket_get_status ($fp); //print_r($status); $bytes = $status["unread_bytes"]; - return $bytes; + return $bytes; } /*************************************** @@ -786,13 +786,13 @@ if(is_resource($this->connection)) { while(strpos($return, $CRLF) === FALSE OR substr($line,3,1) !== ' ') - { + { $line = fgets($this->connection, 512); - $return .= $line; + $return .= $line; } if($this->debug) { - $this->buffer[] = "GET: ".$return."
\n"; + $this->buffer[] = "GET: ".$return."
\n"; } return $return; @@ -803,16 +803,16 @@ /*************************************** ** Sets a variable ***************************************/ - + function set($var, $value){ $this->$var = $value; return TRUE; } } // End of class - - - - + + + + ?> Index: trunk/kernel/include/emailmessage.php =================================================================== diff -u -r3508 -r3515 --- trunk/kernel/include/emailmessage.php (.../emailmessage.php) (revision 3508) +++ trunk/kernel/include/emailmessage.php (.../emailmessage.php) (revision 3515) @@ -709,121 +709,120 @@ return true; } - function DeliverMail($To,$From,$Subject,$Msg,$headers, $ForceSend=0) - { - global $MessagesSent,$objConfig; + function DeliverMail($To,$From,$Subject,$Msg,$headers, $ForceSend=0) + { + global $MessagesSent,$objConfig; - if(($this->MessagesSent >$this->MessagesAtOnce) && !$ForceSend) - { - $this->EnqueueMail($To,$From,$Subject,$Msg,$headers); - return TRUE; - } - else - { + if(($this->MessagesSent >$this->MessagesAtOnce) && !$ForceSend) + { + $this->EnqueueMail($To,$From,$Subject,$Msg,$headers); + return TRUE; + } + else + { + $this->MessagesSent++; - $this->MessagesSent++; + $time = adodb_mktime(); + $conn = &GetADODBConnection(); - $time = adodb_mktime(); - $conn = &GetADODBConnection(); + /* $sql = "INSERT INTO ".GetTablePrefix()."EmailLog VALUES ('', '".htmlspecialchars($From)."', '".htmlspecialchars($To)."', '$Subject', $time, '')"; + $conn->Execute($sql);*/ + /* ensure headers are using \n instead of \n */ -/* $sql = "INSERT INTO ".GetTablePrefix()."EmailLog VALUES ('', '".htmlspecialchars($From)."', '".htmlspecialchars($To)."', '$Subject', $time, '')"; - $conn->Execute($sql);*/ - /* ensure headers are using \r\n instead of \n */ + $headers = "Date: ".adodb_date("r")."\n".$headers; + $headers = "Return-Path: ".$objConfig->Get("Smtp_AdminMailFrom")."\n".$headers; - $headers = "Date: ".adodb_date("r")."\n".$headers; - $headers = "Return-Path: ".$objConfig->Get("Smtp_AdminMailFrom")."\n".$headers; + $headers = str_replace("\n\n","\r\n\r\n",$headers); + $headers = str_replace("\r\n","\n",$headers); + //$headers = str_replace("\n","\r\n",$headers); - $headers = str_replace("\n\n","\r\n\r\n",$headers); - $headers = str_replace("\r\n","\n",$headers); - //$headers = str_replace("\n","\r\n",$headers); + // if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) { + $Msg = str_replace("\n\n","\r\n\r\n",$Msg); + $Msg = str_replace("\r\n","\n",$Msg); + //$Msg = str_replace("\n","\r\n",$Msg); + // } - // if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) { - $Msg = str_replace("\n\n","\r\n\r\n",$Msg); - $Msg = str_replace("\r\n","\n",$Msg); - //$Msg = str_replace("\n","\r\n",$Msg); - // } + //echo "
"; print_r(htmlentities($headers)); echo "
"; + //echo "
"; print_r(htmlentities($Msg)); echo "
"; + $ver = phpversion(); + if(substr($Subject,0,9)=="Subject: ") + $Subject = substr($Subject,9); + if(!strlen($objConfig->Get("Smtp_Server")) || !$this->AllowSockets()) + { + return mail($To,trim($Subject),$Msg, $headers); + } - //echo "
"; print_r(htmlentities($headers)); echo "
"; - //echo "
"; print_r(htmlentities($Msg)); echo "
"; - $ver = phpversion(); - if(substr($Subject,0,9)=="Subject: ") - $Subject = substr($Subject,9); - if(!strlen($objConfig->Get("Smtp_Server")) || !$this->AllowSockets()) - { - return mail($To,trim($Subject),$Msg, $headers); - } + $headers = "Subject: ".trim($Subject)."\n".$headers; - $headers = "Subject: ".trim($Subject)."\n".$headers; + $send_params['recipients'] = array($To); // The recipients (can be multiple) + $send_params['from'] = $From; // This is used as in the MAIL FROM: cmd + $send_params['headers'] = explode("\n",$headers); + // It should end up as the Return-Path: header + $send_params['body'] = $Msg; // The body of the email - $send_params['recipients'] = array($To); // The recipients (can be multiple) - $send_params['from'] = $From; // This is used as in the MAIL FROM: cmd - $send_params['headers'] = explode("\n",$headers); - // It should end up as the Return-Path: header - $send_params['body'] = $Msg; // The body of the email + $params['host'] = $objConfig->Get("Smtp_Server"); // The smtp server host/ip - $params['host'] = $objConfig->Get("Smtp_Server"); // The smtp server host/ip + $params['port'] = 25; // The smtp server port + $params['hello'] = 'INPORTAL'; // What to use when sending the helo command. Typically, your domain/hostname + if($objConfig->Get("Smtp_Authenticate")) // Whether to use basic authentication or not + { + $params['auth'] = TRUE; + $params['user'] = $objConfig->Get("Smtp_User"); + $params['pass'] = $objConfig->get("Smtp_Pass"); + } + else + $params['auth'] = FALSE; + $this->LogLevel=0; + $SmtpServer = new smtp($params); + if($this->LogLevel>0) + { + $SmtpServer->debug=1; + foreach($params as $key=>$value) + { + $this->WriteToMailLog($key."=".$value); + } + } + else + { + //$SmtpServer->debug = 1; + } + $connected = $SmtpServer->connect(); - $params['port'] = 25; // The smtp server port - $params['hello'] = 'INPORTAL'; // What to use when sending the helo command. Typically, your domain/hostname - if($objConfig->Get("Smtp_Authenticate")) // Whether to use basic authentication or not - { - $params['auth'] = TRUE; - $params['user'] = $objConfig->Get("Smtp_User"); - $params['pass'] = $objConfig->get("Smtp_Pass"); - } - else - $params['auth'] = FALSE; - $this->LogLevel=0; - $SmtpServer = new smtp($params); - if($this->LogLevel>0) - { - $SmtpServer->debug=1; - foreach($params as $key=>$value) - { - $this->WriteToMailLog($key."=".$value); - } - } - else - { - //$SmtpServer->debug = 1; - } - $connected = $SmtpServer->connect(); + if($connected) + { + if($this->LogLevel>1) + { + $this->WriteToMailLog("Connected to ".$params['host']); + } + $res = $SmtpServer->send($send_params); + } + $SmtpServer->disconnect(); - if($connected) - { - if($this->LogLevel>1) - { - $this->WriteToMailLog("Connected to ".$params['host']); - } - $res = $SmtpServer->send($send_params); - } - $SmtpServer->disconnect(); + if($this->LogLevel>1) + { + foreach($SmtpServer->buffer as $l) + { + $this->WriteToMailLog($l); + } + } - if($this->LogLevel>1) - { - foreach($SmtpServer->buffer as $l) - { - $this->WriteToMailLog($l); - } - } + if($this->LogLevel>0) + { + if(count($SmtpServer->errors)>0) + { + foreach($SmtpServer->errors as $e) + { + $this->WriteToMailLog($e); + } + } + else + $this->WriteToMailLog("Message to $From Delivered Successfully"); + } + unset($SmtpServer); + return $res; + } + } - if($this->LogLevel>0) - { - if(count($SmtpServer->errors)>0) - { - foreach($SmtpServer->errors as $e) - { - $this->WriteToMailLog($e); - } - } - else - $this->WriteToMailLog("Message to $From Delivered Successfully"); - } - unset($SmtpServer); - return $res; - } - } - function EnqueueMail($To,$From,$Subject,$Msg,$headers) { global $objSession; @@ -877,12 +876,21 @@ { $HasFile = FALSE; $HasFile = (strlen($FileName)>0); - $OB="----=_OuterBoundary_000"; + $OB="----=_OuterBoundary_000".md5( uniqid (rand())); $boundary = "-----=".md5( uniqid (rand())); $f = "\"$FromName\" <".$From.">"; - $headers = "From: $f\r\n"; - $headers .= "MIME-Version: 1.0\r\n"; + $headers = "From: $f\n"; + if(strlen($ToName)>0) + { + $To = "\"$ToName\" <$ToAddr>"; + } + else { + $To = "<".$ToAddr.">"; + } + $headers.="To: $To\n"; + $headers .= "MIME-Version: 1.0\n"; + $conn = &GetADODBConnection(); $time = adodb_mktime(); @@ -898,55 +906,55 @@ $sql = "INSERT INTO ".GetTablePrefix()."EmailLog VALUES ('', ".$conn->qstr($FromName).", ".$conn->qstr($sendTo).", ".$conn->qstr( str_replace("Subject:", "", $Subject) ).", $time, '$SendEvent')"; $conn->Execute($sql); + $msg .="This is a multi-part message in MIME format.\n\n"; if($HasFile) { //Messages start with text/html alternatives in OB - $headers.="Content-Type: multipart/mixed;\r\n\tboundary=\"".$OB."\"\r\n\r\n"; + $headers.="Content-Type: multipart/mixed;\n\tboundary=\"".$OB."\"\n\n"; $msg.="--".$OB."\n"; - $msg.="Content-Type: multipart/alternative; boundary=\"$boundary\"\r\n\r\n"; + $msg.="Content-Type: multipart/alternative; boundary=\"$boundary\"\n\n\n"; } - else - $headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\""; + else { + $headers .= "Content-Type: multipart/alternative; boundary=\"$boundary\"\n"; + } if(is_array($extra_headers)) { for($i=0;$i0) { $msg .= "--" . $boundary . "\n"; $msg .= "Content-Type: text/html; charset=\"iso-8859-1\"\n"; - $msg .= "Content-Transfer-Encoding: 8bit\r\n\r\n"; + $msg .= "Content-Transfer-Encoding: 8bit\n\n"; $msg .= stripslashes($Html); - $msg .= "\r\n\r\n"; + $msg .= "\n\n"; } - $msg .= "--" . $boundary . "--\n\r"; + $msg .= "--" . $boundary . "--\n"; if($HasFile) { if(!strlen($FileLoc)) { $FileLoc = $FileName; } $FileName = basename($FileName); $msg .= "\n--".$OB."\n"; - $msg.="Content-Type: application/octetstream;\n\tname=\"".$FileName."\"\r\n"; + $msg.="Content-Type: application/octetstream;\n\tname=\"".$FileName."\"\n"; $msg.="Content-Transfer-Encoding: base64\n"; - $msg.="Content-Disposition: attachment;\n\tfilename=\"".$FileName."\"\r\n\r\n"; + $msg.="Content-Disposition: attachment;\n\tfilename=\"".$FileName."\"\n\n"; //file goes here $fd=fopen ($FileLoc, "r"); @@ -956,19 +964,10 @@ fclose ($fd); } $FileContent=chunk_split(base64_encode($FileContent)); - $msg .= $FileContent; - $msg .= $OB."--\r\n"; + $msg .= $FileContent."\n"; + $msg .= "--".$OB."--\n"; } - if(strlen($ToName)>0) - { - $To = "\"$ToName\" <$ToAddr>"; - } - else { - $To = "<".$ToAddr.">"; - } - - //$headers.="To: $To\r\n"; if($this->MessagesSent>$this->MessagesAtOnce || $QueueOnly==1) { $this->EnqueueMail($ToAddr,$From,$Subject,$msg,$headers);