| [ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * PHPMailer POP-Before-SMTP Authentication Class. 5 * PHP Version 5.5. 6 * 7 * @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project 8 * 9 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> 10 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 12 * @author Brent R. Matzelle (original founder) 13 * @copyright 2012 - 2020 Marcus Bointon 14 * @copyright 2010 - 2012 Jim Jagielski 15 * @copyright 2004 - 2009 Andy Prevost 16 * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License 17 * @note This program is distributed in the hope that it will be useful - WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 namespace PHPMailer\PHPMailer; 23 24 /** 25 * PHPMailer POP-Before-SMTP Authentication Class. 26 * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication. 27 * 1) This class does not support APOP authentication. 28 * 2) Opening and closing lots of POP3 connections can be quite slow. If you need 29 * to send a batch of emails then just perform the authentication once at the start, 30 * and then loop through your mail sending script. Providing this process doesn't 31 * take longer than the verification period lasts on your POP3 server, you should be fine. 32 * 3) This is really ancient technology; you should only need to use it to talk to very old systems. 33 * 4) This POP3 class is deliberately lightweight and incomplete, implementing just 34 * enough to do authentication. 35 * If you want a more complete class there are other POP3 classes for PHP available. 36 * 37 * @author Richard Davey (original author) <rich@corephp.co.uk> 38 * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk> 39 * @author Jim Jagielski (jimjag) <jimjag@gmail.com> 40 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> 41 */ 42 class POP3 43 { 44 /** 45 * The POP3 PHPMailer Version number. 46 * 47 * @var string 48 * @deprecated This constant will be removed in PHPMailer 8.0. Use `PHPMailer::VERSION` instead. 49 */ 50 const VERSION = '7.0.2'; 51 52 /** 53 * Default POP3 port number. 54 * 55 * @var int 56 */ 57 const DEFAULT_PORT = 110; 58 59 /** 60 * Default timeout in seconds. 61 * 62 * @var int 63 */ 64 const DEFAULT_TIMEOUT = 30; 65 66 /** 67 * POP3 class debug output mode. 68 * Debug output level. 69 * Options: 70 * @see POP3::DEBUG_OFF: No output 71 * @see POP3::DEBUG_SERVER: Server messages, connection/server errors 72 * @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors 73 * 74 * @var int 75 */ 76 public $do_debug = self::DEBUG_OFF; 77 78 /** 79 * POP3 mail server hostname. 80 * 81 * @var string 82 */ 83 public $host; 84 85 /** 86 * POP3 port number. 87 * 88 * @var int 89 */ 90 public $port; 91 92 /** 93 * POP3 Timeout Value in seconds. 94 * 95 * @var int 96 */ 97 public $tval; 98 99 /** 100 * POP3 username. 101 * 102 * @var string 103 */ 104 public $username; 105 106 /** 107 * POP3 password. 108 * 109 * @var string 110 */ 111 public $password; 112 113 /** 114 * Resource handle for the POP3 connection socket. 115 * 116 * @var resource 117 */ 118 protected $pop_conn; 119 120 /** 121 * Are we connected? 122 * 123 * @var bool 124 */ 125 protected $connected = false; 126 127 /** 128 * Error container. 129 * 130 * @var array 131 */ 132 protected $errors = []; 133 134 /** 135 * Line break constant. 136 */ 137 const LE = "\r\n"; 138 139 /** 140 * Debug level for no output. 141 * 142 * @var int 143 */ 144 const DEBUG_OFF = 0; 145 146 /** 147 * Debug level to show server -> client messages 148 * also shows clients connection errors or errors from server 149 * 150 * @var int 151 */ 152 const DEBUG_SERVER = 1; 153 154 /** 155 * Debug level to show client -> server and server -> client messages. 156 * 157 * @var int 158 */ 159 const DEBUG_CLIENT = 2; 160 161 /** 162 * Simple static wrapper for all-in-one POP before SMTP. 163 * 164 * @param string $host The hostname to connect to 165 * @param int|bool $port The port number to connect to 166 * @param int|bool $timeout The timeout value 167 * @param string $username 168 * @param string $password 169 * @param int $debug_level 170 * 171 * @return bool 172 */ 173 public static function popBeforeSmtp( 174 $host, 175 $port = false, 176 $timeout = false, 177 $username = '', 178 $password = '', 179 $debug_level = 0 180 ) { 181 $pop = new self(); 182 183 return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level); 184 } 185 186 /** 187 * Authenticate with a POP3 server. 188 * A connect, login, disconnect sequence 189 * appropriate for POP-before SMTP authorisation. 190 * 191 * @param string $host The hostname to connect to 192 * @param int|bool $port The port number to connect to 193 * @param int|bool $timeout The timeout value 194 * @param string $username 195 * @param string $password 196 * @param int $debug_level 197 * 198 * @return bool 199 */ 200 public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0) 201 { 202 $this->host = $host; 203 //If no port value provided, use default 204 if (false === $port) { 205 $this->port = static::DEFAULT_PORT; 206 } else { 207 $this->port = (int) $port; 208 } 209 //If no timeout value provided, use default 210 if (false === $timeout) { 211 $this->tval = static::DEFAULT_TIMEOUT; 212 } else { 213 $this->tval = (int) $timeout; 214 } 215 $this->do_debug = $debug_level; 216 $this->username = $username; 217 $this->password = $password; 218 //Reset the error log 219 $this->errors = []; 220 //Connect 221 $result = $this->connect($this->host, $this->port, $this->tval); 222 if ($result) { 223 $login_result = $this->login($this->username, $this->password); 224 if ($login_result) { 225 $this->disconnect(); 226 227 return true; 228 } 229 } 230 //We need to disconnect regardless of whether the login succeeded 231 $this->disconnect(); 232 233 return false; 234 } 235 236 /** 237 * Connect to a POP3 server. 238 * 239 * @param string $host 240 * @param int|bool $port 241 * @param int $tval 242 * 243 * @return bool 244 */ 245 public function connect($host, $port = false, $tval = 30) 246 { 247 //Are we already connected? 248 if ($this->connected) { 249 return true; 250 } 251 252 //On Windows this will raise a PHP Warning error if the hostname doesn't exist. 253 //Rather than suppress it with @fsockopen, capture it cleanly instead 254 set_error_handler(function () { 255 call_user_func_array([$this, 'catchWarning'], func_get_args()); 256 }); 257 258 if (false === $port) { 259 $port = static::DEFAULT_PORT; 260 } 261 262 //Connect to the POP3 server 263 $errno = 0; 264 $errstr = ''; 265 $this->pop_conn = fsockopen( 266 $host, //POP3 Host 267 $port, //Port # 268 $errno, //Error Number 269 $errstr, //Error Message 270 $tval 271 ); //Timeout (seconds) 272 //Restore the error handler 273 restore_error_handler(); 274 275 //Did we connect? 276 if (false === $this->pop_conn) { 277 //It would appear not... 278 $this->setError( 279 "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr" 280 ); 281 282 return false; 283 } 284 285 //Increase the stream time-out 286 stream_set_timeout($this->pop_conn, $tval, 0); 287 288 //Get the POP3 server response 289 $pop3_response = $this->getResponse(); 290 //Check for the +OK 291 if ($this->checkResponse($pop3_response)) { 292 //The connection is established and the POP3 server is talking 293 $this->connected = true; 294 295 return true; 296 } 297 298 return false; 299 } 300 301 /** 302 * Log in to the POP3 server. 303 * Does not support APOP (RFC 2828, 4949). 304 * 305 * @param string $username 306 * @param string $password 307 * 308 * @return bool 309 */ 310 public function login($username = '', $password = '') 311 { 312 if (!$this->connected) { 313 $this->setError('Not connected to POP3 server'); 314 return false; 315 } 316 if (empty($username)) { 317 $username = $this->username; 318 } 319 if (empty($password)) { 320 $password = $this->password; 321 } 322 323 //Send the Username 324 $this->sendString("USER $username" . static::LE); 325 $pop3_response = $this->getResponse(); 326 if ($this->checkResponse($pop3_response)) { 327 //Send the Password 328 $this->sendString("PASS $password" . static::LE); 329 $pop3_response = $this->getResponse(); 330 if ($this->checkResponse($pop3_response)) { 331 return true; 332 } 333 } 334 335 return false; 336 } 337 338 /** 339 * Disconnect from the POP3 server. 340 */ 341 public function disconnect() 342 { 343 // If could not connect at all, no need to disconnect 344 if ($this->pop_conn === false) { 345 return; 346 } 347 348 $this->sendString('QUIT' . static::LE); 349 350 // RFC 1939 shows POP3 server sending a +OK response to the QUIT command. 351 // Try to get it. Ignore any failures here. 352 try { 353 $this->getResponse(); 354 } catch (Exception $e) { 355 //Do nothing 356 } 357 358 //The QUIT command may cause the daemon to exit, which will kill our connection 359 //So ignore errors here 360 try { 361 @fclose($this->pop_conn); 362 } catch (Exception $e) { 363 //Do nothing 364 } 365 366 // Clean up attributes. 367 $this->connected = false; 368 $this->pop_conn = false; 369 } 370 371 /** 372 * Get a response from the POP3 server. 373 * 374 * @param int $size The maximum number of bytes to retrieve 375 * 376 * @return string 377 */ 378 protected function getResponse($size = 128) 379 { 380 $response = fgets($this->pop_conn, $size); 381 if ($this->do_debug >= self::DEBUG_SERVER) { 382 echo 'Server -> Client: ', $response; 383 } 384 385 return $response; 386 } 387 388 /** 389 * Send raw data to the POP3 server. 390 * 391 * @param string $string 392 * 393 * @return int 394 */ 395 protected function sendString($string) 396 { 397 if ($this->pop_conn) { 398 if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2 399 echo 'Client -> Server: ', $string; 400 } 401 402 return fwrite($this->pop_conn, $string, strlen($string)); 403 } 404 405 return 0; 406 } 407 408 /** 409 * Checks the POP3 server response. 410 * Looks for for +OK or -ERR. 411 * 412 * @param string $string 413 * 414 * @return bool 415 */ 416 protected function checkResponse($string) 417 { 418 if (strpos($string, '+OK') !== 0) { 419 $this->setError("Server reported an error: $string"); 420 421 return false; 422 } 423 424 return true; 425 } 426 427 /** 428 * Add an error to the internal error store. 429 * Also display debug output if it's enabled. 430 * 431 * @param string $error 432 */ 433 protected function setError($error) 434 { 435 $this->errors[] = $error; 436 if ($this->do_debug >= self::DEBUG_SERVER) { 437 echo '<pre>'; 438 foreach ($this->errors as $e) { 439 print_r($e); 440 } 441 echo '</pre>'; 442 } 443 } 444 445 /** 446 * Get an array of error messages, if any. 447 * 448 * @return array 449 */ 450 public function getErrors() 451 { 452 return $this->errors; 453 } 454 455 /** 456 * POP3 connection error handler. 457 * 458 * @param int $errno 459 * @param string $errstr 460 * @param string $errfile 461 * @param int $errline 462 */ 463 protected function catchWarning($errno, $errstr, $errfile, $errline) 464 { 465 $this->setError( 466 'Connecting to the POP3 server raised a PHP warning:' . 467 "errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline" 468 ); 469 } 470 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Tue May 5 08:20:14 2026 | Cross-referenced by PHPXref |