Changeset 50397 for trunk/src/wp-includes/PHPMailer/SMTP.php
- Timestamp:
- 02/21/2021 09:32:41 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/PHPMailer/SMTP.php
r49713 r50397 36 36 * @var string 37 37 */ 38 const VERSION = '6. 2.0';38 const VERSION = '6.3.0'; 39 39 40 40 /** … … 313 313 public function connect($host, $port = null, $timeout = 30, $options = []) 314 314 { 315 // 315 //Clear errors to avoid confusion 316 316 $this->setError(''); 317 // 317 //Make sure we are __not__ connected 318 318 if ($this->connected()) { 319 // 319 //Already connected, generate error 320 320 $this->setError('Already connected to a server'); 321 321 … … 325 325 $port = self::DEFAULT_PORT; 326 326 } 327 // 327 //Connect to the SMTP server 328 328 $this->edebug( 329 329 "Connection: opening to $host:$port, timeout=$timeout, options=" . … … 341 341 $this->edebug('Connection: opened', self::DEBUG_CONNECTION); 342 342 343 // 343 //Get any announcement 344 344 $this->last_reply = $this->get_lines(); 345 345 $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); 346 347 return true; 346 $responseCode = (int)substr($this->last_reply, 0, 3); 347 if ($responseCode === 220) { 348 return true; 349 } 350 //Anything other than a 220 response means something went wrong 351 //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error 352 //https://tools.ietf.org/html/rfc5321#section-3.1 353 if ($responseCode === 554) { 354 $this->quit(); 355 } 356 //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down) 357 $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION); 358 $this->close(); 359 return false; 348 360 } 349 361 … … 398 410 } 399 411 400 // 412 //Verify we connected properly 401 413 if (!is_resource($connection)) { 402 414 $this->setError( … … 415 427 } 416 428 417 // 418 // 429 //SMTP server can take longer to respond, give longer timeout for first read 430 //Windows does not have support for this timeout function 419 431 if (strpos(PHP_OS, 'WIN') !== 0) { 420 432 $max = (int)ini_get('max_execution_time'); 421 // 433 //Don't bother if unlimited, or if set_time_limit is disabled 422 434 if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) { 423 435 @set_time_limit($timeout); … … 450 462 } 451 463 452 // 464 //Begin encrypted connection 453 465 set_error_handler([$this, 'errorHandler']); 454 466 $crypto_ok = stream_socket_enable_crypto( … … 488 500 489 501 if (array_key_exists('EHLO', $this->server_caps)) { 490 // 502 //SMTP extensions are available; try to find a proper authentication method 491 503 if (!array_key_exists('AUTH', $this->server_caps)) { 492 504 $this->setError('Authentication is not allowed at this stage'); 493 // 494 // 505 //'at this stage' means that auth may be allowed after the stage changes 506 //e.g. after STARTTLS 495 507 496 508 return false; … … 536 548 switch ($authtype) { 537 549 case 'PLAIN': 538 // 550 //Start authentication 539 551 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { 540 552 return false; 541 553 } 542 // 554 //Send encoded username and password 543 555 if ( 544 556 !$this->sendCommand( … … 552 564 break; 553 565 case 'LOGIN': 554 // 566 //Start authentication 555 567 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { 556 568 return false; … … 564 576 break; 565 577 case 'CRAM-MD5': 566 // 578 //Start authentication 567 579 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { 568 580 return false; 569 581 } 570 // 582 //Get the challenge 571 583 $challenge = base64_decode(substr($this->last_reply, 4)); 572 584 573 // 585 //Build the response 574 586 $response = $username . ' ' . $this->hmac($challenge, $password); 575 587 576 // 588 //send encoded credentials 577 589 return $this->sendCommand('Username', base64_encode($response), 235); 578 590 case 'XOAUTH2': … … 583 595 $oauth = $OAuth->getOauth64(); 584 596 585 // 597 //Start authentication 586 598 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { 587 599 return false; … … 613 625 } 614 626 615 // 616 // 617 618 // 619 // 620 // 621 // 622 623 $bytelen = 64; // 627 //The following borrowed from 628 //http://php.net/manual/en/function.mhash.php#27225 629 630 //RFC 2104 HMAC implementation for php. 631 //Creates an md5 HMAC. 632 //Eliminates the need to install mhash to compute a HMAC 633 //by Lance Rushing 634 635 $bytelen = 64; //byte length for md5 624 636 if (strlen($key) > $bytelen) { 625 637 $key = pack('H*', md5($key)); … … 644 656 $sock_status = stream_get_meta_data($this->smtp_conn); 645 657 if ($sock_status['eof']) { 646 // 658 //The socket is valid but we are not connected 647 659 $this->edebug( 648 660 'SMTP NOTICE: EOF caught while checking if connected', … … 654 666 } 655 667 656 return true; // 668 return true; //everything looks good 657 669 } 658 670 … … 672 684 $this->helo_rply = null; 673 685 if (is_resource($this->smtp_conn)) { 674 // close the connection and cleanup686 //Close the connection and cleanup 675 687 fclose($this->smtp_conn); 676 688 $this->smtp_conn = null; //Makes for cleaner serialization … … 707 719 */ 708 720 709 // 721 //Normalize line breaks before exploding 710 722 $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); 711 723 … … 753 765 //Send the lines to the server 754 766 foreach ($lines_out as $line_out) { 755 //RFC2821 section 4.5.2 767 //Dot-stuffing as per RFC5321 section 4.5.2 768 //https://tools.ietf.org/html/rfc5321#section-4.5.2 756 769 if (!empty($line_out) && $line_out[0] === '.') { 757 770 $line_out = '.' . $line_out; … … 787 800 { 788 801 //Try extended hello first (RFC 2821) 789 return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host); 802 if ($this->sendHello('EHLO', $host)) { 803 return true; 804 } 805 806 //Some servers shut down the SMTP service here (RFC 5321) 807 if (substr($this->helo_rply, 0, 3) == '421') { 808 return false; 809 } 810 811 return $this->sendHello('HELO', $host); 790 812 } 791 813 … … 977 999 978 1000 $this->last_reply = $this->get_lines(); 979 // 1001 //Fetch SMTP code and possible error code explanation 980 1002 $matches = []; 981 1003 if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) { 982 1004 $code = (int) $matches[1]; 983 1005 $code_ex = (count($matches) > 2 ? $matches[2] : null); 984 // 1006 //Cut off error code from each response line 985 1007 $detail = preg_replace( 986 1008 "/{$code}[ -]" . … … 990 1012 ); 991 1013 } else { 992 // 1014 //Fall back to simple parsing if regex fails 993 1015 $code = (int) substr($this->last_reply, 0, 3); 994 1016 $code_ex = null; … … 1185 1207 protected function get_lines() 1186 1208 { 1187 // 1209 //If the connection is bad, give up straight away 1188 1210 if (!is_resource($this->smtp_conn)) { 1189 1211 return ''; … … 1238 1260 $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); 1239 1261 $data .= $str; 1240 // 1241 // 1242 // 1262 //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled), 1263 //or 4th character is a space or a line break char, we are done reading, break the loop. 1264 //String array access is a significant micro-optimisation over strlen 1243 1265 if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") { 1244 1266 break; 1245 1267 } 1246 // 1268 //Timed-out? Log and break 1247 1269 $info = stream_get_meta_data($this->smtp_conn); 1248 1270 if ($info['timed_out']) { … … 1253 1275 break; 1254 1276 } 1255 // 1277 //Now check if reads took too long 1256 1278 if ($endtime && time() > $endtime) { 1257 1279 $this->edebug(
Note: See TracChangeset
for help on using the changeset viewer.