%PDF- %PDF-
Direktori : /home/vacivi36/ava/lib/horde/framework/Horde/Imap/Client/Auth/ |
Current File : /home/vacivi36/ava/lib/horde/framework/Horde/Imap/Client/Auth/DigestMD5.php |
<?php /** * Copyright (c) 2002-2003 Richard Heyes * Copyright 2011-2017 Horde LLC (http://www.horde.org/) * * This code is based on the original code contained in the PEAR Auth_SASL * package (v0.5.1): * $Id: DigestMD5.php 294702 2010-02-07 16:03:55Z cweiske $ * * That code is covered by the BSD 3-Clause license, as set forth below: * +-----------------------------------------------------------------------+ * | Copyright (c) 2002-2003 Richard Heyes | * | All rights reserved. | * | | * | Redistribution and use in source and binary forms, with or without | * | modification, are permitted provided that the following conditions | * | are met: | * | | * | o Redistributions of source code must retain the above copyright | * | notice, this list of conditions and the following disclaimer. | * | o Redistributions in binary form must reproduce the above copyright | * | notice, this list of conditions and the following disclaimer in the | * | documentation and/or other materials provided with the distribution.| * | o The names of the authors may not be used to endorse or promote | * | products derived from this software without specific prior written | * | permission. | * | | * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * +-----------------------------------------------------------------------+ * * @category Horde * @copyright 2002-2003 Richard Heyes * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ /** * Provides the code needed to authenticate via the DIGEST-MD5 SASL mechanism * (defined in RFC 2831). This method has been obsoleted by RFC 6331, but * still is in use on legacy servers. * * @author Richard Heyes <richard@php.net> * @author Michael Slusarz <slusarz@horde.org> * @copyright 2002-2003 Richard Heyes * @copyright 2011-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Imap_Client */ class Horde_Imap_Client_Auth_DigestMD5 { /** * Digest response components. * * @var string */ protected $_response; /** * Generate the Digest-MD5 response. * * @param string $id Authentication id (username). * @param string $pass Password. * @param string $challenge The digest challenge sent by the server. * @param string $hostname The hostname of the machine connecting to. * @param string $service The service name (e.g. 'imap', 'pop3'). * * @throws Horde_Imap_Client_Exception */ public function __construct($id, $pass, $challenge, $hostname, $service) { $challenge = $this->_parseChallenge($challenge); $cnonce = $this->_getCnonce(); $digest_uri = sprintf('%s/%s', $service, $hostname); /* Get response value. */ $A1 = sprintf('%s:%s:%s', pack('H32', hash('md5', sprintf('%s:%s:%s', $id, $challenge['realm'], $pass))), $challenge['nonce'], $cnonce); $A2 = 'AUTHENTICATE:' . $digest_uri; $response_value = hash('md5', sprintf('%s:%s:00000001:%s:auth:%s', hash('md5', $A1), $challenge['nonce'], $cnonce, hash('md5', $A2))); $this->_response = array( 'cnonce' => '"' . $cnonce . '"', 'digest-uri' => '"' . $digest_uri . '"', 'maxbuf' => $challenge['maxbuf'], 'nc' => '00000001', 'nonce' => '"' . $challenge['nonce'] . '"', 'qop' => 'auth', 'response' => $response_value, 'username' => '"' . $id . '"' ); if (strlen($challenge['realm'])) { $this->_response['realm'] = '"' . $challenge['realm'] . '"'; } } /** * Cooerce to string. * * @return string The digest response (not base64 encoded). */ public function __toString() { $out = array(); foreach ($this->_response as $key => $val) { $out[] = $key . '=' . $val; } return implode(',', $out); } /** * Return specific digest response directive. * * @return mixed Requested directive, or null if it does not exist. */ public function __get($name) { return isset($this->_response[$name]) ? $this->_response[$name] : null; } /** * Parses and verifies the digest challenge. * * @param string $challenge The digest challenge * * @return array The parsed challenge as an array with directives as keys. * * @throws Horde_Imap_Client_Exception */ protected function _parseChallenge($challenge) { $tokens = array( 'maxbuf' => 65536, 'realm' => '' ); preg_match_all('/([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches, PREG_SET_ORDER); foreach ($matches as $val) { $tokens[$val[1]] = trim($val[2], '"'); } // Required directives. if (!isset($tokens['nonce']) || !isset($tokens['algorithm'])) { throw new Horde_Imap_Client_Exception( Horde_Imap_Client_Translation::r("Authentication failure."), Horde_Imap_Client_Exception::SERVER_CONNECT ); } return $tokens; } /** * Creates the client nonce for the response * * @return string The cnonce value. */ protected function _getCnonce() { if ((@is_readable('/dev/urandom') && ($fd = @fopen('/dev/urandom', 'r'))) || (@is_readable('/dev/random') && ($fd = @fopen('/dev/random', 'r')))) { $str = fread($fd, 32); fclose($fd); } else { $str = ''; for ($i = 0; $i < 32; ++$i) { $str .= chr(mt_rand(0, 255)); } } return base64_encode($str); } }