Submit
Path:
~
/
home
/
decas683
/
public_html
/
wordpress
/
wp-includes
/
File Content:
class-smtp.php
<?php /** * PHPMailer RFC821 SMTP email transport class. * PHP Version 5 * @package PHPMailer * @link 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 2014 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. */ /** * PHPMailer RFC821 SMTP email transport class. * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server. * @package PHPMailer * @author Chris Ryan * @author Marcus Bointon <phpmailer@synchromedia.co.uk> */ class SMTP { /** * The PHPMailer SMTP version number. * @var string */ const VERSION = '5.2.22'; /** * SMTP line break constant. * @var string */ const CRLF = "\r\n"; /** * The SMTP port to use if one is not specified. * @var integer */ const DEFAULT_SMTP_PORT = 25; /** * The maximum line length allowed by RFC 2822 section 2.1.1 * @var integer */ const MAX_LINE_LENGTH = 998; /** * Debug level for no output */ const DEBUG_OFF = 0; /** * Debug level to show client -> server messages */ const DEBUG_CLIENT = 1; /** * Debug level to show client -> server and server -> client messages */ const DEBUG_SERVER = 2; /** * Debug level to show connection status, client -> server and server -> client messages */ const DEBUG_CONNECTION = 3; /** * Debug level to show all messages */ const DEBUG_LOWLEVEL = 4; /** * The PHPMailer SMTP Version number. * @var string * @deprecated Use the `VERSION` constant instead * @see SMTP::VERSION */ public $Version = '5.2.22'; /** * SMTP server port number. * @var integer * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead * @see SMTP::DEFAULT_SMTP_PORT */ public $SMTP_PORT = 25; /** * SMTP reply line ending. * @var string * @deprecated Use the `CRLF` constant instead * @see SMTP::CRLF */ public $CRLF = "\r\n"; /** * Debug output level. * Options: * * self::DEBUG_OFF (`0`) No debug output, default * * self::DEBUG_CLIENT (`1`) Client commands * * self::DEBUG_SERVER (`2`) Client commands and server responses * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages * @var integer */ public $do_debug = self::DEBUG_OFF; /** * How to handle debug output. * Options: * * `echo` Output plain-text as-is, appropriate for CLI * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output * * `error_log` Output to error log as configured in php.ini * * Alternatively, you can provide a callable expecting two params: a message string and the debug level: * <code> * $smtp->Debugoutput = function($str, $level) {echo "debug level $level; message: $str";}; * </code> * @var string|callable */ public $Debugoutput = 'echo'; /** * Whether to use VERP. * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path * @link http://www.postfix.org/VERP_README.html Info on VERP * @var boolean */ public $do_verp = false; /** * The timeout value for connection, in seconds. * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure. * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2 * @var integer */ public $Timeout = 300; /** * How long to wait for commands to complete, in seconds. * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2 * @var integer */ public $Timelimit = 300; /** * @var array patterns to extract smtp transaction id from smtp reply * Only first capture group will be use, use non-capturing group to deal with it * Extend this class to override this property to fulfil your needs. */ protected $smtp_transaction_id_patterns = array( 'exim' => '/[0-9]{3} OK id=(.*)/', 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/' ); /** * The socket for the server connection. * @var resource */ protected $smtp_conn; /** * Error information, if any, for the last SMTP command. * @var array */ protected $error = array( 'error' => '', 'detail' => '', 'smtp_code' => '', 'smtp_code_ex' => '' ); /** * The reply the server sent to us for HELO. * If null, no HELO string has yet been received. * @var string|null */ protected $helo_rply = null; /** * The set of SMTP extensions sent in reply to EHLO command. * Indexes of the array are extension names. * Value at index 'HELO' or 'EHLO' (according to command that was sent) * represents the server name. In case of HELO it is the only element of the array. * Other values can be boolean TRUE or an array containing extension options. * If null, no HELO/EHLO string has yet been received. * @var array|null */ protected $server_caps = null; /** * The most recent reply received from the server. * @var string */ protected $last_reply = ''; /** * Output debugging info via a user-selected method. * @see SMTP::$Debugoutput * @see SMTP::$do_debug * @param string $str Debug string to output * @param integer $level The debug level of this message; see DEBUG_* constants * @return void */ protected function edebug($str, $level = 0) { if ($level > $this->do_debug) { return; } //Avoid clash with built-in function names if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) { call_user_func($this->Debugoutput, $str, $level); return; } switch ($this->Debugoutput) { case 'error_log': //Don't output, just log error_log($str); break; case 'html': //Cleans up output a bit for a better looking, HTML-safe output echo htmlentities( preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8' ) . "<br>\n"; break; case 'echo': default: //Normalize line breaks $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str); echo gmdate('Y-m-d H:i:s') . "\t" . str_replace( "\n", "\n \t ", trim($str) )."\n"; } } /** * Connect to an SMTP server. * @param string $host SMTP server IP or host name * @param integer $port The port number to connect to * @param integer $timeout How long to wait for the connection to open * @param array $options An array of options for stream_context_create() * @access public * @return boolean */ public function connect($host, $port = null, $timeout = 30, $options = array()) { static $streamok; //This is enabled by default since 5.0.0 but some providers disable it //Check this once and cache the result if (is_null($streamok)) { $streamok = function_exists('stream_socket_client'); } // Clear errors to avoid confusion $this->setError(''); // Make sure we are __not__ connected if ($this->connected()) { // Already connected, generate error $this->setError('Already connected to a server'); return false; } if (empty($port)) { $port = self::DEFAULT_SMTP_PORT; } // Connect to the SMTP server $this->edebug( "Connection: opening to $host:$port, timeout=$timeout, options=".var_export($options, true), self::DEBUG_CONNECTION ); $errno = 0; $errstr = ''; if ($streamok) { $socket_context = stream_context_create($options); set_error_handler(array($this, 'errorHandler')); $this->smtp_conn = stream_socket_client( $host . ":" . $port, $errno, $errstr, $timeout, 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( "Connection: stream_socket_client not available, falling back to fsockopen", self::DEBUG_CONNECTION ); set_error_handler(array($this, 'errorHandler')); $this->smtp_conn = fsockopen( $host, $port, $errno, $errstr, $timeout ); restore_error_handler(); } // Verify we connected properly if (!is_resource($this->smtp_conn)) { $this->setError( 'Failed to connect to server', $errno, $errstr ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] . ": $errstr ($errno)", self::DEBUG_CLIENT ); 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 if (substr(PHP_OS, 0, 3) != 'WIN') { $max = ini_get('max_execution_time'); // Don't bother if unlimited if ($max != 0 && $timeout > $max) { @set_time_limit($timeout); } stream_set_timeout($this->smtp_conn, $timeout, 0); } // Get any announcement $announce = $this->get_lines(); $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER); return true; } /** * Initiate a TLS (encrypted) session. * @access public * @return boolean */ public function startTLS() { if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) { return false; } //Allow the best TLS version(s) we can $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT; //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT //so add them back in manually if we can if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) { $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; } // Begin encrypted connection if (!stream_socket_enable_crypto( $this->smtp_conn, true, $crypto_method )) { return false; } return true; } /** * Perform SMTP authentication. * Must be run after hello(). * @see hello() * @param string $username The user name * @param string $password The password * @param string $authtype The auth type (PLAIN, LOGIN, CRAM-MD5) * @param string $realm The auth realm for NTLM * @param string $workstation The auth workstation for NTLM * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth) * @return bool True if successfully authenticated.* @access public */ public function authenticate( $username, $password, $authtype = null, $realm = '', $workstation = '', $OAuth = null ) { if (!$this->server_caps) { $this->setError('Authentication is not allowed before HELO/EHLO'); return false; } if (array_key_exists('EHLO', $this->server_caps)) { // SMTP extensions are available. Let's 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 return false; } self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL); self::edebug( 'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), self::DEBUG_LOWLEVEL ); if (empty($authtype)) { foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN') as $method) { if (in_array($method, $this->server_caps['AUTH'])) { $authtype = $method; break; } } if (empty($authtype)) { $this->setError('No supported authentication methods found'); return false; } self::edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL); } if (!in_array($authtype, $this->server_caps['AUTH'])) { $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); return false; } } elseif (empty($authtype)) { $authtype = 'LOGIN'; } switch ($authtype) { case 'PLAIN': // 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 ) ) { return false; } break; case 'LOGIN': // Start authentication if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) { return false; } if (!$this->sendCommand("Username", base64_encode($username), 334)) { return false; } if (!$this->sendCommand("Password", base64_encode($password), 235)) { return false; } break; case 'CRAM-MD5': // Start authentication if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { return false; } // Get the challenge $challenge = base64_decode(substr($this->last_reply, 4)); // Build the response $response = $username . ' ' . $this->hmac($challenge, $password); // send encoded credentials return $this->sendCommand('Username', base64_encode($response), 235); default: $this->setError("Authentication method \"$authtype\" is not supported"); return false; } return true; } /** * Calculate an MD5 HMAC hash. * Works like hash_hmac('md5', $data, $key) * in case that function is not available * @param string $data The data to hash * @param string $key The key to hash with * @access protected * @return string */ protected function hmac($data, $key) { if (function_exists('hash_hmac')) { return hash_hmac('md5', $data, $key); } // 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 $bytelen = 64; // byte length for md5 if (strlen($key) > $bytelen) { $key = pack('H*', md5($key)); } $key = str_pad($key, $bytelen, chr(0x00)); $ipad = str_pad('', $bytelen, chr(0x36)); $opad = str_pad('', $bytelen, chr(0x5c)); $k_ipad = $key ^ $ipad; $k_opad = $key ^ $opad; return md5($k_opad . pack('H*', md5($k_ipad . $data))); } /** * Check connection state. * @access public * @return boolean True if connected. */ public function connected() { 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 $this->edebug( 'SMTP NOTICE: EOF caught while checking if connected', self::DEBUG_CLIENT ); $this->close(); return false; } return true; // everything looks good } return false; } /** * Close the socket and clean up the state of the class. * Don't use this function without first trying to use QUIT. * @see quit() * @access public * @return void */ public function close() { $this->setError(''); $this->server_caps = null; $this->helo_rply = null; if (is_resource($this->smtp_conn)) { // close the connection and cleanup fclose($this->smtp_conn); $this->smtp_conn = null; //Makes for cleaner serialization $this->edebug('Connection: closed', self::DEBUG_CONNECTION); } } /** * 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 * 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 and additional <CRLF>. * Implements rfc 821: DATA <CRLF> * @param string $msg_data Message data to send * @access public * @return boolean */ public function data($msg_data) { //This will use the standard timelimit if (!$this->sendCommand('DATA', 'DATA', 354)) { return false; } /* The server is ready to accept data! * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into * smaller lines to fit within the limit. * We will also look for lines that start with a '.' and prepend an additional '.'. * NOTE: this does not count towards line-length limit. */ // Normalize line breaks before exploding $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data)); /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field * of the first line (':' separated) does not contain a space then it _should_ be a header and we will * process all lines before a blank line as headers. */ $field = substr($lines[0], 0, strpos($lines[0], ':')); $in_headers = false; if (!empty($field) && strpos($field, ' ') === false) { $in_headers = true; } foreach ($lines as $line) { $lines_out = array(); if ($in_headers and $line == '') { $in_headers = false; } //Break this line up into several smaller lines if it's too long //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len), while (isset($line[self::MAX_LINE_LENGTH])) { //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on //so as to avoid breaking in the middle of a word $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' '); //Deliberately matches both false and 0 if (!$pos) { //No nice break found, add a hard break $pos = self::MAX_LINE_LENGTH - 1; $lines_out[] = substr($line, 0, $pos); $line = substr($line, $pos); } else { //Break at the found point $lines_out[] = substr($line, 0, $pos); //Move along by the amount we dealt with $line = substr($line, $pos + 1); } //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1 if ($in_headers) { $line = "\t" . $line; } } $lines_out[] = $line; //Send the lines to the server foreach ($lines_out as $line_out) { //RFC2821 section 4.5.2 if (!empty($line_out) and $line_out[0] == '.') { $line_out = '.' . $line_out; } $this->client_send($line_out . self::CRLF); } } //Message data has been sent, complete the command //Increase timelimit for end of DATA command $savetimelimit = $this->Timelimit; $this->Timelimit = $this->Timelimit * 2; $result = $this->sendCommand('DATA END', '.', 250); //Restore timelimit $this->Timelimit = $savetimelimit; return $result; } /** * Send an SMTP HELO or EHLO command. * Used to identify the sending server to the receiving server. * This makes sure that client and server are in a known state. * Implements RFC 821: HELO <SP> <domain> <CRLF> * and RFC 2821 EHLO. * @param string $host The host name or IP to connect to * @access public * @return boolean */ public function hello($host = '') { //Try extended hello first (RFC 2821) return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host)); } /** * Send an SMTP HELO or EHLO command. * Low-level implementation used by hello() * @see hello() * @param string $hello The HELO string * @param string $host The hostname to say we are * @access protected * @return boolean */ protected function sendHello($hello, $host) { $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250); $this->helo_rply = $this->last_reply; if ($noerror) { $this->parseHelloFields($hello); } else { $this->server_caps = null; } return $noerror; } /** * Parse a reply to HELO/EHLO command to discover server extensions. * In case of HELO, the only parameter that can be discovered is a server name. * @access protected * @param string $type - 'HELO' or 'EHLO' */ protected function parseHelloFields($type) { $this->server_caps = array(); $lines = explode("\n", $this->helo_rply); foreach ($lines as $n => $s) { //First 4 chars contain response code followed by - or space $s = trim(substr($s, 4)); if (empty($s)) { continue; } $fields = explode(' ', $s); if (!empty($fields)) { if (!$n) { $name = $type; $fields = $fields[0]; } else { $name = array_shift($fields); switch ($name) { case 'SIZE': $fields = ($fields ? $fields[0] : 0); break; case 'AUTH': if (!is_array($fields)) { $fields = array(); } break; default: $fields = true; } } $this->server_caps[$name] = $fields; } } } /** * Send an SMTP MAIL command. * Starts a mail transaction from the email address specified in * $from. Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more recipient * commands may be called followed by a data command. * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF> * @param string $from Source address of this message * @access public * @return boolean */ public function mail($from) { $useVerp = ($this->do_verp ? ' XVERP' : ''); return $this->sendCommand( 'MAIL FROM', 'MAIL FROM:<' . $from . '>' . $useVerp, 250 ); } /** * Send an SMTP QUIT command. * Closes the socket if there is no error or the $close_on_error argument is true. * Implements from rfc 821: QUIT <CRLF> * @param boolean $close_on_error Should the connection close if an error occurs? * @access public * @return boolean */ public function quit($close_on_error = true) { $noerror = $this->sendCommand('QUIT', 'QUIT', 221); $err = $this->error; //Save any error if ($noerror or $close_on_error) { $this->close(); $this->error = $err; //Restore any error from the quit command } return $noerror; } /** * Send an SMTP RCPT command. * Sets the TO argument to $toaddr. * Returns true if the recipient was accepted false if it was rejected. * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF> * @param string $address The address the message is being sent to * @access public * @return boolean */ public function recipient($address) { return $this->sendCommand( 'RCPT TO', 'RCPT TO:<' . $address . '>', array(250, 251) ); } /** * Send an SMTP RSET command. * Abort any transaction that is currently in progress. * Implements rfc 821: RSET <CRLF> * @access public * @return boolean True on success. */ public function reset() { return $this->sendCommand('RSET', 'RSET', 250); } /** * Send a command to an SMTP server and check its return code. * @param string $command The command name - not sent to the server * @param string $commandstring The actual command to send * @param integer|array $expect One or more expected integer success codes * @access protected * @return boolean True on success. */ protected function sendCommand($command, $commandstring, $expect) { if (!$this->connected()) { $this->setError("Called $command without being connected"); return false; } //Reject line breaks in all commands if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) { $this->setError("Command '$command' contained line breaks"); return false; } $this->client_send($commandstring . self::CRLF); $this->last_reply = $this->get_lines(); // Fetch SMTP code and possible error code explanation $matches = array(); if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) { $code = $matches[1]; $code_ex = (count($matches) > 2 ? $matches[2] : null); // Cut off error code from each response line $detail = preg_replace( "/{$code}[ -]".($code_ex ? str_replace('.', '\\.', $code_ex).' ' : '')."/m", '', $this->last_reply ); } else { // Fall back to simple parsing if regex fails $code = substr($this->last_reply, 0, 3); $code_ex = null; $detail = substr($this->last_reply, 4); } $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER); if (!in_array($code, (array)$expect)) { $this->setError( "$command command failed", $detail, $code, $code_ex ); $this->edebug( 'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, self::DEBUG_CLIENT ); return false; } $this->setError(''); return true; } /** * Send an SMTP SAML command. * Starts a mail transaction from the email address specified in $from. * Returns true if successful or false otherwise. If True * the mail transaction is started and then one or more recipient * commands may be called followed by a data command. This command * will send the message to the users terminal if they are logged * in and send them an email. * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF> * @param string $from The address the message is from * @access public * @return boolean */ public function sendAndMail($from) { return $this->sendCommand('SAML', "SAML FROM:$from", 250); } /** * Send an SMTP VRFY command. * @param string $name The name to verify * @access public * @return boolean */ public function verify($name) { return $this->sendCommand('VRFY', "VRFY $name", array(250, 251)); } /** * Send an SMTP NOOP command. * Used to keep keep-alives alive, doesn't actually do anything * @access public * @return boolean */ public function noop() { return $this->sendCommand('NOOP', 'NOOP', 250); } /** * Send an SMTP TURN command. * This is an optional command for SMTP that this class does not support. * This method is here to make the RFC821 Definition complete for this class * and _may_ be implemented in future * Implements from rfc 821: TURN <CRLF> * @access public * @return boolean */ public function turn() { $this->setError('The SMTP TURN command is not implemented'); $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT); return false; } /** * Send raw data to the server. * @param string $data The data to send * @access public * @return integer|boolean The number of bytes sent to the server or false on error */ public function client_send($data) { $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT); return fwrite($this->smtp_conn, $data); } /** * Get the latest error. * @access public * @return array */ public function getError() { return $this->error; } /** * Get SMTP extensions available on the server * @access public * @return array|null */ public function getServerExtList() { return $this->server_caps; } /** * A multipurpose method * The method works in three ways, dependent on argument value and current state * 1. HELO/EHLO was not sent - returns null and set up $this->error * 2. HELO was sent * $name = 'HELO': returns server name * $name = 'EHLO': returns boolean false * $name = any string: returns null and set up $this->error * 3. EHLO was sent * $name = 'HELO'|'EHLO': returns server name * $name = any string: if extension $name exists, returns boolean True * or its options. Otherwise returns boolean False * In other words, one can use this method to detect 3 conditions: * - null returned: handshake was not or we don't know about ext (refer to $this->error) * - false returned: the requested feature exactly not exists * - positive value returned: the requested feature exists * @param string $name Name of SMTP extension or 'HELO'|'EHLO' * @return mixed */ public function getServerExt($name) { if (!$this->server_caps) { $this->setError('No HELO/EHLO was sent'); return null; } // the tight logic knot ;) if (!array_key_exists($name, $this->server_caps)) { if ($name == 'HELO') { return $this->server_caps['EHLO']; } if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) { return false; } $this->setError('HELO handshake was used. Client knows nothing about server extensions'); return null; } return $this->server_caps[$name]; } /** * Get the last reply from the server. * @access public * @return string */ public function getLastReply() { return $this->last_reply; } /** * Read the SMTP server's response. * Either before eof or socket timeout occurs on the operation. * With SMTP we can tell if we have more lines to read if the * 4th character is '-' symbol. If it is a space then we don't * need to read anything else. * @access protected * @return string */ protected function get_lines() { // If the connection is bad, give up straight away if (!is_resource($this->smtp_conn)) { return ''; } $data = ''; $endtime = 0; stream_set_timeout($this->smtp_conn, $this->Timeout); if ($this->Timelimit > 0) { $endtime = time() + $this->Timelimit; } while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) { $str = @fgets($this->smtp_conn, 515); $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL); $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL); $data .= $str; // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen if ((isset($str[3]) and $str[3] == ' ')) { 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)', self::DEBUG_LOWLEVEL ); break; } // Now check if reads took too long if ($endtime and time() > $endtime) { $this->edebug( 'SMTP -> get_lines(): timelimit reached ('. $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL ); break; } } return $data; } /** * Enable or disable VERP address generation. * @param boolean $enabled */ public function setVerp($enabled = false) { $this->do_verp = $enabled; } /** * Get VERP address generation mode. * @return boolean */ public function getVerp() { return $this->do_verp; } /** * Set error messages and codes. * @param string $message The error message * @param string $detail Further detail on the error * @param string $smtp_code An associated SMTP error code * @param string $smtp_code_ex Extended SMTP code */ protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') { $this->error = array( 'error' => $message, 'detail' => $detail, 'smtp_code' => $smtp_code, 'smtp_code_ex' => $smtp_code_ex ); } /** * Set debug output method. * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it. */ public function setDebugOutput($method = 'echo') { $this->Debugoutput = $method; } /** * Get debug output method. * @return string */ public function getDebugOutput() { return $this->Debugoutput; } /** * Set debug output level. * @param integer $level */ public function setDebugLevel($level = 0) { $this->do_debug = $level; } /** * Get debug output level. * @return integer */ public function getDebugLevel() { return $this->do_debug; } /** * Set SMTP timeout. * @param integer $timeout */ public function setTimeout($timeout = 0) { $this->Timeout = $timeout; } /** * Get SMTP timeout. * @return integer */ public function getTimeout() { return $this->Timeout; } /** * Reports an error number and string. * @param integer $errno The error number returned by PHP. * @param string $errmsg The error message returned by PHP. */ protected function errorHandler($errno, $errmsg) { $notice = 'Connection: Failed to connect to server.'; $this->setError( $notice, $errno, $errmsg ); $this->edebug( $notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg, self::DEBUG_CONNECTION ); } /** * Will return the ID of the last smtp transaction based on a list of patterns provided * in SMTP::$smtp_transaction_id_patterns. * If no reply has been received yet, it will return null. * If no pattern has been matched, it will return false. * @return bool|null|string */ public function getLastTransactionID() { $reply = $this->getLastReply(); if (empty($reply)) { return null; } foreach($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) { if(preg_match($smtp_transaction_id_pattern, $reply, $matches)) { return $matches[1]; } } return false; } }
Submit
FILE
FOLDER
Name
Size
Permission
Action
ID3
---
0755
IXR
---
0755
Requests
---
0755
SimplePie
---
0755
Text
---
0755
blocks
---
0755
certificates
---
0755
css
---
0755
customize
---
0755
fonts
---
0755
images
---
0755
js
---
0755
pomo
---
0755
random_compat
---
0755
rest-api
---
0755
theme-compat
---
0755
widgets
---
0755
admin-bar.php
28868 bytes
0644
aejsnhgb.php
760 bytes
0644
atomlib.php
11839 bytes
0644
author-template.php
16354 bytes
0644
blocks.php
16243 bytes
0644
bookmark-template.php
11699 bytes
0644
bookmark.php
13682 bytes
0644
cache.php
21621 bytes
0644
canonical.php
27583 bytes
0644
capabilities.php
28649 bytes
0644
category-template.php
51758 bytes
0644
category.php
11984 bytes
0644
class-IXR.php
2573 bytes
0644
class-feed.php
522 bytes
0644
class-http.php
36164 bytes
0644
class-json.php
40472 bytes
0644
class-oembed.php
33148 bytes
0644
class-phpass.php
7317 bytes
0644
class-phpmailer.php
148234 bytes
0644
class-pop3.php
20919 bytes
0644
class-requests.php
29790 bytes
0644
class-simplepie.php
89264 bytes
0644
class-smtp.php
39478 bytes
0644
class-snoopy.php
37785 bytes
0644
class-walker-category-dropdown.php
2099 bytes
0644
class-walker-category.php
6646 bytes
0644
class-walker-comment.php
11173 bytes
0644
class-walker-nav-menu.php
8392 bytes
0644
class-walker-page-dropdown.php
2279 bytes
0644
class-walker-page.php
6713 bytes
0644
class-wp-admin-bar.php
16969 bytes
0644
class-wp-ajax-response.php
5024 bytes
0644
class-wp-block-parser.php
15215 bytes
0644
class-wp-block-type-registry.php
5089 bytes
0644
class-wp-block-type.php
4815 bytes
0644
class-wp-comment-query.php
41780 bytes
0644
class-wp-comment.php
8936 bytes
0644
class-wp-customize-control.php
24984 bytes
0644
class-wp-customize-manager.php
199201 bytes
0644
class-wp-customize-nav-menus.php
53561 bytes
0644
class-wp-customize-panel.php
9576 bytes
0644
class-wp-customize-section.php
10197 bytes
0644
class-wp-customize-setting.php
28132 bytes
0644
class-wp-customize-widgets.php
65752 bytes
0644
class-wp-dependency.php
1992 bytes
0644
class-wp-editor.php
61023 bytes
0644
class-wp-embed.php
14509 bytes
0644
class-wp-error.php
4585 bytes
0644
class-wp-feed-cache-transient.php
2537 bytes
0644
class-wp-feed-cache.php
745 bytes
0644
class-wp-hook.php
14052 bytes
0644
class-wp-http-cookie.php
6456 bytes
0644
class-wp-http-curl.php
11679 bytes
0644
class-wp-http-encoding.php
6444 bytes
0644
class-wp-http-ixr-client.php
3250 bytes
0644
class-wp-http-proxy.php
5957 bytes
0644
class-wp-http-requests-hooks.php
1872 bytes
0644
class-wp-http-requests-response.php
4273 bytes
0644
class-wp-http-response.php
2871 bytes
0644
class-wp-http-streams.php
14995 bytes
0644
class-wp-image-editor-gd.php
12921 bytes
0644
class-wp-image-editor-imagick.php
21676 bytes
0644
class-wp-image-editor.php
11730 bytes
0644
class-wp-list-util.php
6369 bytes
0644
class-wp-locale-switcher.php
5005 bytes
0644
class-wp-locale.php
14547 bytes
0644
class-wp-matchesmapregex.php
1796 bytes
0644
class-wp-meta-query.php
22283 bytes
0644
class-wp-metadata-lazyloader.php
5372 bytes
0644
class-wp-network-query.php
17160 bytes
0644
class-wp-network.php
12129 bytes
0644
class-wp-oembed-controller.php
5944 bytes
0644
class-wp-post-type.php
18236 bytes
0644
class-wp-post.php
6355 bytes
0644
class-wp-query.php
125035 bytes
0644
class-wp-rewrite.php
58908 bytes
0644
class-wp-role.php
2614 bytes
0644
class-wp-roles.php
8187 bytes
0644
class-wp-session-tokens.php
7338 bytes
0644
class-wp-simplepie-file.php
2272 bytes
0644
class-wp-simplepie-sanitize-kses.php
1774 bytes
0644
class-wp-site-query.php
23221 bytes
0644
class-wp-site.php
7318 bytes
0644
class-wp-tax-query.php
19370 bytes
0644
class-wp-taxonomy.php
9993 bytes
0644
class-wp-term-query.php
34167 bytes
0644
class-wp-term.php
5273 bytes
0644
class-wp-text-diff-renderer-inline.php
712 bytes
0644
class-wp-text-diff-renderer-table.php
16180 bytes
0644
class-wp-theme.php
48760 bytes
0644
class-wp-user-meta-session-tokens.php
2916 bytes
0644
class-wp-user-query.php
29525 bytes
0644
class-wp-user.php
20679 bytes
0644
class-wp-walker.php
12378 bytes
0644
class-wp-widget-factory.php
3746 bytes
0644
class-wp-widget.php
17658 bytes
0644
class-wp-xmlrpc-server.php
202146 bytes
0644
class-wp.php
23974 bytes
0644
class.wp-dependencies.php
11185 bytes
0644
class.wp-scripts.php
16749 bytes
0644
class.wp-styles.php
9794 bytes
0644
comment-template.php
88643 bytes
0644
comment.php
111793 bytes
0644
compat.php
17451 bytes
0644
cron.php
16467 bytes
0644
date.php
35454 bytes
0644
default-constants.php
9561 bytes
0644
default-filters.php
28500 bytes
0644
default-widgets.php
2180 bytes
0644
deprecated.php
114267 bytes
0644
embed-template.php
344 bytes
0644
embed.php
45000 bytes
0644
feed-atom-comments.php
5357 bytes
0644
feed-atom.php
3090 bytes
0644
feed-rdf.php
2670 bytes
0644
feed-rss.php
1246 bytes
0644
feed-rss2-comments.php
4064 bytes
0644
feed-rss2.php
3773 bytes
0644
feed.php
19550 bytes
0644
formatting.php
274103 bytes
0644
functions.php
191048 bytes
0644
functions.wp-scripts.php
12538 bytes
0644
functions.wp-styles.php
8080 bytes
0644
general-template.php
140624 bytes
0644
http.php
22182 bytes
0644
jisakwkc.php
760 bytes
0644
kses.php
54239 bytes
0644
l10n.php
50874 bytes
0644
link-template.php
136453 bytes
0644
load.php
34885 bytes
0644
locale.php
141 bytes
0644
media-template.php
46469 bytes
0644
media.php
141152 bytes
0644
meta.php
45613 bytes
0644
ms-blogs.php
39181 bytes
0644
ms-default-constants.php
4715 bytes
0644
ms-default-filters.php
4653 bytes
0644
ms-deprecated.php
16158 bytes
0644
ms-files.php
2620 bytes
0644
ms-functions.php
91131 bytes
0644
ms-load.php
19248 bytes
0644
ms-settings.php
4088 bytes
0644
nav-menu-template.php
20871 bytes
0644
nav-menu.php
39756 bytes
0644
option.php
67744 bytes
0644
p.php
2819 bytes
0644
pluggable-deprecated.php
6262 bytes
0644
pluggable.php
92744 bytes
0644
plugin.php
31677 bytes
0644
post-formats.php
6976 bytes
0644
post-template.php
58915 bytes
0644
post-thumbnail-template.php
8444 bytes
0644
post.php
227295 bytes
0644
query.php
31500 bytes
0644
registration-functions.php
178 bytes
0644
registration.php
178 bytes
0644
rest-api.php
41411 bytes
0644
revision.php
21305 bytes
0644
rewrite.php
17502 bytes
0644
rss-functions.php
191 bytes
0644
rss.php
23208 bytes
0644
script-loader.php
103362 bytes
0644
session.php
242 bytes
0644
setting.php
26825 bytes
0644
shortcodes.php
21396 bytes
0644
spl-autoload-compat.php
2574 bytes
0644
taxonomy.php
150943 bytes
0644
template-loader.php
2896 bytes
0644
template.php
19792 bytes
0644
theme.php
100092 bytes
0644
update.php
24691 bytes
0644
user.php
121518 bytes
0644
vars.php
5582 bytes
0644
version.php
620 bytes
0644
widgets.php
56164 bytes
0644
wlwmanifest.xml
1045 bytes
0644
wp-db.php
99564 bytes
0644
wp-diff.php
661 bytes
0644
N4ST4R_ID | Naxtarrr