| [ Index ] |
|
Code source de Mantis 1.1.0rc3 |
1 <?php 2 # Mantis - a php based bugtracking system 3 4 # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 5 # Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net 6 7 # Mantis is free software: you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation, either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # Mantis is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with Mantis. If not, see <http://www.gnu.org/licenses/>. 19 20 # -------------------------------------------------------- 21 # $Id: authentication_api.php,v 1.60.2.3 2007-10-19 06:54:58 vboctor Exp $ 22 # -------------------------------------------------------- 23 24 require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'gpc_api.php' ); 25 26 ### Authentication API ### 27 28 $g_script_login_cookie = null; 29 $g_cache_anonymous_user_cookie_string = null; 30 31 #=================================== 32 # Boolean queries and ensures 33 #=================================== 34 35 # -------------------- 36 # Check that there is a user logged-in and authenticated 37 # If the user's account is disabled they will be logged out 38 # If there is no user logged in, redirect to the login page 39 # If parameter is given it is used as a URL to redirect to following 40 # successful login. If none is given, the URL of the current page is used 41 function auth_ensure_user_authenticated( $p_return_page = '' ) { 42 # if logged in 43 if ( auth_is_user_authenticated() ) { 44 # check for access enabled 45 # This also makes sure the cookie is valid 46 if ( OFF == current_user_get_field( 'enabled' ) ) { 47 print_header_redirect( 'logout_page.php' ); 48 } 49 } else { # not logged in 50 if ( is_blank( $p_return_page ) ) { 51 if (!isset($_SERVER['REQUEST_URI'])) { 52 $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']; 53 } 54 $p_return_page = $_SERVER['REQUEST_URI']; 55 } 56 $p_return_page = string_url( $p_return_page ); 57 print_header_redirect( 'login_page.php?return=' . $p_return_page ); 58 } 59 } 60 61 # -------------------- 62 # Return true if there is a currently logged in and authenticated user, 63 # false otherwise 64 function auth_is_user_authenticated() { 65 return ( auth_is_cookie_valid( auth_get_current_user_cookie() ) ); 66 } 67 68 69 #=================================== 70 # Login / Logout 71 #=================================== 72 73 # -------------------- 74 # Attempt to login the user with the given password 75 # If the user fails validation, false is returned 76 # If the user passes validation, the cookies are set and 77 # true is returned. If $p_perm_login is true, the long-term 78 # cookie is created. 79 function auth_attempt_login( $p_username, $p_password, $p_perm_login=false ) { 80 $t_user_id = user_get_id_by_name( $p_username ); 81 82 $t_login_method = config_get( 'login_method' ); 83 84 if ( false === $t_user_id ) { 85 if ( BASIC_AUTH == $t_login_method ) { 86 # attempt to create the user if using BASIC_AUTH 87 $t_cookie_string = user_create( $p_username, $p_password ); 88 89 if ( false === $t_cookie_string ) { 90 # it didn't work 91 return false; 92 } 93 94 # ok, we created the user, get the row again 95 $t_user_id = user_get_id_by_name( $p_username ); 96 97 if ( false === $t_user_id ) { 98 # uh oh, something must be really wrong 99 100 # @@@ trigger an error here? 101 102 return false; 103 } 104 } else { 105 return false; 106 } 107 } 108 109 # check for disabled account 110 if ( !user_is_enabled( $t_user_id ) ) { 111 return false; 112 } 113 114 # max. failed login attempts achieved... 115 if( !user_is_login_request_allowed( $t_user_id ) ) { 116 return false; 117 } 118 119 $t_anon_account = config_get( 'anonymous_account' ); 120 $t_anon_allowed = config_get( 'allow_anonymous_login' ); 121 122 # check for anonymous login 123 if ( !( ( ON == $t_anon_allowed ) && ( $t_anon_account == $p_username) ) ) { 124 # anonymous login didn't work, so check the password 125 126 if ( !auth_does_password_match( $t_user_id, $p_password ) ) { 127 user_increment_failed_login_count( $t_user_id ); 128 return false; 129 } 130 } 131 132 # ok, we're good to login now 133 134 # increment login count 135 user_increment_login_count( $t_user_id ); 136 137 user_reset_failed_login_count_to_zero( $t_user_id ); 138 user_reset_lost_password_in_progress_count_to_zero( $t_user_id ); 139 140 # set the cookies 141 auth_set_cookies( $t_user_id, $p_perm_login ); 142 auth_set_tokens( $t_user_id ); 143 144 return true; 145 } 146 147 # -------------------- 148 # Allows scripts to login using a login name or ( login name + password ) 149 function auth_attempt_script_login( $p_username, $p_password = null ) { 150 global $g_script_login_cookie, $g_cache_current_user_id; 151 152 $t_user_id = user_get_id_by_name( $p_username ); 153 154 $t_user = user_get_row( $t_user_id ); 155 156 # check for disabled account 157 if ( OFF == $t_user['enabled'] ) { 158 return false; 159 } 160 161 # validate password if supplied 162 if ( null !== $p_password ) { 163 if ( !auth_does_password_match( $t_user_id, $p_password ) ) { 164 return false; 165 } 166 } 167 168 # ok, we're good to login now 169 170 # With cases like RSS feeds and MantisConnect there is a login per operation, hence, there is no 171 # real significance of incrementing login count. 172 # increment login count 173 # user_increment_login_count( $t_user_id ); 174 175 # set the cookies 176 $g_script_login_cookie = $t_user['cookie_string']; 177 178 # cache user id for future reference 179 $g_cache_current_user_id = $t_user_id; 180 181 return true; 182 } 183 184 # -------------------- 185 # Logout the current user and remove any remaining cookies from their browser 186 # Returns true on success, false otherwise 187 function auth_logout() { 188 global $g_cache_current_user_id; 189 190 # clear cached userid 191 $g_cache_current_user_id = null; 192 193 # clear cookies, if they were set 194 if (auth_clear_cookies()) { 195 helper_clear_pref_cookies(); 196 } 197 return true; 198 } 199 200 #=================================== 201 # Password functions 202 #=================================== 203 204 # -------------------- 205 # Return true if the password for the user id given matches the given 206 # password (taking into account the global login method) 207 function auth_does_password_match( $p_user_id, $p_test_password ) { 208 $t_configured_login_method = config_get( 'login_method' ); 209 210 if ( LDAP == $t_configured_login_method ) { 211 return ldap_authenticate( $p_user_id, $p_test_password ); 212 } 213 214 $t_password = user_get_field( $p_user_id, 'password' ); 215 $t_login_methods = Array(MD5, CRYPT, PLAIN); 216 foreach ( $t_login_methods as $t_login_method ) { 217 218 # pass the stored password in as the salt 219 if ( auth_process_plain_password( $p_test_password, $t_password, $t_login_method ) == $t_password ) { 220 # Do not support migration to PLAIN, since this would be a crazy thing to do. 221 # Also if we do, then a user will be able to login by providing the MD5 value 222 # that is copied from the database. See #8467 for more details. 223 if ( $t_configured_login_method != PLAIN && $t_login_method == PLAIN ) { 224 continue; 225 } 226 227 # Check for migration to another login method and test whether the password was encrypted 228 # with our previously insecure implemention of the CRYPT method 229 if ( ( $t_login_method != $t_configured_login_method ) || 230 ( ( CRYPT == $t_configured_login_method ) && substr( $t_password, 0, 2 ) == substr( $p_test_password, 0, 2 ) ) ) { 231 user_set_password( $p_user_id, $p_test_password, true ); 232 } 233 234 return true; 235 } 236 } 237 238 return false; 239 } 240 241 # -------------------- 242 # Encrypt and return the plain password given, as appropriate for the current 243 # global login method. 244 # 245 # When generating a new password, no salt should be passed in. 246 # When encrypting a password to compare to a stored password, the stored 247 # password should be passed in as salt. If the auth method is CRYPT then 248 # crypt() will extract the appropriate portion of the stored password as its salt 249 function auth_process_plain_password( $p_password, $p_salt=null, $p_method=null ) { 250 $t_login_method = config_get( 'login_method' ); 251 if ( $p_method !== null ) { 252 $t_login_method = $p_method; 253 } 254 255 switch ( $t_login_method ) { 256 case CRYPT: 257 # a null salt is the same as no salt, which causes a salt to be generated 258 # otherwise, use the salt given 259 $t_processed_password = crypt( $p_password, $p_salt ); 260 break; 261 case MD5: 262 $t_processed_password = md5( $p_password ); 263 break; 264 case BASIC_AUTH: 265 case PLAIN: 266 default: 267 $t_processed_password = $p_password; 268 break; 269 } 270 271 # cut this off to 32 cahracters which the largest possible string in the database 272 return substr( $t_processed_password, 0, 32 ); 273 } 274 275 # -------------------- 276 # Generate a random 12 character password 277 # p_email is unused 278 function auth_generate_random_password( $p_email ) { 279 $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); 280 $t_val = md5( $t_val ); 281 282 return substr( $t_val, 0, 12 ); 283 } 284 285 # -------------------- 286 # Generate a confirm_hash 12 character to valide the password reset request 287 function auth_generate_confirm_hash( $p_user_id ) { 288 $t_confirm_hash_generator = config_get( 'password_confirm_hash_magic_string' ); 289 $t_password = user_get_field( $p_user_id, 'password' ); 290 $t_last_visit = user_get_field( $p_user_id, 'last_visit' ); 291 292 $t_confirm_hash = md5( $t_confirm_hash_generator . $t_password . $t_last_visit ); 293 294 return $t_confirm_hash; 295 } 296 297 #=================================== 298 # Cookie functions 299 #=================================== 300 301 # -------------------- 302 # Set login cookies for the user 303 # If $p_perm_login is true, a long-term cookie is created 304 function auth_set_cookies( $p_user_id, $p_perm_login=false ) { 305 $t_cookie_string = user_get_field( $p_user_id, 'cookie_string' ); 306 307 $t_cookie_name = config_get( 'string_cookie' ); 308 309 if ( $p_perm_login ) { 310 # set permanent cookie (1 year) 311 gpc_set_cookie( $t_cookie_name, $t_cookie_string, true ); 312 } else { 313 # set temp cookie, cookie dies after browser closes 314 gpc_set_cookie( $t_cookie_name, $t_cookie_string, false ); 315 } 316 } 317 318 # -------------------- 319 # Clear login cookies, return true if they were cleared 320 function auth_clear_cookies() { 321 global $g_script_login_cookie; 322 323 $t_cookies_cleared = false; 324 325 # clear cookie, if not logged in from script 326 if ($g_script_login_cookie == null) { 327 $t_cookie_name = config_get( 'string_cookie' ); 328 $t_cookie_path = config_get( 'cookie_path' ); 329 330 gpc_clear_cookie( $t_cookie_name, $t_cookie_path ); 331 $t_cookies_cleared = true; 332 } else { 333 $g_script_login_cookie = null; 334 } 335 return $t_cookies_cleared; 336 } 337 338 # -------------------- 339 # Generate a string to use as the identifier for the login cookie 340 # It is not guaranteed to be unique and should be checked 341 # The string returned should be 64 characters in length 342 function auth_generate_cookie_string() { 343 $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); 344 $t_val = md5( $t_val ) . md5( time() ); 345 346 return substr( $t_val, 0, 64 ); 347 } 348 349 # -------------------- 350 # Generate a UNIQUE string to use as the identifier for the login cookie 351 # The string returned should be 64 characters in length 352 function auth_generate_unique_cookie_string() { 353 do { 354 $t_cookie_string = auth_generate_cookie_string(); 355 } while ( !auth_is_cookie_string_unique( $t_cookie_string ) ); 356 357 return $t_cookie_string; 358 } 359 360 # -------------------- 361 # Return true if the cookie login identifier is unique, false otherwise 362 function auth_is_cookie_string_unique( $p_cookie_string ) { 363 $t_user_table = config_get( 'mantis_user_table' ); 364 365 $c_cookie_string = db_prepare_string( $p_cookie_string ); 366 367 $query = "SELECT COUNT(*) 368 FROM $t_user_table 369 WHERE cookie_string='$c_cookie_string'"; 370 $result = db_query( $query ); 371 $t_count = db_result( $result ); 372 373 if ( $t_count > 0 ) { 374 return false; 375 } else { 376 return true; 377 } 378 } 379 380 # -------------------- 381 # Return the current user login cookie string, 382 # note that the cookie cached by a script login superceeds the cookie provided by 383 # the browser. This shouldn't normally matter, except that the password verification uses 384 # this routine to bypass the normal authentication, and can get confused when a normal user 385 # logs in, then runs the verify script. the act of fetching config variables may get the wrong 386 # userid. 387 # if no user is logged in and anonymous login is enabled, returns cookie for anonymous user 388 # otherwise returns '' (an empty string) 389 function auth_get_current_user_cookie() { 390 global $g_script_login_cookie, $g_cache_anonymous_user_cookie_string; 391 392 # if logging in via a script, return that cookie 393 if ( $g_script_login_cookie !== null ) { 394 return $g_script_login_cookie; 395 } 396 397 # fetch user cookie 398 $t_cookie_name = config_get( 'string_cookie' ); 399 $t_cookie = gpc_get_cookie( $t_cookie_name, '' ); 400 401 # if cookie not found, and anonymous login enabled, use cookie of anonymous account. 402 if ( is_blank( $t_cookie ) ) { 403 if ( ON == config_get( 'allow_anonymous_login' ) ) { 404 if ( $g_cache_anonymous_user_cookie_string === null ) { 405 if ( function_exists( 'db_is_connected' ) && db_is_connected() ) { 406 # get anonymous information if database is available 407 $query = sprintf('SELECT id, cookie_string FROM %s WHERE username = \'%s\'', 408 config_get( 'mantis_user_table' ), config_get( 'anonymous_account' ) ); 409 $result = db_query( $query ); 410 411 if ( 1 == db_num_rows( $result ) ) { 412 $row = db_fetch_array( $result ); 413 $t_cookie = $row['cookie_string']; 414 415 $g_cache_anonymous_user_cookie_string = $t_cookie; 416 $g_cache_current_user_id = $row['id']; 417 } 418 } 419 } else { 420 $t_cookie = $g_cache_anonymous_user_cookie_string; 421 } 422 } 423 } 424 425 return $t_cookie; 426 } 427 428 #=================================== 429 # Re-Authentication Tokens 430 #=================================== 431 432 /** 433 * Set authentication tokens for secure session. 434 * @param integer User ID 435 */ 436 function auth_set_tokens( $p_user_id ) { 437 $t_auth_token = token_get( TOKEN_AUTHENTICATED, $p_user_id ); 438 if ( null == $t_auth_token ) { 439 token_set( TOKEN_AUTHENTICATED, true, TOKEN_EXPIRY_AUTHENTICATED, $p_user_id ); 440 } else { 441 token_touch( $t_auth_token['id'], TOKEN_EXPIRY_AUTHENTICATED ); 442 } 443 } 444 445 /** 446 * Check for authentication tokens, and display re-authentication page if needed. 447 * Currently, if using BASIC or HTTP authentication methods, or if logged in anonymously, 448 * this function will always "authenticate" the user (do nothing). 449 */ 450 function auth_reauthenticate() { 451 if ( BASIC_AUTH == config_get( 'login_method' ) || 452 HTTP_AUTH == config_get( 'login_method' ) ) { 453 return true; 454 } 455 456 $t_auth_token = token_get( TOKEN_AUTHENTICATED ); 457 if ( null != $t_auth_token ) { 458 token_touch( $t_auth_token['id'], TOKEN_EXPIRY_AUTHENTICATED ); 459 return true; 460 } else { 461 $t_anon_account = config_get( 'anonymous_account' ); 462 $t_anon_allowed = config_get( 'allow_anonymous_login' ); 463 464 $t_user_id = auth_get_current_user_id(); 465 $t_username = user_get_field( $t_user_id, 'username' ); 466 467 # check for anonymous login 468 if ( ON == $t_anon_allowed && $t_anon_account == $t_username ) { 469 return true; 470 } 471 472 return auth_reauthenticate_page( $t_user_id, $t_username ); 473 } 474 } 475 476 /** 477 * Generate the intermediate authentication page. 478 * @param integer User ID 479 * @param string Username 480 */ 481 function auth_reauthenticate_page( $p_user_id, $p_username ) { 482 $t_error = false; 483 484 if ( true == gpc_get_bool( '_authenticate' ) ) { 485 $f_password = gpc_get_string( 'password', '' ); 486 487 if ( auth_attempt_login( $p_username, $f_password ) ) { 488 auth_set_tokens( $p_user_id ); 489 return true; 490 } else { 491 $t_error = true; 492 } 493 } 494 495 html_page_top1(); 496 html_page_top2(); 497 498 ?> 499 <div align="center"> 500 <p> 501 <?php 502 echo lang_get( 'reauthenticate_message' ); 503 if ( $t_error != false ) { 504 echo '<br/><font color="red">',lang_get( 'login_error' ),'</font>'; 505 } 506 ?> 507 </p> 508 <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"> 509 510 <?php 511 print_hidden_inputs( gpc_strip_slashes( $_POST ) ); 512 print_hidden_inputs( gpc_strip_slashes( $_GET ) ); 513 ?> 514 515 <input type="hidden" name="_authenticate" value="1" /> 516 517 <table class="width50 center"> 518 <tr> 519 <td class="form-title"><?php echo lang_get( 'reauthenticate_title' ); ?></td> 520 </tr> 521 522 <tr class="row-1"> 523 <td class="category"><?php echo lang_get( 'username' ); ?></td> 524 <td><input type="text" disabled="disabled" size="32" maxlength="32" value="<?php echo $p_username; ?>" /></td> 525 </tr> 526 527 <tr class="row-2"> 528 <td class="category"><?php echo lang_get( 'password' ); ?></td> 529 <td><input type="password" name="password" size="16" maxlength="32" /></td> 530 </tr> 531 532 <tr> 533 <td class="center" colspan="2"><input type="submit" class="button" value="<?php echo lang_get( 'login_button' ); ?>" /></td> 534 </tr> 535 </table> 536 537 </form> 538 </div> 539 540 <?php 541 html_page_bottom1(); 542 543 exit; 544 } 545 546 #=================================== 547 # Data Access 548 #=================================== 549 550 ######################################### 551 # is cookie valid? 552 553 function auth_is_cookie_valid( $p_cookie_string ) { 554 global $g_cache_current_user_id; 555 556 # fail if DB isn't accessible 557 if ( !db_is_connected() ) { 558 return false; 559 } 560 561 # fail if cookie is blank 562 if ( '' === $p_cookie_string ) { 563 return false; 564 } 565 566 # succeeed if user has already been authenticated 567 if ( null !== $g_cache_current_user_id ) { 568 return true; 569 } 570 571 # look up cookie in the database to see if it is valid 572 $t_user_table = config_get( 'mantis_user_table' ); 573 574 $c_cookie_string = db_prepare_string( $p_cookie_string ); 575 576 $query = "SELECT id 577 FROM $t_user_table 578 WHERE cookie_string='$c_cookie_string'"; 579 $result = db_query( $query ); 580 581 # return true if a matching cookie was found 582 return ( 1 == db_num_rows( $result ) ); 583 } 584 585 ######################################### 586 # SECURITY NOTE: cache globals are initialized here to prevent them 587 # being spoofed if register_globals is turned on 588 # 589 $g_cache_current_user_id = null; 590 591 function auth_get_current_user_id() { 592 global $g_cache_current_user_id; 593 594 if ( null !== $g_cache_current_user_id ) { 595 return $g_cache_current_user_id; 596 } 597 598 $t_user_table = config_get( 'mantis_user_table' ); 599 600 $t_cookie_string = auth_get_current_user_cookie(); 601 602 # @@@ error with an error saying they aren't logged in? 603 # Or redirect to the login page maybe? 604 605 $c_cookie_string = db_prepare_string( $t_cookie_string ); 606 607 $query = "SELECT id 608 FROM $t_user_table 609 WHERE cookie_string='$c_cookie_string'"; 610 $result = db_query( $query ); 611 612 # The cookie was invalid. Clear the cookie (to allow people to log in again) 613 # and give them an Access Denied message. 614 if ( db_num_rows( $result ) < 1 ) { 615 auth_clear_cookies(); 616 access_denied(); # never returns 617 return false; 618 } 619 620 $t_user_id = (int)db_result( $result ); 621 $g_cache_current_user_id = $t_user_id; 622 623 return $t_user_id; 624 } 625 626 #=================================== 627 # HTTP Auth 628 #=================================== 629 630 function auth_http_prompt() { 631 header( "HTTP/1.0 401 Authorization Required" ); 632 header( "WWW-Authenticate: Basic realm=\"" . lang_get( 'http_auth_realm' ) . "\"" ); 633 header( 'status: 401 Unauthorized' ); 634 635 echo '<center>'; 636 echo '<p>'.error_string(ERROR_ACCESS_DENIED).'</p>'; 637 print_bracket_link( 'main_page.php', lang_get( 'proceed' ) ); 638 echo '</center>'; 639 640 exit; 641 } 642 643 function auth_http_set_logout_pending( $p_pending ) { 644 $t_cookie_name = config_get( 'logout_cookie' ); 645 646 if ( $p_pending ) { 647 gpc_set_cookie( $t_cookie_name, "1", false ); 648 } else { 649 $t_cookie_path = config_get( 'cookie_path' ); 650 gpc_clear_cookie( $t_cookie_name, $t_cookie_path ); 651 } 652 } 653 654 function auth_http_is_logout_pending() { 655 $t_cookie_name = config_get( 'logout_cookie' ); 656 $t_cookie = gpc_get_cookie( $t_cookie_name, '' ); 657 658 return( $t_cookie > '' ); 659 } 660 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 09:42:17 2007 | par Balluche grâce à PHPXref 0.7 |
|