smtp.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 992 行 · 第 1/3 页
PHP
992 行
if (PEAR::isError($error = $this->_put('QUIT'))) {
return $error;
}
if (PEAR::isError($error = $this->_parseResponse(221))) {
return $error;
}
if (PEAR::isError($error = $this->_socket->disconnect())) {
return PEAR::raiseError('Failed to disconnect socket: ' .
$error->getMessage());
}
return true;
}
/**
* Attempt to send the EHLO command and obtain a list of ESMTP
* extensions available, and failing that just send HELO.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
*
* @access private
* @since 1.1.0
*/
function _negotiate()
{
if (PEAR::isError($error = $this->_put('EHLO', $this->localhost))) {
return $error;
}
if (PEAR::isError($this->_parseResponse(250))) {
/* If we receive a 503 response, we're already authenticated. */
if ($this->_code === 503) {
return true;
}
/* If the EHLO failed, try the simpler HELO command. */
if (PEAR::isError($error = $this->_put('HELO', $this->localhost))) {
return $error;
}
if (PEAR::isError($this->_parseResponse(250))) {
return PEAR::raiseError('HELO was not accepted: ', $this->_code);
}
return true;
}
foreach ($this->_arguments as $argument) {
$verb = strtok($argument, ' ');
$arguments = substr($argument, strlen($verb) + 1,
strlen($argument) - strlen($verb) - 1);
$this->_esmtp[$verb] = $arguments;
}
return true;
}
/**
* Returns the name of the best authentication method that the server
* has advertised.
*
* @return mixed Returns a string containing the name of the best
* supported authentication method or a PEAR_Error object
* if a failure condition is encountered.
* @access private
* @since 1.1.0
*/
function _getBestAuthMethod()
{
$available_methods = explode(' ', $this->_esmtp['AUTH']);
foreach ($this->auth_methods as $method) {
if (in_array($method, $available_methods)) {
return $method;
}
}
return PEAR::raiseError('No supported authentication methods');
}
/**
* Attempt to do SMTP authentication.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
* @param string The requested authentication method. If none is
* specified, the best supported method will be used.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access public
* @since 1.0
*/
function auth($uid, $pwd , $method = '')
{
if (empty($this->_esmtp['AUTH'])) {
return PEAR::raiseError('SMTP server does no support authentication');
}
/* If no method has been specified, get the name of the best
* supported method advertised by the SMTP server. */
if (empty($method)) {
if (PEAR::isError($method = $this->_getBestAuthMethod())) {
/* Return the PEAR_Error object from _getBestAuthMethod(). */
return $method;
}
} else {
$method = strtoupper($method);
if (!in_array($method, $this->auth_methods)) {
return PEAR::raiseError("$method is not a supported authentication method");
}
}
switch ($method) {
case 'DIGEST-MD5':
$result = $this->_authDigest_MD5($uid, $pwd);
break;
case 'CRAM-MD5':
$result = $this->_authCRAM_MD5($uid, $pwd);
break;
case 'LOGIN':
$result = $this->_authLogin($uid, $pwd);
break;
case 'PLAIN':
$result = $this->_authPlain($uid, $pwd);
break;
default:
$result = PEAR::raiseError("$method is not a supported authentication method");
break;
}
/* If an error was encountered, return the PEAR_Error object. */
if (PEAR::isError($result)) {
return $result;
}
return true;
}
/**
* Authenticates the user using the DIGEST-MD5 method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authDigest_MD5($uid, $pwd)
{
if (PEAR::isError($error = $this->_put('AUTH', 'DIGEST-MD5'))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$challenge = base64_decode($this->_arguments[0]);
$digest = &Auth_SASL::factory('digestmd5');
$auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge,
$this->host, "smtp"));
if (PEAR::isError($error = $this->_put($auth_str))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
return $error;
}
/* We don't use the protocol's third step because SMTP doesn't
* allow subsequent authentication, so we just silently ignore
* it. */
if (PEAR::isError($error = $this->_put(' '))) {
return $error;
}
/* 235: Authentication successful */
if (PEAR::isError($error = $this->_parseResponse(235))) {
return $error;
}
}
/**
* Authenticates the user using the CRAM-MD5 method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authCRAM_MD5($uid, $pwd)
{
if (PEAR::isError($error = $this->_put('AUTH', 'CRAM-MD5'))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$challenge = base64_decode($this->_arguments[0]);
$cram = &Auth_SASL::factory('crammd5');
$auth_str = base64_encode($cram->getResponse($uid, $pwd, $challenge));
if (PEAR::isError($error = $this->_put($auth_str))) {
return $error;
}
/* 235: Authentication successful */
if (PEAR::isError($error = $this->_parseResponse(235))) {
return $error;
}
}
/**
* Authenticates the user using the LOGIN method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authLogin($uid, $pwd)
{
if (PEAR::isError($error = $this->_put('AUTH', 'LOGIN'))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
if (PEAR::isError($error = $this->_put(base64_encode($uid)))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
return $error;
}
if (PEAR::isError($error = $this->_put(base64_encode($pwd)))) {
return $error;
}
/* 235: Authentication successful */
if (PEAR::isError($error = $this->_parseResponse(235))) {
return $error;
}
return true;
}
/**
* Authenticates the user using the PLAIN method.
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access private
* @since 1.1.0
*/
function _authPlain($uid, $pwd)
{
if (PEAR::isError($error = $this->_put('AUTH', 'PLAIN'))) {
return $error;
}
/* 334: Continue authentication request */
if (PEAR::isError($error = $this->_parseResponse(334))) {
/* 503: Error: already authenticated */
if ($this->_code === 503) {
return true;
}
return $error;
}
$auth_str = base64_encode(chr(0) . $uid . chr(0) . $pwd);
if (PEAR::isError($error = $this->_put($auth_str))) {
return $error;
}
/* 235: Authentication successful */
if (PEAR::isError($error = $this->_parseResponse(235))) {
return $error;
}
return true;
}
/**
* Send the HELO command.
*
* @param string The domain name to say we are.
*
* @return mixed Returns a PEAR_Error with an error message on any
* kind of failure, or true on success.
* @access public
* @since 1.0
*/
function helo($domain)
{
if (PEAR::isError($error = $this->_put('HELO', $domain))) {
return $error;
}
if (PEAR::isError($error = $this->_parseResponse(250))) {
return $error;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?