3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Authentication\Adapter
;
12 use Zend\Authentication\Result
as AuthenticationResult
;
13 use Zend\Stdlib\ErrorHandler
;
14 use Zend\Crypt\Utils
as CryptUtils
;
16 class Digest
extends AbstractAdapter
19 * Filename against which authentication queries are performed
26 * Digest authentication realm
33 * Sets adapter options
35 * @param mixed $filename
37 * @param mixed $identity
38 * @param mixed $credential
40 public function __construct($filename = null, $realm = null, $identity = null, $credential = null)
42 if ($filename !== null) {
43 $this->setFilename($filename);
45 if ($realm !== null) {
46 $this->setRealm($realm);
48 if ($identity !== null) {
49 $this->setIdentity($identity);
51 if ($credential !== null) {
52 $this->setCredential($credential);
57 * Returns the filename option value or null if it has not yet been set
61 public function getFilename()
63 return $this->filename
;
67 * Sets the filename option value
69 * @param mixed $filename
70 * @return Digest Provides a fluent interface
72 public function setFilename($filename)
74 $this->filename
= (string) $filename;
79 * Returns the realm option value or null if it has not yet been set
83 public function getRealm()
89 * Sets the realm option value
92 * @return Digest Provides a fluent interface
94 public function setRealm($realm)
96 $this->realm
= (string) $realm;
101 * Returns the username option value or null if it has not yet been set
103 * @return string|null
105 public function getUsername()
107 return $this->getIdentity();
111 * Sets the username option value
113 * @param mixed $username
114 * @return Digest Provides a fluent interface
116 public function setUsername($username)
118 return $this->setIdentity($username);
122 * Returns the password option value or null if it has not yet been set
124 * @return string|null
126 public function getPassword()
128 return $this->getCredential();
132 * Sets the password option value
134 * @param mixed $password
135 * @return Digest Provides a fluent interface
137 public function setPassword($password)
139 return $this->setCredential($password);
143 * Defined by Zend\Authentication\Adapter\AdapterInterface
145 * @throws Exception\ExceptionInterface
146 * @return AuthenticationResult
148 public function authenticate()
150 $optionsRequired = array('filename', 'realm', 'identity', 'credential');
151 foreach ($optionsRequired as $optionRequired) {
152 if (null === $this->$optionRequired) {
153 throw new Exception\
RuntimeException("Option '$optionRequired' must be set before authentication");
157 ErrorHandler
::start(E_WARNING
);
158 $fileHandle = fopen($this->filename
, 'r');
159 $error = ErrorHandler
::stop();
160 if (false === $fileHandle) {
161 throw new Exception\
UnexpectedValueException("Cannot open '$this->filename' for reading", 0, $error);
164 $id = "$this->identity:$this->realm";
165 $idLength = strlen($id);
168 'code' => AuthenticationResult
::FAILURE
,
170 'realm' => $this->realm
,
171 'username' => $this->identity
,
173 'messages' => array()
176 while (($line = fgets($fileHandle)) !== false) {
181 if (substr($line, 0, $idLength) === $id) {
182 if (CryptUtils
::compareStrings(substr($line, -32), md5("$this->identity:$this->realm:$this->credential"))) {
183 $result['code'] = AuthenticationResult
::SUCCESS
;
185 $result['code'] = AuthenticationResult
::FAILURE_CREDENTIAL_INVALID
;
186 $result['messages'][] = 'Password incorrect';
188 return new AuthenticationResult($result['code'], $result['identity'], $result['messages']);
192 $result['code'] = AuthenticationResult
::FAILURE_IDENTITY_NOT_FOUND
;
193 $result['messages'][] = "Username '$this->identity' and realm '$this->realm' combination not found";
194 return new AuthenticationResult($result['code'], $result['identity'], $result['messages']);