pop3.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,227 行 · 第 1/3 页
PHP
1,227 行
<?php
// +-----------------------------------------------------------------------+
// | Copyright (c) 2002, Richard Heyes |
// | All rights reserved. |
// | |
// | Redistribution and use in source and binary forms, with or without |
// | modification, are permitted provided that the following conditions |
// | are met: |
// | |
// | o Redistributions of source code must retain the above copyright |
// | notice, this list of conditions and the following disclaimer. |
// | o Redistributions in binary form must reproduce the above copyright |
// | notice, this list of conditions and the following disclaimer in the |
// | documentation and/or other materials provided with the distribution.|
// | o The names of the authors may not be used to endorse or promote |
// | products derived from this software without specific prior written |
// | permission. |
// | |
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// | |
// +-----------------------------------------------------------------------+
// | Author: Richard Heyes <richard@phpguru.org> |
// | Co-Author: Damian Fernandez Sosa <damlists@cnba.uba.ar> |
// +-----------------------------------------------------------------------+
//
// $Id: POP3.php 6819 2007-06-20 13:09:21Z kevin_fourie $
require_once('Net/Socket.php');
/**
* +----------------------------- IMPORTANT ------------------------------+
* | Usage of this class compared to native php extensions such as IMAP |
* | is slow and may be feature deficient. If available you are STRONGLY |
* | recommended to use the php extensions. |
* +----------------------------------------------------------------------+
*
* POP3 Access Class
*
* For usage see the example script
*/
define('NET_POP3_STATE_DISCONNECTED', 1, true);
define('NET_POP3_STATE_AUTHORISATION', 2, true);
define('NET_POP3_STATE_TRANSACTION', 4, true);
class Net_POP3 {
/*
* Some basic information about the mail drop
* garnered from the STAT command
*
* @var array
*/
var $_maildrop;
/*
* Used for APOP to store the timestamp
*
* @var string
*/
var $_timestamp;
/*
* Timeout that is passed to the socket object
*
* @var integer
*/
var $_timeout;
/*
* Socket object
*
* @var object
*/
var $_socket;
/*
* Current state of the connection. Used with the
* constants defined above.
*
* @var integer
*/
var $_state;
/*
* Hostname to connect to
*
* @var string
*/
var $_host;
/*
* Port to connect to
*
* @var integer
*/
var $_port;
/**
* To allow class debuging
* @var boolean
*/
var $_debug = false;
/**
* The auth methods this class support
* @var array
*/
//var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER');
//Disabling DIGEST-MD5 for now
var $supportedAuthMethods=array( 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER');
//var $supportedAuthMethods=array( 'CRAM-MD5', 'PLAIN' , 'LOGIN');
//var $supportedAuthMethods=array( 'PLAIN' , 'LOGIN');
/**
* The auth methods this class support
* @var array
*/
var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5');
/**
* The capability response
* @var array
*/
var $_capability;
/*
* Constructor. Sets up the object variables, and instantiates
* the socket object.
*
*/
function Net_POP3()
{
$this->_timestamp = ''; // Used for APOP
$this->_maildrop = array();
$this->_timeout = 3;
$this->_state = NET_POP3_STATE_DISCONNECTED;
$this->_socket =& new Net_Socket();
/*
* Include the Auth_SASL package. If the package is not available,
* we disable the authentication methods that depend upon it.
*/
if ((@include_once 'Auth/SASL.php') == false) {
if($this->_debug){
echo "AUTH_SASL NOT PRESENT!\n";
}
foreach($this->supportedSASLAuthMethods as $SASLMethod){
$pos = array_search( $SASLMethod, $this->supportedAuthMethods );
if($this->_debug){
echo "DISABLING METHOD $SASLMethod\n";
}
unset($this->supportedAuthMethods[$pos]);
}
}
}
/**
* Handles the errors the class can find
* on the server
*
* @access private
* @return PEAR_Error
*/
function _raiseError($msg, $code =-1)
{
include_once 'PEAR.php';
return PEAR::raiseError($msg, $code);
}
/*
* Connects to the given host on the given port.
* Also looks for the timestamp in the greeting
* needed for APOP authentication
*
* @param string $host Hostname/IP address to connect to
* @param string $port Port to use to connect to on host
* @return bool Success/Failure
*/
function connect($host = 'localhost', $port = 110)
{
$this->_host = $host;
$this->_port = $port;
$result = $this->_socket->connect($host, $port, false, $this->_timeout);
if ($result === true) {
$data = $this->_recvLn();
if( $this->_checkResponse($data) ){
// if the response begins with '+OK' ...
// if (@substr(strtoupper($data), 0, 3) == '+OK') {
// Check for string matching apop timestamp
if (preg_match('/<.+@.+>/U', $data, $matches)) {
$this->_timestamp = $matches[0];
}
$this->_maildrop = array();
$this->_state = NET_POP3_STATE_AUTHORISATION;
return true;
}
}
$this->_socket->disconnect();
return false;
}
/*
* Disconnect function. Sends the QUIT command
* and closes the socket.
*
* @return bool Success/Failure
*/
function disconnect()
{
return $this->_cmdQuit();
}
/*
* Performs the login procedure. If there is a timestamp
* stored, APOP will be tried first, then basic USER/PASS.
*
* @param string $user Username to use
* @param string $pass Password to use
* @param mixed $apop Whether to try APOP first, if used as string you can select the auth methd to use ( $pop3->login('validlogin', 'validpass', "CRAM-MD5");
* Valid methods are: 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER'
* @return mixed true on Success/ PEAR_ERROR on error
*/
function login($user, $pass, $apop = true)
{
if ($this->_state == NET_POP3_STATE_AUTHORISATION) {
if(PEAR::isError($ret= $this->_cmdAuthenticate($user , $pass , $apop ) ) ){
return $ret;
}
if( ! PEAR::isError($ret)){
$this->_state = NET_POP3_STATE_TRANSACTION;
return true;
}
}
return $this->_raiseError('Generic login error' , 1);
}
/**
* Parses the response from the capability command. Stores
* the result in $this->_capability
*
* @access private
*/
function _parseCapability()
{
if(!PEAR::isError($data = $this->_sendCmd('CAPA'))){
$data = $this->_getMultiline();
}else {
// CAPA command not supported, reset data var
// to avoid Notice errors of preg_split on an object
$data = '';
}
$data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY);
for ($i = 0; $i < count($data); $i++) {
$capa='';
if (preg_match('/^([a-z,\-]+)( ((.*))|$)$/i', $data[$i], $matches)) {
$capa=strtolower($matches[1]);
switch ($capa) {
case 'implementation':
$this->_capability['implementation'] = $matches[3];
break;
case 'sasl':
$this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
break;
default :
$this->_capability[$capa] = $matches[2];
break;
}
}
}
}
/**
* Returns the name of the best authentication method that the server
* has advertised.
*
* @param string if !=null,authenticate with this method ($userMethod).
*
* @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.0
*/
function _getBestAuthMethod($userMethod = null)
{
/*
return 'USER';
return 'APOP';
return 'DIGEST-MD5';
return 'CRAM-MD5';
*/
$this->_parseCapability();
//unset($this->_capability['sasl']);
if( isset($this->_capability['sasl']) ){
$serverMethods=$this->_capability['sasl'];
}else{
$serverMethods=array('USER');
// Check for timestamp before attempting APOP
if ($this->_timestamp != null)
{
$serverMethods[] = 'APOP';
}
}
if($userMethod !== null && $userMethod !== true ){
$methods = array();
$methods[] = $userMethod;
return $userMethod;
}else{
$methods = $this->supportedAuthMethods;
}
if( ($methods != null) && ($serverMethods != null)){
foreach ( $methods as $method ) {
if ( in_array( $method , $serverMethods ) ) {
return $method;
}
}
$serverMethods=implode(',' , $serverMethods );
$myMethods=implode(',' ,$this->supportedAuthMethods);
return $this->_raiseError("$method NOT supported authentication method!. This server " .
"supports these methods: $serverMethods, but I support $myMethods");
}else{
return $this->_raiseError("This server don't support any Auth methods");
}
}
/* Handles the authentication using any known method
*
* @param string The userid to authenticate as.
* @param string The password to authenticate with.
* @param string The method to use ( if $usermethod == '' then the class chooses the best method (the stronger is the best ) )
*
* @return mixed string or PEAR_Error
*
* @access private
* @since 1.0
*/
function _cmdAuthenticate($uid , $pwd , $userMethod = null )
{
if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) {
return $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 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?