Ticket #37210: 0001-Upgrade-PHPMailer-from-5.2.14-to-5.2.19.patch
| File 0001-Upgrade-PHPMailer-from-5.2.14-to-5.2.19.patch, 31.6 KB (added by , 9 years ago) |
|---|
-
wp-includes/class-phpmailer.php
From 485b44a703e97f2fd72801543777df6a64768d0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Faria?= <sergio91pt@gmail.com> Date: Tue, 27 Dec 2016 12:40:08 +0000 Subject: [PATCH] Upgrade PHPMailer from 5.2.14 to 5.2.19 Merged update with conflicts. Fixes CVE-2016-10033. --- wp-includes/class-phpmailer.php | 229 +++++++++++++++++++++++++++++----------- wp-includes/class-smtp.php | 82 ++++++++++++-- 2 files changed, 240 insertions(+), 71 deletions(-) diff --git a/wp-includes/class-phpmailer.php b/wp-includes/class-phpmailer.php index 2c481c0..6230829 100644
a b class PHPMailer 31 31 * The PHPMailer Version number. 32 32 * @var string 33 33 */ 34 public $Version = '5.2.1 4';34 public $Version = '5.2.19'; 35 35 36 36 /** 37 37 * Email priority. … … class PHPMailer 201 201 /** 202 202 * An ID to be used in the Message-ID header. 203 203 * If empty, a unique id will be generated. 204 * You can set your own, but it must be in the format "<id@domain>", 205 * as defined in RFC5322 section 3.6.4 or it will be ignored. 206 * @see https://tools.ietf.org/html/rfc5322#section-3.6.4 204 207 * @var string 205 208 */ 206 209 public $MessageID = ''; … … class PHPMailer 352 355 /** 353 356 * Whether to split multiple to addresses into multiple messages 354 357 * or send them all in one message. 358 * Only supported in `mail` and `sendmail` transports, not in SMTP. 355 359 * @var boolean 356 360 */ 357 361 public $SingleTo = false; … … class PHPMailer 394 398 395 399 /** 396 400 * DKIM Identity. 397 * Usually the email address used as the source of the email 401 * Usually the email address used as the source of the email. 398 402 * @var string 399 403 */ 400 404 public $DKIM_identity = ''; … … class PHPMailer 420 424 public $DKIM_private = ''; 421 425 422 426 /** 427 * DKIM private key string. 428 * If set, takes precedence over `$DKIM_private`. 429 * @var string 430 */ 431 public $DKIM_private_string = ''; 432 433 /** 423 434 * Callback Action function name. 424 435 * 425 436 * The function that handles the result of the send email action. … … class PHPMailer 447 458 public $XMailer = ''; 448 459 449 460 /** 461 * Which validator to use by default when validating email addresses. 462 * May be a callable to inject your own validator, but there are several built-in validators. 463 * @see PHPMailer::validateAddress() 464 * @var string|callable 465 * @static 466 */ 467 public static $validator = 'auto'; 468 469 /** 450 470 * An instance of the SMTP sender class. 451 471 * @var SMTP 452 472 * @access protected … … class PHPMailer 634 654 * Constructor. 635 655 * @param boolean $exceptions Should we throw external exceptions? 636 656 */ 637 public function __construct($exceptions = false)657 public function __construct($exceptions = null) 638 658 { 639 $this->exceptions = (boolean)$exceptions; 659 if ($exceptions !== null) { 660 $this->exceptions = (boolean)$exceptions; 661 } 640 662 } 641 663 642 664 /** … … class PHPMailer 645 667 public function __destruct() 646 668 { 647 669 //Close any open SMTP connection nicely 648 if ($this->Mailer == 'smtp') { 649 $this->smtpClose(); 650 } 670 $this->smtpClose(); 651 671 } 652 672 653 673 /** … … class PHPMailer 671 691 } else { 672 692 $subject = $this->encodeHeader($this->secureHeader($subject)); 673 693 } 674 if (ini_get('safe_mode') || !($this->UseSendmailOptions)) { 694 695 //Can't use additional_parameters in safe_mode, calling mail() with null params breaks 696 //@link http://php.net/manual/en/function.mail.php 697 if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) { 675 698 $result = @mail($to, $subject, $body, $header); 676 699 } else { 677 700 $result = @mail($to, $subject, $body, $header, $params); 678 701 } 679 702 return $result; 680 703 } 681 682 704 /** 683 705 * Output debugging info via user-defined method. 684 706 * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug). … … class PHPMailer 713 735 case 'echo': 714 736 default: 715 737 //Normalize line breaks 716 $str = preg_replace('/ (\r\n|\r|\n)/ms', "\n", $str);738 $str = preg_replace('/\r\n?/ms', "\n", $str); 717 739 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace( 718 740 "\n", 719 741 "\n \t ", … … class PHPMailer 850 872 $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim 851 873 if (($pos = strrpos($address, '@')) === false) { 852 874 // At-sign is misssing. 853 $error_message = $this->lang('invalid_address') . $address;875 $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address"; 854 876 $this->setError($error_message); 855 877 $this->edebug($error_message); 856 878 if ($this->exceptions) { … … class PHPMailer 900 922 return false; 901 923 } 902 924 if (!$this->validateAddress($address)) { 903 $error_message = $this->lang('invalid_address') . $address;925 $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address"; 904 926 $this->setError($error_message); 905 927 $this->edebug($error_message); 906 928 if ($this->exceptions) { … … class PHPMailer 939 961 if (($pos = strrpos($address, '@')) === false or 940 962 (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and 941 963 !$this->validateAddress($address)) { 942 $error_message = $this->lang('invalid_address') . $address;964 $error_message = $this->lang('invalid_address') . " (setFrom) $address"; 943 965 $this->setError($error_message); 944 966 $this->edebug($error_message); 945 967 if ($this->exceptions) { … … class PHPMailer 972 994 /** 973 995 * Check that a string looks like an email address. 974 996 * @param string $address The email address to check 975 * @param string $patternselect A selector for the validation pattern to use :997 * @param string|callable $patternselect A selector for the validation pattern to use : 976 998 * * `auto` Pick best pattern automatically; 977 999 * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14; 978 1000 * * `pcre` Use old PCRE implementation; 979 1001 * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL; 980 1002 * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements. 981 1003 * * `noregex` Don't use a regex: super fast, really dumb. 1004 * Alternatively you may pass in a callable to inject your own validator, for example: 1005 * PHPMailer::validateAddress('user@example.com', function($address) { 1006 * return (strpos($address, '@') !== false); 1007 * }); 1008 * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator. 982 1009 * @return boolean 983 1010 * @static 984 1011 * @access public 985 1012 */ 986 public static function validateAddress($address, $patternselect = 'auto')1013 public static function validateAddress($address, $patternselect = null) 987 1014 { 1015 if (is_null($patternselect)) { 1016 $patternselect = self::$validator; 1017 } 1018 if (is_callable($patternselect)) { 1019 return call_user_func($patternselect, $address); 1020 } 988 1021 //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 989 1022 if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) { 990 1023 return false; … … class PHPMailer 1161 1194 } 1162 1195 $this->$address_kind = $this->punyencodeAddress($this->$address_kind); 1163 1196 if (!$this->validateAddress($this->$address_kind)) { 1164 $error_message = $this->lang('invalid_address') . $this->$address_kind;1197 $error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind; 1165 1198 $this->setError($error_message); 1166 1199 $this->edebug($error_message); 1167 1200 if ($this->exceptions) { … … class PHPMailer 1172 1205 } 1173 1206 1174 1207 // Set whether the message is multipart/alternative 1175 if ( !empty($this->AltBody)) {1208 if ($this->alternativeExists()) { 1176 1209 $this->ContentType = 'multipart/alternative'; 1177 1210 } 1178 1211 … … class PHPMailer 1206 1239 1207 1240 // Sign with DKIM if enabled 1208 1241 if (!empty($this->DKIM_domain) 1209 && !empty($this->DKIM_private)1210 1242 && !empty($this->DKIM_selector) 1211 && file_exists($this->DKIM_private)) { 1243 && (!empty($this->DKIM_private_string) 1244 || (!empty($this->DKIM_private) && file_exists($this->DKIM_private)) 1245 ) 1246 ) { 1212 1247 $header_dkim = $this->DKIM_Add( 1213 1248 $this->MIMEHeader . $this->mailHeader, 1214 1249 $this->encodeHeader($this->secureHeader($this->Subject)), … … class PHPMailer 1274 1309 */ 1275 1310 protected function sendmailSend($header, $body) 1276 1311 { 1277 if ( $this->Sender != '') {1312 if (!empty($this->Sender)) { 1278 1313 if ($this->Mailer == 'qmail') { 1279 1314 $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender)); 1280 1315 } else { … … class PHPMailer 1349 1384 } 1350 1385 $to = implode(', ', $toArr); 1351 1386 1352 if (empty($this->Sender)) {1353 $params = ' ';1354 } else{1355 $params = sprintf('-f%s', $this->Sender);1387 $params = null; 1388 //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver 1389 if (!empty($this->Sender) and $this->validateAddress($this->Sender)) { 1390 $params = sprintf('-f%s', escapeshellarg($this->Sender)); 1356 1391 } 1357 if ( $this->Sender != '' and !ini_get('safe_mode')) {1392 if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) { 1358 1393 $old_from = ini_get('sendmail_from'); 1359 1394 ini_set('sendmail_from', $this->Sender); 1360 1395 } 1361 1396 $result = false; 1362 if ($this->SingleTo &&count($toArr) > 1) {1397 if ($this->SingleTo and count($toArr) > 1) { 1363 1398 foreach ($toArr as $toAddr) { 1364 1399 $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params); 1365 1400 $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From); … … class PHPMailer 1409 1444 if (!$this->smtpConnect($this->SMTPOptions)) { 1410 1445 throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL); 1411 1446 } 1412 if ('' == $this->Sender) { 1413 $smtp_from = $this->From; 1414 } else { 1447 if (!empty($this->Sender) and $this->validateAddress($this->Sender)) { 1415 1448 $smtp_from = $this->Sender; 1449 } else { 1450 $smtp_from = $this->From; 1416 1451 } 1417 1452 if (!$this->smtp->mail($smtp_from)) { 1418 1453 $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError())); … … class PHPMailer 1466 1501 * @throws phpmailerException 1467 1502 * @return boolean 1468 1503 */ 1469 public function smtpConnect($options = array())1504 public function smtpConnect($options = null) 1470 1505 { 1471 1506 if (is_null($this->smtp)) { 1472 1507 $this->smtp = $this->getSMTPInstance(); 1473 1508 } 1474 1509 1510 //If no options are provided, use whatever is set in the instance 1511 if (is_null($options)) { 1512 $options = $this->SMTPOptions; 1513 } 1514 1475 1515 // Already connected? 1476 1516 if ($this->smtp->connected()) { 1477 1517 return true; … … class PHPMailer 1541 1581 if (!$this->smtp->startTLS()) { 1542 1582 throw new phpmailerException($this->lang('connect_host')); 1543 1583 } 1544 // We must resend HELO after tlsnegotiation1584 // We must resend EHLO after TLS negotiation 1545 1585 $this->smtp->hello($hello); 1546 1586 } 1547 1587 if ($this->SMTPAuth) { … … class PHPMailer 1580 1620 */ 1581 1621 public function smtpClose() 1582 1622 { 1583 if ( $this->smtp !== null) {1623 if (is_a($this->smtp, 'SMTP')) { 1584 1624 if ($this->smtp->connected()) { 1585 1625 $this->smtp->quit(); 1586 1626 $this->smtp->close(); … … class PHPMailer 1599 1639 */ 1600 1640 public function setLanguage($langcode = 'en', $lang_path = '') 1601 1641 { 1642 // Backwards compatibility for renamed language codes 1643 $renamed_langcodes = array( 1644 'br' => 'pt_br', 1645 'cz' => 'cs', 1646 'dk' => 'da', 1647 'no' => 'nb', 1648 'se' => 'sv', 1649 ); 1650 1651 if (isset($renamed_langcodes[$langcode])) { 1652 $langcode = $renamed_langcodes[$langcode]; 1653 } 1654 1602 1655 // Define full set of translatable strings in English 1603 1656 $PHPMAILER_LANG = array( 1604 1657 'authenticate' => 'SMTP Error: Could not authenticate.', … … class PHPMailer 1625 1678 // Calculate an absolute path so it can work if CWD is not here 1626 1679 $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR; 1627 1680 } 1681 //Validate $langcode 1682 if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) { 1683 $langcode = 'en'; 1684 } 1628 1685 $foundlang = true; 1629 1686 $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php'; 1630 1687 // There is no English translation file … … class PHPMailer 1918 1975 $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); 1919 1976 } 1920 1977 1921 if ($this->MessageID != '') { 1978 // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 1979 // https://tools.ietf.org/html/rfc5322#section-3.6.4 1980 if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) { 1922 1981 $this->lastMessageID = $this->MessageID; 1923 1982 } else { 1924 1983 $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname()); … … class PHPMailer 2020 2079 */ 2021 2080 public function getSentMIMEMessage() 2022 2081 { 2023 return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody; 2082 return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody; 2083 } 2084 2085 /** 2086 * Create unique ID 2087 * @return string 2088 */ 2089 protected function generateId() { 2090 return md5(uniqid(time())); 2024 2091 } 2025 2092 2026 2093 /** … … class PHPMailer 2034 2101 { 2035 2102 $body = ''; 2036 2103 //Create unique IDs and preset boundaries 2037 $this->uniqueid = md5(uniqid(time()));2104 $this->uniqueid = $this->generateId(); 2038 2105 $this->boundary[1] = 'b1_' . $this->uniqueid; 2039 2106 $this->boundary[2] = 'b2_' . $this->uniqueid; 2040 2107 $this->boundary[3] = 'b3_' . $this->uniqueid; … … class PHPMailer 2050 2117 //Can we do a 7-bit downgrade? 2051 2118 if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) { 2052 2119 $bodyEncoding = '7bit'; 2120 //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit 2053 2121 $bodyCharSet = 'us-ascii'; 2054 2122 } 2055 //If lines are too long, change to quoted-printable transfer encoding 2123 //If lines are too long, and we're not already using an encoding that will shorten them, 2124 //change to quoted-printable transfer encoding for the body part only 2056 2125 if (self::hasLineLongerThanMax($this->Body)) { 2057 $this->Encoding = 'quoted-printable';2058 2126 $bodyEncoding = 'quoted-printable'; 2059 2127 } 2060 2128 2061 2129 $altBodyEncoding = $this->Encoding; 2062 2130 $altBodyCharSet = $this->CharSet; 2063 //Can we do a 7-bit downgrade?2131 //Can we do a 7-bit downgrade? 2064 2132 if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) { 2065 2133 $altBodyEncoding = '7bit'; 2134 //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit 2066 2135 $altBodyCharSet = 'us-ascii'; 2067 } 2068 //If lines are too long, change to quoted-printable transfer encoding 2069 if (self::hasLineLongerThanMax($this->AltBody)) { 2136 } 2137 //If lines are too long, and we're not already using an encoding that will shorten them, 2138 //change to quoted-printable transfer encoding for the alt body part only 2139 if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) { 2070 2140 $altBodyEncoding = 'quoted-printable'; 2071 2141 } 2072 2142 //Use this as a preamble in all multipart message types … … class PHPMailer 2169 2239 $body .= $this->attachAll('attachment', $this->boundary[1]); 2170 2240 break; 2171 2241 default: 2172 // catch case 'plain' and case '' 2173 $body .= $this->encodeString($this->Body, $bodyEncoding); 2242 // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types 2243 //Reset the `Encoding` property in case we changed it for line length reasons 2244 $this->Encoding = $bodyEncoding; 2245 $body .= $this->encodeString($this->Body, $this->Encoding); 2174 2246 break; 2175 2247 } 2176 2248 … … class PHPMailer 2276 2348 2277 2349 /** 2278 2350 * Set the message type. 2279 * PHPMailer only supports some preset message types, 2280 * not arbitrary MIME structures. 2351 * PHPMailer only supports some preset message types, not arbitrary MIME structures. 2281 2352 * @access protected 2282 2353 * @return void 2283 2354 */ … … class PHPMailer 2295 2366 } 2296 2367 $this->message_type = implode('_', $type); 2297 2368 if ($this->message_type == '') { 2369 //The 'plain' message_type refers to the message having a single body element, not that it is plain-text 2298 2370 $this->message_type = 'plain'; 2299 2371 } 2300 2372 } … … class PHPMailer 3209 3281 } 3210 3282 3211 3283 /** 3212 * Create a message from an HTML string. 3213 * Automatically makes modifications for inline images and backgrounds 3214 * and creates a plain-text version by converting the HTML. 3215 * Overwrites any existing values in $this->Body and $this->AltBody 3284 * Create a message body from an HTML string. 3285 * Automatically inlines images and creates a plain-text version by converting the HTML, 3286 * overwriting any existing values in Body and AltBody. 3287 * $basedir is used when handling relative image paths, e.g. <img src="images/a.png"> 3288 * will look for an image file in $basedir/images/a.png and convert it to inline. 3289 * If you don't want to apply these transformations to your HTML, just set Body and AltBody yourself. 3216 3290 * @access public 3217 3291 * @param string $message HTML message string 3218 * @param string $basedir base line directory for path3292 * @param string $basedir base directory for relative paths to images 3219 3293 * @param boolean|callable $advanced Whether to use the internal HTML to text converter 3220 3294 * or your own custom converter @see PHPMailer::html2text() 3221 * @return string $message 3295 * @return string $message The transformed message Body 3222 3296 */ 3223 3297 public function msgHTML($message, $basedir = '', $advanced = false) 3224 3298 { … … class PHPMailer 3241 3315 $message 3242 3316 ); 3243 3317 } 3244 } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[ A-z]+://#', $url)) {3318 } elseif (substr($url, 0, 4) !== 'cid:' && !preg_match('#^[a-z][a-z0-9+.-]*://#i', $url)) { 3245 3319 // Do not change urls for absolute images (thanks to corvuscorax) 3246 3320 // Do not change urls that are already inline images 3247 3321 $filename = basename($url); … … class PHPMailer 3277 3351 // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better 3278 3352 $this->Body = $this->normalizeBreaks($message); 3279 3353 $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); 3280 if ( empty($this->AltBody)) {3354 if (!$this->alternativeExists()) { 3281 3355 $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . 3282 3356 self::CRLF . self::CRLF; 3283 3357 } … … class PHPMailer 3288 3362 * Convert an HTML string into plain text. 3289 3363 * This is used by msgHTML(). 3290 3364 * Note - older versions of this function used a bundled advanced converter 3291 * which was been removed for license reasons in #232 3365 * which was been removed for license reasons in #232. 3292 3366 * Example usage: 3293 3367 * <code> 3294 3368 * // Use default conversion … … class PHPMailer 3588 3662 * @access public 3589 3663 * @param string $signHeader 3590 3664 * @throws phpmailerException 3591 * @return string 3665 * @return string The DKIM signature value 3592 3666 */ 3593 3667 public function DKIM_Sign($signHeader) 3594 3668 { … … class PHPMailer 3598 3672 } 3599 3673 return ''; 3600 3674 } 3601 $privKeyStr = file_get_contents($this->DKIM_private);3602 if ( $this->DKIM_passphrase != '') {3675 $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : file_get_contents($this->DKIM_private); 3676 if ('' != $this->DKIM_passphrase) { 3603 3677 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase); 3604 3678 } else { 3605 $privKey = $privKeyStr;3679 $privKey = openssl_pkey_get_private($privKeyStr); 3606 3680 } 3607 if (openssl_sign($signHeader, $signature, $privKey)) { 3608 return base64_encode($signature); 3681 //Workaround for missing digest algorithms in old PHP & OpenSSL versions 3682 //@link http://stackoverflow.com/a/11117338/333340 3683 if (version_compare(PHP_VERSION, '5.3.0') >= 0 and 3684 in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) { 3685 if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) { 3686 openssl_pkey_free($privKey); 3687 return base64_encode($signature); 3688 } 3689 } else { 3690 $pinfo = openssl_pkey_get_details($privKey); 3691 $hash = hash('sha256', $signHeader); 3692 //'Magic' constant for SHA256 from RFC3447 3693 //@link https://tools.ietf.org/html/rfc3447#page-43 3694 $t = '3031300d060960864801650304020105000420' . $hash; 3695 $pslen = $pinfo['bits'] / 8 - (strlen($t) / 2 + 3); 3696 $eb = pack('H*', '0001' . str_repeat('FF', $pslen) . '00' . $t); 3697 3698 if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) { 3699 openssl_pkey_free($privKey); 3700 return base64_encode($signature); 3701 } 3609 3702 } 3703 openssl_pkey_free($privKey); 3610 3704 return ''; 3611 3705 } 3612 3706 … … class PHPMailer 3623 3717 foreach ($lines as $key => $line) { 3624 3718 list($heading, $value) = explode(':', $line, 2); 3625 3719 $heading = strtolower($heading); 3626 $value = preg_replace('/\s +/', ' ', $value); // Compress useless spaces3720 $value = preg_replace('/\s{2,}/', ' ', $value); // Compress useless spaces 3627 3721 $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value 3628 3722 } 3629 3723 $signHeader = implode("\r\n", $lines); … … class PHPMailer 3661 3755 */ 3662 3756 public function DKIM_Add($headers_line, $subject, $body) 3663 3757 { 3664 $DKIMsignatureType = 'rsa-sha 1'; // Signature & hash algorithms3758 $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms 3665 3759 $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body 3666 3760 $DKIMquery = 'dns/txt'; // Query method 3667 3761 $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) … … class PHPMailer 3669 3763 $headers = explode($this->LE, $headers_line); 3670 3764 $from_header = ''; 3671 3765 $to_header = ''; 3766 $date_header = ''; 3672 3767 $current = ''; 3673 3768 foreach ($headers as $header) { 3674 3769 if (strpos($header, 'From:') === 0) { … … class PHPMailer 3677 3772 } elseif (strpos($header, 'To:') === 0) { 3678 3773 $to_header = $header; 3679 3774 $current = 'to_header'; 3775 } elseif (strpos($header, 'Date:') === 0) { 3776 $date_header = $header; 3777 $current = 'date_header'; 3680 3778 } else { 3681 3779 if (!empty($$current) && strpos($header, ' =?') === 0) { 3682 3780 $$current .= $header; … … class PHPMailer 3687 3785 } 3688 3786 $from = str_replace('|', '=7C', $this->DKIM_QP($from_header)); 3689 3787 $to = str_replace('|', '=7C', $this->DKIM_QP($to_header)); 3788 $date = str_replace('|', '=7C', $this->DKIM_QP($date_header)); 3690 3789 $subject = str_replace( 3691 3790 '|', 3692 3791 '=7C', … … class PHPMailer 3694 3793 ); // Copied header fields (dkim-quoted-printable) 3695 3794 $body = $this->DKIM_BodyC($body); 3696 3795 $DKIMlen = strlen($body); // Length of body 3697 $DKIMb64 = base64_encode(pack('H*', sha1($body))); // Base64 of packed binary SHA-1hash of body3796 $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body 3698 3797 if ('' == $this->DKIM_identity) { 3699 3798 $ident = ''; 3700 3799 } else { … … class PHPMailer 3707 3806 $this->DKIM_selector . 3708 3807 ";\r\n" . 3709 3808 "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" . 3710 "\th=From:To: Subject;\r\n" .3809 "\th=From:To:Date:Subject;\r\n" . 3711 3810 "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" . 3712 3811 "\tz=$from\r\n" . 3713 3812 "\t|$to\r\n" . 3813 "\t|$date\r\n" . 3714 3814 "\t|$subject;\r\n" . 3715 3815 "\tbh=" . $DKIMb64 . ";\r\n" . 3716 3816 "\tb="; 3717 3817 $toSign = $this->DKIM_HeaderC( 3718 3818 $from_header . "\r\n" . 3719 3819 $to_header . "\r\n" . 3820 $date_header . "\r\n" . 3720 3821 $subject_header . "\r\n" . 3721 3822 $dkimhdrs 3722 3823 ); -
wp-includes/class-smtp.php
diff --git a/wp-includes/class-smtp.php b/wp-includes/class-smtp.php index f17ca0f..61056cf 100644
a b class SMTP 30 30 * The PHPMailer SMTP version number. 31 31 * @var string 32 32 */ 33 const VERSION = '5.2.1 4';33 const VERSION = '5.2.19'; 34 34 35 35 /** 36 36 * SMTP line break constant. … … class SMTP 81 81 * @deprecated Use the `VERSION` constant instead 82 82 * @see SMTP::VERSION 83 83 */ 84 public $Version = '5.2.1 4';84 public $Version = '5.2.19'; 85 85 86 86 /** 87 87 * SMTP server port number. … … class SMTP 150 150 */ 151 151 public $Timelimit = 300; 152 152 153 /** 154 * @var array patterns to extract smtp transaction id from smtp reply 155 * Only first capture group will be use, use non-capturing group to deal with it 156 * Extend this class to override this property to fulfil your needs. 157 */ 158 protected $smtp_transaction_id_patterns = array( 159 'exim' => '/[0-9]{3} OK id=(.*)/', 160 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 161 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/' 162 ); 163 153 164 /** 154 165 * The socket for the server connection. 155 166 * @var resource … … class SMTP 206 217 } 207 218 //Avoid clash with built-in function names 208 219 if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { 209 call_user_func($this->Debugoutput, $str, $ this->do_debug);220 call_user_func($this->Debugoutput, $str, $level); 210 221 return; 211 222 } 212 223 switch ($this->Debugoutput) { … … class SMTP 272 283 $errstr = ''; 273 284 if ($streamok) { 274 285 $socket_context = stream_context_create($options); 275 //Suppress errors; connection failures are handled at a higher level276 $this->smtp_conn = @stream_socket_client(286 set_error_handler(array($this, 'errorHandler')); 287 $this->smtp_conn = stream_socket_client( 277 288 $host . ":" . $port, 278 289 $errno, 279 290 $errstr, … … class SMTP 281 292 STREAM_CLIENT_CONNECT, 282 293 $socket_context 283 294 ); 295 restore_error_handler(); 284 296 } else { 285 297 //Fall back to fsockopen which should work in more places, but is missing some features 286 298 $this->edebug( 287 299 "Connection: stream_socket_client not available, falling back to fsockopen", 288 300 self::DEBUG_CONNECTION 289 301 ); 302 set_error_handler(array($this, 'errorHandler')); 290 303 $this->smtp_conn = fsockopen( 291 304 $host, 292 305 $port, … … class SMTP 294 307 $errstr, 295 308 $timeout 296 309 ); 310 restore_error_handler(); 297 311 } 298 312 // Verify we connected properly 299 313 if (!is_resource($this->smtp_conn)) { … … class SMTP 336 350 if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { 337 351 return false; 338 352 } 353 354 //Allow the best TLS version(s) we can 355 $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT; 356 357 //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT 358 //so add them back in manually if we can 359 if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { 360 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; 361 $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; 362 } 363 339 364 // Begin encrypted connection 340 365 if (!stream_socket_enable_crypto( 341 366 $this->smtp_conn, 342 367 true, 343 STREAM_CRYPTO_METHOD_TLS_CLIENT368 $crypto_method 344 369 )) { 345 370 return false; 346 371 } … … class SMTP 673 698 protected function parseHelloFields($type) 674 699 { 675 700 $this->server_caps = array(); 676 $lines = explode("\n", $this-> last_reply);701 $lines = explode("\n", $this->helo_rply); 677 702 678 703 foreach ($lines as $n => $s) { 679 704 //First 4 chars contain response code followed by - or space … … class SMTP 1115 1140 { 1116 1141 return $this->Timeout; 1117 1142 } 1143 1144 /** 1145 * Reports an error number and string. 1146 * @param integer $errno The error number returned by PHP. 1147 * @param string $errmsg The error message returned by PHP. 1148 */ 1149 protected function errorHandler($errno, $errmsg) 1150 { 1151 $notice = 'Connection: Failed to connect to server.'; 1152 $this->setError( 1153 $notice, 1154 $errno, 1155 $errmsg 1156 ); 1157 $this->edebug( 1158 $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg, 1159 self::DEBUG_CONNECTION 1160 ); 1161 } 1162 1163 /** 1164 * Will return the ID of the last smtp transaction based on a list of patterns provided 1165 * in SMTP::$smtp_transaction_id_patterns. 1166 * If no reply has been received yet, it will return null. 1167 * If no pattern has been matched, it will return false. 1168 * @return bool|null|string 1169 */ 1170 public function getLastTransactionID() 1171 { 1172 $reply = $this->getLastReply(); 1173 1174 if (empty($reply)) { 1175 return null; 1176 } 1177 1178 foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { 1179 if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) { 1180 return $matches[1]; 1181 } 1182 } 1183 1184 return false; 1185 } 1118 1186 }