X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/baca9ce86a38dc54c4574890ee2d352fd81f78b2..61343b82c4f0da4c68e4c6373daafff4a81efdd1:/wp-includes/class-smtp.php diff --git a/wp-includes/class-smtp.php b/wp-includes/class-smtp.php index 6977bffa..72361bbb 100644 --- a/wp-includes/class-smtp.php +++ b/wp-includes/class-smtp.php @@ -2,7 +2,7 @@ /*~ class.smtp.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 5.2.1 | +| Version: 5.2.4 | | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ | | ------------------------------------------------------------------------- | | Admin: Jim Jagielski (project admininistrator) | @@ -32,15 +32,15 @@ * @author Jim Jagielski * @copyright 2010 - 2012 Jim Jagielski * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) - * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $ */ /** - * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP - * commands except TURN which will always return a not implemented - * error. SMTP also provides some utility methods for sending mail - * to an SMTP server. - * original author: Chris Ryan + * PHP RFC821 SMTP client + * + * Implements all the RFC 821 SMTP commands except TURN which will always return a not implemented error. + * SMTP also provides some utility methods for sending mail to an SMTP server. + * @author Chris Ryan + * @package PHPMailer */ class SMTP { @@ -51,7 +51,7 @@ class SMTP { public $SMTP_PORT = 25; /** - * SMTP reply line ending + * SMTP reply line ending (don't change) * @var string */ public $CRLF = "\r\n"; @@ -62,30 +62,70 @@ class SMTP { */ public $do_debug; // the level of debug to perform + /** + * Sets the function/method to use for debugging output. + * Right now we only honor "echo" or "error_log" + * @var string + */ + public $Debugoutput = "echo"; + /** * Sets VERP use on/off (default is off) * @var bool */ public $do_verp = false; + /** + * Sets the SMTP timeout value for reads, in seconds + * @var int + */ + public $Timeout = 15; + + /** + * Sets the SMTP timelimit value for reads, in seconds + * @var int + */ + public $Timelimit = 30; + /** * Sets the SMTP PHPMailer Version number * @var string */ - public $Version = '5.2.1'; + public $Version = '5.2.4'; ///////////////////////////////////////////////// // PROPERTIES, PRIVATE AND PROTECTED ///////////////////////////////////////////////// - private $smtp_conn; // the socket to the server - private $error; // error if any on the last call - private $helo_rply; // the reply the server sent to us for HELO + /** + * @var resource The socket to the server + */ + private $smtp_conn; + /** + * @var string Error message, if any, for the last call + */ + private $error; + /** + * @var string The reply the server sent to us for HELO + */ + private $helo_rply; + + /** + * Outputs debugging info via user-defined method + * @param string $str + */ + private function edebug($str) { + if ($this->Debugoutput == "error_log") { + error_log($str); + } else { + echo $str; + } + } /** * Initialize the class so that the data is in a known state. * @access public - * @return void + * @return SMTP */ public function __construct() { $this->smtp_conn = 0; @@ -110,6 +150,9 @@ class SMTP { * SMTP CODE SUCCESS: 220 * SMTP CODE FAILURE: 421 * @access public + * @param string $host + * @param int $port + * @param int $tval * @return bool */ public function Connect($host, $port = 0, $tval = 30) { @@ -139,21 +182,26 @@ class SMTP { "errno" => $errno, "errstr" => $errstr); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
'); } return false; } // SMTP server can take longer to respond, give longer timeout for first read // Windows does not have support for this timeout function - if(substr(PHP_OS, 0, 3) != "WIN") - socket_set_timeout($this->smtp_conn, $tval, 0); + if(substr(PHP_OS, 0, 3) != "WIN") { + $max = ini_get('max_execution_time'); + if ($max != 0 && $tval > $max) { // don't bother if unlimited + @set_time_limit($tval); + } + stream_set_timeout($this->smtp_conn, $tval, 0); + } // get any announcement $announce = $this->get_lines(); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
'); } return true; @@ -182,7 +230,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 220) { @@ -191,7 +239,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -208,60 +256,164 @@ class SMTP { * Performs SMTP authentication. Must be run after running the * Hello() method. Returns true if successfully authenticated. * @access public + * @param string $username + * @param string $password + * @param string $authtype + * @param string $realm + * @param string $workstation * @return bool */ - public function Authenticate($username, $password) { - // Start authentication - fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 334) { - $this->error = - array("error" => "AUTH not accepted from server", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; - } - return false; - } - - // Send encoded username - fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 334) { - $this->error = - array("error" => "Username not accepted from server", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; - } - return false; - } - - // Send encoded password - fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 235) { - $this->error = - array("error" => "Password not accepted from server", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; - } - return false; + public function Authenticate($username, $password, $authtype='LOGIN', $realm='', $workstation='') { + if (empty($authtype)) { + $authtype = 'LOGIN'; + } + + switch ($authtype) { + case 'PLAIN': + // Start authentication + fputs($this->smtp_conn,"AUTH PLAIN" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); + } + return false; + } + // Send encoded username and password + fputs($this->smtp_conn, base64_encode("\0".$username."\0".$password) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Authentication not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); + } + return false; + } + break; + case 'LOGIN': + // Start authentication + fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); + } + return false; + } + + // Send encoded username + fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 334) { + $this->error = + array("error" => "Username not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); + } + return false; + } + + // Send encoded password + fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Password not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); + } + return false; + } + break; + case 'NTLM': + /* + * ntlm_sasl_client.php + ** Bundled with Permission + ** + ** How to telnet in windows: http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx + ** PROTOCOL Documentation http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication + */ + require_once('ntlm_sasl_client.php'); + $temp = new stdClass(); + $ntlm_client = new ntlm_sasl_client_class; + if(! $ntlm_client->Initialize($temp)){//let's test if every function its available + $this->error = array("error" => $temp->error); + if($this->do_debug >= 1) { + $this->edebug("You need to enable some modules in your php.ini file: " . $this->error["error"] . $this->CRLF); + } + return false; + } + $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);//msg1 + + fputs($this->smtp_conn,"AUTH NTLM " . base64_encode($msg1) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + + if($code != 334) { + $this->error = + array("error" => "AUTH not accepted from server", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF); + } + return false; + } + + $challange = substr($rply,3);//though 0 based, there is a white space after the 3 digit number....//msg2 + $challange = base64_decode($challange); + $ntlm_res = $ntlm_client->NTLMResponse(substr($challange,24,8),$password); + $msg3 = $ntlm_client->TypeMsg3($ntlm_res,$username,$realm,$workstation);//msg3 + // Send encoded username + fputs($this->smtp_conn, base64_encode($msg3) . $this->CRLF); + + $rply = $this->get_lines(); + $code = substr($rply,0,3); + + if($code != 235) { + $this->error = + array("error" => "Could not authenticate", + "smtp_code" => $code, + "smtp_msg" => substr($rply,4)); + if($this->do_debug >= 1) { + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF); + } + return false; + } + break; } - return true; } @@ -276,7 +428,7 @@ class SMTP { if($sock_status["eof"]) { // the socket is valid but we are not connected if($this->do_debug >= 1) { - echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"; + $this->edebug("SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected"); } $this->Close(); return false; @@ -324,6 +476,7 @@ class SMTP { * SMTP CODE FAILURE: 451,554 * SMTP CODE ERROR : 500,501,503,421 * @access public + * @param string $msg_data * @return bool */ public function Data($msg_data) { @@ -341,7 +494,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 354) { @@ -350,7 +503,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -435,7 +588,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 250) { @@ -444,7 +597,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -461,6 +614,7 @@ class SMTP { * SMTP CODE SUCCESS: 250 * SMTP CODE ERROR : 500, 501, 504, 421 * @access public + * @param string $host * @return bool */ public function Hello($host = '') { @@ -491,6 +645,8 @@ class SMTP { /** * Sends a HELO/EHLO command. * @access private + * @param string $hello + * @param string $host * @return bool */ private function SendHello($hello, $host) { @@ -500,7 +656,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
'); } if($code != 250) { @@ -509,7 +665,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -531,6 +687,7 @@ class SMTP { * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,421 * @access public + * @param string $from * @return bool */ public function Mail($from) { @@ -542,14 +699,14 @@ class SMTP { return false; } - $useVerp = ($this->do_verp ? "XVERP" : ""); + $useVerp = ($this->do_verp ? " XVERP" : ""); fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); $rply = $this->get_lines(); $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 250) { @@ -558,7 +715,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -574,6 +731,7 @@ class SMTP { * SMTP CODE SUCCESS: 221 * SMTP CODE ERROR : 500 * @access public + * @param bool $close_on_error * @return bool */ public function Quit($close_on_error = true) { @@ -592,7 +750,7 @@ class SMTP { $byemsg = $this->get_lines(); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
'); } $rval = true; @@ -606,7 +764,7 @@ class SMTP { "smtp_rply" => substr($byemsg,4)); $rval = false; if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
'); } } @@ -627,6 +785,7 @@ class SMTP { * SMTP CODE FAILURE: 550,551,552,553,450,451,452 * SMTP CODE ERROR : 500,501,503,421 * @access public + * @param string $to * @return bool */ public function Recipient($to) { @@ -644,7 +803,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 250 && $code != 251) { @@ -653,7 +812,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -687,7 +846,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 250) { @@ -696,7 +855,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -718,6 +877,7 @@ class SMTP { * SMTP CODE SUCCESS: 552,451,452 * SMTP CODE SUCCESS: 500,501,502,421 * @access public + * @param string $from * @return bool */ public function SendAndMail($from) { @@ -735,7 +895,7 @@ class SMTP { $code = substr($rply,0,3); if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
'); } if($code != 250) { @@ -744,7 +904,7 @@ class SMTP { "smtp_code" => $code, "smtp_msg" => substr($rply,4)); if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'; + $this->edebug("SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
'); } return false; } @@ -768,7 +928,7 @@ class SMTP { $this->error = array("error" => "This method, TURN, of the SMTP ". "is not implemented"); if($this->do_debug >= 1) { - echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
'; + $this->edebug("SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
'); } return false; } @@ -797,22 +957,47 @@ class SMTP { */ private function get_lines() { $data = ""; - while(!feof($this->smtp_conn)) { + $endtime = 0; + /* If for some reason the fp is bad, don't inf loop */ + if (!is_resource($this->smtp_conn)) { + return $data; + } + stream_set_timeout($this->smtp_conn, $this->Timeout); + if ($this->Timelimit > 0) { + $endtime = time() + $this->Timelimit; + } + while(is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { $str = @fgets($this->smtp_conn,515); if($this->do_debug >= 4) { - echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
'; - echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
'; + $this->edebug("SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
'); + $this->edebug("SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
'); } $data .= $str; if($this->do_debug >= 4) { - echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
'; + $this->edebug("SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
'); } // if 4th character is a space, we are done reading, break the loop if(substr($str,3,1) == " ") { break; } + // Timed-out? Log and break + $info = stream_get_meta_data($this->smtp_conn); + if ($info['timed_out']) { + if($this->do_debug >= 4) { + $this->edebug("SMTP -> get_lines(): timed-out (" . $this->Timeout . " seconds)
"); + } + break; + } + // Now check if reads took too long + if ($endtime) { + if (time() > $endtime) { + if($this->do_debug >= 4) { + $this->edebug("SMTP -> get_lines(): timelimit reached (" . $this->Timelimit . " seconds)
"); + } + break; + } + } } return $data; } } - ?>