[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/PHPMailer/ -> POP3.php (source)

   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  }


Generated : Tue May 5 08:20:14 2026 Cross-referenced by PHPXref