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

/public_html/lib/auth.php

https://bitbucket.org/kumagi/fluxflex_pukiwiki
PHP | 227 lines | 158 code | 33 blank | 36 comment | 33 complexity | 64699162745d75f71b7497d43393a56f MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. // PukiWiki - Yet another WikiWikiWeb clone
  3. // $Id: auth.php,v 1.19 2005/06/13 14:02:07 henoheno Exp $
  4. // Copyright (C) 2003-2005 PukiWiki Developers Team
  5. // License: GPL v2 or (at your option) any later version
  6. //
  7. // Authentication related functions
  8. define('PKWK_PASSPHRASE_LIMIT_LENGTH', 512);
  9. // Passwd-auth related ----
  10. function pkwk_login($pass = '')
  11. {
  12. global $adminpass;
  13. if (! PKWK_READONLY && isset($adminpass) &&
  14. pkwk_hash_compute($pass, $adminpass) === $adminpass) {
  15. return TRUE;
  16. } else {
  17. sleep(2); // Blocking brute force attack
  18. return FALSE;
  19. }
  20. }
  21. // Compute RFC2307 'userPassword' value, like slappasswd (OpenLDAP)
  22. // $phrase : Pass-phrase
  23. // $scheme : Specify '{scheme}' or '{scheme}salt'
  24. // $prefix : Output with a scheme-prefix or not
  25. // $canonical : Correct or Preserve $scheme prefix
  26. function pkwk_hash_compute($phrase = '', $scheme = '{x-php-md5}', $prefix = TRUE, $canonical = FALSE)
  27. {
  28. if (! is_string($phrase) || ! is_string($scheme)) return FALSE;
  29. if (strlen($phrase) > PKWK_PASSPHRASE_LIMIT_LENGTH)
  30. die('pkwk_hash_compute(): malicious message length');
  31. // With a {scheme}salt or not
  32. $matches = array();
  33. if (preg_match('/^(\{.+\})(.*)$/', $scheme, $matches)) {
  34. $scheme = & $matches[1];
  35. $salt = & $matches[2];
  36. } else if ($scheme != '') {
  37. $scheme = ''; // Cleartext
  38. $salt = '';
  39. }
  40. // Compute and add a scheme-prefix
  41. switch (strtolower($scheme)) {
  42. // PHP crypt()
  43. case '{x-php-crypt}' :
  44. $hash = ($prefix ? ($canonical ? '{x-php-crypt}' : $scheme) : '') .
  45. ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
  46. break;
  47. // PHP md5()
  48. case '{x-php-md5}' :
  49. $hash = ($prefix ? ($canonical ? '{x-php-md5}' : $scheme) : '') .
  50. md5($phrase);
  51. break;
  52. // PHP sha1()
  53. case '{x-php-sha1}' :
  54. $hash = ($prefix ? ($canonical ? '{x-php-sha1}' : $scheme) : '') .
  55. sha1($phrase);
  56. break;
  57. // LDAP CRYPT
  58. case '{crypt}' :
  59. $hash = ($prefix ? ($canonical ? '{CRYPT}' : $scheme) : '') .
  60. ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
  61. break;
  62. // LDAP MD5
  63. case '{md5}' :
  64. $hash = ($prefix ? ($canonical ? '{MD5}' : $scheme) : '') .
  65. base64_encode(hex2bin(md5($phrase)));
  66. break;
  67. // LDAP SMD5
  68. case '{smd5}' :
  69. // MD5 Key length = 128bits = 16bytes
  70. $salt = ($salt != '' ? substr(base64_decode($salt), 16) : substr(crypt(''), -8));
  71. $hash = ($prefix ? ($canonical ? '{SMD5}' : $scheme) : '') .
  72. base64_encode(hex2bin(md5($phrase . $salt)) . $salt);
  73. break;
  74. // LDAP SHA
  75. case '{sha}' :
  76. $hash = ($prefix ? ($canonical ? '{SHA}' : $scheme) : '') .
  77. base64_encode(hex2bin(sha1($phrase)));
  78. break;
  79. // LDAP SSHA
  80. case '{ssha}' :
  81. // SHA-1 Key length = 160bits = 20bytes
  82. $salt = ($salt != '' ? substr(base64_decode($salt), 20) : substr(crypt(''), -8));
  83. $hash = ($prefix ? ($canonical ? '{SSHA}' : $scheme) : '') .
  84. base64_encode(hex2bin(sha1($phrase . $salt)) . $salt);
  85. break;
  86. // LDAP CLEARTEXT and just cleartext
  87. case '{cleartext}' : /* FALLTHROUGH */
  88. case '' :
  89. $hash = ($prefix ? ($canonical ? '{CLEARTEXT}' : $scheme) : '') .
  90. $phrase;
  91. break;
  92. // Invalid scheme
  93. default:
  94. $hash = FALSE;
  95. break;
  96. }
  97. return $hash;
  98. }
  99. // Basic-auth related ----
  100. // Check edit-permission
  101. function check_editable($page, $auth_flag = TRUE, $exit_flag = TRUE)
  102. {
  103. global $script, $_title_cannotedit, $_msg_unfreeze;
  104. if (edit_auth($page, $auth_flag, $exit_flag) && is_editable($page)) {
  105. // Editable
  106. return TRUE;
  107. } else {
  108. // Not editable
  109. if ($exit_flag === FALSE) {
  110. return FALSE; // Without exit
  111. } else {
  112. // With exit
  113. $body = $title = str_replace('$1',
  114. htmlspecialchars(strip_bracket($page)), $_title_cannotedit);
  115. if (is_freeze($page))
  116. $body .= '(<a href="' . $script . '?cmd=unfreeze&amp;page=' .
  117. rawurlencode($page) . '">' . $_msg_unfreeze . '</a>)';
  118. $page = str_replace('$1', make_search($page), $_title_cannotedit);
  119. catbody($title, $page, $body);
  120. exit;
  121. }
  122. }
  123. }
  124. // Check read-permission
  125. function check_readable($page, $auth_flag = TRUE, $exit_flag = TRUE)
  126. {
  127. return read_auth($page, $auth_flag, $exit_flag);
  128. }
  129. function edit_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
  130. {
  131. global $edit_auth, $edit_auth_pages, $_title_cannotedit;
  132. return $edit_auth ? basic_auth($page, $auth_flag, $exit_flag,
  133. $edit_auth_pages, $_title_cannotedit) : TRUE;
  134. }
  135. function read_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
  136. {
  137. global $read_auth, $read_auth_pages, $_title_cannotread;
  138. return $read_auth ? basic_auth($page, $auth_flag, $exit_flag,
  139. $read_auth_pages, $_title_cannotread) : TRUE;
  140. }
  141. // Basic authentication
  142. function basic_auth($page, $auth_flag, $exit_flag, $auth_pages, $title_cannot)
  143. {
  144. global $auth_method_type, $auth_users, $_msg_auth;
  145. // Checked by:
  146. $target_str = '';
  147. if ($auth_method_type == 'pagename') {
  148. $target_str = $page; // Page name
  149. } else if ($auth_method_type == 'contents') {
  150. $target_str = join('', get_source($page)); // Its contents
  151. }
  152. $user_list = array();
  153. foreach($auth_pages as $key=>$val)
  154. if (preg_match($key, $target_str))
  155. $user_list = array_merge($user_list, explode(',', $val));
  156. if (empty($user_list)) return TRUE; // No limit
  157. $matches = array();
  158. if (! isset($_SERVER['PHP_AUTH_USER']) &&
  159. ! isset($_SERVER ['PHP_AUTH_PW']) &&
  160. isset($_SERVER['HTTP_AUTHORIZATION']) &&
  161. preg_match('/^Basic (.*)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches))
  162. {
  163. // Basic-auth with $_SERVER['HTTP_AUTHORIZATION']
  164. list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
  165. explode(':', base64_decode($matches[1]));
  166. }
  167. if (PKWK_READONLY ||
  168. ! isset($_SERVER['PHP_AUTH_USER']) ||
  169. ! in_array($_SERVER['PHP_AUTH_USER'], $user_list) ||
  170. ! isset($auth_users[$_SERVER['PHP_AUTH_USER']]) ||
  171. pkwk_hash_compute(
  172. $_SERVER['PHP_AUTH_PW'],
  173. $auth_users[$_SERVER['PHP_AUTH_USER']]
  174. ) !== $auth_users[$_SERVER['PHP_AUTH_USER']])
  175. {
  176. // Auth failed
  177. pkwk_common_headers();
  178. if ($auth_flag) {
  179. header('WWW-Authenticate: Basic realm="' . $_msg_auth . '"');
  180. header('HTTP/1.0 401 Unauthorized');
  181. }
  182. if ($exit_flag) {
  183. $body = $title = str_replace('$1',
  184. htmlspecialchars(strip_bracket($page)), $title_cannot);
  185. $page = str_replace('$1', make_search($page), $title_cannot);
  186. catbody($title, $page, $body);
  187. exit;
  188. }
  189. return FALSE;
  190. } else {
  191. return TRUE;
  192. }
  193. }
  194. ?>