htpasswd.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. include_once ("model/meta_model.php");
  3. /**
  4. * htpasswd tools for Apache Basic Auth.
  5. *
  6. * Uses crypt only!
  7. */
  8. class htpasswd {
  9. var $fp;
  10. var $metafp;
  11. var $filename;
  12. var $metafilename;
  13. var $use_metadata;
  14. /* All ht-files. These files are stored within the secured folder. */
  15. const HTPASSWD_NAME = ".htpasswd";
  16. const HTACCESS_NAME = ".htaccess";
  17. const HTMETA_NAME = ".htmeta";
  18. function htpasswd($configpath, $use_metadata = false) {
  19. $path = realpath ( $configpath );
  20. $htaccessfile = $path . "/" . self::HTACCESS_NAME;
  21. $htpasswdfile = $path . "/" . self::HTPASSWD_NAME;
  22. @$this->use_metadata = $use_metadata;
  23. if (! file_exists ( $htaccessfile )) {
  24. $bdfp = fopen ( $htaccessfile, 'w' );
  25. $htaccess_content = "AuthType Basic\nAuthName \"Password Protected Area\"\nAuthUserFile \"" . $htpasswdfile . "\"\nRequire valid-user" . "<Files .ht*>\nOrder deny,allow\nDeny from all\n</Files>";
  26. fwrite ( $bdfp, $htaccess_content );
  27. }
  28. @$this->fp = @$this::open_or_create ( $htpasswdfile );
  29. if ($use_metadata) {
  30. $htmetafile = $path . "/" . self::HTMETA_NAME;
  31. @$this->metafp = @$this::open_or_create ( $htmetafile );
  32. $this->metafilename = $htmetafile;
  33. }
  34. $this->filename = $htpasswdfile;
  35. }
  36. function user_exists($username) {
  37. return self::exists ( @$this->fp, $username );
  38. }
  39. function meta_exists($username) {
  40. return self::exists ( @$this->metafp, $username );
  41. }
  42. function meta_find_user_for_mail($email) {
  43. while ( ! feof ( $this->metafp ) && $meta = explode ( ":", $line = rtrim ( fgets ( $this->metafp ) ) ) ) {
  44. if (count ( $meta ) > 1) {
  45. $username = trim ( $meta [0] );
  46. $lemail = $meta [1];
  47. if ($lemail == $email) {
  48. return $username;
  49. }
  50. }
  51. }
  52. return null;
  53. }
  54. function get_metadata() {
  55. rewind ( $this->metafp );
  56. $meta_model_map = array ();
  57. $metaarr = array ();
  58. while ( ! feof ( $this->metafp ) && $line = rtrim ( fgets ( $this->metafp ) ) ) {
  59. $metaarr = explode ( ":", $line );
  60. $model = new meta_model ();
  61. $model->user = $metaarr [0];
  62. if (count ( $metaarr ) > 1) {
  63. $model->email = $metaarr [1];
  64. }
  65. if (count ( $metaarr ) > 2) {
  66. $model->name = $metaarr [2];
  67. }
  68. if (count ( $metaarr ) > 3) {
  69. $model->mailkey = $metaarr [3];
  70. }
  71. $meta_model_map [$model->user] = $model;
  72. }
  73. return $meta_model_map;
  74. }
  75. function get_users() {
  76. rewind ( $this->fp );
  77. $users = array ();
  78. $i = 0;
  79. while ( ! feof ( $this->fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) ) ) {
  80. $users [$i] = $lusername;
  81. $i ++;
  82. }
  83. return $users;
  84. }
  85. function user_add($username, $password) {
  86. if ($this->user_exists ( $username ))
  87. return false;
  88. fseek ( $this->fp, 0, SEEK_END );
  89. fwrite ( $this->fp, $username . ':' . self::htcrypt ( $password ) . "\n" );
  90. return true;
  91. }
  92. function meta_add(meta_model $meta_model) {
  93. if (self::exists ( @$this->metafp, $meta_model->user )) {
  94. return false;
  95. }
  96. fseek ( $this->metafp, 0, SEEK_END );
  97. fwrite ( $this->metafp, $meta_model->user . ':' . $meta_model->email . ':' . $meta_model->name . ':' . $meta_model->mailkey . "\n" );
  98. return true;
  99. }
  100. /**
  101. * Login check
  102. * first 2 characters of hash is the salt.
  103. *
  104. * @param user $username
  105. * @param pass $password
  106. * @return boolean true if password is correct!
  107. */
  108. function user_check($username, $password) {
  109. rewind ( $this->fp );
  110. while ( ! feof ( $this->fp ) && $userpass = explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) {
  111. $lusername = trim ( $userpass [0] );
  112. $hash = $userpass [1];
  113. if ($lusername == $username) {
  114. return (self::check_password_hash ( $password, $hash ));
  115. }
  116. }
  117. return false;
  118. }
  119. function user_delete($username) {
  120. return self::delete ( @$this->fp, $username, @$this->filename );
  121. }
  122. function meta_delete($username) {
  123. return self::delete ( @$this->metafp, $username, @$this->metafilename );
  124. }
  125. function user_update($username, $password) {
  126. rewind ( $this->fp );
  127. while ( ! feof ( $this->fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) ) ) {
  128. if ($lusername == $username) {
  129. fseek ( $this->fp, (- 15 - strlen ( $username )), SEEK_CUR );
  130. fwrite ( $this->fp, $username . ':' . self::htcrypt ( $password ) . "\n" );
  131. return true;
  132. }
  133. }
  134. return false;
  135. }
  136. function meta_update(meta_model $meta_model) {
  137. $this->meta_delete ( $meta_model->user );
  138. $this->meta_add ( $meta_model );
  139. return false;
  140. }
  141. static function write_meta_line($fp, meta_model $meta_model) {
  142. fwrite ( $fp, $meta_model->user . ':' . $meta_model->email . ':' . $meta_model->name . "\n" );
  143. }
  144. static function exists($fp, $username) {
  145. rewind ( $fp );
  146. while ( ! feof ( $fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $fp ) ) ) ) ) ) {
  147. if ($lusername == $username)
  148. return true;
  149. }
  150. return false;
  151. }
  152. static function open_or_create($filename) {
  153. if (! file_exists ( $filename )) {
  154. return fopen ( $filename, 'w+' );
  155. } else {
  156. return fopen ( $filename, 'r+' );
  157. }
  158. }
  159. static function delete($fp, $username, $filename) {
  160. $data = '';
  161. rewind ( $fp );
  162. while ( ! feof ( $fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $fp ) ) ) ) ) ) {
  163. if (! trim ( $line ))
  164. break;
  165. if ($lusername != $username)
  166. $data .= $line . "\n";
  167. }
  168. $fp = fopen ( $filename, 'w' );
  169. fwrite ( $fp, rtrim ( $data ) . (trim ( $data ) ? "\n" : '') );
  170. fclose ( $fp );
  171. $fp = fopen ( $filename, 'r+' );
  172. return true;
  173. }
  174. static function htcrypt($password) {
  175. return crypt ( $password, substr ( str_replace ( '+', '.', base64_encode ( pack ( 'N4', mt_rand (), mt_rand (), mt_rand (), mt_rand () ) ) ), 0, 22 ) );
  176. }
  177. static function check_password_hash($password, $hash) {
  178. $salt = substr ( $hash, 0, 2 );
  179. if (crypt ( $password, $salt ) == $hash) {
  180. return true;
  181. } else {
  182. return false;
  183. }
  184. }
  185. }
  186. ?>