File indexing completed on 2025-03-02 05:29:34

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Mail
0017  * @subpackage Protocol
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 
0024 /**
0025  * @see Zend_Mail_Protocol_Smtp
0026  */
0027 // require_once 'Zend/Mail/Protocol/Smtp.php';
0028 
0029 
0030 /**
0031  * Performs CRAM-MD5 authentication
0032  *
0033  * @category   Zend
0034  * @package    Zend_Mail
0035  * @subpackage Protocol
0036  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0037  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0038  */
0039 class Zend_Mail_Protocol_Smtp_Auth_Crammd5 extends Zend_Mail_Protocol_Smtp
0040 {
0041     /**
0042      * Constructor.
0043      *
0044      * @param  string $host   (Default: 127.0.0.1)
0045      * @param  int    $port   (Default: null)
0046      * @param  array  $config Auth-specific parameters
0047      * @return void
0048      */
0049     public function __construct($host = '127.0.0.1', $port = null, $config = null)
0050     {
0051         if (is_array($config)) {
0052             if (isset($config['username'])) {
0053                 $this->_username = $config['username'];
0054             }
0055             if (isset($config['password'])) {
0056                 $this->_password = $config['password'];
0057             }
0058         }
0059 
0060         parent::__construct($host, $port, $config);
0061     }
0062 
0063 
0064     /**
0065      * @todo Perform CRAM-MD5 authentication with supplied credentials
0066      *
0067      * @return void
0068      */
0069     public function auth()
0070     {
0071         // Ensure AUTH has not already been initiated.
0072         parent::auth();
0073 
0074         $this->_send('AUTH CRAM-MD5');
0075         $challenge = $this->_expect(334);
0076         $challenge = base64_decode($challenge);
0077         $digest = $this->_hmacMd5($this->_password, $challenge);
0078         $this->_send(base64_encode($this->_username . ' ' . $digest));
0079         $this->_expect(235);
0080         $this->_auth = true;
0081     }
0082 
0083 
0084     /**
0085      * Prepare CRAM-MD5 response to server's ticket
0086      *
0087      * @param  string $key   Challenge key (usually password)
0088      * @param  string $data  Challenge data
0089      * @param  string $block Length of blocks
0090      * @return string
0091      */
0092     protected function _hmacMd5($key, $data, $block = 64)
0093     {
0094         if (strlen($key) > 64) {
0095             $key = pack('H32', md5($key));
0096         } elseif (strlen($key) < 64) {
0097             $key = str_pad($key, $block, "\0");
0098         }
0099 
0100         $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
0101         $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
0102 
0103         $inner = pack('H32', md5($k_ipad . $data));
0104         $digest = md5($k_opad . $inner);
0105 
0106         return $digest;
0107     }
0108 }