X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/53f4633144ed68c8b8fb5861f992b5489894a940..073c5ed6408e2f00dc1863b463fe205467628905:/wp-includes/class-smtp.php
diff --git a/wp-includes/class-smtp.php b/wp-includes/class-smtp.php
index 1eae77a1..3ad08192 100644
--- a/wp-includes/class-smtp.php
+++ b/wp-includes/class-smtp.php
@@ -28,25 +28,25 @@ class SMTP
{
/**
* The PHPMailer SMTP version number.
- * @type string
+ * @var string
*/
- const VERSION = '5.2.10';
+ const VERSION = '5.2.22';
/**
* SMTP line break constant.
- * @type string
+ * @var string
*/
const CRLF = "\r\n";
/**
* The SMTP port to use if one is not specified.
- * @type integer
+ * @var integer
*/
const DEFAULT_SMTP_PORT = 25;
/**
* The maximum line length allowed by RFC 2822 section 2.1.1
- * @type integer
+ * @var integer
*/
const MAX_LINE_LENGTH = 998;
@@ -77,15 +77,15 @@ class SMTP
/**
* The PHPMailer SMTP Version number.
- * @type string
+ * @var string
* @deprecated Use the `VERSION` constant instead
* @see SMTP::VERSION
*/
- public $Version = '5.2.10';
+ public $Version = '5.2.22';
/**
* SMTP server port number.
- * @type integer
+ * @var integer
* @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead
* @see SMTP::DEFAULT_SMTP_PORT
*/
@@ -93,7 +93,7 @@ class SMTP
/**
* SMTP reply line ending.
- * @type string
+ * @var string
* @deprecated Use the `CRLF` constant instead
* @see SMTP::CRLF
*/
@@ -107,7 +107,7 @@ class SMTP
* * self::DEBUG_SERVER (`2`) Client commands and server responses
* * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status
* * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages
- * @type integer
+ * @var integer
*/
public $do_debug = self::DEBUG_OFF;
@@ -122,7 +122,7 @@ class SMTP
*
* $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";};
*
- * @type string|callable
+ * @var string|callable
*/
public $Debugoutput = 'echo';
@@ -130,7 +130,7 @@ class SMTP
* Whether to use VERP.
* @link http://en.wikipedia.org/wiki/Variable_envelope_return_path
* @link http://www.postfix.org/VERP_README.html Info on VERP
- * @type boolean
+ * @var boolean
*/
public $do_verp = false;
@@ -139,26 +139,37 @@ class SMTP
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
* This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.
* @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2
- * @type integer
+ * @var integer
*/
public $Timeout = 300;
/**
* How long to wait for commands to complete, in seconds.
* Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2
- * @type integer
+ * @var integer
*/
public $Timelimit = 300;
+ /**
+ * @var array patterns to extract smtp transaction id from smtp reply
+ * Only first capture group will be use, use non-capturing group to deal with it
+ * Extend this class to override this property to fulfil your needs.
+ */
+ protected $smtp_transaction_id_patterns = array(
+ 'exim' => '/[0-9]{3} OK id=(.*)/',
+ 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',
+ 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
+ );
+
/**
* The socket for the server connection.
- * @type resource
+ * @var resource
*/
protected $smtp_conn;
/**
* Error information, if any, for the last SMTP command.
- * @type array
+ * @var array
*/
protected $error = array(
'error' => '',
@@ -170,7 +181,7 @@ class SMTP
/**
* The reply the server sent to us for HELO.
* If null, no HELO string has yet been received.
- * @type string|null
+ * @var string|null
*/
protected $helo_rply = null;
@@ -181,13 +192,13 @@ class SMTP
* represents the server name. In case of HELO it is the only element of the array.
* Other values can be boolean TRUE or an array containing extension options.
* If null, no HELO/EHLO string has yet been received.
- * @type array|null
+ * @var array|null
*/
protected $server_caps = null;
/**
* The most recent reply received from the server.
- * @type string
+ * @var string
*/
protected $last_reply = '';
@@ -206,7 +217,7 @@ class SMTP
}
//Avoid clash with built-in function names
if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
- call_user_func($this->Debugoutput, $str, $this->do_debug);
+ call_user_func($this->Debugoutput, $str, $level);
return;
}
switch ($this->Debugoutput) {
@@ -272,8 +283,8 @@ class SMTP
$errstr = '';
if ($streamok) {
$socket_context = stream_context_create($options);
- //Suppress errors; connection failures are handled at a higher level
- $this->smtp_conn = @stream_socket_client(
+ set_error_handler(array($this, 'errorHandler'));
+ $this->smtp_conn = stream_socket_client(
$host . ":" . $port,
$errno,
$errstr,
@@ -281,12 +292,14 @@ class SMTP
STREAM_CLIENT_CONNECT,
$socket_context
);
+ restore_error_handler();
} else {
//Fall back to fsockopen which should work in more places, but is missing some features
$this->edebug(
"Connection: stream_socket_client not available, falling back to fsockopen",
self::DEBUG_CONNECTION
);
+ set_error_handler(array($this, 'errorHandler'));
$this->smtp_conn = fsockopen(
$host,
$port,
@@ -294,6 +307,7 @@ class SMTP
$errstr,
$timeout
);
+ restore_error_handler();
}
// Verify we connected properly
if (!is_resource($this->smtp_conn)) {
@@ -336,11 +350,22 @@ class SMTP
if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
return false;
}
+
+ //Allow the best TLS version(s) we can
+ $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+
+ //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
+ //so add them back in manually if we can
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
+ }
+
// Begin encrypted connection
if (!stream_socket_enable_crypto(
$this->smtp_conn,
true,
- STREAM_CRYPTO_METHOD_TLS_CLIENT
+ $crypto_method
)) {
return false;
}
@@ -351,20 +376,21 @@ class SMTP
* Perform SMTP authentication.
* Must be run after hello().
* @see hello()
- * @param string $username The user name
- * @param string $password The password
- * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5)
- * @param string $realm The auth realm for NTLM
+ * @param string $username The user name
+ * @param string $password The password
+ * @param string $authtype The auth type (PLAIN, LOGIN, CRAM-MD5)
+ * @param string $realm The auth realm for NTLM
* @param string $workstation The auth workstation for NTLM
- * @access public
- * @return boolean True if successfully authenticated.
+ * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)
+ * @return bool True if successfully authenticated.* @access public
*/
public function authenticate(
$username,
$password,
$authtype = null,
$realm = '',
- $workstation = ''
+ $workstation = '',
+ $OAuth = null
) {
if (!$this->server_caps) {
$this->setError('Authentication is not allowed before HELO/EHLO');
@@ -388,7 +414,7 @@ class SMTP
);
if (empty($authtype)) {
- foreach (array('LOGIN', 'CRAM-MD5', 'PLAIN') as $method) {
+ foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN') as $method) {
if (in_array($method, $this->server_caps['AUTH'])) {
$authtype = $method;
break;
@@ -672,10 +698,12 @@ class SMTP
protected function parseHelloFields($type)
{
$this->server_caps = array();
- $lines = explode("\n", $this->last_reply);
+ $lines = explode("\n", $this->helo_rply);
+
foreach ($lines as $n => $s) {
+ //First 4 chars contain response code followed by - or space
$s = trim(substr($s, 4));
- if (!$s) {
+ if (empty($s)) {
continue;
}
$fields = explode(' ', $s);
@@ -685,11 +713,20 @@ class SMTP
$fields = $fields[0];
} else {
$name = array_shift($fields);
- if ($name == 'SIZE') {
- $fields = ($fields) ? $fields[0] : 0;
+ switch ($name) {
+ case 'SIZE':
+ $fields = ($fields ? $fields[0] : 0);
+ break;
+ case 'AUTH':
+ if (!is_array($fields)) {
+ $fields = array();
+ }
+ break;
+ default:
+ $fields = true;
}
}
- $this->server_caps[$name] = ($fields ? $fields : true);
+ $this->server_caps[$name] = $fields;
}
}
}
@@ -739,15 +776,15 @@ class SMTP
* Sets the TO argument to $toaddr.
* Returns true if the recipient was accepted false if it was rejected.
* Implements from rfc 821: RCPT TO:
- * @param string $toaddr The address the message is being sent to
+ * @param string $address The address the message is being sent to
* @access public
* @return boolean
*/
- public function recipient($toaddr)
+ public function recipient($address)
{
return $this->sendCommand(
'RCPT TO',
- 'RCPT TO:<' . $toaddr . '>',
+ 'RCPT TO:<' . $address . '>',
array(250, 251)
);
}
@@ -766,9 +803,9 @@ class SMTP
/**
* Send a command to an SMTP server and check its return code.
- * @param string $command The command name - not sent to the server
+ * @param string $command The command name - not sent to the server
* @param string $commandstring The actual command to send
- * @param integer|array $expect One or more expected integer success codes
+ * @param integer|array $expect One or more expected integer success codes
* @access protected
* @return boolean True on success.
*/
@@ -778,6 +815,11 @@ class SMTP
$this->setError("Called $command without being connected");
return false;
}
+ //Reject line breaks in all commands
+ if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
+ $this->setError("Command '$command' contained line breaks");
+ return false;
+ }
$this->client_send($commandstring . self::CRLF);
$this->last_reply = $this->get_lines();
@@ -981,10 +1023,9 @@ class SMTP
}
while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
$str = @fgets($this->smtp_conn, 515);
- $this->edebug("SMTP -> get_lines(): \$data was \"$data\"", self::DEBUG_LOWLEVEL);
- $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
- $data .= $str;
$this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
+ $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
+ $data .= $str;
// If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen
if ((isset($str[3]) and $str[3] == ' ')) {
break;
@@ -1099,4 +1140,47 @@ class SMTP
{
return $this->Timeout;
}
+
+ /**
+ * Reports an error number and string.
+ * @param integer $errno The error number returned by PHP.
+ * @param string $errmsg The error message returned by PHP.
+ */
+ protected function errorHandler($errno, $errmsg)
+ {
+ $notice = 'Connection: Failed to connect to server.';
+ $this->setError(
+ $notice,
+ $errno,
+ $errmsg
+ );
+ $this->edebug(
+ $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg,
+ self::DEBUG_CONNECTION
+ );
+ }
+
+ /**
+ * Will return the ID of the last smtp transaction based on a list of patterns provided
+ * in SMTP::$smtp_transaction_id_patterns.
+ * If no reply has been received yet, it will return null.
+ * If no pattern has been matched, it will return false.
+ * @return bool|null|string
+ */
+ public function getLastTransactionID()
+ {
+ $reply = $this->getLastReply();
+
+ if (empty($reply)) {
+ return null;
+ }
+
+ foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
+ if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
+ return $matches[1];
+ }
+ }
+
+ return false;
+ }
}