Update PHPMailer
							parent
							
								
									94e8b2e6af
								
							
						
					
					
						commit
						406cdcce31
					
				|  | @ -0,0 +1,247 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer - PHP email creation and transport class. | ||||
|  * PHP Version 5.5. | ||||
|  * | ||||
|  * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project | ||||
|  * | ||||
|  * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> | ||||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2023 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  * @note      This program is distributed in the hope that it will be useful - WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| /** | ||||
|  * Configure PHPMailer with DSN string. | ||||
|  * | ||||
|  * @see https://en.wikipedia.org/wiki/Data_source_name | ||||
|  * | ||||
|  * @author Oleg Voronkovich <oleg-voronkovich@yandex.ru> | ||||
|  */ | ||||
| class DSNConfigurator | ||||
| { | ||||
|     /** | ||||
|      * Create new PHPMailer instance configured by DSN. | ||||
|      * | ||||
|      * @param string $dsn        DSN | ||||
|      * @param bool   $exceptions Should we throw external exceptions? | ||||
|      * | ||||
|      * @return PHPMailer | ||||
|      */ | ||||
|     public static function mailer($dsn, $exceptions = null) | ||||
|     { | ||||
|         static $configurator = null; | ||||
| 
 | ||||
|         if (null === $configurator) { | ||||
|             $configurator = new DSNConfigurator(); | ||||
|         } | ||||
| 
 | ||||
|         return $configurator->configure(new PHPMailer($exceptions), $dsn); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Configure PHPMailer instance with DSN string. | ||||
|      * | ||||
|      * @param PHPMailer $mailer PHPMailer instance | ||||
|      * @param string    $dsn    DSN | ||||
|      * | ||||
|      * @return PHPMailer | ||||
|      */ | ||||
|     public function configure(PHPMailer $mailer, $dsn) | ||||
|     { | ||||
|         $config = $this->parseDSN($dsn); | ||||
| 
 | ||||
|         $this->applyConfig($mailer, $config); | ||||
| 
 | ||||
|         return $mailer; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse DSN string. | ||||
|      * | ||||
|      * @param string $dsn DSN | ||||
|      * | ||||
|      * @throws Exception If DSN is malformed | ||||
|      * | ||||
|      * @return array Configuration | ||||
|      */ | ||||
|     private function parseDSN($dsn) | ||||
|     { | ||||
|         $config = $this->parseUrl($dsn); | ||||
| 
 | ||||
|         if (false === $config || !isset($config['scheme']) || !isset($config['host'])) { | ||||
|             throw new Exception( | ||||
|                 sprintf('Malformed DSN: "%s".', $dsn) | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         if (isset($config['query'])) { | ||||
|             parse_str($config['query'], $config['query']); | ||||
|         } | ||||
| 
 | ||||
|         return $config; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Apply configuration to mailer. | ||||
|      * | ||||
|      * @param PHPMailer $mailer PHPMailer instance | ||||
|      * @param array     $config Configuration | ||||
|      * | ||||
|      * @throws Exception If scheme is invalid | ||||
|      */ | ||||
|     private function applyConfig(PHPMailer $mailer, $config) | ||||
|     { | ||||
|         switch ($config['scheme']) { | ||||
|             case 'mail': | ||||
|                 $mailer->isMail(); | ||||
|                 break; | ||||
|             case 'sendmail': | ||||
|                 $mailer->isSendmail(); | ||||
|                 break; | ||||
|             case 'qmail': | ||||
|                 $mailer->isQmail(); | ||||
|                 break; | ||||
|             case 'smtp': | ||||
|             case 'smtps': | ||||
|                 $mailer->isSMTP(); | ||||
|                 $this->configureSMTP($mailer, $config); | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new Exception( | ||||
|                     sprintf( | ||||
|                         'Invalid scheme: "%s". Allowed values: "mail", "sendmail", "qmail", "smtp", "smtps".', | ||||
|                         $config['scheme'] | ||||
|                     ) | ||||
|                 ); | ||||
|         } | ||||
| 
 | ||||
|         if (isset($config['query'])) { | ||||
|             $this->configureOptions($mailer, $config['query']); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Configure SMTP. | ||||
|      * | ||||
|      * @param PHPMailer $mailer PHPMailer instance | ||||
|      * @param array     $config Configuration | ||||
|      */ | ||||
|     private function configureSMTP($mailer, $config) | ||||
|     { | ||||
|         $isSMTPS = 'smtps' === $config['scheme']; | ||||
| 
 | ||||
|         if ($isSMTPS) { | ||||
|             $mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; | ||||
|         } | ||||
| 
 | ||||
|         $mailer->Host = $config['host']; | ||||
| 
 | ||||
|         if (isset($config['port'])) { | ||||
|             $mailer->Port = $config['port']; | ||||
|         } elseif ($isSMTPS) { | ||||
|             $mailer->Port = SMTP::DEFAULT_SECURE_PORT; | ||||
|         } | ||||
| 
 | ||||
|         $mailer->SMTPAuth = isset($config['user']) || isset($config['pass']); | ||||
| 
 | ||||
|         if (isset($config['user'])) { | ||||
|             $mailer->Username = $config['user']; | ||||
|         } | ||||
| 
 | ||||
|         if (isset($config['pass'])) { | ||||
|             $mailer->Password = $config['pass']; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Configure options. | ||||
|      * | ||||
|      * @param PHPMailer $mailer  PHPMailer instance | ||||
|      * @param array     $options Options | ||||
|      * | ||||
|      * @throws Exception If option is unknown | ||||
|      */ | ||||
|     private function configureOptions(PHPMailer $mailer, $options) | ||||
|     { | ||||
|         $allowedOptions = get_object_vars($mailer); | ||||
| 
 | ||||
|         unset($allowedOptions['Mailer']); | ||||
|         unset($allowedOptions['SMTPAuth']); | ||||
|         unset($allowedOptions['Username']); | ||||
|         unset($allowedOptions['Password']); | ||||
|         unset($allowedOptions['Hostname']); | ||||
|         unset($allowedOptions['Port']); | ||||
|         unset($allowedOptions['ErrorInfo']); | ||||
| 
 | ||||
|         $allowedOptions = \array_keys($allowedOptions); | ||||
| 
 | ||||
|         foreach ($options as $key => $value) { | ||||
|             if (!in_array($key, $allowedOptions)) { | ||||
|                 throw new Exception( | ||||
|                     sprintf( | ||||
|                         'Unknown option: "%s". Allowed values: "%s"', | ||||
|                         $key, | ||||
|                         implode('", "', $allowedOptions) | ||||
|                     ) | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             switch ($key) { | ||||
|                 case 'AllowEmpty': | ||||
|                 case 'SMTPAutoTLS': | ||||
|                 case 'SMTPKeepAlive': | ||||
|                 case 'SingleTo': | ||||
|                 case 'UseSendmailOptions': | ||||
|                 case 'do_verp': | ||||
|                 case 'DKIM_copyHeaderFields': | ||||
|                     $mailer->$key = (bool) $value; | ||||
|                     break; | ||||
|                 case 'Priority': | ||||
|                 case 'SMTPDebug': | ||||
|                 case 'WordWrap': | ||||
|                     $mailer->$key = (int) $value; | ||||
|                     break; | ||||
|                 default: | ||||
|                     $mailer->$key = $value; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parse a URL. | ||||
|      * Wrapper for the built-in parse_url function to work around a bug in PHP 5.5. | ||||
|      * | ||||
|      * @param string $url URL | ||||
|      * | ||||
|      * @return array|false | ||||
|      */ | ||||
|     protected function parseUrl($url) | ||||
|     { | ||||
|         if (\PHP_VERSION_ID >= 50600 || false === strpos($url, '?')) { | ||||
|             return parse_url($url); | ||||
|         } | ||||
| 
 | ||||
|         $chunks = explode('?', $url); | ||||
|         if (is_array($chunks)) { | ||||
|             $result = parse_url($chunks[0]); | ||||
|             if (is_array($result)) { | ||||
|                 $result['query'] = $chunks[1]; | ||||
|             } | ||||
|             return $result; | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
|  | @ -1,4 +1,5 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer Exception class. | ||||
|  * PHP Version 5.5. | ||||
|  | @ -9,7 +10,7 @@ | |||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2017 Marcus Bointon | ||||
|  * @copyright 2012 - 2020 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  | @ -18,6 +19,8 @@ | |||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer exception handler. | ||||
|  * | ||||
|  | @ -32,6 +35,6 @@ class Exception extends \Exception | |||
|      */ | ||||
|     public function errorMessage() | ||||
|     { | ||||
|         return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n"; | ||||
|         return '<strong>' . htmlspecialchars($this->getMessage(), ENT_COMPAT | ENT_HTML401) . "</strong><br />\n"; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer - PHP email creation and transport class. | ||||
|  * PHP Version 5.5. | ||||
|  | @ -9,7 +10,7 @@ | |||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2015 Marcus Bointon | ||||
|  * @copyright 2012 - 2020 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  | @ -18,6 +19,8 @@ | |||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| use League\OAuth2\Client\Grant\RefreshToken; | ||||
| use League\OAuth2\Client\Provider\AbstractProvider; | ||||
| use League\OAuth2\Client\Token\AccessToken; | ||||
|  | @ -30,7 +33,7 @@ use League\OAuth2\Client\Token\AccessToken; | |||
|  * | ||||
|  * @author  Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> | ||||
|  */ | ||||
| class OAuth | ||||
| class OAuth implements OAuthTokenProvider | ||||
| { | ||||
|     /** | ||||
|      * An instance of the League OAuth Client Provider. | ||||
|  | @ -120,7 +123,7 @@ class OAuth | |||
|      */ | ||||
|     public function getOauth64() | ||||
|     { | ||||
|         // Get a new token if it's not available or has expired
 | ||||
|         //Get a new token if it's not available or has expired
 | ||||
|         if (null === $this->oauthToken || $this->oauthToken->hasExpired()) { | ||||
|             $this->oauthToken = $this->getToken(); | ||||
|         } | ||||
|  |  | |||
|  | @ -0,0 +1,44 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer - PHP email creation and transport class. | ||||
|  * PHP Version 5.5. | ||||
|  * | ||||
|  * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project | ||||
|  * | ||||
|  * @author    Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> | ||||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2020 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  * @note      This program is distributed in the hope that it will be useful - WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| /** | ||||
|  * OAuthTokenProvider - OAuth2 token provider interface. | ||||
|  * Provides base64 encoded OAuth2 auth strings for SMTP authentication. | ||||
|  * | ||||
|  * @see     OAuth | ||||
|  * @see     SMTP::authenticate() | ||||
|  * | ||||
|  * @author  Peter Scopes (pdscopes) | ||||
|  * @author  Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> | ||||
|  */ | ||||
| interface OAuthTokenProvider | ||||
| { | ||||
|     /** | ||||
|      * Generate a base64-encoded OAuth token ensuring that the access token has not expired. | ||||
|      * The string to be base 64 encoded should be in the form: | ||||
|      * "user=<user_email_address>\001auth=Bearer <access_token>\001\001" | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getOauth64(); | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -1,4 +1,5 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer POP-Before-SMTP Authentication Class. | ||||
|  * PHP Version 5.5. | ||||
|  | @ -9,7 +10,7 @@ | |||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2019 Marcus Bointon | ||||
|  * @copyright 2012 - 2020 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  | @ -18,6 +19,8 @@ | |||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer POP-Before-SMTP Authentication Class. | ||||
|  * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication. | ||||
|  | @ -43,7 +46,7 @@ class POP3 | |||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     const VERSION = '6.1.5'; | ||||
|     const VERSION = '6.8.0'; | ||||
| 
 | ||||
|     /** | ||||
|      * Default POP3 port number. | ||||
|  | @ -60,12 +63,16 @@ class POP3 | |||
|     const DEFAULT_TIMEOUT = 30; | ||||
| 
 | ||||
|     /** | ||||
|      * Debug display level. | ||||
|      * Options: 0 = no, 1+ = yes. | ||||
|      * POP3 class debug output mode. | ||||
|      * Debug output level. | ||||
|      * Options: | ||||
|      * @see POP3::DEBUG_OFF: No output | ||||
|      * @see POP3::DEBUG_SERVER: Server messages, connection/server errors | ||||
|      * @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     public $do_debug = 0; | ||||
|     public $do_debug = self::DEBUG_OFF; | ||||
| 
 | ||||
|     /** | ||||
|      * POP3 mail server hostname. | ||||
|  | @ -128,6 +135,28 @@ class POP3 | |||
|      */ | ||||
|     const LE = "\r\n"; | ||||
| 
 | ||||
|     /** | ||||
|      * Debug level for no output. | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     const DEBUG_OFF = 0; | ||||
| 
 | ||||
|     /** | ||||
|      * Debug level to show server -> client messages | ||||
|      * also shows clients connection errors or errors from server | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     const DEBUG_SERVER = 1; | ||||
| 
 | ||||
|     /** | ||||
|      * Debug level to show client -> server and server -> client messages. | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     const DEBUG_CLIENT = 2; | ||||
| 
 | ||||
|     /** | ||||
|      * Simple static wrapper for all-in-one POP before SMTP. | ||||
|      * | ||||
|  | @ -170,13 +199,13 @@ class POP3 | |||
|     public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) | ||||
|     { | ||||
|         $this->host = $host; | ||||
|         // If no port value provided, use default
 | ||||
|         //If no port value provided, use default
 | ||||
|         if (false === $port) { | ||||
|             $this->port = static::DEFAULT_PORT; | ||||
|         } else { | ||||
|             $this->port = (int) $port; | ||||
|         } | ||||
|         // If no timeout value provided, use default
 | ||||
|         //If no timeout value provided, use default
 | ||||
|         if (false === $timeout) { | ||||
|             $this->tval = static::DEFAULT_TIMEOUT; | ||||
|         } else { | ||||
|  | @ -185,9 +214,9 @@ class POP3 | |||
|         $this->do_debug = $debug_level; | ||||
|         $this->username = $username; | ||||
|         $this->password = $password; | ||||
|         //  Reset the error log
 | ||||
|         //Reset the error log
 | ||||
|         $this->errors = []; | ||||
|         //  connect
 | ||||
|         //Connect
 | ||||
|         $result = $this->connect($this->host, $this->port, $this->tval); | ||||
|         if ($result) { | ||||
|             $login_result = $this->login($this->username, $this->password); | ||||
|  | @ -197,7 +226,7 @@ class POP3 | |||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         // We need to disconnect regardless of whether the login succeeded
 | ||||
|         //We need to disconnect regardless of whether the login succeeded
 | ||||
|         $this->disconnect(); | ||||
| 
 | ||||
|         return false; | ||||
|  | @ -214,7 +243,7 @@ class POP3 | |||
|      */ | ||||
|     public function connect($host, $port = false, $tval = 30) | ||||
|     { | ||||
|         //  Are we already connected?
 | ||||
|         //Are we already connected?
 | ||||
|         if ($this->connected) { | ||||
|             return true; | ||||
|         } | ||||
|  | @ -227,22 +256,22 @@ class POP3 | |||
|             $port = static::DEFAULT_PORT; | ||||
|         } | ||||
| 
 | ||||
|         //  connect to the POP3 server
 | ||||
|         //Connect to the POP3 server
 | ||||
|         $errno = 0; | ||||
|         $errstr = ''; | ||||
|         $this->pop_conn = fsockopen( | ||||
|             $host, //  POP3 Host
 | ||||
|             $port, //  Port #
 | ||||
|             $errno, //  Error Number
 | ||||
|             $errstr, //  Error Message
 | ||||
|             $host, //POP3 Host
 | ||||
|             $port, //Port #
 | ||||
|             $errno, //Error Number
 | ||||
|             $errstr, //Error Message
 | ||||
|             $tval | ||||
|         ); //  Timeout (seconds)
 | ||||
|         //  Restore the error handler
 | ||||
|         ); //Timeout (seconds)
 | ||||
|         //Restore the error handler
 | ||||
|         restore_error_handler(); | ||||
| 
 | ||||
|         //  Did we connect?
 | ||||
|         //Did we connect?
 | ||||
|         if (false === $this->pop_conn) { | ||||
|             //  It would appear not...
 | ||||
|             //It would appear not...
 | ||||
|             $this->setError( | ||||
|                 "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr" | ||||
|             ); | ||||
|  | @ -250,14 +279,14 @@ class POP3 | |||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         //  Increase the stream time-out
 | ||||
|         //Increase the stream time-out
 | ||||
|         stream_set_timeout($this->pop_conn, $tval, 0); | ||||
| 
 | ||||
|         //  Get the POP3 server response
 | ||||
|         //Get the POP3 server response
 | ||||
|         $pop3_response = $this->getResponse(); | ||||
|         //  Check for the +OK
 | ||||
|         //Check for the +OK
 | ||||
|         if ($this->checkResponse($pop3_response)) { | ||||
|             //  The connection is established and the POP3 server is talking
 | ||||
|             //The connection is established and the POP3 server is talking
 | ||||
|             $this->connected = true; | ||||
| 
 | ||||
|             return true; | ||||
|  | @ -279,6 +308,7 @@ class POP3 | |||
|     { | ||||
|         if (!$this->connected) { | ||||
|             $this->setError('Not connected to POP3 server'); | ||||
|             return false; | ||||
|         } | ||||
|         if (empty($username)) { | ||||
|             $username = $this->username; | ||||
|  | @ -287,11 +317,11 @@ class POP3 | |||
|             $password = $this->password; | ||||
|         } | ||||
| 
 | ||||
|         // Send the Username
 | ||||
|         //Send the Username
 | ||||
|         $this->sendString("USER $username" . static::LE); | ||||
|         $pop3_response = $this->getResponse(); | ||||
|         if ($this->checkResponse($pop3_response)) { | ||||
|             // Send the Password
 | ||||
|             //Send the Password
 | ||||
|             $this->sendString("PASS $password" . static::LE); | ||||
|             $pop3_response = $this->getResponse(); | ||||
|             if ($this->checkResponse($pop3_response)) { | ||||
|  | @ -307,7 +337,21 @@ class POP3 | |||
|      */ | ||||
|     public function disconnect() | ||||
|     { | ||||
|         $this->sendString('QUIT'); | ||||
|         // If could not connect at all, no need to disconnect
 | ||||
|         if ($this->pop_conn === false) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         $this->sendString('QUIT' . static::LE); | ||||
| 
 | ||||
|         // RFC 1939 shows POP3 server sending a +OK response to the QUIT command.
 | ||||
|         // Try to get it.  Ignore any failures here.
 | ||||
|         try { | ||||
|             $this->getResponse(); | ||||
|         } catch (Exception $e) { | ||||
|             //Do nothing
 | ||||
|         } | ||||
| 
 | ||||
|         //The QUIT command may cause the daemon to exit, which will kill our connection
 | ||||
|         //So ignore errors here
 | ||||
|         try { | ||||
|  | @ -315,6 +359,10 @@ class POP3 | |||
|         } catch (Exception $e) { | ||||
|             //Do nothing
 | ||||
|         } | ||||
| 
 | ||||
|         // Clean up attributes.
 | ||||
|         $this->connected = false; | ||||
|         $this->pop_conn  = false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -327,7 +375,7 @@ class POP3 | |||
|     protected function getResponse($size = 128) | ||||
|     { | ||||
|         $response = fgets($this->pop_conn, $size); | ||||
|         if ($this->do_debug >= 1) { | ||||
|         if ($this->do_debug >= self::DEBUG_SERVER) { | ||||
|             echo 'Server -> Client: ', $response; | ||||
|         } | ||||
| 
 | ||||
|  | @ -344,7 +392,7 @@ class POP3 | |||
|     protected function sendString($string) | ||||
|     { | ||||
|         if ($this->pop_conn) { | ||||
|             if ($this->do_debug >= 2) { //Show client messages when debug >= 2
 | ||||
|             if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2
 | ||||
|                 echo 'Client -> Server: ', $string; | ||||
|             } | ||||
| 
 | ||||
|  | @ -382,7 +430,7 @@ class POP3 | |||
|     protected function setError($error) | ||||
|     { | ||||
|         $this->errors[] = $error; | ||||
|         if ($this->do_debug >= 1) { | ||||
|         if ($this->do_debug >= self::DEBUG_SERVER) { | ||||
|             echo '<pre>'; | ||||
|             foreach ($this->errors as $e) { | ||||
|                 print_r($e); | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer RFC821 SMTP email transport class. | ||||
|  * PHP Version 5.5. | ||||
|  | @ -9,7 +10,7 @@ | |||
|  * @author    Jim Jagielski (jimjag) <jimjag@gmail.com> | ||||
|  * @author    Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> | ||||
|  * @author    Brent R. Matzelle (original founder) | ||||
|  * @copyright 2012 - 2019 Marcus Bointon | ||||
|  * @copyright 2012 - 2020 Marcus Bointon | ||||
|  * @copyright 2010 - 2012 Jim Jagielski | ||||
|  * @copyright 2004 - 2009 Andy Prevost | ||||
|  * @license   http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License | ||||
|  | @ -18,6 +19,8 @@ | |||
|  * FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
| 
 | ||||
| namespace PHPMailer\PHPMailer; | ||||
| 
 | ||||
| /** | ||||
|  * PHPMailer RFC821 SMTP email transport class. | ||||
|  * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. | ||||
|  | @ -32,7 +35,7 @@ class SMTP | |||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     const VERSION = '6.1.5'; | ||||
|     const VERSION = '6.8.0'; | ||||
| 
 | ||||
|     /** | ||||
|      * SMTP line break constant. | ||||
|  | @ -48,6 +51,13 @@ class SMTP | |||
|      */ | ||||
|     const DEFAULT_PORT = 25; | ||||
| 
 | ||||
|     /** | ||||
|      * The SMTPs port to use if one is not specified. | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     const DEFAULT_SECURE_PORT = 465; | ||||
| 
 | ||||
|     /** | ||||
|      * The maximum line length allowed by RFC 5321 section 4.5.3.1.6, | ||||
|      * *excluding* a trailing CRLF break. | ||||
|  | @ -183,6 +193,9 @@ class SMTP | |||
|         'Amazon_SES' => '/[\d]{3} Ok (.*)/', | ||||
|         'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', | ||||
|         'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', | ||||
|         'Haraka' => '/[\d]{3} Message Queued \((.*)\)/', | ||||
|         'ZoneMTA' => '/[\d]{3} Message queued as (.*)/', | ||||
|         'Mailjet' => '/[\d]{3} OK queued as (.*)/', | ||||
|     ]; | ||||
| 
 | ||||
|     /** | ||||
|  | @ -309,17 +322,11 @@ class SMTP | |||
|      */ | ||||
|     public function connect($host, $port = null, $timeout = 30, $options = []) | ||||
|     { | ||||
|         static $streamok; | ||||
|         //This is enabled by default since 5.0.0 but some providers disable it
 | ||||
|         //Check this once and cache the result
 | ||||
|         if (null === $streamok) { | ||||
|             $streamok = function_exists('stream_socket_client'); | ||||
|         } | ||||
|         // Clear errors to avoid confusion
 | ||||
|         //Clear errors to avoid confusion
 | ||||
|         $this->setError(''); | ||||
|         // Make sure we are __not__ connected
 | ||||
|         //Make sure we are __not__ connected
 | ||||
|         if ($this->connected()) { | ||||
|             // Already connected, generate error
 | ||||
|             //Already connected, generate error
 | ||||
|             $this->setError('Already connected to a server'); | ||||
| 
 | ||||
|             return false; | ||||
|  | @ -327,18 +334,66 @@ class SMTP | |||
|         if (empty($port)) { | ||||
|             $port = self::DEFAULT_PORT; | ||||
|         } | ||||
|         // Connect to the SMTP server
 | ||||
|         //Connect to the SMTP server
 | ||||
|         $this->edebug( | ||||
|             "Connection: opening to $host:$port, timeout=$timeout, options=" . | ||||
|             (count($options) > 0 ? var_export($options, true) : 'array()'), | ||||
|             self::DEBUG_CONNECTION | ||||
|         ); | ||||
| 
 | ||||
|         $this->smtp_conn = $this->getSMTPConnection($host, $port, $timeout, $options); | ||||
| 
 | ||||
|         if ($this->smtp_conn === false) { | ||||
|             //Error info already set inside `getSMTPConnection()`
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         $this->edebug('Connection: opened', self::DEBUG_CONNECTION); | ||||
| 
 | ||||
|         //Get any announcement
 | ||||
|         $this->last_reply = $this->get_lines(); | ||||
|         $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); | ||||
|         $responseCode = (int)substr($this->last_reply, 0, 3); | ||||
|         if ($responseCode === 220) { | ||||
|             return true; | ||||
|         } | ||||
|         //Anything other than a 220 response means something went wrong
 | ||||
|         //RFC 5321 says the server will wait for us to send a QUIT in response to a 554 error
 | ||||
|         //https://tools.ietf.org/html/rfc5321#section-3.1
 | ||||
|         if ($responseCode === 554) { | ||||
|             $this->quit(); | ||||
|         } | ||||
|         //This will handle 421 responses which may not wait for a QUIT (e.g. if the server is being shut down)
 | ||||
|         $this->edebug('Connection: closing due to error', self::DEBUG_CONNECTION); | ||||
|         $this->close(); | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create connection to the SMTP server. | ||||
|      * | ||||
|      * @param string $host    SMTP server IP or host name | ||||
|      * @param int    $port    The port number to connect to | ||||
|      * @param int    $timeout How long to wait for the connection to open | ||||
|      * @param array  $options An array of options for stream_context_create() | ||||
|      * | ||||
|      * @return false|resource | ||||
|      */ | ||||
|     protected function getSMTPConnection($host, $port = null, $timeout = 30, $options = []) | ||||
|     { | ||||
|         static $streamok; | ||||
|         //This is enabled by default since 5.0.0 but some providers disable it
 | ||||
|         //Check this once and cache the result
 | ||||
|         if (null === $streamok) { | ||||
|             $streamok = function_exists('stream_socket_client'); | ||||
|         } | ||||
| 
 | ||||
|         $errno = 0; | ||||
|         $errstr = ''; | ||||
|         if ($streamok) { | ||||
|             $socket_context = stream_context_create($options); | ||||
|             set_error_handler([$this, 'errorHandler']); | ||||
|             $this->smtp_conn = stream_socket_client( | ||||
|             $connection = stream_socket_client( | ||||
|                 $host . ':' . $port, | ||||
|                 $errno, | ||||
|                 $errstr, | ||||
|  | @ -346,7 +401,6 @@ 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( | ||||
|  | @ -354,17 +408,18 @@ class SMTP | |||
|                 self::DEBUG_CONNECTION | ||||
|             ); | ||||
|             set_error_handler([$this, 'errorHandler']); | ||||
|             $this->smtp_conn = fsockopen( | ||||
|             $connection = fsockopen( | ||||
|                 $host, | ||||
|                 $port, | ||||
|                 $errno, | ||||
|                 $errstr, | ||||
|                 $timeout | ||||
|             ); | ||||
|             restore_error_handler(); | ||||
|         } | ||||
|         // Verify we connected properly
 | ||||
|         if (!is_resource($this->smtp_conn)) { | ||||
|         restore_error_handler(); | ||||
| 
 | ||||
|         //Verify we connected properly
 | ||||
|         if (!is_resource($connection)) { | ||||
|             $this->setError( | ||||
|                 'Failed to connect to server', | ||||
|                 '', | ||||
|  | @ -379,22 +434,19 @@ class SMTP | |||
| 
 | ||||
|             return false; | ||||
|         } | ||||
|         $this->edebug('Connection: opened', self::DEBUG_CONNECTION); | ||||
|         // SMTP server can take longer to respond, give longer timeout for first read
 | ||||
|         // Windows does not have support for this timeout function
 | ||||
| 
 | ||||
|         //SMTP server can take longer to respond, give longer timeout for first read
 | ||||
|         //Windows does not have support for this timeout function
 | ||||
|         if (strpos(PHP_OS, 'WIN') !== 0) { | ||||
|             $max = (int) ini_get('max_execution_time'); | ||||
|             // Don't bother if unlimited
 | ||||
|             if (0 !== $max && $timeout > $max) { | ||||
|             $max = (int)ini_get('max_execution_time'); | ||||
|             //Don't bother if unlimited, or if set_time_limit is disabled
 | ||||
|             if (0 !== $max && $timeout > $max && strpos(ini_get('disable_functions'), 'set_time_limit') === false) { | ||||
|                 @set_time_limit($timeout); | ||||
|             } | ||||
|             stream_set_timeout($this->smtp_conn, $timeout, 0); | ||||
|             stream_set_timeout($connection, $timeout, 0); | ||||
|         } | ||||
|         // Get any announcement
 | ||||
|         $announce = $this->get_lines(); | ||||
|         $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); | ||||
| 
 | ||||
|         return true; | ||||
|         return $connection; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -418,7 +470,7 @@ class SMTP | |||
|             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; | ||||
|         } | ||||
| 
 | ||||
|         // Begin encrypted connection
 | ||||
|         //Begin encrypted connection
 | ||||
|         set_error_handler([$this, 'errorHandler']); | ||||
|         $crypto_ok = stream_socket_enable_crypto( | ||||
|             $this->smtp_conn, | ||||
|  | @ -439,7 +491,7 @@ class SMTP | |||
|      * @param string $username The user name | ||||
|      * @param string $password The password | ||||
|      * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) | ||||
|      * @param OAuth  $OAuth    An optional OAuth instance for XOAUTH2 authentication | ||||
|      * @param OAuthTokenProvider $OAuth An optional OAuthTokenProvider instance for XOAUTH2 authentication | ||||
|      * | ||||
|      * @return bool True if successfully authenticated | ||||
|      */ | ||||
|  | @ -456,11 +508,11 @@ class SMTP | |||
|         } | ||||
| 
 | ||||
|         if (array_key_exists('EHLO', $this->server_caps)) { | ||||
|             // SMTP extensions are available; try to find a proper authentication method
 | ||||
|             //SMTP extensions are available; try to find a proper authentication method
 | ||||
|             if (!array_key_exists('AUTH', $this->server_caps)) { | ||||
|                 $this->setError('Authentication is not allowed at this stage'); | ||||
|                 // 'at this stage' means that auth may be allowed after the stage changes
 | ||||
|                 // e.g. after STARTTLS
 | ||||
|                 //'at this stage' means that auth may be allowed after the stage changes
 | ||||
|                 //e.g. after STARTTLS
 | ||||
| 
 | ||||
|                 return false; | ||||
|             } | ||||
|  | @ -504,22 +556,25 @@ class SMTP | |||
|         } | ||||
|         switch ($authtype) { | ||||
|             case 'PLAIN': | ||||
|                 // Start authentication
 | ||||
|                 //Start authentication
 | ||||
|                 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 // Send encoded username and password
 | ||||
|                 if (!$this->sendCommand( | ||||
|                     'User & Password', | ||||
|                     base64_encode("\0" . $username . "\0" . $password), | ||||
|                     235 | ||||
|                 ) | ||||
|                 //Send encoded username and password
 | ||||
|                 if ( | ||||
|                     //Format from https://tools.ietf.org/html/rfc4616#section-2
 | ||||
|                     //We skip the first field (it's forgery), so the string starts with a null byte
 | ||||
|                     !$this->sendCommand( | ||||
|                         'User & Password', | ||||
|                         base64_encode("\0" . $username . "\0" . $password), | ||||
|                         235 | ||||
|                     ) | ||||
|                 ) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 break; | ||||
|             case 'LOGIN': | ||||
|                 // Start authentication
 | ||||
|                 //Start authentication
 | ||||
|                 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | @ -531,17 +586,17 @@ class SMTP | |||
|                 } | ||||
|                 break; | ||||
|             case 'CRAM-MD5': | ||||
|                 // Start authentication
 | ||||
|                 //Start authentication
 | ||||
|                 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 // Get the challenge
 | ||||
|                 //Get the challenge
 | ||||
|                 $challenge = base64_decode(substr($this->last_reply, 4)); | ||||
| 
 | ||||
|                 // Build the response
 | ||||
|                 //Build the response
 | ||||
|                 $response = $username . ' ' . $this->hmac($challenge, $password); | ||||
| 
 | ||||
|                 // send encoded credentials
 | ||||
|                 //send encoded credentials
 | ||||
|                 return $this->sendCommand('Username', base64_encode($response), 235); | ||||
|             case 'XOAUTH2': | ||||
|                 //The OAuth instance must be set up prior to requesting auth.
 | ||||
|  | @ -550,7 +605,7 @@ class SMTP | |||
|                 } | ||||
|                 $oauth = $OAuth->getOauth64(); | ||||
| 
 | ||||
|                 // Start authentication
 | ||||
|                 //Start authentication
 | ||||
|                 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | @ -580,15 +635,15 @@ class SMTP | |||
|             return hash_hmac('md5', $data, $key); | ||||
|         } | ||||
| 
 | ||||
|         // The following borrowed from
 | ||||
|         // http://php.net/manual/en/function.mhash.php#27225
 | ||||
|         //The following borrowed from
 | ||||
|         //http://php.net/manual/en/function.mhash.php#27225
 | ||||
| 
 | ||||
|         // RFC 2104 HMAC implementation for php.
 | ||||
|         // Creates an md5 HMAC.
 | ||||
|         // Eliminates the need to install mhash to compute a HMAC
 | ||||
|         // by Lance Rushing
 | ||||
|         //RFC 2104 HMAC implementation for php.
 | ||||
|         //Creates an md5 HMAC.
 | ||||
|         //Eliminates the need to install mhash to compute a HMAC
 | ||||
|         //by Lance Rushing
 | ||||
| 
 | ||||
|         $bytelen = 64; // byte length for md5
 | ||||
|         $bytelen = 64; //byte length for md5
 | ||||
|         if (strlen($key) > $bytelen) { | ||||
|             $key = pack('H*', md5($key)); | ||||
|         } | ||||
|  | @ -611,7 +666,7 @@ class SMTP | |||
|         if (is_resource($this->smtp_conn)) { | ||||
|             $sock_status = stream_get_meta_data($this->smtp_conn); | ||||
|             if ($sock_status['eof']) { | ||||
|                 // The socket is valid but we are not connected
 | ||||
|                 //The socket is valid but we are not connected
 | ||||
|                 $this->edebug( | ||||
|                     'SMTP NOTICE: EOF caught while checking if connected', | ||||
|                     self::DEBUG_CLIENT | ||||
|  | @ -621,7 +676,7 @@ class SMTP | |||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             return true; // everything looks good
 | ||||
|             return true; //everything looks good
 | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|  | @ -635,11 +690,10 @@ class SMTP | |||
|      */ | ||||
|     public function close() | ||||
|     { | ||||
|         $this->setError(''); | ||||
|         $this->server_caps = null; | ||||
|         $this->helo_rply = null; | ||||
|         if (is_resource($this->smtp_conn)) { | ||||
|             // close the connection and cleanup
 | ||||
|             //Close the connection and cleanup
 | ||||
|             fclose($this->smtp_conn); | ||||
|             $this->smtp_conn = null; //Makes for cleaner serialization
 | ||||
|             $this->edebug('Connection: closed', self::DEBUG_CONNECTION); | ||||
|  | @ -649,7 +703,7 @@ class SMTP | |||
|     /** | ||||
|      * Send an SMTP DATA command. | ||||
|      * Issues a data command and sends the msg_data to the server, | ||||
|      * finializing the mail transaction. $msg_data is the message | ||||
|      * finalizing the mail transaction. $msg_data is the message | ||||
|      * that is to be send with the headers. Each header needs to be | ||||
|      * on a single line followed by a <CRLF> with the message headers | ||||
|      * and the message body being separated by an additional <CRLF>. | ||||
|  | @ -674,7 +728,7 @@ class SMTP | |||
|          * NOTE: this does not count towards line-length limit. | ||||
|          */ | ||||
| 
 | ||||
|         // Normalize line breaks before exploding
 | ||||
|         //Normalize line breaks before exploding
 | ||||
|         $lines = explode("\n", str_replace(["\r\n", "\r"], "\n", $msg_data)); | ||||
| 
 | ||||
|         /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field | ||||
|  | @ -720,7 +774,8 @@ class SMTP | |||
| 
 | ||||
|             //Send the lines to the server
 | ||||
|             foreach ($lines_out as $line_out) { | ||||
|                 //RFC2821 section 4.5.2
 | ||||
|                 //Dot-stuffing as per RFC5321 section 4.5.2
 | ||||
|                 //https://tools.ietf.org/html/rfc5321#section-4.5.2
 | ||||
|                 if (!empty($line_out) && $line_out[0] === '.') { | ||||
|                     $line_out = '.' . $line_out; | ||||
|                 } | ||||
|  | @ -754,7 +809,16 @@ class SMTP | |||
|     public function hello($host = '') | ||||
|     { | ||||
|         //Try extended hello first (RFC 2821)
 | ||||
|         return $this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host); | ||||
|         if ($this->sendHello('EHLO', $host)) { | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         //Some servers shut down the SMTP service here (RFC 5321)
 | ||||
|         if (substr($this->helo_rply, 0, 3) == '421') { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return $this->sendHello('HELO', $host); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -944,12 +1008,12 @@ class SMTP | |||
|         $this->client_send($commandstring . static::LE, $command); | ||||
| 
 | ||||
|         $this->last_reply = $this->get_lines(); | ||||
|         // Fetch SMTP code and possible error code explanation
 | ||||
|         //Fetch SMTP code and possible error code explanation
 | ||||
|         $matches = []; | ||||
|         if (preg_match('/^([\d]{3})[ -](?:([\d]\\.[\d]\\.[\d]{1,2}) )?/', $this->last_reply, $matches)) { | ||||
|             $code = (int) $matches[1]; | ||||
|             $code_ex = (count($matches) > 2 ? $matches[2] : null); | ||||
|             // Cut off error code from each response line
 | ||||
|             //Cut off error code from each response line
 | ||||
|             $detail = preg_replace( | ||||
|                 "/{$code}[ -]" . | ||||
|                 ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . '/m', | ||||
|  | @ -957,7 +1021,7 @@ class SMTP | |||
|                 $this->last_reply | ||||
|             ); | ||||
|         } else { | ||||
|             // Fall back to simple parsing if regex fails
 | ||||
|             //Fall back to simple parsing if regex fails
 | ||||
|             $code = (int) substr($this->last_reply, 0, 3); | ||||
|             $code_ex = null; | ||||
|             $detail = substr($this->last_reply, 4); | ||||
|  | @ -980,7 +1044,10 @@ class SMTP | |||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         $this->setError(''); | ||||
|         //Don't clear the error store when using keepalive
 | ||||
|         if ($command !== 'RSET') { | ||||
|             $this->setError(''); | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
|  | @ -1056,8 +1123,10 @@ class SMTP | |||
|     { | ||||
|         //If SMTP transcripts are left enabled, or debug output is posted online
 | ||||
|         //it can leak credentials, so hide credentials in all but lowest level
 | ||||
|         if (self::DEBUG_LOWLEVEL > $this->do_debug && | ||||
|             in_array($command, ['User & Password', 'Username', 'Password'], true)) { | ||||
|         if ( | ||||
|             self::DEBUG_LOWLEVEL > $this->do_debug && | ||||
|             in_array($command, ['User & Password', 'Username', 'Password'], true) | ||||
|         ) { | ||||
|             $this->edebug('CLIENT -> SERVER: [credentials hidden]', self::DEBUG_CLIENT); | ||||
|         } else { | ||||
|             $this->edebug('CLIENT -> SERVER: ' . $data, self::DEBUG_CLIENT); | ||||
|  | @ -1111,7 +1180,7 @@ class SMTP | |||
|         if (!$this->server_caps) { | ||||
|             $this->setError('No HELO/EHLO was sent'); | ||||
| 
 | ||||
|             return; | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         if (!array_key_exists($name, $this->server_caps)) { | ||||
|  | @ -1123,7 +1192,7 @@ class SMTP | |||
|             } | ||||
|             $this->setError('HELO handshake was used; No information about server extensions available'); | ||||
| 
 | ||||
|             return; | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         return $this->server_caps[$name]; | ||||
|  | @ -1150,7 +1219,7 @@ class SMTP | |||
|      */ | ||||
|     protected function get_lines() | ||||
|     { | ||||
|         // If the connection is bad, give up straight away
 | ||||
|         //If the connection is bad, give up straight away
 | ||||
|         if (!is_resource($this->smtp_conn)) { | ||||
|             return ''; | ||||
|         } | ||||
|  | @ -1164,33 +1233,61 @@ class SMTP | |||
|         $selW = null; | ||||
|         while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { | ||||
|             //Must pass vars in here as params are by reference
 | ||||
|             if (!stream_select($selR, $selW, $selW, $this->Timelimit)) { | ||||
|             //solution for signals inspired by https://github.com/symfony/symfony/pull/6540
 | ||||
|             set_error_handler([$this, 'errorHandler']); | ||||
|             $n = stream_select($selR, $selW, $selW, $this->Timelimit); | ||||
|             restore_error_handler(); | ||||
| 
 | ||||
|             if ($n === false) { | ||||
|                 $message = $this->getError()['detail']; | ||||
| 
 | ||||
|                 $this->edebug( | ||||
|                     'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', | ||||
|                     'SMTP -> get_lines(): select failed (' . $message . ')', | ||||
|                     self::DEBUG_LOWLEVEL | ||||
|                 ); | ||||
| 
 | ||||
|                 //stream_select returns false when the `select` system call is interrupted
 | ||||
|                 //by an incoming signal, try the select again
 | ||||
|                 if (stripos($message, 'interrupted system call') !== false) { | ||||
|                     $this->edebug( | ||||
|                         'SMTP -> get_lines(): retrying stream_select', | ||||
|                         self::DEBUG_LOWLEVEL | ||||
|                     ); | ||||
|                     $this->setError(''); | ||||
|                     continue; | ||||
|                 } | ||||
| 
 | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             if (!$n) { | ||||
|                 $this->edebug( | ||||
|                     'SMTP -> get_lines(): select timed-out in (' . $this->Timelimit . ' sec)', | ||||
|                     self::DEBUG_LOWLEVEL | ||||
|                 ); | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
|             //Deliberate noise suppression - errors are handled afterwards
 | ||||
|             $str = @fgets($this->smtp_conn, self::MAX_REPLY_LENGTH); | ||||
|             $this->edebug('SMTP INBOUND: "' . trim($str) . '"', self::DEBUG_LOWLEVEL); | ||||
|             $data .= $str; | ||||
|             // If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
 | ||||
|             // or 4th character is a space or a line break char, we are done reading, break the loop.
 | ||||
|             // String array access is a significant micro-optimisation over strlen
 | ||||
|             //If response is only 3 chars (not valid, but RFC5321 S4.2 says it must be handled),
 | ||||
|             //or 4th character is a space or a line break char, we are done reading, break the loop.
 | ||||
|             //String array access is a significant micro-optimisation over strlen
 | ||||
|             if (!isset($str[3]) || $str[3] === ' ' || $str[3] === "\r" || $str[3] === "\n") { | ||||
|                 break; | ||||
|             } | ||||
|             // Timed-out? Log and break
 | ||||
|             //Timed-out? Log and break
 | ||||
|             $info = stream_get_meta_data($this->smtp_conn); | ||||
|             if ($info['timed_out']) { | ||||
|                 $this->edebug( | ||||
|                     'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', | ||||
|                     'SMTP -> get_lines(): stream timed-out (' . $this->Timeout . ' sec)', | ||||
|                     self::DEBUG_LOWLEVEL | ||||
|                 ); | ||||
|                 break; | ||||
|             } | ||||
|             // Now check if reads took too long
 | ||||
|             //Now check if reads took too long
 | ||||
|             if ($endtime && time() > $endtime) { | ||||
|                 $this->edebug( | ||||
|                     'SMTP -> get_lines(): timelimit reached (' . | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Anonymous Contributor
						Anonymous Contributor