$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; } }