diff -r 000000000000 -r 4eba9c11703f web/Zend/Auth/Adapter/Digest.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/Zend/Auth/Adapter/Digest.php Mon Dec 13 18:29:26 2010 +0100 @@ -0,0 +1,252 @@ +$methodName($$option); + } + } + } + + /** + * Returns the filename option value or null if it has not yet been set + * + * @return string|null + */ + public function getFilename() + { + return $this->_filename; + } + + /** + * Sets the filename option value + * + * @param mixed $filename + * @return Zend_Auth_Adapter_Digest Provides a fluent interface + */ + public function setFilename($filename) + { + $this->_filename = (string) $filename; + return $this; + } + + /** + * Returns the realm option value or null if it has not yet been set + * + * @return string|null + */ + public function getRealm() + { + return $this->_realm; + } + + /** + * Sets the realm option value + * + * @param mixed $realm + * @return Zend_Auth_Adapter_Digest Provides a fluent interface + */ + public function setRealm($realm) + { + $this->_realm = (string) $realm; + return $this; + } + + /** + * Returns the username option value or null if it has not yet been set + * + * @return string|null + */ + public function getUsername() + { + return $this->_username; + } + + /** + * Sets the username option value + * + * @param mixed $username + * @return Zend_Auth_Adapter_Digest Provides a fluent interface + */ + public function setUsername($username) + { + $this->_username = (string) $username; + return $this; + } + + /** + * Returns the password option value or null if it has not yet been set + * + * @return string|null + */ + public function getPassword() + { + return $this->_password; + } + + /** + * Sets the password option value + * + * @param mixed $password + * @return Zend_Auth_Adapter_Digest Provides a fluent interface + */ + public function setPassword($password) + { + $this->_password = (string) $password; + return $this; + } + + /** + * Defined by Zend_Auth_Adapter_Interface + * + * @throws Zend_Auth_Adapter_Exception + * @return Zend_Auth_Result + */ + public function authenticate() + { + $optionsRequired = array('filename', 'realm', 'username', 'password'); + foreach ($optionsRequired as $optionRequired) { + if (null === $this->{"_$optionRequired"}) { + /** + * @see Zend_Auth_Adapter_Exception + */ + require_once 'Zend/Auth/Adapter/Exception.php'; + throw new Zend_Auth_Adapter_Exception("Option '$optionRequired' must be set before authentication"); + } + } + + if (false === ($fileHandle = @fopen($this->_filename, 'r'))) { + /** + * @see Zend_Auth_Adapter_Exception + */ + require_once 'Zend/Auth/Adapter/Exception.php'; + throw new Zend_Auth_Adapter_Exception("Cannot open '$this->_filename' for reading"); + } + + $id = "$this->_username:$this->_realm"; + $idLength = strlen($id); + + $result = array( + 'code' => Zend_Auth_Result::FAILURE, + 'identity' => array( + 'realm' => $this->_realm, + 'username' => $this->_username, + ), + 'messages' => array() + ); + + while ($line = trim(fgets($fileHandle))) { + if (substr($line, 0, $idLength) === $id) { + if ($this->_secureStringCompare(substr($line, -32), md5("$this->_username:$this->_realm:$this->_password"))) { + $result['code'] = Zend_Auth_Result::SUCCESS; + } else { + $result['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID; + $result['messages'][] = 'Password incorrect'; + } + return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']); + } + } + + $result['code'] = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND; + $result['messages'][] = "Username '$this->_username' and realm '$this->_realm' combination not found"; + return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']); + } + + /** + * Securely compare two strings for equality while avoided C level memcmp() + * optimisations capable of leaking timing information useful to an attacker + * attempting to iteratively guess the unknown string (e.g. password) being + * compared against. + * + * @param string $a + * @param string $b + * @return bool + */ + protected function _secureStringCompare($a, $b) + { + if (strlen($a) !== strlen($b)) { + return false; + } + $result = 0; + for ($i = 0; $i < strlen($a); $i++) { + $result |= ord($a[$i]) ^ ord($b[$i]); + } + return $result == 0; + } +}