PageRenderTime 47ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ezc/Authentication/src/filters/htpasswd/htpasswd_filter.php

https://bitbucket.org/crevillo/enetcall
PHP | 234 lines | 99 code | 14 blank | 121 comment | 11 complexity | 2657c852fb14991cdaa189db0d0d0eb8 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * File containing the ezcAuthenticationHtpasswdFilter class.
  4. *
  5. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  6. * @license http://ez.no/licenses/new_bsd New BSD License
  7. * @filesource
  8. * @package Authentication
  9. * @version //autogen//
  10. */
  11. /**
  12. * Filter to authenticate against an Unix htpasswd file.
  13. *
  14. * It supports files created with the htpasswd command options
  15. * -m (MD5 encryption - different than the PHP md5() function)
  16. * -d (CRYPT encryption)
  17. * -s (SHA encryption)
  18. * -p (plain text)
  19. *
  20. * The encryption used for the password field in the file will be detected
  21. * automatically.
  22. *
  23. * The password property can be specified as plain text or in encrypted form,
  24. * depending on the option 'plain' in the ezcAuthenticationHtpasswdOptions object
  25. * used as options.
  26. *
  27. * Example:
  28. * <code>
  29. * $credentials = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 'b1b3773a05c0ed0176787a4f1574ff0075f7521e' );
  30. * $authentication = new ezcAuthentication( $credentials );
  31. * $authentication->session = new ezcAuthenticationSession();
  32. * $authentication->addFilter( new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd' ) );
  33. * // add other filters if needed
  34. * if ( !$authentication->run() )
  35. * {
  36. * // authentication did not succeed, so inform the user
  37. * $status = $authentication->getStatus();
  38. * $err = array(
  39. * 'ezcAuthenticationHtpasswdFilter' => array(
  40. * ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
  41. * ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
  42. * )
  43. * );
  44. * foreach ( $status as $line )
  45. * {
  46. * list( $key, $value ) = each( $line );
  47. * echo $err[$key][$value] . "\n";
  48. * }
  49. * }
  50. * else
  51. * {
  52. * // authentication succeeded, so allow the user to see his content
  53. * }
  54. * </code>
  55. *
  56. * @property string $file
  57. * The path and file name of the htpasswd file to use.
  58. *
  59. * @package Authentication
  60. * @version //autogen//
  61. * @mainclass
  62. */
  63. class ezcAuthenticationHtpasswdFilter extends ezcAuthenticationFilter
  64. {
  65. /**
  66. * Username is not found in the htpasswd file.
  67. */
  68. const STATUS_USERNAME_INCORRECT = 1;
  69. /**
  70. * Password is incorrect.
  71. */
  72. const STATUS_PASSWORD_INCORRECT = 2;
  73. /**
  74. * Holds the properties of this class.
  75. *
  76. * @var array(string=>mixed)
  77. */
  78. private $properties = array();
  79. /**
  80. * Creates a new object of this class.
  81. *
  82. * @throws ezcBaseValueException
  83. * if the value provided is not correct for the property $file
  84. * @throws ezcBaseFileNotFoundException
  85. * if $file does not exist
  86. * @throws ezcBaseFilePermissionException
  87. * if $file cannot be opened for reading
  88. * @param string $file The path and file name of the htpasswd file to use
  89. * @param ezcAuthenticationHtpasswdOptions $options Options for this class
  90. */
  91. public function __construct( $file, ezcAuthenticationHtpasswdOptions $options = null )
  92. {
  93. $this->file = $file;
  94. $this->options = ( $options === null ) ? new ezcAuthenticationHtpasswdOptions() : $options;
  95. }
  96. /**
  97. * Sets the property $name to $value.
  98. *
  99. * @throws ezcBasePropertyNotFoundException
  100. * if the property $name does not exist
  101. * @throws ezcBaseValueException
  102. * if $value is not correct for the property $name
  103. * @throws ezcBaseFileNotFoundException
  104. * if the $value file does not exist
  105. * @throws ezcBaseFilePermissionException
  106. * if the $value file cannot be opened for reading
  107. * @param string $name The name of the property to set
  108. * @param mixed $value The new value of the property
  109. * @ignore
  110. */
  111. public function __set( $name, $value )
  112. {
  113. switch ( $name )
  114. {
  115. case 'file':
  116. if ( !is_string( $value ) )
  117. {
  118. throw new ezcBaseValueException( $name, $value, 'string' );
  119. }
  120. if ( !file_exists( $value ) )
  121. {
  122. throw new ezcBaseFileNotFoundException( $value );
  123. }
  124. if ( !is_readable( $value ) )
  125. {
  126. throw new ezcBaseFilePermissionException( $value, ezcBaseFileException::READ );
  127. }
  128. $this->properties[$name] = $value;
  129. break;
  130. default:
  131. throw new ezcBasePropertyNotFoundException( $name );
  132. }
  133. }
  134. /**
  135. * Returns the value of the property $name.
  136. *
  137. * @throws ezcBasePropertyNotFoundException
  138. * if the property $name does not exist
  139. * @param string $name The name of the property for which to return the value
  140. * @return mixed
  141. * @ignore
  142. */
  143. public function __get( $name )
  144. {
  145. switch ( $name )
  146. {
  147. case 'file':
  148. return $this->properties[$name];
  149. default:
  150. throw new ezcBasePropertyNotFoundException( $name );
  151. }
  152. }
  153. /**
  154. * Returns true if the property $name is set, otherwise false.
  155. *
  156. * @param string $name The name of the property to test if it is set
  157. * @return bool
  158. * @ignore
  159. */
  160. public function __isset( $name )
  161. {
  162. switch ( $name )
  163. {
  164. case 'file':
  165. return isset( $this->properties[$name] );
  166. default:
  167. return false;
  168. }
  169. }
  170. /**
  171. * Runs the filter and returns a status code when finished.
  172. *
  173. * @param ezcAuthenticationPasswordCredentials $credentials Authentication credentials
  174. * @return int
  175. */
  176. public function run( $credentials )
  177. {
  178. $fh = fopen( $this->file, 'r' );
  179. $found = false;
  180. while ( $line = fgets( $fh ) )
  181. {
  182. if ( substr( $line, 0, strlen( $credentials->id ) + 1 ) === $credentials->id . ':' )
  183. {
  184. $found = true;
  185. break;
  186. }
  187. }
  188. fclose( $fh );
  189. if ( $found )
  190. {
  191. $parts = explode( ':', $line );
  192. $hashFromFile = trim( $parts[1] );
  193. if ( substr( $hashFromFile, 0, 6 ) === '$apr1$' )
  194. {
  195. $password = ( $this->options->plain ) ? ezcAuthenticationMath::apr1( $credentials->password, $hashFromFile ) :
  196. '$apr1$' . $credentials->password;
  197. }
  198. elseif ( substr( $hashFromFile, 0, 5 ) === '{SHA}' )
  199. {
  200. $password = ( $this->options->plain ) ? '{SHA}' . base64_encode( pack( 'H40', sha1( $credentials->password ) ) ) :
  201. '{SHA}' . $credentials->password;
  202. }
  203. else
  204. {
  205. $password = ( $this->options->plain ) ? crypt( $credentials->password, $hashFromFile ) :
  206. $credentials->password;
  207. }
  208. if ( $password === $hashFromFile )
  209. {
  210. return self::STATUS_OK;
  211. }
  212. else
  213. {
  214. return self::STATUS_PASSWORD_INCORRECT;
  215. }
  216. }
  217. return self::STATUS_USERNAME_INCORRECT;
  218. }
  219. }
  220. ?>