"Fossies" - the Fresh Open Source Software Archive

Member "PHPMailer-6.4.1/src/POP3.php" (29 Apr 2021, 11732 Bytes) of package /linux/www/PHPMailer-6.4.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "POP3.php" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 6.4.0_vs_6.4.1.

    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   http://www.gnu.org/copyleft/lesser.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      */
   49     const VERSION = '6.4.1';
   50 
   51     /**
   52      * Default POP3 port number.
   53      *
   54      * @var int
   55      */
   56     const DEFAULT_PORT = 110;
   57 
   58     /**
   59      * Default timeout in seconds.
   60      *
   61      * @var int
   62      */
   63     const DEFAULT_TIMEOUT = 30;
   64 
   65     /**
   66      * POP3 class debug output mode.
   67      * Debug output level.
   68      * Options:
   69      * @see POP3::DEBUG_OFF: No output
   70      * @see POP3::DEBUG_SERVER: Server messages, connection/server errors
   71      * @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors
   72      *
   73      * @var int
   74      */
   75     public $do_debug = self::DEBUG_OFF;
   76 
   77     /**
   78      * POP3 mail server hostname.
   79      *
   80      * @var string
   81      */
   82     public $host;
   83 
   84     /**
   85      * POP3 port number.
   86      *
   87      * @var int
   88      */
   89     public $port;
   90 
   91     /**
   92      * POP3 Timeout Value in seconds.
   93      *
   94      * @var int
   95      */
   96     public $tval;
   97 
   98     /**
   99      * POP3 username.
  100      *
  101      * @var string
  102      */
  103     public $username;
  104 
  105     /**
  106      * POP3 password.
  107      *
  108      * @var string
  109      */
  110     public $password;
  111 
  112     /**
  113      * Resource handle for the POP3 connection socket.
  114      *
  115      * @var resource
  116      */
  117     protected $pop_conn;
  118 
  119     /**
  120      * Are we connected?
  121      *
  122      * @var bool
  123      */
  124     protected $connected = false;
  125 
  126     /**
  127      * Error container.
  128      *
  129      * @var array
  130      */
  131     protected $errors = [];
  132 
  133     /**
  134      * Line break constant.
  135      */
  136     const LE = "\r\n";
  137 
  138     /**
  139      * Debug level for no output.
  140      *
  141      * @var int
  142      */
  143     const DEBUG_OFF = 0;
  144 
  145     /**
  146      * Debug level to show server -> client messages
  147      * also shows clients connection errors or errors from server
  148      *
  149      * @var int
  150      */
  151     const DEBUG_SERVER = 1;
  152 
  153     /**
  154      * Debug level to show client -> server and server -> client messages.
  155      *
  156      * @var int
  157      */
  158     const DEBUG_CLIENT = 2;
  159 
  160     /**
  161      * Simple static wrapper for all-in-one POP before SMTP.
  162      *
  163      * @param string   $host        The hostname to connect to
  164      * @param int|bool $port        The port number to connect to
  165      * @param int|bool $timeout     The timeout value
  166      * @param string   $username
  167      * @param string   $password
  168      * @param int      $debug_level
  169      *
  170      * @return bool
  171      */
  172     public static function popBeforeSmtp(
  173         $host,
  174         $port = false,
  175         $timeout = false,
  176         $username = '',
  177         $password = '',
  178         $debug_level = 0
  179     ) {
  180         $pop = new self();
  181 
  182         return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
  183     }
  184 
  185     /**
  186      * Authenticate with a POP3 server.
  187      * A connect, login, disconnect sequence
  188      * appropriate for POP-before SMTP authorisation.
  189      *
  190      * @param string   $host        The hostname to connect to
  191      * @param int|bool $port        The port number to connect to
  192      * @param int|bool $timeout     The timeout value
  193      * @param string   $username
  194      * @param string   $password
  195      * @param int      $debug_level
  196      *
  197      * @return bool
  198      */
  199     public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
  200     {
  201         $this->host = $host;
  202         //If no port value provided, use default
  203         if (false === $port) {
  204             $this->port = static::DEFAULT_PORT;
  205         } else {
  206             $this->port = (int) $port;
  207         }
  208         //If no timeout value provided, use default
  209         if (false === $timeout) {
  210             $this->tval = static::DEFAULT_TIMEOUT;
  211         } else {
  212             $this->tval = (int) $timeout;
  213         }
  214         $this->do_debug = $debug_level;
  215         $this->username = $username;
  216         $this->password = $password;
  217         //Reset the error log
  218         $this->errors = [];
  219         //Connect
  220         $result = $this->connect($this->host, $this->port, $this->tval);
  221         if ($result) {
  222             $login_result = $this->login($this->username, $this->password);
  223             if ($login_result) {
  224                 $this->disconnect();
  225 
  226                 return true;
  227             }
  228         }
  229         //We need to disconnect regardless of whether the login succeeded
  230         $this->disconnect();
  231 
  232         return false;
  233     }
  234 
  235     /**
  236      * Connect to a POP3 server.
  237      *
  238      * @param string   $host
  239      * @param int|bool $port
  240      * @param int      $tval
  241      *
  242      * @return bool
  243      */
  244     public function connect($host, $port = false, $tval = 30)
  245     {
  246         //Are we already connected?
  247         if ($this->connected) {
  248             return true;
  249         }
  250 
  251         //On Windows this will raise a PHP Warning error if the hostname doesn't exist.
  252         //Rather than suppress it with @fsockopen, capture it cleanly instead
  253         set_error_handler([$this, 'catchWarning']);
  254 
  255         if (false === $port) {
  256             $port = static::DEFAULT_PORT;
  257         }
  258 
  259         //Connect to the POP3 server
  260         $errno = 0;
  261         $errstr = '';
  262         $this->pop_conn = fsockopen(
  263             $host, //POP3 Host
  264             $port, //Port #
  265             $errno, //Error Number
  266             $errstr, //Error Message
  267             $tval
  268         ); //Timeout (seconds)
  269         //Restore the error handler
  270         restore_error_handler();
  271 
  272         //Did we connect?
  273         if (false === $this->pop_conn) {
  274             //It would appear not...
  275             $this->setError(
  276                 "Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
  277             );
  278 
  279             return false;
  280         }
  281 
  282         //Increase the stream time-out
  283         stream_set_timeout($this->pop_conn, $tval, 0);
  284 
  285         //Get the POP3 server response
  286         $pop3_response = $this->getResponse();
  287         //Check for the +OK
  288         if ($this->checkResponse($pop3_response)) {
  289             //The connection is established and the POP3 server is talking
  290             $this->connected = true;
  291 
  292             return true;
  293         }
  294 
  295         return false;
  296     }
  297 
  298     /**
  299      * Log in to the POP3 server.
  300      * Does not support APOP (RFC 2828, 4949).
  301      *
  302      * @param string $username
  303      * @param string $password
  304      *
  305      * @return bool
  306      */
  307     public function login($username = '', $password = '')
  308     {
  309         if (!$this->connected) {
  310             $this->setError('Not connected to POP3 server');
  311         }
  312         if (empty($username)) {
  313             $username = $this->username;
  314         }
  315         if (empty($password)) {
  316             $password = $this->password;
  317         }
  318 
  319         //Send the Username
  320         $this->sendString("USER $username" . static::LE);
  321         $pop3_response = $this->getResponse();
  322         if ($this->checkResponse($pop3_response)) {
  323             //Send the Password
  324             $this->sendString("PASS $password" . static::LE);
  325             $pop3_response = $this->getResponse();
  326             if ($this->checkResponse($pop3_response)) {
  327                 return true;
  328             }
  329         }
  330 
  331         return false;
  332     }
  333 
  334     /**
  335      * Disconnect from the POP3 server.
  336      */
  337     public function disconnect()
  338     {
  339         $this->sendString('QUIT');
  340         //The QUIT command may cause the daemon to exit, which will kill our connection
  341         //So ignore errors here
  342         try {
  343             @fclose($this->pop_conn);
  344         } catch (Exception $e) {
  345             //Do nothing
  346         }
  347     }
  348 
  349     /**
  350      * Get a response from the POP3 server.
  351      *
  352      * @param int $size The maximum number of bytes to retrieve
  353      *
  354      * @return string
  355      */
  356     protected function getResponse($size = 128)
  357     {
  358         $response = fgets($this->pop_conn, $size);
  359         if ($this->do_debug >= self::DEBUG_SERVER) {
  360             echo 'Server -> Client: ', $response;
  361         }
  362 
  363         return $response;
  364     }
  365 
  366     /**
  367      * Send raw data to the POP3 server.
  368      *
  369      * @param string $string
  370      *
  371      * @return int
  372      */
  373     protected function sendString($string)
  374     {
  375         if ($this->pop_conn) {
  376             if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2
  377                 echo 'Client -> Server: ', $string;
  378             }
  379 
  380             return fwrite($this->pop_conn, $string, strlen($string));
  381         }
  382 
  383         return 0;
  384     }
  385 
  386     /**
  387      * Checks the POP3 server response.
  388      * Looks for for +OK or -ERR.
  389      *
  390      * @param string $string
  391      *
  392      * @return bool
  393      */
  394     protected function checkResponse($string)
  395     {
  396         if (strpos($string, '+OK') !== 0) {
  397             $this->setError("Server reported an error: $string");
  398 
  399             return false;
  400         }
  401 
  402         return true;
  403     }
  404 
  405     /**
  406      * Add an error to the internal error store.
  407      * Also display debug output if it's enabled.
  408      *
  409      * @param string $error
  410      */
  411     protected function setError($error)
  412     {
  413         $this->errors[] = $error;
  414         if ($this->do_debug >= self::DEBUG_SERVER) {
  415             echo '<pre>';
  416             foreach ($this->errors as $e) {
  417                 print_r($e);
  418             }
  419             echo '</pre>';
  420         }
  421     }
  422 
  423     /**
  424      * Get an array of error messages, if any.
  425      *
  426      * @return array
  427      */
  428     public function getErrors()
  429     {
  430         return $this->errors;
  431     }
  432 
  433     /**
  434      * POP3 connection error handler.
  435      *
  436      * @param int    $errno
  437      * @param string $errstr
  438      * @param string $errfile
  439      * @param int    $errline
  440      */
  441     protected function catchWarning($errno, $errstr, $errfile, $errline)
  442     {
  443         $this->setError(
  444             'Connecting to the POP3 server raised a PHP warning:' .
  445             "errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
  446         );
  447     }
  448 }