diff options
author | matt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2009-01-14 06:40:55 +0300 |
---|---|---|
committer | matt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105> | 2009-01-14 06:40:55 +0300 |
commit | 76071515bf1aa9e1def7f4c185b1ab0cc9c385e6 (patch) | |
tree | 3f10980a093701ec7d7b69af024a6dedca08e0fe /libs/Zend/Mail/Protocol | |
parent | 032b512a4262fa432e5c2aa97d35daaab912ca2b (diff) |
Fixing #452
Diffstat (limited to 'libs/Zend/Mail/Protocol')
-rw-r--r-- | libs/Zend/Mail/Protocol/Abstract.php | 770 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Exception.php | 78 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Imap.php | 1610 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Pop3.php | 922 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Smtp.php | 886 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php | 216 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Smtp/Auth/Login.php | 196 | ||||
-rw-r--r-- | libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php | 192 |
8 files changed, 2435 insertions, 2435 deletions
diff --git a/libs/Zend/Mail/Protocol/Abstract.php b/libs/Zend/Mail/Protocol/Abstract.php index 06988c184e..5b55a22406 100644 --- a/libs/Zend/Mail/Protocol/Abstract.php +++ b/libs/Zend/Mail/Protocol/Abstract.php @@ -1,385 +1,385 @@ -<?php
-
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Validate
- */
-require_once 'Zend/Validate.php';
-
-
-/**
- * @see Zend_Validate_Hostname
- */
-require_once 'Zend/Validate/Hostname.php';
-
-
-/**
- * Zend_Mail_Protocol_Abstract
- *
- * Provides low-level methods for concrete adapters to communicate with a remote mail server and track requests and responses.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
- * @todo Implement proxy settings
- */
-abstract class Zend_Mail_Protocol_Abstract
-{
- /**
- * Mail default EOL string
- */
- const EOL = "\r\n";
-
-
- /**
- * Default timeout in seconds for initiating session
- */
- const TIMEOUT_CONNECTION = 30;
-
-
- /**
- * Hostname or IP address of remote server
- * @var string
- */
- protected $_host;
-
-
- /**
- * Port number of connection
- * @var integer
- */
- protected $_port;
-
-
- /**
- * Instance of Zend_Validate to check hostnames
- * @var Zend_Validate
- */
- protected $_validHost;
-
-
- /**
- * Socket connection resource
- * @var resource
- */
- protected $_socket;
-
-
- /**
- * Last request sent to server
- * @var string
- */
- protected $_request;
-
-
- /**
- * Array of server responses to last request
- * @var array
- */
- protected $_response;
-
-
- /**
- * String template for parsing server responses using sscanf (default: 3 digit code and response string)
- * @var resource
- */
- protected $_template = '%d%s';
-
-
- /**
- * Log of mail requests and server responses for a session
- * @var string
- */
- private $_log;
-
-
- /**
- * Constructor.
- *
- * @param string $host OPTIONAL Hostname of remote connection (default: 127.0.0.1)
- * @param integer $port OPTIONAL Port number (default: null)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null)
- {
- $this->_validHost = new Zend_Validate();
- $this->_validHost->addValidator(new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL));
-
- if (!$this->_validHost->isValid($host)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages()));
- }
-
- $this->_host = $host;
- $this->_port = $port;
- }
-
-
- /**
- * Class destructor to cleanup open resources
- *
- * @return void
- */
- public function __destruct()
- {
- $this->_disconnect();
- }
-
-
- /**
- * Create a connection to the remote host
- *
- * Concrete adapters for this class will implement their own unique connect scripts, using the _connect() method to create the socket resource.
- */
- abstract public function connect();
-
-
- /**
- * Retrieve the last client request
- *
- * @return string
- */
- public function getRequest()
- {
- return $this->_request;
- }
-
-
- /**
- * Retrieve the last server response
- *
- * @return array
- */
- public function getResponse()
- {
- return $this->_response;
- }
-
-
- /**
- * Retrieve the transaction log
- *
- * @return string
- */
- public function getLog()
- {
- return $this->_log;
- }
-
-
- /**
- * Reset the transaction log
- *
- * @return void
- */
- public function resetLog()
- {
- $this->_log = '';
- }
-
-
- /**
- * Connect to the server using the supplied transport and target
- *
- * An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222'
- *
- * @param string $remote Remote
- * @throws Zend_Mail_Protocol_Exception
- * @return boolean
- */
- protected function _connect($remote)
- {
- $errorNum = 0;
- $errorStr = '';
-
- // open connection
- $this->_socket = stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);
-
- if ($this->_socket === false) {
- if ($errorNum == 0) {
- $errorStr = 'Could not open socket';
- }
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($errorStr);
- }
-
- if (($result = stream_set_timeout($this->_socket, self::TIMEOUT_CONNECTION)) === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not set stream timeout');
- }
-
- return $result;
- }
-
-
- /**
- * Disconnect from remote host and free resource
- *
- * @return void
- */
- protected function _disconnect()
- {
- if (is_resource($this->_socket)) {
- fclose($this->_socket);
- }
- }
-
-
- /**
- * Send the given request followed by a LINEEND to the server.
- *
- * @param string $request
- * @throws Zend_Mail_Protocol_Exception
- * @return integer|boolean Number of bytes written to remote host
- */
- protected function _send($request)
- {
- if (!is_resource($this->_socket)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
- }
-
- $this->_request = $request;
-
- $result = fwrite($this->_socket, $request . self::EOL);
-
- // Save request to internal log
- $this->_log .= $request . self::EOL;
-
- if ($result === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host);
- }
-
- return $result;
- }
-
-
- /**
- * Get a line from the stream.
- *
- * @var integer $timeout Per-request timeout value if applicable
- * @throws Zend_Mail_Protocol_Exception
- * @return string
- */
- protected function _receive($timeout = null)
- {
- if (!is_resource($this->_socket)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host);
- }
-
- // Adapters may wish to supply per-commend timeouts according to appropriate RFC
- if ($timeout !== null) {
- stream_set_timeout($this->_socket, $timeout);
- }
-
- // Retrieve response
- $reponse = fgets($this->_socket, 1024);
-
- // Save request to internal log
- $this->_log .= $reponse;
-
- // Check meta data to ensure connection is still valid
- $info = stream_get_meta_data($this->_socket);
-
- if (!empty($info['timed_out'])) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($this->_host . ' has timed out');
- }
-
- if ($reponse === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host);
- }
-
- return $reponse;
- }
-
-
- /**
- * Parse server response for successful codes
- *
- * Read the response from the stream and check for expected return code.
- * Throws a Zend_Mail_Protocol_Exception if an unexpected code is returned.
- *
- * @param string|array $code One or more codes that indicate a successful response
- * @throws Zend_Mail_Protocol_Exception
- * @return string Last line of response string
- */
- protected function _expect($code, $timeout = null)
- {
- $this->_response = array();
- $cmd = '';
- $msg = '';
-
- if (!is_array($code)) {
- $code = array($code);
- }
-
- do {
- $this->_response[] = $result = $this->_receive($timeout);
- sscanf($result, $this->_template, $cmd, $msg);
-
- if ($cmd === null || !in_array($cmd, $code)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($result);
- }
-
- } while (strpos($msg, '-') === 0); // The '-' message prefix indicates an information string instead of a response string.
-
- return $msg;
- }
-}
+<?php + +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Validate + */ +require_once 'Zend/Validate.php'; + + +/** + * @see Zend_Validate_Hostname + */ +require_once 'Zend/Validate/Hostname.php'; + + +/** + * Zend_Mail_Protocol_Abstract + * + * Provides low-level methods for concrete adapters to communicate with a remote mail server and track requests and responses. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $ + * @todo Implement proxy settings + */ +abstract class Zend_Mail_Protocol_Abstract +{ + /** + * Mail default EOL string + */ + const EOL = "\r\n"; + + + /** + * Default timeout in seconds for initiating session + */ + const TIMEOUT_CONNECTION = 30; + + + /** + * Hostname or IP address of remote server + * @var string + */ + protected $_host; + + + /** + * Port number of connection + * @var integer + */ + protected $_port; + + + /** + * Instance of Zend_Validate to check hostnames + * @var Zend_Validate + */ + protected $_validHost; + + + /** + * Socket connection resource + * @var resource + */ + protected $_socket; + + + /** + * Last request sent to server + * @var string + */ + protected $_request; + + + /** + * Array of server responses to last request + * @var array + */ + protected $_response; + + + /** + * String template for parsing server responses using sscanf (default: 3 digit code and response string) + * @var resource + */ + protected $_template = '%d%s'; + + + /** + * Log of mail requests and server responses for a session + * @var string + */ + private $_log; + + + /** + * Constructor. + * + * @param string $host OPTIONAL Hostname of remote connection (default: 127.0.0.1) + * @param integer $port OPTIONAL Port number (default: null) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null) + { + $this->_validHost = new Zend_Validate(); + $this->_validHost->addValidator(new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL)); + + if (!$this->_validHost->isValid($host)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessages())); + } + + $this->_host = $host; + $this->_port = $port; + } + + + /** + * Class destructor to cleanup open resources + * + * @return void + */ + public function __destruct() + { + $this->_disconnect(); + } + + + /** + * Create a connection to the remote host + * + * Concrete adapters for this class will implement their own unique connect scripts, using the _connect() method to create the socket resource. + */ + abstract public function connect(); + + + /** + * Retrieve the last client request + * + * @return string + */ + public function getRequest() + { + return $this->_request; + } + + + /** + * Retrieve the last server response + * + * @return array + */ + public function getResponse() + { + return $this->_response; + } + + + /** + * Retrieve the transaction log + * + * @return string + */ + public function getLog() + { + return $this->_log; + } + + + /** + * Reset the transaction log + * + * @return void + */ + public function resetLog() + { + $this->_log = ''; + } + + + /** + * Connect to the server using the supplied transport and target + * + * An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222' + * + * @param string $remote Remote + * @throws Zend_Mail_Protocol_Exception + * @return boolean + */ + protected function _connect($remote) + { + $errorNum = 0; + $errorStr = ''; + + // open connection + $this->_socket = stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION); + + if ($this->_socket === false) { + if ($errorNum == 0) { + $errorStr = 'Could not open socket'; + } + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($errorStr); + } + + if (($result = stream_set_timeout($this->_socket, self::TIMEOUT_CONNECTION)) === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not set stream timeout'); + } + + return $result; + } + + + /** + * Disconnect from remote host and free resource + * + * @return void + */ + protected function _disconnect() + { + if (is_resource($this->_socket)) { + fclose($this->_socket); + } + } + + + /** + * Send the given request followed by a LINEEND to the server. + * + * @param string $request + * @throws Zend_Mail_Protocol_Exception + * @return integer|boolean Number of bytes written to remote host + */ + protected function _send($request) + { + if (!is_resource($this->_socket)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host); + } + + $this->_request = $request; + + $result = fwrite($this->_socket, $request . self::EOL); + + // Save request to internal log + $this->_log .= $request . self::EOL; + + if ($result === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not send request to ' . $this->_host); + } + + return $result; + } + + + /** + * Get a line from the stream. + * + * @var integer $timeout Per-request timeout value if applicable + * @throws Zend_Mail_Protocol_Exception + * @return string + */ + protected function _receive($timeout = null) + { + if (!is_resource($this->_socket)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No connection has been established to ' . $this->_host); + } + + // Adapters may wish to supply per-commend timeouts according to appropriate RFC + if ($timeout !== null) { + stream_set_timeout($this->_socket, $timeout); + } + + // Retrieve response + $reponse = fgets($this->_socket, 1024); + + // Save request to internal log + $this->_log .= $reponse; + + // Check meta data to ensure connection is still valid + $info = stream_get_meta_data($this->_socket); + + if (!empty($info['timed_out'])) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($this->_host . ' has timed out'); + } + + if ($reponse === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Could not read from ' . $this->_host); + } + + return $reponse; + } + + + /** + * Parse server response for successful codes + * + * Read the response from the stream and check for expected return code. + * Throws a Zend_Mail_Protocol_Exception if an unexpected code is returned. + * + * @param string|array $code One or more codes that indicate a successful response + * @throws Zend_Mail_Protocol_Exception + * @return string Last line of response string + */ + protected function _expect($code, $timeout = null) + { + $this->_response = array(); + $cmd = ''; + $msg = ''; + + if (!is_array($code)) { + $code = array($code); + } + + do { + $this->_response[] = $result = $this->_receive($timeout); + sscanf($result, $this->_template, $cmd, $msg); + + if ($cmd === null || !in_array($cmd, $code)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($result); + } + + } while (strpos($msg, '-') === 0); // The '-' message prefix indicates an information string instead of a response string. + + return $msg; + } +} diff --git a/libs/Zend/Mail/Protocol/Exception.php b/libs/Zend/Mail/Protocol/Exception.php index 928c549a96..c3add11bbb 100644 --- a/libs/Zend/Mail/Protocol/Exception.php +++ b/libs/Zend/Mail/Protocol/Exception.php @@ -1,39 +1,39 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Exception
- */
-require_once 'Zend/Mail/Exception.php';
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Exception extends Zend_Mail_Exception
-{}
-
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Exception + */ +require_once 'Zend/Mail/Exception.php'; + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Exception extends Zend_Mail_Exception +{} + diff --git a/libs/Zend/Mail/Protocol/Imap.php b/libs/Zend/Mail/Protocol/Imap.php index 8b78478867..e21a0025c9 100644 --- a/libs/Zend/Mail/Protocol/Imap.php +++ b/libs/Zend/Mail/Protocol/Imap.php @@ -1,805 +1,805 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Imap
-{
- /**
- * socket to imap server
- * @var resource|null
- */
- protected $_socket;
-
- /**
- * counter for request tag
- * @var int
- */
- protected $_tagCount = 0;
-
-
- /**
- * Public constructor
- *
- * @param string $host hostname of IP address of IMAP server, if given connect() is called
- * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl)
- * @param bool $ssl use ssl? 'SSL', 'TLS' or false
- * @throws Zend_Mail_Protocol_Exception
- */
- function __construct($host = '', $port = null, $ssl = false)
- {
- if ($host) {
- $this->connect($host, $port, $ssl);
- }
- }
-
- /**
- * Public destructor
- */
- public function __destruct()
- {
- $this->logout();
- }
-
- /**
- * Open connection to POP3 server
- *
- * @param string $host hostname of IP address of POP3 server
- * @param int|null $port of IMAP server, default is 143 (993 for ssl)
- * @param string|bool $ssl use 'SSL', 'TLS' or false
- * @return string welcome message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function connect($host, $port = null, $ssl = false)
- {
- if ($ssl == 'SSL') {
- $host = 'ssl://' . $host;
- }
-
- if ($port === null) {
- $port = $ssl === 'SSL' ? 993 : 143;
- }
-
- $this->_socket = @fsockopen($host, $port);
- if (!$this->_socket) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot connect to host');
- }
-
- if (!$this->_assumedNextLine('* OK')) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('host doesn\'t allow connection');
- }
-
- if ($ssl === 'TLS') {
- $result = $this->requestAndResponse('STARTTLS');
- $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
- }
- }
- }
-
- /**
- * get the next line from socket with error checking, but nothing else
- *
- * @return string next line
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _nextLine()
- {
- $line = @fgets($this->_socket);
- if ($line === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot read - connection closed?');
- }
-
- return $line;
- }
-
- /**
- * get next line and assume it starts with $start. some requests give a simple
- * feedback so we can quickly check if we can go on.
- *
- * @param string $start the first bytes we assume to be in the next line
- * @return bool line starts with $start
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _assumedNextLine($start)
- {
- $line = $this->_nextLine();
- return strpos($line, $start) === 0;
- }
-
- /**
- * get next line and split the tag. that's the normal case for a response line
- *
- * @param string $tag tag of line is returned by reference
- * @return string next line
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _nextTaggedLine(&$tag)
- {
- $line = $this->_nextLine();
-
- // seperate tag from line
- list($tag, $line) = explode(' ', $line, 2);
-
- return $line;
- }
-
- /**
- * split a given line in tokens. a token is literal of any form or a list
- *
- * @param string $line line to decode
- * @return array tokens, literals are returned as string, lists as array
- * @throws Zend_Mail_Protocol_Exception
- */
- protected function _decodeLine($line)
- {
- $tokens = array();
- $stack = array();
-
- /*
- We start to decode the response here. The unterstood tokens are:
- literal
- "literal" or also "lit\\er\"al"
- {bytes}<NL>literal
- (literals*)
- All tokens are returned in an array. Literals in braces (the last unterstood
- token in the list) are returned as an array of tokens. I.e. the following response:
- "foo" baz {3}<NL>bar ("f\\\"oo" bar)
- would be returned as:
- array('foo', 'baz', 'bar', array('f\\\"oo', 'bar'));
-
- // TODO: add handling of '[' and ']' to parser for easier handling of response text
- */
- // replace any trailling <NL> including spaces with a single space
- $line = rtrim($line) . ' ';
- while (($pos = strpos($line, ' ')) !== false) {
- $token = substr($line, 0, $pos);
- while ($token[0] == '(') {
- array_push($stack, $tokens);
- $tokens = array();
- $token = substr($token, 1);
- }
- if ($token[0] == '"') {
- if (preg_match('%^"((.|\\\\|\\")*?)" *%', $line, $matches)) {
- $tokens[] = $matches[1];
- $line = substr($line, strlen($matches[0]));
- continue;
- }
- }
- if ($token[0] == '{') {
- $endPos = strpos($token, '}');
- $chars = substr($token, 1, $endPos - 1);
- if (is_numeric($chars)) {
- $token = '';
- while (strlen($token) < $chars) {
- $token .= $this->_nextLine();
- }
- $line = '';
- if (strlen($token) > $chars) {
- $line = substr($token, $chars);
- $token = substr($token, 0, $chars);
- } else {
- $line .= $this->_nextLine();
- }
- $tokens[] = $token;
- $line = trim($line) . ' ';
- continue;
- }
- }
- if ($stack && $token[strlen($token) - 1] == ')') {
- // closing braces are not seperated by spaces, so we need to count them
- $braces = strlen($token);
- $token = rtrim($token, ')');
- // only count braces if more than one
- $braces -= strlen($token) + 1;
- // only add if token had more than just closing braces
- if ($token) {
- $tokens[] = $token;
- }
- $token = $tokens;
- $tokens = array_pop($stack);
- // special handline if more than one closing brace
- while ($braces-- > 0) {
- $tokens[] = $token;
- $token = $tokens;
- $tokens = array_pop($stack);
- }
- }
- $tokens[] = $token;
- $line = substr($line, $pos + 1);
- }
-
- // maybe the server forgot to send some closing braces
- while ($stack) {
- $child = $tokens;
- $tokens = array_pop($stack);
- $tokens[] = $child;
- }
-
- return $tokens;
- }
-
- /**
- * read a response "line" (could also be more than one real line if response has {..}<NL>)
- * and do a simple decode
- *
- * @param array|string $tokens decoded tokens are returned by reference, if $dontParse
- * is true the unparsed line is returned here
- * @param string $wantedTag check for this tag for response code. Default '*' is
- * continuation tag.
- * @param bool $dontParse if true only the unparsed line is returned $tokens
- * @return bool if returned tag matches wanted tag
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)
- {
- $line = $this->_nextTaggedLine($tag);
- if (!$dontParse) {
- $tokens = $this->_decodeLine($line);
- } else {
- $tokens = $line;
- }
-
- // if tag is wanted tag we might be at the end of a multiline response
- return $tag == $wantedTag;
- }
-
- /**
- * read all lines of response until given tag is found (last line of response)
- *
- * @param string $tag the tag of your request
- * @param string|array $filter you can filter the response so you get only the
- * given response lines
- * @param bool $dontParse if true every line is returned unparsed instead of
- * the decoded tokens
- * @return null|bool|array tokens if success, false if error, null if bad request
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readResponse($tag, $dontParse = false)
- {
- $lines = array();
- while (!$this->readLine($tokens, $tag, $dontParse)) {
- $lines[] = $tokens;
- }
-
- if ($dontParse) {
- // last to chars are still needed for response code
- $tokens = array(substr($tokens, 0, 2));
- }
- // last line has response code
- if ($tokens[0] == 'OK') {
- return $lines ? $lines : true;
- } else if ($tokens[0] == 'NO'){
- return false;
- }
- return null;
- }
-
- /**
- * send a request
- *
- * @param string $command your request command
- * @param array $tokens additional parameters to command, use escapeString() to prepare
- * @param string $tag provide a tag otherwise an autogenerated is returned
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function sendRequest($command, $tokens = array(), &$tag = null)
- {
- if (!$tag) {
- ++$this->_tagCount;
- $tag = 'TAG' . $this->_tagCount;
- }
-
- $line = $tag . ' ' . $command;
-
- foreach ($tokens as $token) {
- if (is_array($token)) {
- if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?');
- }
- if (!$this->_assumedNextLine('+ OK')) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot send literal string');
- }
- $line = $token[1];
- } else {
- $line .= ' ' . $token;
- }
- }
-
- if (@fputs($this->_socket, $line . "\r\n") === false) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?');
- }
- }
-
- /**
- * send a request and get response at once
- *
- * @param string $command command as in sendRequest()
- * @param array $tokens parameters as in sendRequest()
- * @param bool $dontParse if true unparsed lines are returned instead of tokens
- * @return mixed response as in readResponse()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function requestAndResponse($command, $tokens = array(), $dontParse = false)
- {
- $this->sendRequest($command, $tokens, $tag);
- $response = $this->readResponse($tag, $dontParse);
-
- return $response;
- }
-
- /**
- * escape one or more literals i.e. for sendRequest
- *
- * @param string|array $string the literal/-s
- * @return string|array escape literals, literals with newline ar returned
- * as array('{size}', 'string');
- */
- public function escapeString($string)
- {
- if (func_num_args() < 2) {
- if (strpos($string, "\n") !== false) {
- return array('{' . strlen($string) . '}', $string);
- } else {
- return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"';
- }
- }
- $result = array();
- foreach (func_get_args() as $string) {
- $result[] = $this->escapeString($string);
- }
- return $result;
- }
-
- /**
- * escape a list with literals or lists
- *
- * @param array $list list with literals or lists as PHP array
- * @return string escaped list for imap
- */
- public function escapeList($list)
- {
- $result = array();
- foreach ($list as $k => $v) {
- if (!is_array($v)) {
-// $result[] = $this->escapeString($v);
- $result[] = $v;
- continue;
- }
- $result[] = $this->escapeList($v);
- }
- return '(' . implode(' ', $result) . ')';
- }
-
- /**
- * Login to IMAP server.
- *
- * @param string $user username
- * @param string $password password
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function login($user, $password)
- {
- return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true);
- }
-
- /**
- * logout of imap server
- *
- * @return bool success
- */
- public function logout()
- {
- $result = false;
- if ($this->_socket) {
- try {
- $result = $this->requestAndResponse('LOGOUT', array(), true);
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignoring exception
- }
- fclose($this->_socket);
- $this->_socket = null;
- }
- return $result;
- }
-
-
- /**
- * Get capabilities from IMAP server
- *
- * @return array list of capabilities
- * @throws Zend_Mail_Protocol_Exception
- */
- public function capability()
- {
- $response = $this->requestAndResponse('CAPABILITY');
-
- if (!$response) {
- return $response;
- }
-
- $capabilities = array();
- foreach ($response as $line) {
- $capabilities = array_merge($capabilities, $line);
- }
- return $capabilities;
- }
-
- /**
- * Examine and select have the same response. The common code for both
- * is in this method
- *
- * @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command
- * @param string $box which folder to change to or examine
- * @return bool|array false if error, array with returned information
- * otherwise (flags, exists, recent, uidvalidity)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX')
- {
- $this->sendRequest($command, array($this->escapeString($box)), $tag);
-
- $result = array();
- while (!$this->readLine($tokens, $tag)) {
- if ($tokens[0] == 'FLAGS') {
- array_shift($tokens);
- $result['flags'] = $tokens;
- continue;
- }
- switch ($tokens[1]) {
- case 'EXISTS':
- case 'RECENT':
- $result[strtolower($tokens[1])] = $tokens[0];
- break;
- case '[UIDVALIDITY':
- $result['uidvalidity'] = (int)$tokens[2];
- break;
- default:
- // ignore
- }
- }
-
- if ($tokens[0] != 'OK') {
- return false;
- }
- return $result;
- }
-
- /**
- * change folder
- *
- * @param string $box change to this folder
- * @return bool|array see examineOrselect()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function select($box = 'INBOX')
- {
- return $this->examineOrSelect('SELECT', $box);
- }
-
- /**
- * examine folder
- *
- * @param string $box examine this folder
- * @return bool|array see examineOrselect()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function examine($box = 'INBOX')
- {
- return $this->examineOrSelect('EXAMINE', $box);
- }
-
- /**
- * fetch one or more items of one or more messages
- *
- * @param string|array $items items to fetch from message(s) as string (if only one item)
- * or array of strings
- * @param int $from message for items or start message if $to !== null
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @return string|array if only one item of one message is fetched it's returned as string
- * if items of one message are fetched it's returned as (name => value)
- * if one items of messages are fetched it's returned as (msgno => value)
- * if items of messages are fetchted it's returned as (msgno => (name => value))
- * @throws Zend_Mail_Protocol_Exception
- */
- public function fetch($items, $from, $to = null)
- {
- if (is_array($from)) {
- $set = implode(',', $from);
- } else if ($to === null) {
- $set = (int)$from;
- } else if ($to === INF) {
- $set = (int)$from . ':*';
- } else {
- $set = (int)$from . ':' . (int)$to;
- }
-
- $items = (array)$items;
- $itemList = $this->escapeList($items);
-
- $this->sendRequest('FETCH', array($set, $itemList), $tag);
-
- $result = array();
- while (!$this->readLine($tokens, $tag)) {
- // ignore other responses
- if ($tokens[1] != 'FETCH') {
- continue;
- }
- // ignore other messages
- if ($to === null && !is_array($from) && $tokens[0] != $from) {
- continue;
- }
- // if we only want one item we return that one directly
- if (count($items) == 1) {
- if ($tokens[2][0] == $items[0]) {
- $data = $tokens[2][1];
- } else {
- // maybe the server send an other field we didn't wanted
- $count = count($tokens[2]);
- // we start with 2, because 0 was already checked
- for ($i = 2; $i < $count; $i += 2) {
- if ($tokens[2][$i] != $items[0]) {
- continue;
- }
- $data = $tokens[2][$i + 1];
- break;
- }
- }
- } else {
- $data = array();
- while (key($tokens[2]) !== null) {
- $data[current($tokens[2])] = next($tokens[2]);
- next($tokens[2]);
- }
- }
- // if we want only one message we can ignore everything else and just return
- if ($to === null && !is_array($from) && $tokens[0] == $from) {
- // we still need to read all lines
- while (!$this->readLine($tokens, $tag));
- return $data;
- }
- $result[$tokens[0]] = $data;
- }
-
- if ($to === null && !is_array($from)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('the single id was not found in response');
- }
-
- return $result;
- }
-
- /**
- * get mailbox list
- *
- * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword
- *
- * @param string $reference mailbox reference for list
- * @param string $mailbox mailbox name match with wildcards
- * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..))
- * @throws Zend_Mail_Protocol_Exception
- */
- public function listMailbox($reference = '', $mailbox = '*')
- {
- $result = array();
- $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox));
- if (!$list) {
- return $result;
- }
-
- foreach ($list as $item) {
- if (count($item) != 4 || $item[0] != 'LIST') {
- continue;
- }
- $result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]);
- }
-
- return $result;
- }
-
- /**
- * set flags
- *
- * @param array $flags flags to set, add or remove - see $mode
- * @param int $from message for items or start message if $to !== null
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
- * @param bool $silent if false the return values are the new flags for the wanted messages
- * @return bool|array new flags if $silent is false, else true or false depending on success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function store(array $flags, $from, $to = null, $mode = null, $silent = true)
- {
- $item = 'FLAGS';
- if ($mode == '+' || $mode == '-') {
- $item = $mode . $item;
- }
- if ($silent) {
- $item .= '.SILENT';
- }
-
- $flags = $this->escapeList($flags);
- $set = (int)$from;
- if ($to != null) {
- $set .= ':' . ($to == INF ? '*' : (int)$to);
- }
-
- $result = $this->requestAndResponse('STORE', array($set, $item, $flags), $silent);
-
- if ($silent) {
- return $result ? true : false;
- }
-
- $tokens = $result;
- $result = array();
- foreach ($tokens as $token) {
- if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') {
- continue;
- }
- $result[$token[0]] = $token[2][1];
- }
-
- return $result;
- }
-
- /**
- * append a new message to given folder
- *
- * @param string $folder name of target folder
- * @param string $message full message content
- * @param array $flags flags for new message
- * @param string $date date for new message
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function append($folder, $message, $flags = null, $date = null)
- {
- $tokens = array();
- $tokens[] = $this->escapeString($folder);
- if ($flags !== null) {
- $tokens[] = $this->escapeList($flags);
- }
- if ($date !== null) {
- $tokens[] = $this->escapeString($date);
- }
- $tokens[] = $this->escapeString($message);
-
- return $this->requestAndResponse('APPEND', $tokens, true);
- }
-
- /**
- * copy message set from current folder to other folder
- *
- * @param string $folder destination folder
- * @param int|null $to if null only one message ($from) is fetched, else it's the
- * last message, INF means last message avaible
- * @return bool success
- * @throws Zend_Mail_Protocol_Exception
- */
- public function copy($folder, $from, $to = null)
- {
- $set = (int)$from;
- if ($to != null) {
- $set .= ':' . ($to == INF ? '*' : (int)$to);
- }
-
- return $this->requestAndResponse('COPY', array($set, $this->escapeString($folder)), true);
- }
-
- /**
- * create a new folder (and parent folders if needed)
- *
- * @param string $folder folder name
- * @return bool success
- */
- public function create($folder)
- {
- return $this->requestAndResponse('CREATE', array($this->escapeString($folder)), true);
- }
-
- /**
- * rename an existing folder
- *
- * @param string $old old name
- * @param string $new new name
- * @return bool success
- */
- public function rename($old, $new)
- {
- return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true);
- }
-
- /**
- * remove a folder
- *
- * @param string $folder folder name
- * @return bool success
- */
- public function delete($folder)
- {
- return $this->requestAndResponse('DELETE', array($this->escapeString($folder)), true);
- }
-
- /**
- * permanently remove messages
- *
- * @return bool success
- */
- public function expunge()
- {
- // TODO: parse response?
- return $this->requestAndResponse('EXPUNGE');
- }
-
- /**
- * send noop
- *
- * @return bool success
- */
- public function noop()
- {
- // TODO: parse response
- return $this->requestAndResponse('NOOP');
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Imap.php 8928 2008-03-20 19:41:41Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Imap +{ + /** + * socket to imap server + * @var resource|null + */ + protected $_socket; + + /** + * counter for request tag + * @var int + */ + protected $_tagCount = 0; + + + /** + * Public constructor + * + * @param string $host hostname of IP address of IMAP server, if given connect() is called + * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl) + * @param bool $ssl use ssl? 'SSL', 'TLS' or false + * @throws Zend_Mail_Protocol_Exception + */ + function __construct($host = '', $port = null, $ssl = false) + { + if ($host) { + $this->connect($host, $port, $ssl); + } + } + + /** + * Public destructor + */ + public function __destruct() + { + $this->logout(); + } + + /** + * Open connection to POP3 server + * + * @param string $host hostname of IP address of POP3 server + * @param int|null $port of IMAP server, default is 143 (993 for ssl) + * @param string|bool $ssl use 'SSL', 'TLS' or false + * @return string welcome message + * @throws Zend_Mail_Protocol_Exception + */ + public function connect($host, $port = null, $ssl = false) + { + if ($ssl == 'SSL') { + $host = 'ssl://' . $host; + } + + if ($port === null) { + $port = $ssl === 'SSL' ? 993 : 143; + } + + $this->_socket = @fsockopen($host, $port); + if (!$this->_socket) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot connect to host'); + } + + if (!$this->_assumedNextLine('* OK')) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('host doesn\'t allow connection'); + } + + if ($ssl === 'TLS') { + $result = $this->requestAndResponse('STARTTLS'); + $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot enable TLS'); + } + } + } + + /** + * get the next line from socket with error checking, but nothing else + * + * @return string next line + * @throws Zend_Mail_Protocol_Exception + */ + protected function _nextLine() + { + $line = @fgets($this->_socket); + if ($line === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot read - connection closed?'); + } + + return $line; + } + + /** + * get next line and assume it starts with $start. some requests give a simple + * feedback so we can quickly check if we can go on. + * + * @param string $start the first bytes we assume to be in the next line + * @return bool line starts with $start + * @throws Zend_Mail_Protocol_Exception + */ + protected function _assumedNextLine($start) + { + $line = $this->_nextLine(); + return strpos($line, $start) === 0; + } + + /** + * get next line and split the tag. that's the normal case for a response line + * + * @param string $tag tag of line is returned by reference + * @return string next line + * @throws Zend_Mail_Protocol_Exception + */ + protected function _nextTaggedLine(&$tag) + { + $line = $this->_nextLine(); + + // seperate tag from line + list($tag, $line) = explode(' ', $line, 2); + + return $line; + } + + /** + * split a given line in tokens. a token is literal of any form or a list + * + * @param string $line line to decode + * @return array tokens, literals are returned as string, lists as array + * @throws Zend_Mail_Protocol_Exception + */ + protected function _decodeLine($line) + { + $tokens = array(); + $stack = array(); + + /* + We start to decode the response here. The unterstood tokens are: + literal + "literal" or also "lit\\er\"al" + {bytes}<NL>literal + (literals*) + All tokens are returned in an array. Literals in braces (the last unterstood + token in the list) are returned as an array of tokens. I.e. the following response: + "foo" baz {3}<NL>bar ("f\\\"oo" bar) + would be returned as: + array('foo', 'baz', 'bar', array('f\\\"oo', 'bar')); + + // TODO: add handling of '[' and ']' to parser for easier handling of response text + */ + // replace any trailling <NL> including spaces with a single space + $line = rtrim($line) . ' '; + while (($pos = strpos($line, ' ')) !== false) { + $token = substr($line, 0, $pos); + while ($token[0] == '(') { + array_push($stack, $tokens); + $tokens = array(); + $token = substr($token, 1); + } + if ($token[0] == '"') { + if (preg_match('%^"((.|\\\\|\\")*?)" *%', $line, $matches)) { + $tokens[] = $matches[1]; + $line = substr($line, strlen($matches[0])); + continue; + } + } + if ($token[0] == '{') { + $endPos = strpos($token, '}'); + $chars = substr($token, 1, $endPos - 1); + if (is_numeric($chars)) { + $token = ''; + while (strlen($token) < $chars) { + $token .= $this->_nextLine(); + } + $line = ''; + if (strlen($token) > $chars) { + $line = substr($token, $chars); + $token = substr($token, 0, $chars); + } else { + $line .= $this->_nextLine(); + } + $tokens[] = $token; + $line = trim($line) . ' '; + continue; + } + } + if ($stack && $token[strlen($token) - 1] == ')') { + // closing braces are not seperated by spaces, so we need to count them + $braces = strlen($token); + $token = rtrim($token, ')'); + // only count braces if more than one + $braces -= strlen($token) + 1; + // only add if token had more than just closing braces + if ($token) { + $tokens[] = $token; + } + $token = $tokens; + $tokens = array_pop($stack); + // special handline if more than one closing brace + while ($braces-- > 0) { + $tokens[] = $token; + $token = $tokens; + $tokens = array_pop($stack); + } + } + $tokens[] = $token; + $line = substr($line, $pos + 1); + } + + // maybe the server forgot to send some closing braces + while ($stack) { + $child = $tokens; + $tokens = array_pop($stack); + $tokens[] = $child; + } + + return $tokens; + } + + /** + * read a response "line" (could also be more than one real line if response has {..}<NL>) + * and do a simple decode + * + * @param array|string $tokens decoded tokens are returned by reference, if $dontParse + * is true the unparsed line is returned here + * @param string $wantedTag check for this tag for response code. Default '*' is + * continuation tag. + * @param bool $dontParse if true only the unparsed line is returned $tokens + * @return bool if returned tag matches wanted tag + * @throws Zend_Mail_Protocol_Exception + */ + public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false) + { + $line = $this->_nextTaggedLine($tag); + if (!$dontParse) { + $tokens = $this->_decodeLine($line); + } else { + $tokens = $line; + } + + // if tag is wanted tag we might be at the end of a multiline response + return $tag == $wantedTag; + } + + /** + * read all lines of response until given tag is found (last line of response) + * + * @param string $tag the tag of your request + * @param string|array $filter you can filter the response so you get only the + * given response lines + * @param bool $dontParse if true every line is returned unparsed instead of + * the decoded tokens + * @return null|bool|array tokens if success, false if error, null if bad request + * @throws Zend_Mail_Protocol_Exception + */ + public function readResponse($tag, $dontParse = false) + { + $lines = array(); + while (!$this->readLine($tokens, $tag, $dontParse)) { + $lines[] = $tokens; + } + + if ($dontParse) { + // last to chars are still needed for response code + $tokens = array(substr($tokens, 0, 2)); + } + // last line has response code + if ($tokens[0] == 'OK') { + return $lines ? $lines : true; + } else if ($tokens[0] == 'NO'){ + return false; + } + return null; + } + + /** + * send a request + * + * @param string $command your request command + * @param array $tokens additional parameters to command, use escapeString() to prepare + * @param string $tag provide a tag otherwise an autogenerated is returned + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function sendRequest($command, $tokens = array(), &$tag = null) + { + if (!$tag) { + ++$this->_tagCount; + $tag = 'TAG' . $this->_tagCount; + } + + $line = $tag . ' ' . $command; + + foreach ($tokens as $token) { + if (is_array($token)) { + if (@fputs($this->_socket, $line . ' ' . $token[0] . "\r\n") === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); + } + if (!$this->_assumedNextLine('+ OK')) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot send literal string'); + } + $line = $token[1]; + } else { + $line .= ' ' . $token; + } + } + + if (@fputs($this->_socket, $line . "\r\n") === false) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot write - connection closed?'); + } + } + + /** + * send a request and get response at once + * + * @param string $command command as in sendRequest() + * @param array $tokens parameters as in sendRequest() + * @param bool $dontParse if true unparsed lines are returned instead of tokens + * @return mixed response as in readResponse() + * @throws Zend_Mail_Protocol_Exception + */ + public function requestAndResponse($command, $tokens = array(), $dontParse = false) + { + $this->sendRequest($command, $tokens, $tag); + $response = $this->readResponse($tag, $dontParse); + + return $response; + } + + /** + * escape one or more literals i.e. for sendRequest + * + * @param string|array $string the literal/-s + * @return string|array escape literals, literals with newline ar returned + * as array('{size}', 'string'); + */ + public function escapeString($string) + { + if (func_num_args() < 2) { + if (strpos($string, "\n") !== false) { + return array('{' . strlen($string) . '}', $string); + } else { + return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"'; + } + } + $result = array(); + foreach (func_get_args() as $string) { + $result[] = $this->escapeString($string); + } + return $result; + } + + /** + * escape a list with literals or lists + * + * @param array $list list with literals or lists as PHP array + * @return string escaped list for imap + */ + public function escapeList($list) + { + $result = array(); + foreach ($list as $k => $v) { + if (!is_array($v)) { +// $result[] = $this->escapeString($v); + $result[] = $v; + continue; + } + $result[] = $this->escapeList($v); + } + return '(' . implode(' ', $result) . ')'; + } + + /** + * Login to IMAP server. + * + * @param string $user username + * @param string $password password + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function login($user, $password) + { + return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true); + } + + /** + * logout of imap server + * + * @return bool success + */ + public function logout() + { + $result = false; + if ($this->_socket) { + try { + $result = $this->requestAndResponse('LOGOUT', array(), true); + } catch (Zend_Mail_Protocol_Exception $e) { + // ignoring exception + } + fclose($this->_socket); + $this->_socket = null; + } + return $result; + } + + + /** + * Get capabilities from IMAP server + * + * @return array list of capabilities + * @throws Zend_Mail_Protocol_Exception + */ + public function capability() + { + $response = $this->requestAndResponse('CAPABILITY'); + + if (!$response) { + return $response; + } + + $capabilities = array(); + foreach ($response as $line) { + $capabilities = array_merge($capabilities, $line); + } + return $capabilities; + } + + /** + * Examine and select have the same response. The common code for both + * is in this method + * + * @param string $command can be 'EXAMINE' or 'SELECT' and this is used as command + * @param string $box which folder to change to or examine + * @return bool|array false if error, array with returned information + * otherwise (flags, exists, recent, uidvalidity) + * @throws Zend_Mail_Protocol_Exception + */ + public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX') + { + $this->sendRequest($command, array($this->escapeString($box)), $tag); + + $result = array(); + while (!$this->readLine($tokens, $tag)) { + if ($tokens[0] == 'FLAGS') { + array_shift($tokens); + $result['flags'] = $tokens; + continue; + } + switch ($tokens[1]) { + case 'EXISTS': + case 'RECENT': + $result[strtolower($tokens[1])] = $tokens[0]; + break; + case '[UIDVALIDITY': + $result['uidvalidity'] = (int)$tokens[2]; + break; + default: + // ignore + } + } + + if ($tokens[0] != 'OK') { + return false; + } + return $result; + } + + /** + * change folder + * + * @param string $box change to this folder + * @return bool|array see examineOrselect() + * @throws Zend_Mail_Protocol_Exception + */ + public function select($box = 'INBOX') + { + return $this->examineOrSelect('SELECT', $box); + } + + /** + * examine folder + * + * @param string $box examine this folder + * @return bool|array see examineOrselect() + * @throws Zend_Mail_Protocol_Exception + */ + public function examine($box = 'INBOX') + { + return $this->examineOrSelect('EXAMINE', $box); + } + + /** + * fetch one or more items of one or more messages + * + * @param string|array $items items to fetch from message(s) as string (if only one item) + * or array of strings + * @param int $from message for items or start message if $to !== null + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @return string|array if only one item of one message is fetched it's returned as string + * if items of one message are fetched it's returned as (name => value) + * if one items of messages are fetched it's returned as (msgno => value) + * if items of messages are fetchted it's returned as (msgno => (name => value)) + * @throws Zend_Mail_Protocol_Exception + */ + public function fetch($items, $from, $to = null) + { + if (is_array($from)) { + $set = implode(',', $from); + } else if ($to === null) { + $set = (int)$from; + } else if ($to === INF) { + $set = (int)$from . ':*'; + } else { + $set = (int)$from . ':' . (int)$to; + } + + $items = (array)$items; + $itemList = $this->escapeList($items); + + $this->sendRequest('FETCH', array($set, $itemList), $tag); + + $result = array(); + while (!$this->readLine($tokens, $tag)) { + // ignore other responses + if ($tokens[1] != 'FETCH') { + continue; + } + // ignore other messages + if ($to === null && !is_array($from) && $tokens[0] != $from) { + continue; + } + // if we only want one item we return that one directly + if (count($items) == 1) { + if ($tokens[2][0] == $items[0]) { + $data = $tokens[2][1]; + } else { + // maybe the server send an other field we didn't wanted + $count = count($tokens[2]); + // we start with 2, because 0 was already checked + for ($i = 2; $i < $count; $i += 2) { + if ($tokens[2][$i] != $items[0]) { + continue; + } + $data = $tokens[2][$i + 1]; + break; + } + } + } else { + $data = array(); + while (key($tokens[2]) !== null) { + $data[current($tokens[2])] = next($tokens[2]); + next($tokens[2]); + } + } + // if we want only one message we can ignore everything else and just return + if ($to === null && !is_array($from) && $tokens[0] == $from) { + // we still need to read all lines + while (!$this->readLine($tokens, $tag)); + return $data; + } + $result[$tokens[0]] = $data; + } + + if ($to === null && !is_array($from)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('the single id was not found in response'); + } + + return $result; + } + + /** + * get mailbox list + * + * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword + * + * @param string $reference mailbox reference for list + * @param string $mailbox mailbox name match with wildcards + * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..)) + * @throws Zend_Mail_Protocol_Exception + */ + public function listMailbox($reference = '', $mailbox = '*') + { + $result = array(); + $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox)); + if (!$list) { + return $result; + } + + foreach ($list as $item) { + if (count($item) != 4 || $item[0] != 'LIST') { + continue; + } + $result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]); + } + + return $result; + } + + /** + * set flags + * + * @param array $flags flags to set, add or remove - see $mode + * @param int $from message for items or start message if $to !== null + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given + * @param bool $silent if false the return values are the new flags for the wanted messages + * @return bool|array new flags if $silent is false, else true or false depending on success + * @throws Zend_Mail_Protocol_Exception + */ + public function store(array $flags, $from, $to = null, $mode = null, $silent = true) + { + $item = 'FLAGS'; + if ($mode == '+' || $mode == '-') { + $item = $mode . $item; + } + if ($silent) { + $item .= '.SILENT'; + } + + $flags = $this->escapeList($flags); + $set = (int)$from; + if ($to != null) { + $set .= ':' . ($to == INF ? '*' : (int)$to); + } + + $result = $this->requestAndResponse('STORE', array($set, $item, $flags), $silent); + + if ($silent) { + return $result ? true : false; + } + + $tokens = $result; + $result = array(); + foreach ($tokens as $token) { + if ($token[1] != 'FETCH' || $token[2][0] != 'FLAGS') { + continue; + } + $result[$token[0]] = $token[2][1]; + } + + return $result; + } + + /** + * append a new message to given folder + * + * @param string $folder name of target folder + * @param string $message full message content + * @param array $flags flags for new message + * @param string $date date for new message + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function append($folder, $message, $flags = null, $date = null) + { + $tokens = array(); + $tokens[] = $this->escapeString($folder); + if ($flags !== null) { + $tokens[] = $this->escapeList($flags); + } + if ($date !== null) { + $tokens[] = $this->escapeString($date); + } + $tokens[] = $this->escapeString($message); + + return $this->requestAndResponse('APPEND', $tokens, true); + } + + /** + * copy message set from current folder to other folder + * + * @param string $folder destination folder + * @param int|null $to if null only one message ($from) is fetched, else it's the + * last message, INF means last message avaible + * @return bool success + * @throws Zend_Mail_Protocol_Exception + */ + public function copy($folder, $from, $to = null) + { + $set = (int)$from; + if ($to != null) { + $set .= ':' . ($to == INF ? '*' : (int)$to); + } + + return $this->requestAndResponse('COPY', array($set, $this->escapeString($folder)), true); + } + + /** + * create a new folder (and parent folders if needed) + * + * @param string $folder folder name + * @return bool success + */ + public function create($folder) + { + return $this->requestAndResponse('CREATE', array($this->escapeString($folder)), true); + } + + /** + * rename an existing folder + * + * @param string $old old name + * @param string $new new name + * @return bool success + */ + public function rename($old, $new) + { + return $this->requestAndResponse('RENAME', $this->escapeString($old, $new), true); + } + + /** + * remove a folder + * + * @param string $folder folder name + * @return bool success + */ + public function delete($folder) + { + return $this->requestAndResponse('DELETE', array($this->escapeString($folder)), true); + } + + /** + * permanently remove messages + * + * @return bool success + */ + public function expunge() + { + // TODO: parse response? + return $this->requestAndResponse('EXPUNGE'); + } + + /** + * send noop + * + * @return bool success + */ + public function noop() + { + // TODO: parse response + return $this->requestAndResponse('NOOP'); + } +} diff --git a/libs/Zend/Mail/Protocol/Pop3.php b/libs/Zend/Mail/Protocol/Pop3.php index e9a7a2275d..55d2704569 100644 --- a/libs/Zend/Mail/Protocol/Pop3.php +++ b/libs/Zend/Mail/Protocol/Pop3.php @@ -1,461 +1,461 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to version 1.0 of the Zend Framework
- * license, that is bundled with this package in the file LICENSE.txt, and
- * is available through the world-wide-web at the following URL:
- * http://framework.zend.com/license/new-bsd. If you did not receive
- * a copy of the Zend Framework license and are unable to obtain it
- * through the world-wide-web, please send a note to license@zend.com
- * so we can mail you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Pop3
-{
- /**
- * saves if server supports top
- * @var null|bool
- */
- public $hasTop = null;
-
- /**
- * socket to pop3
- * @var null|resource
- */
- protected $_socket;
-
- /**
- * greeting timestamp for apop
- * @var null|string
- */
- protected $_timestamp;
-
-
- /**
- * Public constructor
- *
- * @param string $host hostname of IP address of POP3 server, if given connect() is called
- * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl)
- * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($host = '', $port = null, $ssl = false)
- {
- if ($host) {
- $this->connect($host, $port, $ssl);
- }
- }
-
-
- /**
- * Public destructor
- */
- public function __destruct()
- {
- $this->logout();
- }
-
-
- /**
- * Open connection to POP3 server
- *
- * @param string $host hostname of IP address of POP3 server
- * @param int|null $port of POP3 server, default is 110 (995 for ssl)
- * @param string|bool $ssl use 'SSL', 'TLS' or false
- * @return string welcome message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function connect($host, $port = null, $ssl = false)
- {
- if ($ssl == 'SSL') {
- $host = 'ssl://' . $host;
- }
-
- if ($port === null) {
- $port = $ssl == 'SSL' ? 995 : 110;
- }
-
- $this->_socket = @fsockopen($host, $port);
- if (!$this->_socket) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot connect to host');
- }
-
- $welcome = $this->readResponse();
-
- strtok($welcome, '<');
- $this->_timestamp = strtok('>');
- if (!strpos($this->_timestamp, '@')) {
- $this->_timestamp = null;
- } else {
- $this->_timestamp = '<' . $this->_timestamp . '>';
- }
-
- if ($ssl === 'TLS') {
- $this->request('STLS');
- $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('cannot enable TLS');
- }
- }
-
- return $welcome;
- }
-
-
- /**
- * Send a request
- *
- * @param string $request your request without newline
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function sendRequest($request)
- {
- $result = @fputs($this->_socket, $request . "\r\n");
- if (!$result) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('send failed - connection closed?');
- }
- }
-
-
- /**
- * read a response
- *
- * @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>"
- * @return string response
- * @throws Zend_Mail_Protocol_Exception
- */
- public function readResponse($multiline = false)
- {
- $result = @fgets($this->_socket);
- if (!is_string($result)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('read failed - connection closed?');
- }
-
- $result = trim($result);
- if (strpos($result, ' ')) {
- list($status, $message) = explode(' ', $result, 2);
- } else {
- $status = $result;
- $message = '';
- }
-
- if ($status != '+OK') {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('last request failed');
- }
-
- if ($multiline) {
- $message = '';
- $line = fgets($this->_socket);
- while ($line && trim($line) != '.') {
- $message .= $line;
- $line = fgets($this->_socket);
- };
- }
-
- return $message;
- }
-
-
- /**
- * Send request and get resposne
- *
- * @see sendRequest(), readResponse()
- *
- * @param string $request request
- * @param bool $multiline multiline response?
- * @return string result from readResponse()
- * @throws Zend_Mail_Protocol_Exception
- */
- public function request($request, $multiline = false)
- {
- $this->sendRequest($request);
- return $this->readResponse($multiline);
- }
-
-
- /**
- * End communication with POP3 server (also closes socket)
- *
- * @return null
- */
- public function logout()
- {
- if (!$this->_socket) {
- return;
- }
-
- try {
- $this->request('QUIT');
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignore error - we're closing the socket anyway
- }
-
- fclose($this->_socket);
- $this->_socket = null;
- }
-
-
- /**
- * Get capabilities from POP3 server
- *
- * @return array list of capabilities
- * @throws Zend_Mail_Protocol_Exception
- */
- public function capa()
- {
- $result = $this->request('CAPA', true);
- return explode("\n", $result);
- }
-
-
- /**
- * Login to POP3 server. Can use APOP
- *
- * @param string $user username
- * @param string $password password
- * @param bool $try_apop should APOP be tried?
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function login($user, $password, $tryApop = true)
- {
- if ($tryApop && $this->_timestamp) {
- try {
- $this->request("APOP $user " . md5($this->_timestamp . $password));
- return;
- } catch (Zend_Mail_Protocol_Exception $e) {
- // ignore
- }
- }
-
- $result = $this->request("USER $user");
- $result = $this->request("PASS $password");
- }
-
-
- /**
- * Make STAT call for message count and size sum
- *
- * @param int $messages out parameter with count of messages
- * @param int $octets out parameter with size in octects of messages
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function status(&$messages, &$octets)
- {
- $messages = 0;
- $octets = 0;
- $result = $this->request('STAT');
-
- list($messages, $octets) = explode(' ', $result);
- }
-
-
- /**
- * Make LIST call for size of message(s)
- *
- * @param int|null $msgno number of message, null for all
- * @return int|array size of given message or list with array(num => size)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function getList($msgno = null)
- {
- if ($msgno !== null) {
- $result = $this->request("LIST $msgno");
-
- list(, $result) = explode(' ', $result);
- return (int)$result;
- }
-
- $result = $this->request('LIST', true);
- $messages = array();
- $line = strtok($result, "\n");
- while ($line) {
- list($no, $size) = explode(' ', trim($line));
- $messages[(int)$no] = (int)$size;
- $line = strtok("\n");
- }
-
- return $messages;
- }
-
-
- /**
- * Make UIDL call for getting a uniqueid
- *
- * @param int|null $msgno number of message, null for all
- * @return string|array uniqueid of message or list with array(num => uniqueid)
- * @throws Zend_Mail_Protocol_Exception
- */
- public function uniqueid($msgno = null)
- {
- if ($msgno !== null) {
- $result = $this->request("UIDL $msgno");
-
- list(, $result) = explode(' ', $result);
- return $result;
- }
-
- $result = $this->request('UIDL', true);
-
- $result = explode("\n", $result);
- $messages = array();
- foreach ($result as $line) {
- if (!$line) {
- continue;
- }
- list($no, $id) = explode(' ', trim($line), 2);
- $messages[(int)$no] = $id;
- }
-
- return $messages;
-
- }
-
-
- /**
- * Make TOP call for getting headers and maybe some body lines
- * This method also sets hasTop - before it it's not known if top is supported
- *
- * The fallback makes normale RETR call, which retrieves the whole message. Additional
- * lines are not removed.
- *
- * @param int $msgno number of message
- * @param int $lines number of wanted body lines (empty line is inserted after header lines)
- * @param bool $fallback fallback with full retrieve if top is not supported
- * @return string message headers with wanted body lines
- * @throws Zend_Mail_Protocol_Exception
- */
- public function top($msgno, $lines = 0, $fallback = false)
- {
- if ($this->hasTop === false) {
- if ($fallback) {
- return $this->retrieve($msgno);
- } else {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted');
- }
- }
- $this->hasTop = true;
-
- $lines = (!$lines || $lines < 1) ? 0 : (int)$lines;
-
- try {
- $result = $this->request("TOP $msgno $lines", true);
- } catch (Zend_Mail_Protocol_Exception $e) {
- $this->hasTop = false;
- if ($fallback) {
- $result = $this->retrieve($msgno);
- } else {
- throw $e;
- }
- }
-
- return $result;
- }
-
-
- /**
- * Make a RETR call for retrieving a full message with headers and body
- *
- * @deprecated since 1.1.0; this method has a typo - please use retrieve()
- * @param int $msgno message number
- * @return string message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function retrive($msgno)
- {
- return $this->retrieve($msgno);
- }
-
-
- /**
- * Make a RETR call for retrieving a full message with headers and body
- *
- * @param int $msgno message number
- * @return string message
- * @throws Zend_Mail_Protocol_Exception
- */
- public function retrieve($msgno)
- {
- $result = $this->request("RETR $msgno", true);
- return $result;
- }
-
- /**
- * Make a NOOP call, maybe needed for keeping the server happy
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function noop()
- {
- $this->request('NOOP');
- }
-
-
- /**
- * Make a DELE count to remove a message
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function delete($msgno)
- {
- $this->request("DELE $msgno");
- }
-
-
- /**
- * Make RSET call, which rollbacks delete requests
- *
- * @return null
- * @throws Zend_Mail_Protocol_Exception
- */
- public function undelete()
- {
- $this->request('RSET');
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to version 1.0 of the Zend Framework + * license, that is bundled with this package in the file LICENSE.txt, and + * is available through the world-wide-web at the following URL: + * http://framework.zend.com/license/new-bsd. If you did not receive + * a copy of the Zend Framework license and are unable to obtain it + * through the world-wide-web, please send a note to license@zend.com + * so we can mail you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Pop3.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Pop3 +{ + /** + * saves if server supports top + * @var null|bool + */ + public $hasTop = null; + + /** + * socket to pop3 + * @var null|resource + */ + protected $_socket; + + /** + * greeting timestamp for apop + * @var null|string + */ + protected $_timestamp; + + + /** + * Public constructor + * + * @param string $host hostname of IP address of POP3 server, if given connect() is called + * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl) + * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($host = '', $port = null, $ssl = false) + { + if ($host) { + $this->connect($host, $port, $ssl); + } + } + + + /** + * Public destructor + */ + public function __destruct() + { + $this->logout(); + } + + + /** + * Open connection to POP3 server + * + * @param string $host hostname of IP address of POP3 server + * @param int|null $port of POP3 server, default is 110 (995 for ssl) + * @param string|bool $ssl use 'SSL', 'TLS' or false + * @return string welcome message + * @throws Zend_Mail_Protocol_Exception + */ + public function connect($host, $port = null, $ssl = false) + { + if ($ssl == 'SSL') { + $host = 'ssl://' . $host; + } + + if ($port === null) { + $port = $ssl == 'SSL' ? 995 : 110; + } + + $this->_socket = @fsockopen($host, $port); + if (!$this->_socket) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot connect to host'); + } + + $welcome = $this->readResponse(); + + strtok($welcome, '<'); + $this->_timestamp = strtok('>'); + if (!strpos($this->_timestamp, '@')) { + $this->_timestamp = null; + } else { + $this->_timestamp = '<' . $this->_timestamp . '>'; + } + + if ($ssl === 'TLS') { + $this->request('STLS'); + $result = stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('cannot enable TLS'); + } + } + + return $welcome; + } + + + /** + * Send a request + * + * @param string $request your request without newline + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function sendRequest($request) + { + $result = @fputs($this->_socket, $request . "\r\n"); + if (!$result) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('send failed - connection closed?'); + } + } + + + /** + * read a response + * + * @param boolean $multiline response has multiple lines and should be read until "<nl>.<nl>" + * @return string response + * @throws Zend_Mail_Protocol_Exception + */ + public function readResponse($multiline = false) + { + $result = @fgets($this->_socket); + if (!is_string($result)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('read failed - connection closed?'); + } + + $result = trim($result); + if (strpos($result, ' ')) { + list($status, $message) = explode(' ', $result, 2); + } else { + $status = $result; + $message = ''; + } + + if ($status != '+OK') { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('last request failed'); + } + + if ($multiline) { + $message = ''; + $line = fgets($this->_socket); + while ($line && trim($line) != '.') { + $message .= $line; + $line = fgets($this->_socket); + }; + } + + return $message; + } + + + /** + * Send request and get resposne + * + * @see sendRequest(), readResponse() + * + * @param string $request request + * @param bool $multiline multiline response? + * @return string result from readResponse() + * @throws Zend_Mail_Protocol_Exception + */ + public function request($request, $multiline = false) + { + $this->sendRequest($request); + return $this->readResponse($multiline); + } + + + /** + * End communication with POP3 server (also closes socket) + * + * @return null + */ + public function logout() + { + if (!$this->_socket) { + return; + } + + try { + $this->request('QUIT'); + } catch (Zend_Mail_Protocol_Exception $e) { + // ignore error - we're closing the socket anyway + } + + fclose($this->_socket); + $this->_socket = null; + } + + + /** + * Get capabilities from POP3 server + * + * @return array list of capabilities + * @throws Zend_Mail_Protocol_Exception + */ + public function capa() + { + $result = $this->request('CAPA', true); + return explode("\n", $result); + } + + + /** + * Login to POP3 server. Can use APOP + * + * @param string $user username + * @param string $password password + * @param bool $try_apop should APOP be tried? + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function login($user, $password, $tryApop = true) + { + if ($tryApop && $this->_timestamp) { + try { + $this->request("APOP $user " . md5($this->_timestamp . $password)); + return; + } catch (Zend_Mail_Protocol_Exception $e) { + // ignore + } + } + + $result = $this->request("USER $user"); + $result = $this->request("PASS $password"); + } + + + /** + * Make STAT call for message count and size sum + * + * @param int $messages out parameter with count of messages + * @param int $octets out parameter with size in octects of messages + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function status(&$messages, &$octets) + { + $messages = 0; + $octets = 0; + $result = $this->request('STAT'); + + list($messages, $octets) = explode(' ', $result); + } + + + /** + * Make LIST call for size of message(s) + * + * @param int|null $msgno number of message, null for all + * @return int|array size of given message or list with array(num => size) + * @throws Zend_Mail_Protocol_Exception + */ + public function getList($msgno = null) + { + if ($msgno !== null) { + $result = $this->request("LIST $msgno"); + + list(, $result) = explode(' ', $result); + return (int)$result; + } + + $result = $this->request('LIST', true); + $messages = array(); + $line = strtok($result, "\n"); + while ($line) { + list($no, $size) = explode(' ', trim($line)); + $messages[(int)$no] = (int)$size; + $line = strtok("\n"); + } + + return $messages; + } + + + /** + * Make UIDL call for getting a uniqueid + * + * @param int|null $msgno number of message, null for all + * @return string|array uniqueid of message or list with array(num => uniqueid) + * @throws Zend_Mail_Protocol_Exception + */ + public function uniqueid($msgno = null) + { + if ($msgno !== null) { + $result = $this->request("UIDL $msgno"); + + list(, $result) = explode(' ', $result); + return $result; + } + + $result = $this->request('UIDL', true); + + $result = explode("\n", $result); + $messages = array(); + foreach ($result as $line) { + if (!$line) { + continue; + } + list($no, $id) = explode(' ', trim($line), 2); + $messages[(int)$no] = $id; + } + + return $messages; + + } + + + /** + * Make TOP call for getting headers and maybe some body lines + * This method also sets hasTop - before it it's not known if top is supported + * + * The fallback makes normale RETR call, which retrieves the whole message. Additional + * lines are not removed. + * + * @param int $msgno number of message + * @param int $lines number of wanted body lines (empty line is inserted after header lines) + * @param bool $fallback fallback with full retrieve if top is not supported + * @return string message headers with wanted body lines + * @throws Zend_Mail_Protocol_Exception + */ + public function top($msgno, $lines = 0, $fallback = false) + { + if ($this->hasTop === false) { + if ($fallback) { + return $this->retrieve($msgno); + } else { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('top not supported and no fallback wanted'); + } + } + $this->hasTop = true; + + $lines = (!$lines || $lines < 1) ? 0 : (int)$lines; + + try { + $result = $this->request("TOP $msgno $lines", true); + } catch (Zend_Mail_Protocol_Exception $e) { + $this->hasTop = false; + if ($fallback) { + $result = $this->retrieve($msgno); + } else { + throw $e; + } + } + + return $result; + } + + + /** + * Make a RETR call for retrieving a full message with headers and body + * + * @deprecated since 1.1.0; this method has a typo - please use retrieve() + * @param int $msgno message number + * @return string message + * @throws Zend_Mail_Protocol_Exception + */ + public function retrive($msgno) + { + return $this->retrieve($msgno); + } + + + /** + * Make a RETR call for retrieving a full message with headers and body + * + * @param int $msgno message number + * @return string message + * @throws Zend_Mail_Protocol_Exception + */ + public function retrieve($msgno) + { + $result = $this->request("RETR $msgno", true); + return $result; + } + + /** + * Make a NOOP call, maybe needed for keeping the server happy + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function noop() + { + $this->request('NOOP'); + } + + + /** + * Make a DELE count to remove a message + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function delete($msgno) + { + $this->request("DELE $msgno"); + } + + + /** + * Make RSET call, which rollbacks delete requests + * + * @return null + * @throws Zend_Mail_Protocol_Exception + */ + public function undelete() + { + $this->request('RSET'); + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp.php b/libs/Zend/Mail/Protocol/Smtp.php index e804d1b1a5..baae3253f0 100644 --- a/libs/Zend/Mail/Protocol/Smtp.php +++ b/libs/Zend/Mail/Protocol/Smtp.php @@ -1,443 +1,443 @@ -<?php
-
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mime
- */
-require_once 'Zend/Mime.php';
-
-
-/**
- * @see Zend_Mail_Protocol_Abstract
- */
-require_once 'Zend/Mail/Protocol/Abstract.php';
-
-
-/**
- * Smtp implementation of Zend_Mail_Protocol_Abstract
- *
- * Minimum implementation according to RFC2821: EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp extends Zend_Mail_Protocol_Abstract
-{
- /**
- * The transport method for the socket
- *
- * @var string
- */
- protected $_transport = 'tcp';
-
-
- /**
- * Indicates that a session is requested to be secure
- *
- * @var string
- */
- protected $_secure;
-
-
- /**
- * Indicates an smtp session has been started by the HELO command
- *
- * @var boolean
- */
- protected $_sess = false;
-
-
- /**
- * Indicates the HELO command has been issues
- *
- * @var unknown_type
- */
- protected $_helo = false;
-
-
- /**
- * Indicates an smtp AUTH has been issued and authenticated
- *
- * @var unknown_type
- */
- protected $_auth = false;
-
-
- /**
- * Indicates a MAIL command has been issued
- *
- * @var unknown_type
- */
- protected $_mail = false;
-
-
- /**
- * Indicates one or more RCTP commands have been issued
- *
- * @var unknown_type
- */
- protected $_rcpt = false;
-
-
- /**
- * Indicates that DATA has been issued and sent
- *
- * @var unknown_type
- */
- protected $_data = null;
-
-
- /**
- * Constructor.
- *
- * @param string $host
- * @param integer $port
- * @param array $config
- * @return void
- * @throws Zend_Mail_Protocol_Exception
- */
- public function __construct($host = '127.0.0.1', $port = null, array $config = array())
- {
- if (isset($config['ssl'])) {
- switch (strtolower($config['ssl'])) {
- case 'tls':
- $this->_secure = 'tls';
- break;
-
- case 'ssl':
- $this->_transport = 'ssl';
- $this->_secure = 'ssl';
- if ($port == null) {
- $port = 465;
- }
- break;
-
- default:
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception($config['ssl'] . ' is unsupported SSL type');
- break;
- }
- }
-
- // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null.
- if ($port == null) {
- if (($port = ini_get('smtp_port')) == '') {
- $port = 25;
- }
- }
-
- parent::__construct($host, $port);
- }
-
-
- /**
- * Connect to the server with the parameters given in the constructor.
- *
- * @return boolean
- */
- public function connect()
- {
- return $this->_connect($this->_transport . '://' . $this->_host . ':'. $this->_port);
- }
-
-
- /**
- * Initiate HELO/EHLO sequence and set flag to indicate valid smtp session
- *
- * @param string $host The client hostname or IP address (default: 127.0.0.1)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function helo($host = '127.0.0.1')
- {
- // Respect RFC 2821 and disallow HELO attempts if session is already initiated.
- if ($this->_sess === true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Cannot issue HELO to existing session');
- }
-
- // Validate client hostname
- if (!$this->_validHost->isValid($host)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessage()));
- }
-
- // Initiate helo sequence
- $this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_ehlo($host);
-
- // If a TLS session is required, commence negotiation
- if ($this->_secure == 'tls') {
- $this->_send('STARTTLS');
- $this->_expect(220, 180);
- if (!stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Unable to connect via TLS');
- }
- $this->_ehlo($host);
- }
-
- $this->_startSession();
- $this->auth();
- }
-
-
- /**
- * Send EHLO or HELO depending on capabilities of smtp host
- *
- * @param string $host The client hostname or IP address (default: 127.0.0.1)
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- protected function _ehlo($host)
- {
- // Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO.
- try {
- $this->_send('EHLO ' . $host);
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- } catch (Zend_Mail_Protocol_Exception $e) {
- $this->_send('HELO ' . $host);
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- } catch (Zend_Mail_Protocol_Exception $e) {
- throw $e;
- }
- }
-
-
- /**
- * Issues MAIL command
- *
- * @param string $from Sender mailbox
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function mail($from)
- {
- if ($this->_sess !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('A valid session has not been started');
- }
-
- $this->_send('MAIL FROM:<' . $from . '>');
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
-
- // Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821
- $this->_mail = true;
- $this->_rcpt = false;
- $this->_data = false;
- }
-
-
- /**
- * Issues RCPT command
- *
- * @param string $to Receiver(s) mailbox
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function rcpt($to)
- {
- if ($this->_mail !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No sender reverse path has been supplied');
- }
-
- // Set rcpt to true, as per 4.1.1.3 of RFC 2821
- $this->_send('RCPT TO:<' . $to . '>');
- $this->_expect(array(250, 251), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_rcpt = true;
- }
-
-
- /**
- * Issues DATA command
- *
- * @param string $data
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function data($data)
- {
- // Ensure recipients have been set
- if ($this->_rcpt !== true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('No recipient forward path has been supplied');
- }
-
- $this->_send('DATA');
- $this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2
-
- foreach (explode(Zend_Mime::LINEEND, $data) as $line) {
- if (strpos($line, '.') === 0) {
- // Escape lines prefixed with a '.'
- $line = '.' . $line;
- }
- $this->_send($line);
- }
-
- $this->_send('.');
- $this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2
- $this->_data = true;
- }
-
-
- /**
- * Issues the RSET command end validates answer
- *
- * Can be used to restore a clean smtp communication state when a transaction has been cancelled or commencing a new transaction.
- *
- * @return void
- */
- public function rset()
- {
- $this->_send('RSET');
- // MS ESMTP doesn't follow RFC, see [ZF-1377]
- $this->_expect(array(250, 220));
-
- $this->_mail = false;
- $this->_rcpt = false;
- $this->_data = false;
- }
-
-
- /**
- * Issues the NOOP command end validates answer
- *
- * Not used by Zend_Mail, could be used to keep a connection alive or check if it is still open.
- *
- * @return void
- */
- public function noop()
- {
- $this->_send('NOOP');
- $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- }
-
-
- /**
- * Issues the VRFY command end validates answer
- *
- * Not used by Zend_Mail.
- *
- * @param string $user User Name or eMail to verify
- * @return void
- */
- public function vrfy($user)
- {
- $this->_send('VRFY ' . $user);
- $this->_expect(array(250, 251, 252), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- }
-
-
- /**
- * Issues the QUIT command and clears the current session
- *
- * @return void
- */
- public function quit()
- {
- if ($this->_sess) {
- $this->_send('QUIT');
- $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2
- $this->_stopSession();
- }
- }
-
-
- /**
- * Default authentication method
- *
- * This default method is implemented by AUTH adapters to properly authenticate to a remote host.
- *
- * @throws Zend_Mail_Protocol_Exception
- * @return void
- */
- public function auth()
- {
- if ($this->_auth === true) {
- /**
- * @see Zend_Mail_Protocol_Exception
- */
- require_once 'Zend/Mail/Protocol/Exception.php';
- throw new Zend_Mail_Protocol_Exception('Already authenticated for this session');
- }
- }
-
-
- /**
- * Closes connection
- *
- * @return void
- */
- public function disconnect()
- {
- $this->_disconnect();
- }
-
-
- /**
- * Start mail session
- *
- * @return void
- */
- protected function _startSession()
- {
- $this->_sess = true;
- }
-
-
- /**
- * Stop mail session
- *
- * @return void
- */
- protected function _stopSession()
- {
- $this->_sess = false;
- }
-}
+<?php + +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Smtp.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + + +/** + * @see Zend_Mail_Protocol_Abstract + */ +require_once 'Zend/Mail/Protocol/Abstract.php'; + + +/** + * Smtp implementation of Zend_Mail_Protocol_Abstract + * + * Minimum implementation according to RFC2821: EHLO, MAIL FROM, RCPT TO, DATA, RSET, NOOP, QUIT + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp extends Zend_Mail_Protocol_Abstract +{ + /** + * The transport method for the socket + * + * @var string + */ + protected $_transport = 'tcp'; + + + /** + * Indicates that a session is requested to be secure + * + * @var string + */ + protected $_secure; + + + /** + * Indicates an smtp session has been started by the HELO command + * + * @var boolean + */ + protected $_sess = false; + + + /** + * Indicates the HELO command has been issues + * + * @var unknown_type + */ + protected $_helo = false; + + + /** + * Indicates an smtp AUTH has been issued and authenticated + * + * @var unknown_type + */ + protected $_auth = false; + + + /** + * Indicates a MAIL command has been issued + * + * @var unknown_type + */ + protected $_mail = false; + + + /** + * Indicates one or more RCTP commands have been issued + * + * @var unknown_type + */ + protected $_rcpt = false; + + + /** + * Indicates that DATA has been issued and sent + * + * @var unknown_type + */ + protected $_data = null; + + + /** + * Constructor. + * + * @param string $host + * @param integer $port + * @param array $config + * @return void + * @throws Zend_Mail_Protocol_Exception + */ + public function __construct($host = '127.0.0.1', $port = null, array $config = array()) + { + if (isset($config['ssl'])) { + switch (strtolower($config['ssl'])) { + case 'tls': + $this->_secure = 'tls'; + break; + + case 'ssl': + $this->_transport = 'ssl'; + $this->_secure = 'ssl'; + if ($port == null) { + $port = 465; + } + break; + + default: + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception($config['ssl'] . ' is unsupported SSL type'); + break; + } + } + + // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null. + if ($port == null) { + if (($port = ini_get('smtp_port')) == '') { + $port = 25; + } + } + + parent::__construct($host, $port); + } + + + /** + * Connect to the server with the parameters given in the constructor. + * + * @return boolean + */ + public function connect() + { + return $this->_connect($this->_transport . '://' . $this->_host . ':'. $this->_port); + } + + + /** + * Initiate HELO/EHLO sequence and set flag to indicate valid smtp session + * + * @param string $host The client hostname or IP address (default: 127.0.0.1) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function helo($host = '127.0.0.1') + { + // Respect RFC 2821 and disallow HELO attempts if session is already initiated. + if ($this->_sess === true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Cannot issue HELO to existing session'); + } + + // Validate client hostname + if (!$this->_validHost->isValid($host)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception(join(', ', $this->_validHost->getMessage())); + } + + // Initiate helo sequence + $this->_expect(220, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_ehlo($host); + + // If a TLS session is required, commence negotiation + if ($this->_secure == 'tls') { + $this->_send('STARTTLS'); + $this->_expect(220, 180); + if (!stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Unable to connect via TLS'); + } + $this->_ehlo($host); + } + + $this->_startSession(); + $this->auth(); + } + + + /** + * Send EHLO or HELO depending on capabilities of smtp host + * + * @param string $host The client hostname or IP address (default: 127.0.0.1) + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + protected function _ehlo($host) + { + // Support for older, less-compliant remote servers. Tries multiple attempts of EHLO or HELO. + try { + $this->_send('EHLO ' . $host); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } catch (Zend_Mail_Protocol_Exception $e) { + $this->_send('HELO ' . $host); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } catch (Zend_Mail_Protocol_Exception $e) { + throw $e; + } + } + + + /** + * Issues MAIL command + * + * @param string $from Sender mailbox + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function mail($from) + { + if ($this->_sess !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('A valid session has not been started'); + } + + $this->_send('MAIL FROM:<' . $from . '>'); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + + // Set mail to true, clear recipients and any existing data flags as per 4.1.1.2 of RFC 2821 + $this->_mail = true; + $this->_rcpt = false; + $this->_data = false; + } + + + /** + * Issues RCPT command + * + * @param string $to Receiver(s) mailbox + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function rcpt($to) + { + if ($this->_mail !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No sender reverse path has been supplied'); + } + + // Set rcpt to true, as per 4.1.1.3 of RFC 2821 + $this->_send('RCPT TO:<' . $to . '>'); + $this->_expect(array(250, 251), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_rcpt = true; + } + + + /** + * Issues DATA command + * + * @param string $data + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function data($data) + { + // Ensure recipients have been set + if ($this->_rcpt !== true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('No recipient forward path has been supplied'); + } + + $this->_send('DATA'); + $this->_expect(354, 120); // Timeout set for 2 minutes as per RFC 2821 4.5.3.2 + + foreach (explode(Zend_Mime::LINEEND, $data) as $line) { + if (strpos($line, '.') === 0) { + // Escape lines prefixed with a '.' + $line = '.' . $line; + } + $this->_send($line); + } + + $this->_send('.'); + $this->_expect(250, 600); // Timeout set for 10 minutes as per RFC 2821 4.5.3.2 + $this->_data = true; + } + + + /** + * Issues the RSET command end validates answer + * + * Can be used to restore a clean smtp communication state when a transaction has been cancelled or commencing a new transaction. + * + * @return void + */ + public function rset() + { + $this->_send('RSET'); + // MS ESMTP doesn't follow RFC, see [ZF-1377] + $this->_expect(array(250, 220)); + + $this->_mail = false; + $this->_rcpt = false; + $this->_data = false; + } + + + /** + * Issues the NOOP command end validates answer + * + * Not used by Zend_Mail, could be used to keep a connection alive or check if it is still open. + * + * @return void + */ + public function noop() + { + $this->_send('NOOP'); + $this->_expect(250, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } + + + /** + * Issues the VRFY command end validates answer + * + * Not used by Zend_Mail. + * + * @param string $user User Name or eMail to verify + * @return void + */ + public function vrfy($user) + { + $this->_send('VRFY ' . $user); + $this->_expect(array(250, 251, 252), 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } + + + /** + * Issues the QUIT command and clears the current session + * + * @return void + */ + public function quit() + { + if ($this->_sess) { + $this->_send('QUIT'); + $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + $this->_stopSession(); + } + } + + + /** + * Default authentication method + * + * This default method is implemented by AUTH adapters to properly authenticate to a remote host. + * + * @throws Zend_Mail_Protocol_Exception + * @return void + */ + public function auth() + { + if ($this->_auth === true) { + /** + * @see Zend_Mail_Protocol_Exception + */ + require_once 'Zend/Mail/Protocol/Exception.php'; + throw new Zend_Mail_Protocol_Exception('Already authenticated for this session'); + } + } + + + /** + * Closes connection + * + * @return void + */ + public function disconnect() + { + $this->_disconnect(); + } + + + /** + * Start mail session + * + * @return void + */ + protected function _startSession() + { + $this->_sess = true; + } + + + /** + * Stop mail session + * + * @return void + */ + protected function _stopSession() + { + $this->_sess = false; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php index d23d0e0e1f..337c7ebc98 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Crammd5.php @@ -1,108 +1,108 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Crammd5.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs CRAM-MD5 authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Zend_Mail_Protocol_Smtp
-{
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * @todo Perform CRAM-MD5 authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH CRAM-MD5');
- $challenge = $this->_expect(334);
- $challenge = base64_decode($challenge);
- $digest = $this->_hmacMd5($this->_password, $challenge);
- $this->_send(base64_encode($this->_username . ' ' . $digest));
- $this->_expect(235);
- $this->_auth = true;
- }
-
-
- /**
- * Prepare CRAM-MD5 response to server's ticket
- *
- * @param string $key Challenge key (usually password)
- * @param string $data Challenge data
- * @param string $block Length of blocks
- * @return string
- */
- protected function _hmacMd5($key, $data, $block = 64)
- {
- if (strlen($key) > 64) {
- $key = pack('H32', md5($key));
- } elseif (strlen($key) < 64) {
- $key = str_pad($key, $block, chr(0));
- }
-
- $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
- $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
-
- $inner = pack('H32', md5($k_ipad . $data));
- $digest = md5($k_opad . $inner);
-
- return $digest;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Crammd5.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs CRAM-MD5 authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Zend_Mail_Protocol_Smtp +{ + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * @todo Perform CRAM-MD5 authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH CRAM-MD5'); + $challenge = $this->_expect(334); + $challenge = base64_decode($challenge); + $digest = $this->_hmacMd5($this->_password, $challenge); + $this->_send(base64_encode($this->_username . ' ' . $digest)); + $this->_expect(235); + $this->_auth = true; + } + + + /** + * Prepare CRAM-MD5 response to server's ticket + * + * @param string $key Challenge key (usually password) + * @param string $data Challenge data + * @param string $block Length of blocks + * @return string + */ + protected function _hmacMd5($key, $data, $block = 64) + { + if (strlen($key) > 64) { + $key = pack('H32', md5($key)); + } elseif (strlen($key) < 64) { + $key = str_pad($key, $block, chr(0)); + } + + $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64); + $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64); + + $inner = pack('H32', md5($k_ipad . $data)); + $digest = md5($k_opad . $inner); + + return $digest; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php index dead2ace33..6332207199 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Login.php @@ -1,98 +1,98 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Login.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs LOGIN authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Login extends Zend_Mail_Protocol_Smtp
-{
- /**
- * LOGIN username
- *
- * @var string
- */
- protected $_username;
-
-
- /**
- * LOGIN password
- *
- * @var string
- */
- protected $_password;
-
-
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * Perform LOGIN authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH LOGIN');
- $this->_expect(334);
- $this->_send(base64_encode($this->_username));
- $this->_expect(334);
- $this->_send(base64_encode($this->_password));
- $this->_expect(235);
- $this->_auth = true;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Login.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs LOGIN authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Login extends Zend_Mail_Protocol_Smtp +{ + /** + * LOGIN username + * + * @var string + */ + protected $_username; + + + /** + * LOGIN password + * + * @var string + */ + protected $_password; + + + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * Perform LOGIN authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH LOGIN'); + $this->_expect(334); + $this->_send(base64_encode($this->_username)); + $this->_expect(334); + $this->_send(base64_encode($this->_password)); + $this->_expect(235); + $this->_auth = true; + } +} diff --git a/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php b/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php index 5a85c996c8..cb8d019770 100644 --- a/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php +++ b/libs/Zend/Mail/Protocol/Smtp/Auth/Plain.php @@ -1,96 +1,96 @@ -<?php
-/**
- * Zend Framework
- *
- * LICENSE
- *
- * This source file is subject to the new BSD license that is bundled
- * with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://framework.zend.com/license/new-bsd
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@zend.com so we can send you a copy immediately.
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id: Plain.php 8064 2008-02-16 10:58:39Z thomas $
- */
-
-
-/**
- * @see Zend_Mail_Protocol_Smtp
- */
-require_once 'Zend/Mail/Protocol/Smtp.php';
-
-
-/**
- * Performs PLAIN authentication
- *
- * @category Zend
- * @package Zend_Mail
- * @subpackage Protocol
- * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-class Zend_Mail_Protocol_Smtp_Auth_Plain extends Zend_Mail_Protocol_Smtp
-{
- /**
- * PLAIN username
- *
- * @var string
- */
- protected $_username;
-
-
- /**
- * PLAIN password
- *
- * @var string
- */
- protected $_password;
-
-
- /**
- * Constructor.
- *
- * @param string $host (Default: 127.0.0.1)
- * @param int $port (Default: null)
- * @param array $config Auth-specific parameters
- * @return void
- */
- public function __construct($host = '127.0.0.1', $port = null, $config = null)
- {
- if (is_array($config)) {
- if (isset($config['username'])) {
- $this->_username = $config['username'];
- }
- if (isset($config['password'])) {
- $this->_password = $config['password'];
- }
- }
-
- parent::__construct($host, $port, $config);
- }
-
-
- /**
- * Perform PLAIN authentication with supplied credentials
- *
- * @return void
- */
- public function auth()
- {
- // Ensure AUTH has not already been initiated.
- parent::auth();
-
- $this->_send('AUTH PLAIN');
- $this->_expect(334);
- $this->_send(base64_encode(chr(0) . $this->_username . chr(0) . $this->_password));
- $this->_expect(235);
- $this->_auth = true;
- }
-}
+<?php +/** + * Zend Framework + * + * LICENSE + * + * This source file is subject to the new BSD license that is bundled + * with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * http://framework.zend.com/license/new-bsd + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@zend.com so we can send you a copy immediately. + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id: Plain.php 8064 2008-02-16 10:58:39Z thomas $ + */ + + +/** + * @see Zend_Mail_Protocol_Smtp + */ +require_once 'Zend/Mail/Protocol/Smtp.php'; + + +/** + * Performs PLAIN authentication + * + * @category Zend + * @package Zend_Mail + * @subpackage Protocol + * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ +class Zend_Mail_Protocol_Smtp_Auth_Plain extends Zend_Mail_Protocol_Smtp +{ + /** + * PLAIN username + * + * @var string + */ + protected $_username; + + + /** + * PLAIN password + * + * @var string + */ + protected $_password; + + + /** + * Constructor. + * + * @param string $host (Default: 127.0.0.1) + * @param int $port (Default: null) + * @param array $config Auth-specific parameters + * @return void + */ + public function __construct($host = '127.0.0.1', $port = null, $config = null) + { + if (is_array($config)) { + if (isset($config['username'])) { + $this->_username = $config['username']; + } + if (isset($config['password'])) { + $this->_password = $config['password']; + } + } + + parent::__construct($host, $port, $config); + } + + + /** + * Perform PLAIN authentication with supplied credentials + * + * @return void + */ + public function auth() + { + // Ensure AUTH has not already been initiated. + parent::auth(); + + $this->_send('AUTH PLAIN'); + $this->_expect(334); + $this->_send(base64_encode(chr(0) . $this->_username . chr(0) . $this->_password)); + $this->_expect(235); + $this->_auth = true; + } +} |