htpasswd.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. include_once("model/meta_model.php");
  3. /**
  4. * htpasswd tools for Apache Basic Auth.
  5. * Uses crypt only!
  6. *
  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 .
  26. "\"\nRequire valid-user" .
  27. "<Files .ht*>\nOrder deny,allow\nDeny from all\n</Files>";
  28. fwrite($bdfp,$htaccess_content);
  29. }
  30. @$this->fp = @$this::open_or_create($htpasswdfile);
  31. if ($use_metadata) {
  32. $htmetafile = $path . "/" . self::HTMETA_NAME;
  33. @$this->metafp = @$this::open_or_create($htmetafile);
  34. }
  35. $this->filename = $htpasswdfile;
  36. $this->metafilename = $htmetafile;
  37. }
  38. function open_or_create($filename) {
  39. if (!file_exists($filename)) {
  40. return fopen ( $filename, 'w+' );
  41. } else {
  42. return fopen ( $filename, 'r+' );
  43. }
  44. }
  45. function user_exists($username) {
  46. rewind ( $this->fp );
  47. while ( ! feof ( $this->fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) ) ) {
  48. if ($lusername == $username)
  49. return true;
  50. }
  51. return false;
  52. }
  53. function get_metadata() {
  54. rewind ( $this->metafp );
  55. $meta_model_map = array();
  56. $metaarr = array();
  57. while ( ! feof ( $this->metafp ) && $line = rtrim ( fgets ( $this->metafp ) ) ) {
  58. $metaarr = explode(":", $line);
  59. $model = new meta_model();
  60. $model->user = $metaarr[0];
  61. $model->email = $metaarr[1];
  62. $model->name = $metaarr[2];
  63. $meta_model_map[$model->user] = $model;
  64. }
  65. return $meta_model_map;
  66. }
  67. function get_users() {
  68. rewind ( $this->fp );
  69. $users = array();
  70. $i = 0;
  71. while ( ! feof ( $this->fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) ) ) {
  72. $users[$i] = $lusername;
  73. $i++;
  74. }
  75. return $users;
  76. }
  77. function user_add($username, $password) {
  78. if ($this->user_exists ( $username ))
  79. return false;
  80. fseek ( $this->fp, 0, SEEK_END );
  81. fwrite ( $this->fp, $username . ':' . self::htcrypt($password) . "\n" );
  82. return true;
  83. }
  84. /**
  85. * Login check
  86. * first 2 characters of hash is the salt.
  87. * @param user $username
  88. * @param pass $password
  89. * @return boolean true if password is correct!
  90. */
  91. function user_check($username, $password) {
  92. rewind ( $this->fp );
  93. while ( ! feof ( $this->fp ) && $userpass = explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) {
  94. $lusername = trim($userpass[0]);
  95. $hash = $userpass[1];
  96. if ($lusername == $username) {
  97. return (self::check_password_hash($password, $hash));
  98. }
  99. }
  100. return false;
  101. }
  102. static function check_password_hash($password, $hash) {
  103. $salt = substr($hash,0,2);
  104. if (crypt($password,$salt)==$hash) {
  105. return true;
  106. } else {
  107. return false;
  108. }
  109. }
  110. static function htcrypt($password) {
  111. return crypt ( $password, substr ( str_replace ( '+', '.', base64_encode ( pack ( 'N4', mt_rand (), mt_rand (), mt_rand (), mt_rand () ) ) ), 0, 22 ) );
  112. }
  113. function user_delete($username) {
  114. return self::delete(@$this->fp, $username, @$this->filename);
  115. }
  116. function meta_delete($username) {
  117. return self::delete(@$this->metafp, $username, @$this->metafilename);
  118. }
  119. static function delete($fp, $username, $filename) {
  120. $data = '';
  121. rewind ( $fp );
  122. while ( ! feof ( $fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $fp ) ) ) ) ) ) {
  123. if (! trim ( $line ))
  124. break;
  125. if ($lusername != $username)
  126. $data .= $line . "\n";
  127. }
  128. $fp = fopen ( $filename, 'w' );
  129. fwrite ( $fp, rtrim ( $data ) . (trim ( $data ) ? "\n" : '') );
  130. fclose ( $fp );
  131. $fp = fopen ( $filename, 'r+' );
  132. return true;
  133. }
  134. function user_update($username, $password) {
  135. rewind ( $this->fp );
  136. while ( ! feof ( $this->fp ) && trim ( $lusername = array_shift ( explode ( ":", $line = rtrim ( fgets ( $this->fp ) ) ) ) ) ) {
  137. if ($lusername == $username) {
  138. fseek ( $this->fp, (- 15 - strlen ( $username )), SEEK_CUR );
  139. fwrite ( $this->fp, $username . ':' . self::htcrypt($password) . "\n" );
  140. return true;
  141. }
  142. }
  143. return false;
  144. }
  145. }
  146. ?>