PageRenderTime 68ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/MantisBT/core/authentication_api.php

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