OSDN Git Service

初回コミット(v2.6.17.1)
[magic3/magic3.git] / widgets / wiki_main / include / lib / auth.php
1 <?php
2 /**
3  * ユーザ認証ライブラリ
4  *
5  * PHP versions 5
6  *
7  * LICENSE: This source file is licensed under the terms of the GNU General Public License.
8  *
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
15  */
16 // Copyright (C) 2003-2005 PukiWiki Developers Team
17 // License: GPL v2 or (at your option) any later version
18 //
19 // Authentication related functions
20
21 define('PKWK_PASSPHRASE_LIMIT_LENGTH', 512);
22
23 // Passwd-auth related ----
24
25 function pkwk_login($pass = '')
26 {
27         // modified for Magic3 by naoki on 2008/10/10
28         //global $adminpass;
29
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()){          // 編集権限ありのとき
35                         return true;
36                 } else if (WikiConfig::isPasswordAuth()){               // パスワード認証のとき
37                         $password = WikiConfig::getPassword();
38                         if (empty($pass) || empty($password)){
39                                 return false;
40                         } else if ($pass != $password){
41                                 return false;
42                         } else {
43                                 return true;
44                         }
45                 } else {
46                         return false;
47                 }
48         } else {
49                 sleep(2);       // Blocking brute force attack
50                 return false;
51         }
52 }
53
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)
60 {
61         if (! is_string($phrase) || ! is_string($scheme)) return FALSE;
62
63         if (strlen($phrase) > PKWK_PASSPHRASE_LIMIT_LENGTH)
64                 die('pkwk_hash_compute(): malicious message length');
65
66         // With a {scheme}salt or not
67         $matches = array();
68         if (preg_match('/^(\{.+\})(.*)$/', $scheme, $matches)) {
69                 $scheme = $matches[1];
70                 $salt   = $matches[2];
71         } else if ($scheme != '') {
72                 $scheme  = ''; // Cleartext
73                 $salt    = '';
74         }
75
76         // Compute and add a scheme-prefix
77         switch (strtolower($scheme)) {
78
79         // PHP crypt()
80         case '{x-php-crypt}' :
81                 $hash = ($prefix ? ($canonical ? '{x-php-crypt}' : $scheme) : '') .
82                         ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
83                 break;
84
85         // PHP md5()
86         case '{x-php-md5}'   :
87                 $hash = ($prefix ? ($canonical ? '{x-php-md5}' : $scheme) : '') .
88                         md5($phrase);
89                 break;
90
91         // PHP sha1()
92         case '{x-php-sha1}'  :
93                 $hash = ($prefix ? ($canonical ? '{x-php-sha1}' : $scheme) : '') .
94                         sha1($phrase);
95                 break;
96
97         // LDAP CRYPT
98         case '{crypt}'       :
99                 $hash = ($prefix ? ($canonical ? '{CRYPT}' : $scheme) : '') .
100                         ($salt != '' ? crypt($phrase, $salt) : crypt($phrase));
101                 break;
102
103         // LDAP MD5
104         case '{md5}'         :
105                 $hash = ($prefix ? ($canonical ? '{MD5}' : $scheme) : '') .
106                         base64_encode(hex2bin(md5($phrase)));
107                 break;
108
109         // LDAP SMD5
110         case '{smd5}'        :
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);
115                 break;
116
117         // LDAP SHA
118         case '{sha}'         :
119                 $hash = ($prefix ? ($canonical ? '{SHA}' : $scheme) : '') .
120                         base64_encode(hex2bin(sha1($phrase)));
121                 break;
122
123         // LDAP SSHA
124         case '{ssha}'        :
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);
129                 break;
130
131         // LDAP CLEARTEXT and just cleartext
132         case '{cleartext}'   : /* FALLTHROUGH */
133         case ''              :
134                 $hash = ($prefix ? ($canonical ? '{CLEARTEXT}' : $scheme) : '') .
135                         $phrase;
136                 break;
137
138         // Invalid scheme
139         default:
140                 $hash = FALSE;
141                 break;
142         }
143
144         return $hash;
145 }
146
147
148 // Basic-auth related ----
149
150 // Check edit-permission
151 function check_editable($page, $auth_flag = TRUE, $exit_flag = TRUE)
152 {
153         global $script, $_title_cannotedit, $_msg_unfreeze;
154
155         if (edit_auth($page, $auth_flag, $exit_flag) && is_editable($page)) {
156                 // Editable
157                 return TRUE;
158         } else {
159                 return false;
160                 // Not editable
161                 if ($exit_flag === FALSE) {
162                         return FALSE; // Without exit
163                 } else {
164                         // With 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&amp;page=' .
170                                         rawurlencode($page) . '">' . $_msg_unfreeze . '</a>)';*/
171                         if (is_freeze($page)){
172                                 $body .= '(<a href="' . $script . WikiParam::convQuery('?cmd=unfreeze&amp;page=' . rawurlencode($page)) . '">' . $_msg_unfreeze . '</a>)';
173                         }
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);
177                         catbody($body);
178                         //exit;
179                 }
180         }
181 }
182
183 // Check read-permission
184 function check_readable($page, $auth_flag = TRUE, $exit_flag = TRUE)
185 {
186         return read_auth($page, $auth_flag, $exit_flag);
187 }
188
189 function edit_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
190 {
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;
194 }
195
196 function read_auth($page, $auth_flag = TRUE, $exit_flag = TRUE)
197 {
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;
201 }
202
203 // Basic authentication
204 function basic_auth($page, $auth_flag, $exit_flag, $auth_pages, $title_cannot)
205 {
206         global $auth_method_type, $auth_users, $_msg_auth;
207
208         // Checked by:
209         $target_str = '';
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
214         }
215
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));
220
221         if (empty($user_list)) return TRUE; // No limit
222
223         $matches = array();
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))
228         {
229
230                 // Basic-auth with $_SERVER['HTTP_AUTHORIZATION']
231                 list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
232                         explode(':', base64_decode($matches[1]));
233         }
234
235         if (PKWK_READONLY ||
236                 ! isset($_SERVER['PHP_AUTH_USER']) ||
237                 ! in_array($_SERVER['PHP_AUTH_USER'], $user_list) ||
238                 ! isset($auth_users[$_SERVER['PHP_AUTH_USER']]) ||
239                 pkwk_hash_compute(
240                         $_SERVER['PHP_AUTH_PW'],
241                         $auth_users[$_SERVER['PHP_AUTH_USER']]
242                         ) !== $auth_users[$_SERVER['PHP_AUTH_USER']])
243         {
244                 // Auth failed
245                 pkwk_common_headers();
246                 if ($auth_flag) {
247                         header('WWW-Authenticate: Basic realm="' . $_msg_auth . '"');
248                         header('HTTP/1.0 401 Unauthorized');
249                 }
250                 if ($exit_flag) {
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);
256                         catbody($body);
257                         exit;
258                 }
259                 return FALSE;
260         } else {
261                 return TRUE;
262         }
263 }
264 ?>