7 * LICENSE: This source file is licensed under the terms of the GNU General Public License.
9 * @package Magic3 Framework
10 * @author 平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
11 * @copyright Copyright 2006-2010 Magic3 Project.
12 * @license http://www.gnu.org/copyleft/gpl.html GPL License
13 * @version SVN: $Id: auth.php 3474 2010-08-13 10:36:48Z fishbone $
14 * @link http://www.magic3.org
16 // Copyright (C) 2003-2005 PukiWiki Developers Team
17 // License: GPL v2 or (at your option) any later version
19 // Authentication related functions
21 define('PKWK_PASSPHRASE_LIMIT_LENGTH', 512);
23 // Passwd-auth related ----
25 function pkwk_login($pass = '')
27 // modified for Magic3 by naoki on 2008/10/10
30 /*if (! PKWK_READONLY && isset($adminpass) &&
31 pkwk_hash_compute($pass, $adminpass) === $adminpass) {*/
32 //if (!PKWK_READONLY && !empty($pass)){ // パスワードチェック
33 if (!PKWK_READONLY){ // パスワードチェック
34 if (WikiConfig::isUserWithEditAuth()){ // 編集権限ありのとき
36 } else if (WikiConfig::isPasswordAuth()){ // パスワード認証のとき
37 $password = WikiConfig::getPassword();
38 if (empty($pass) || empty($password)){
40 } else if ($pass != $password){
49 sleep(2); // Blocking brute force attack
54 // Compute RFC2307 'userPassword' value, like slappasswd (OpenLDAP)
55 // $phrase : Pass-phrase
56 // $scheme : Specify '{scheme}' or '{scheme}salt'
57 // $prefix : Output with a scheme-prefix or not
58 // $canonical : Correct or Preserve $scheme prefix
59 function pkwk_hash_compute($phrase = '', $scheme = '{x-php-md5}', $prefix = TRUE, $canonical = FALSE)
61 if (! is_string($phrase) || ! is_string($scheme)) return FALSE;
63 if (strlen($phrase) > PKWK_PASSPHRASE_LIMIT_LENGTH)
64 die('pkwk_hash_compute(): malicious message length');
66 // With a {scheme}salt or not
68 if (preg_match('/^(\{.+\})(.*)$/', $scheme, $matches)) {
69 $scheme = $matches[1];
71 } else if ($scheme != '') {
72 $scheme = ''; // Cleartext
76 // Compute and add a scheme-prefix
77 switch (strtolower($scheme)) {
80 case '{x-php-crypt}' :
81 $hash = ($prefix ? ($canonical ? '{x-php-crypt}' : $scheme) : '') .
82 ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
87 $hash = ($prefix ? ($canonical ? '{x-php-md5}' : $scheme) : '') .
93 $hash = ($prefix ? ($canonical ? '{x-php-sha1}' : $scheme) : '') .
99 $hash = ($prefix ? ($canonical ? '{CRYPT}' : $scheme) : '') .
100 ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
105 $hash = ($prefix ? ($canonical ? '{MD5}' : $scheme) : '') .
106 base64_encode(hex2bin(md5($phrase)));
111 // MD5 Key length = 128bits = 16bytes
112 $salt = ($salt != '' ? substr(base64_decode($salt), 16) : substr(crypt(''), -8));
113 $hash = ($prefix ? ($canonical ? '{SMD5}' : $scheme) : '') .
114 base64_encode(hex2bin(md5($phrase . $salt)) . $salt);
119 $hash = ($prefix ? ($canonical ? '{SHA}' : $scheme) : '') .
120 base64_encode(hex2bin(sha1($phrase)));
125 // SHA-1 Key length = 160bits = 20bytes
126 $salt = ($salt != '' ? substr(base64_decode($salt), 20) : substr(crypt(''), -8));
127 $hash = ($prefix ? ($canonical ? '{SSHA}' : $scheme) : '') .
128 base64_encode(hex2bin(sha1($phrase . $salt)) . $salt);
131 // LDAP CLEARTEXT and just cleartext
132 case '{cleartext}' : /* FALLTHROUGH */
134 $hash = ($prefix ? ($canonical ? '{CLEARTEXT}' : $scheme) : '') .
148 // Basic-auth related ----
150 // Check edit-permission
151 function check_editable($page, $auth_flag = TRUE, $exit_flag = TRUE)
153 global $script, $_title_cannotedit, $_msg_unfreeze;
155 if (edit_auth($page, $auth_flag, $exit_flag) && is_editable($page)) {
161 if ($exit_flag === FALSE) {
162 return FALSE; // Without exit
165 $body = $title = str_replace('$1',
166 htmlspecialchars(strip_bracket($page)), $_title_cannotedit);
167 // modified for Magic3 by naoki on 2008/10/10
168 /*if (is_freeze($page))
169 $body .= '(<a href="' . $script . '?cmd=unfreeze&page=' .
170 rawurlencode($page) . '">' . $_msg_unfreeze . '</a>)';*/
171 if (is_freeze($page)){
172 $body .= '(<a href="' . $script . WikiParam::convQuery('?cmd=unfreeze&page=' . rawurlencode($page)) . '">' . $_msg_unfreeze . '</a>)';
174 $page = str_replace('$1', make_search($page), $_title_cannotedit);
175 // modified for Magic3 by naoki on 2008/9/29
176 //catbody($title, $page, $body);
183 // Check read-permission
184 function check_readable($page, $auth_flag = TRUE, $exit_flag = TRUE)
186 return read_auth($page, $auth_flag, $exit_flag);
189 function edit_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
191 global $edit_auth, $edit_auth_pages, $_title_cannotedit;
192 return $edit_auth ? basic_auth($page, $auth_flag, $exit_flag,
193 $edit_auth_pages, $_title_cannotedit) : TRUE;
196 function read_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
198 global $read_auth, $read_auth_pages, $_title_cannotread;
199 return $read_auth ? basic_auth($page, $auth_flag, $exit_flag,
200 $read_auth_pages, $_title_cannotread) : TRUE;
203 // Basic authentication
204 function basic_auth($page, $auth_flag, $exit_flag, $auth_pages, $title_cannot)
206 global $auth_method_type, $auth_users, $_msg_auth;
210 if ($auth_method_type == 'pagename') {
211 $target_str = $page; // Page name
212 } else if ($auth_method_type == 'contents') {
213 $target_str = join('', get_source($page)); // Its contents
216 $user_list = array();
217 foreach($auth_pages as $key=>$val)
218 if (preg_match($key, $target_str))
219 $user_list = array_merge($user_list, explode(',', $val));
221 if (empty($user_list)) return TRUE; // No limit
224 if (! isset($_SERVER['PHP_AUTH_USER']) &&
225 ! isset($_SERVER ['PHP_AUTH_PW']) &&
226 isset($_SERVER['HTTP_AUTHORIZATION']) &&
227 preg_match('/^Basic (.*)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches))
230 // Basic-auth with $_SERVER['HTTP_AUTHORIZATION']
231 list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
232 explode(':', base64_decode($matches[1]));
236 ! isset($_SERVER['PHP_AUTH_USER']) ||
237 ! in_array($_SERVER['PHP_AUTH_USER'], $user_list) ||
238 ! isset($auth_users[$_SERVER['PHP_AUTH_USER']]) ||
240 $_SERVER['PHP_AUTH_PW'],
241 $auth_users[$_SERVER['PHP_AUTH_USER']]
242 ) !== $auth_users[$_SERVER['PHP_AUTH_USER']])
245 pkwk_common_headers();
247 header('WWW-Authenticate: Basic realm="' . $_msg_auth . '"');
248 header('HTTP/1.0 401 Unauthorized');
251 $body = $title = str_replace('$1',
252 htmlspecialchars(strip_bracket($page)), $title_cannot);
253 $page = str_replace('$1', make_search($page), $title_cannot);
254 // modified for Magic3 by naoki on 2008/9/29
255 //catbody($title, $page, $body);