PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Auth/Adapter/Digest.php

https://bitbucket.org/luizbrandaoj/mini-blog
PHP | 252 lines | 104 code | 23 blank | 125 comment | 11 complexity | ed24998a8768f9730711f94a62737b2e MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Auth
  17. * @subpackage Adapter
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Digest.php 23775 2011-03-01 17:25:24Z ralph $
  21. */
  22. /**
  23. * @see Zend_Auth_Adapter_Interface
  24. */
  25. require_once 'Zend/Auth/Adapter/Interface.php';
  26. /**
  27. * @category Zend
  28. * @package Zend_Auth
  29. * @subpackage Adapter
  30. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Auth_Adapter_Digest implements Zend_Auth_Adapter_Interface
  34. {
  35. /**
  36. * Filename against which authentication queries are performed
  37. *
  38. * @var string
  39. */
  40. protected $_filename;
  41. /**
  42. * Digest authentication realm
  43. *
  44. * @var string
  45. */
  46. protected $_realm;
  47. /**
  48. * Digest authentication user
  49. *
  50. * @var string
  51. */
  52. protected $_username;
  53. /**
  54. * Password for the user of the realm
  55. *
  56. * @var string
  57. */
  58. protected $_password;
  59. /**
  60. * Sets adapter options
  61. *
  62. * @param mixed $filename
  63. * @param mixed $realm
  64. * @param mixed $username
  65. * @param mixed $password
  66. * @return void
  67. */
  68. public function __construct($filename = null, $realm = null, $username = null, $password = null)
  69. {
  70. $options = array('filename', 'realm', 'username', 'password');
  71. foreach ($options as $option) {
  72. if (null !== $$option) {
  73. $methodName = 'set' . ucfirst($option);
  74. $this->$methodName($$option);
  75. }
  76. }
  77. }
  78. /**
  79. * Returns the filename option value or null if it has not yet been set
  80. *
  81. * @return string|null
  82. */
  83. public function getFilename()
  84. {
  85. return $this->_filename;
  86. }
  87. /**
  88. * Sets the filename option value
  89. *
  90. * @param mixed $filename
  91. * @return Zend_Auth_Adapter_Digest Provides a fluent interface
  92. */
  93. public function setFilename($filename)
  94. {
  95. $this->_filename = (string) $filename;
  96. return $this;
  97. }
  98. /**
  99. * Returns the realm option value or null if it has not yet been set
  100. *
  101. * @return string|null
  102. */
  103. public function getRealm()
  104. {
  105. return $this->_realm;
  106. }
  107. /**
  108. * Sets the realm option value
  109. *
  110. * @param mixed $realm
  111. * @return Zend_Auth_Adapter_Digest Provides a fluent interface
  112. */
  113. public function setRealm($realm)
  114. {
  115. $this->_realm = (string) $realm;
  116. return $this;
  117. }
  118. /**
  119. * Returns the username option value or null if it has not yet been set
  120. *
  121. * @return string|null
  122. */
  123. public function getUsername()
  124. {
  125. return $this->_username;
  126. }
  127. /**
  128. * Sets the username option value
  129. *
  130. * @param mixed $username
  131. * @return Zend_Auth_Adapter_Digest Provides a fluent interface
  132. */
  133. public function setUsername($username)
  134. {
  135. $this->_username = (string) $username;
  136. return $this;
  137. }
  138. /**
  139. * Returns the password option value or null if it has not yet been set
  140. *
  141. * @return string|null
  142. */
  143. public function getPassword()
  144. {
  145. return $this->_password;
  146. }
  147. /**
  148. * Sets the password option value
  149. *
  150. * @param mixed $password
  151. * @return Zend_Auth_Adapter_Digest Provides a fluent interface
  152. */
  153. public function setPassword($password)
  154. {
  155. $this->_password = (string) $password;
  156. return $this;
  157. }
  158. /**
  159. * Defined by Zend_Auth_Adapter_Interface
  160. *
  161. * @throws Zend_Auth_Adapter_Exception
  162. * @return Zend_Auth_Result
  163. */
  164. public function authenticate()
  165. {
  166. $optionsRequired = array('filename', 'realm', 'username', 'password');
  167. foreach ($optionsRequired as $optionRequired) {
  168. if (null === $this->{"_$optionRequired"}) {
  169. /**
  170. * @see Zend_Auth_Adapter_Exception
  171. */
  172. require_once 'Zend/Auth/Adapter/Exception.php';
  173. throw new Zend_Auth_Adapter_Exception("Option '$optionRequired' must be set before authentication");
  174. }
  175. }
  176. if (false === ($fileHandle = @fopen($this->_filename, 'r'))) {
  177. /**
  178. * @see Zend_Auth_Adapter_Exception
  179. */
  180. require_once 'Zend/Auth/Adapter/Exception.php';
  181. throw new Zend_Auth_Adapter_Exception("Cannot open '$this->_filename' for reading");
  182. }
  183. $id = "$this->_username:$this->_realm";
  184. $idLength = strlen($id);
  185. $result = array(
  186. 'code' => Zend_Auth_Result::FAILURE,
  187. 'identity' => array(
  188. 'realm' => $this->_realm,
  189. 'username' => $this->_username,
  190. ),
  191. 'messages' => array()
  192. );
  193. while ($line = trim(fgets($fileHandle))) {
  194. if (substr($line, 0, $idLength) === $id) {
  195. if ($this->_secureStringCompare(substr($line, -32), md5("$this->_username:$this->_realm:$this->_password"))) {
  196. $result['code'] = Zend_Auth_Result::SUCCESS;
  197. } else {
  198. $result['code'] = Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID;
  199. $result['messages'][] = 'Password incorrect';
  200. }
  201. return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']);
  202. }
  203. }
  204. $result['code'] = Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND;
  205. $result['messages'][] = "Username '$this->_username' and realm '$this->_realm' combination not found";
  206. return new Zend_Auth_Result($result['code'], $result['identity'], $result['messages']);
  207. }
  208. /**
  209. * Securely compare two strings for equality while avoided C level memcmp()
  210. * optimisations capable of leaking timing information useful to an attacker
  211. * attempting to iteratively guess the unknown string (e.g. password) being
  212. * compared against.
  213. *
  214. * @param string $a
  215. * @param string $b
  216. * @return bool
  217. */
  218. protected function _secureStringCompare($a, $b)
  219. {
  220. if (strlen($a) !== strlen($b)) {
  221. return false;
  222. }
  223. $result = 0;
  224. for ($i = 0; $i < strlen($a); $i++) {
  225. $result |= ord($a[$i]) ^ ord($b[$i]);
  226. }
  227. return $result == 0;
  228. }
  229. }