diff options
author | mkanat%bugzilla.org <> | 2009-12-13 21:46:24 +0100 |
---|---|---|
committer | mkanat%bugzilla.org <> | 2009-12-13 21:46:24 +0100 |
commit | 72cb2bc73e71f54c2223bb78af29fee888590b53 (patch) | |
tree | 45aacc0944bd4b7d4b7391b0bff7bc67b15c722e /Bugzilla/Auth | |
parent | cb4a8bf4954c38d06358c4a7509f3fac6fb1e705 (diff) | |
download | bugzilla-72cb2bc73e71f54c2223bb78af29fee888590b53.tar.gz bugzilla-72cb2bc73e71f54c2223bb78af29fee888590b53.tar.xz |
Bug 355283: Lock out a user account on a particular IP for 30 minutes if they fail to log in 5 times from that IP.
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit
Diffstat (limited to 'Bugzilla/Auth')
-rw-r--r-- | Bugzilla/Auth/Verify/DB.pm | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm index 695671a31..d8794472e 100644 --- a/Bugzilla/Auth/Verify/DB.pm +++ b/Bugzilla/Auth/Verify/DB.pm @@ -41,37 +41,51 @@ sub check_credentials { my $dbh = Bugzilla->dbh; my $username = $login_data->{username}; - my $user_id = login_to_id($username); + my $user = new Bugzilla::User({ name => $username }); - return { failure => AUTH_NO_SUCH_USER } unless $user_id; + return { failure => AUTH_NO_SUCH_USER } unless $user; - $login_data->{bz_username} = $username; - my $password = $login_data->{password}; + $login_data->{user} = $user; + $login_data->{bz_username} = $user->login; + + if ($user->account_is_locked_out) { + return { failure => AUTH_LOCKOUT, user => $user }; + } - trick_taint($username); - my ($real_password_crypted) = $dbh->selectrow_array( - "SELECT cryptpassword FROM profiles WHERE userid = ?", - undef, $user_id); + my $password = $login_data->{password}; + my $real_password_crypted = $user->cryptpassword; # Using the internal crypted password as the salt, # crypt the password the user entered. my $entered_password_crypted = bz_crypt($password, $real_password_crypted); - - return { failure => AUTH_LOGINFAILED } - if $entered_password_crypted ne $real_password_crypted; + + if ($entered_password_crypted ne $real_password_crypted) { + # Record the login failure + $user->note_login_failure(); + + # Immediately check if we are locked out + if ($user->account_is_locked_out) { + return { failure => AUTH_LOCKOUT, user => $user, + just_locked_out => 1 }; + } + + return { failure => AUTH_LOGINFAILED, + failure_count => scalar(@{ $user->account_ip_login_failures }), + }; + } # The user's credentials are okay, so delete any outstanding - # password tokens they may have generated. - Bugzilla::Token::DeletePasswordTokens($user_id, "user_logged_in"); + # password tokens or login failures they may have generated. + Bugzilla::Token::DeletePasswordTokens($user->id, "user_logged_in"); + $user->clear_login_failures(); # If their old password was using crypt() or some different hash # than we're using now, convert the stored password to using # whatever hashing system we're using now. my $current_algorithm = PASSWORD_DIGEST_ALGORITHM; if ($real_password_crypted !~ /{\Q$current_algorithm\E}$/) { - my $new_crypted = bz_crypt($password); - $dbh->do('UPDATE profiles SET cryptpassword = ? WHERE userid = ?', - undef, $new_crypted, $user_id); + $user->set_password($password); + $user->update(); } return $login_data; |