Exemple #1
0
		$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;
    }
}