$blocked = login_check_blocked($nick); if ($blocked) { echo '<body class="login">'; require ('general/login_page.php'); exit; } //Checks if password has expired $check_status = check_pass_status($nick, $pass); switch ($check_status) { case 1: //first change case 2: //pass expired $expired_pass = true; $_GET['no_login'] = 1; login_change_password($nick); break; case 0: $expired_pass = false; break; } } if (($nick_in_db !== false) && $expired_pass) { //login ok and password has expired echo '<body class="login">'; require_once ('general/login_page.php'); exit; } else if (($nick_in_db !== false) && (!$expired_pass)) { //login ok and password has not expired $check_managers = enterprise_hook("license_check_manager_users_num"); $check_regulars = enterprise_hook("license_check_regular_users_num");
$errmsg = ''; if (fRequest::isPost()) { $old_password = fRequest::get('old-password'); $new_password = fRequest::get('new-password'); $confirm_password = fRequest::get('confirm-password'); $token = fAuthorization::getUserToken(); $username = $token['name']; $user_id = $token['id']; if (empty($old_password) or empty($new_password) or empty($confirm_password)) { $errmsg = '密码不能为空'; } else { if ($new_password != $confirm_password) { $errmsg = '两次输入的新密码不一致'; } else { if (login_check_credential($db, $username, $old_password) == false) { $errmsg = '旧密码错误'; } else { if (login_change_password($db, $user_id, $new_password)) { fURL::redirect(fSession::delete('change-password-referer', SITE_BASE)); } else { $errmsg = '修改密码失败'; } } } } } else { if (fSession::get('change-password-referer') == null) { fSession::set('change-password-referer', login_get_referer(SITE_BASE)); } } include __DIR__ . '/tpl/change-password.php';
/** execute the selected login procedure * * The login process is controlled via the parameter 'login' * provided by the user via 'index.php?login=N or via the * 'action' property in a HTML-form. These numbers correspond to the * LOGIN_PROCEDURE_* constants defined near the top of this file. * Here's a reminder: * * 1. LOGIN_PROCEDURE_NORMAL this is the usual procedure for logging in * 2. LOGIN_PROCEDURE_CHANGE_PASSWORD this is the procedure to change the user's password * 3. LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER this is phase 1 of the 'forgot password' procedure * 4. LOGIN_PROCEDURE_SEND_BYPASS this is phase 2 of the 'forgot password' procedure * * Note that this routine only returns to the caller after either a succesful * regular login (i.e. after completing LOGIN_PROCEDURE_NORMAL). All the * other variants and error conditions yield another screen and an immediate exit and * hence no return to caller. If this routine returns, it returns the user_id * of the authenticated user (the primary key into the users table). It is up to the caller to * retrieve additional information about this user; any information read from the database * during login is discarded. This prevents password hashes still lying around. * * Note that a successful login has the side effect of garbage collection: * whenever we experience a successful login any obsolete sessions are removed. * This makes sure that locked records eventually will be unlocked, once the corresponding * session no longer exists. The garbage collection routine is also called from * the PHP session handler every once in a while, but here we make 100% sure that * garbage is collected at least at every login. (Note: obsolete sessions should not * be a problem for visitors that are not logged in, because you have to be logged in * to be able to lock a record.) * * @param int $procedure the login procedure to execute * @param string $message the message to display when showing the login dialog * @return void|int no return on error, otherwise the user_id of the authenticated user * @uses $CFG * @uses dbsession_setup() * @uses dbsession_garbage_collection() */ function was_login($procedure = LOGIN_PROCEDURE_SHOWLOGIN, $message = '') { global $CFG; // get rid of the cookie (if we received one) and the corresponding session; // the user's browser should NOT present us with a cookie during the login procedures. if (isset($_COOKIE[$CFG->session_name])) { was_logout(); exit; } // If this IP-address is currently blacklisted, tell the visitor access is denied if (login_is_blacklisted($_SERVER['REMOTE_ADDR'])) { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('access_denied', 'loginlib')); exit; } switch (intval($procedure)) { case LOGIN_PROCEDURE_NORMAL: if (isset($_POST['login_username']) && isset($_POST['login_password'])) { $username = magic_unquote($_POST['login_username']); $password = magic_unquote($_POST['login_password']); $user = authenticate_user(BY_PASSWORD, $username, $password); if ($user !== FALSE) { login_failure_reset($_SERVER['REMOTE_ADDR']); if (db_bool_is(FALSE, $user['bypass_mode'])) { // valid credentials and not in a bypass mode: start session and return user_id require_once $CFG->progdir . '/lib/dbsessionlib.php'; dbsession_setup($CFG->session_name); $session_key = dbsession_create($user['user_id'], $_SERVER['REMOTE_ADDR']); session_id($session_key); session_start(); $_SESSION['session_id'] = dbsession_get_session_id($session_key); $user_id = intval($user['user_id']); $_SESSION['user_id'] = $user_id; $_SESSION['redirect'] = $user['redirect']; $_SESSION['language_key'] = $user['language_key']; $_SESSION['remote_addr'] = $_SERVER['REMOTE_ADDR']; $_SESSION['salt'] = $CFG->salt; // allow for extra check on rogue sessions $_SESSION['username'] = $username; logger('login: \'' . $username . '\' (' . $user_id . '): success', WLOG_INFO, $user_id); // now that we logged on successfully, make sure that obsolete sessions // will not bother us (or other logged in users). Note the 900 seconds minimum duration; // $time_out = max(900,intval(ini_get('session.gc_maxlifetime'))); global $CFG; $time_out = max(900, intval($CFG->session_expiry)); dbsession_garbage_collection($time_out); return $user_id; // SUCCESS! User is logged in, tell caller! } else { show_login(LOGIN_PROCEDURE_CHANGE_PASSWORD, t('must_change_password', 'loginlib')); exit; } } // Invalid credentials; pretend we're busy (slow user down), increment failure count... $failure_count = login_failure_increment($_SERVER['REMOTE_ADDR'], LOGIN_PROCEDURE_NORMAL, $username); login_failure_delay($_SERVER['REMOTE_ADDR']); if ($failure_count < intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_NORMAL, t('invalid_credentials_please_retry', 'loginlib')); } elseif ($failure_count == intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER, t('do_you_want_to_try_forgot_password_procedure', 'loginlib')); } else { login_failure_blacklist_address($_SERVER['REMOTE_ADDR'], 60 * intval($CFG->login_blacklist_interval), $username); show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('contact_webmaster_for_new_password', 'loginlib')); } } else { show_login(LOGIN_PROCEDURE_NORMAL); } exit; break; case LOGIN_PROCEDURE_CHANGE_PASSWORD: if (isset($_POST['login_username']) && isset($_POST['login_password']) && isset($_POST['login_new_password1']) && isset($_POST['login_new_password2'])) { $username = magic_unquote($_POST['login_username']); $password = magic_unquote($_POST['login_password']); $new_password1 = magic_unquote($_POST['login_new_password1']); $new_password2 = magic_unquote($_POST['login_new_password2']); $user = authenticate_user(BY_PASSWORD, $username, $password); // // step 1 - perform some checks on the proposed new passwords // if ($user !== FALSE) { // user authenticated: we can now also check re-use of existing passwords $salt = $user['salt']; $password_hash = $user['password_hash']; $bypass_hash = $user['bypass_hash']; } else { // user not authenticated so we cannot check for re-use of existing passwords $salt = ''; $password_hash = ''; $bypass_hash = ''; } if (!acceptable_new_password($new_password1, $new_password2, $salt, $password_hash, $bypass_hash)) { show_login(LOGIN_PROCEDURE_CHANGE_PASSWORD, t('invalid_new_passwords', 'loginlib', array('{MIN_LENGTH}' => MINIMUM_PASSWORD_LENGTH, '{MIN_LOWER}' => MINIMUM_PASSWORD_LOWERCASE, '{MIN_UPPER}' => MINIMUM_PASSWORD_UPPERCASE, '{MIN_DIGIT}' => MINIMUM_PASSWORD_DIGITS))); exit; } // // step 2 - if authenticated, actually change password and reset failure counters/blacklists // if ($user !== FALSE) { // allow the user in: // - start new session, // - immediately write/close it, // - send user an email about success with changing password, // - and finally leave the user with message box on screen // login_change_password($user['user_id'], $new_password1); login_failure_reset($_SERVER['REMOTE_ADDR']); require_once $CFG->progdir . '/lib/dbsessionlib.php'; dbsession_setup($CFG->session_name); $session_key = dbsession_create($user['user_id'], $_SERVER['REMOTE_ADDR']); session_id($session_key); session_start(); $_SESSION['session_id'] = dbsession_get_session_id($session_key); $user_id = intval($user['user_id']); $_SESSION['user_id'] = $user_id; $_SESSION['redirect'] = $user['redirect']; $_SESSION['language_key'] = $user['language_key']; $_SESSION['remote_addr'] = $_SERVER['REMOTE_ADDR']; $_SESSION['salt'] = $CFG->salt; // allow for extra check on rogue sessions $_SESSION['username'] = $username; session_write_close(); // save the session login_send_confirmation($user); logger('login: \'' . $username . '\' (' . $user_id . '), change password: success', WLOG_INFO, $user_id); show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('password_changed', 'loginlib')); exit; } // Invalid credentials; pretend we're busy (slow user down), increment failure count... $failure_count = login_failure_increment($_SERVER['REMOTE_ADDR'], LOGIN_PROCEDURE_CHANGE_PASSWORD, $username); login_failure_delay($_SERVER['REMOTE_ADDR']); if ($failure_count < intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_CHANGE_PASSWORD, t('invalid_credentials_please_retry', 'loginlib')); } elseif ($failure_count == intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER, t('too_many_login_attempts', 'loginlib')); } else { login_failure_blacklist_address($_SERVER['REMOTE_ADDR'], 60 * intval($CFG->login_blacklist_interval), $username); show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('too_many_change_password_attempts', 'loginlib')); } } else { show_login(LOGIN_PROCEDURE_CHANGE_PASSWORD); } exit; break; case LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER: if (isset($_POST['login_username']) && isset($_POST['login_email'])) { $username = magic_unquote($_POST['login_username']); $email = magic_unquote($_POST['login_email']); $user = authenticate_user(BY_EMAIL, $username, $email); if ($user !== FALSE) { if (login_send_laissez_passer($user)) { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('see_mail_for_further_instructions', 'loginlib')); } else { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('failure_sending_laissez_passer_mail', 'loginlib')); } exit; } else { // Not authenticated; pretend we're busy (slow user down), increment failure count... $failure_count = login_failure_increment($_SERVER['REMOTE_ADDR'], LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER, $username); login_failure_delay($_SERVER['REMOTE_ADDR']); if ($failure_count < intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER, t('invalid_username_email_please_retry', 'loginlib')); } elseif ($failure_count == intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('too_many_login_attempts', 'loginlib')); } else { login_failure_blacklist_address($_SERVER['REMOTE_ADDR'], 60 * intval($CFG->login_blacklist_interval), $username); show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('too_many_login_attempts', 'loginlib')); } exit; } } else { show_login(LOGIN_PROCEDURE_SEND_LAISSEZ_PASSER); } exit; break; case LOGIN_PROCEDURE_SEND_BYPASS: if (isset($_GET['code']) && isset($_GET['username'])) { $laissez_passer = magic_unquote($_GET['code']); $username = magic_unquote($_GET['username']); } elseif (isset($_POST['login_username']) && isset($_POST['login_laissez_passer'])) { $laissez_passer = magic_unquote($_POST['login_laissez_passer']); $username = magic_unquote($_POST['login_username']); } else { show_login(LOGIN_PROCEDURE_SEND_BYPASS); exit; } // still here? Then we check the laissez_passer and send a second email to the user $user = authenticate_user(BY_LAISSEZ_PASSER, $username, $laissez_passer); if ($user !== FALSE) { login_failure_reset($_SERVER['REMOTE_ADDR']); if (login_send_bypass($user)) { show_login(LOGIN_PROCEDURE_NORMAL, t('see_mail_for_new_temporary_password', 'loginlib')); } else { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('failure_sending_temporary_password', 'loginlib')); } } else { $failure_count = login_failure_increment($_SERVER['REMOTE_ADDR'], LOGIN_PROCEDURE_SEND_BYPASS, $username); login_failure_delay($_SERVER['REMOTE_ADDR']); if ($failure_count < intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_SEND_BYPASS, t('invalid_laissez_passer_please_retry', 'loginlib')); } elseif ($failure_count == intval($CFG->login_max_failures)) { show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('too_many_login_attempts', 'loginlib')); } else { login_failure_blacklist_address($_SERVER['REMOTE_ADDR'], 60 * intval($CFG->login_blacklist_interval), $username); show_login(LOGIN_PROCEDURE_MESSAGE_BOX, t('too_many_login_attempts', 'loginlib')); } } exit; break; case LOGIN_PROCEDURE_SHOWLOGIN: show_login(LOGIN_PROCEDURE_NORMAL, $message); exit; break; default: show_login(LOGIN_PROCEDURE_NORMAL); exit; break; } }