aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Auth/Persist/Cookie.pm')
-rw-r--r--Bugzilla/Auth/Persist/Cookie.pm267
1 files changed, 138 insertions, 129 deletions
diff --git a/Bugzilla/Auth/Persist/Cookie.pm b/Bugzilla/Auth/Persist/Cookie.pm
index 2d1291f3b..af6b0d77d 100644
--- a/Bugzilla/Auth/Persist/Cookie.pm
+++ b/Bugzilla/Auth/Persist/Cookie.pm
@@ -20,145 +20,154 @@ use Bugzilla::Token;
use List::Util qw(first);
sub new {
- my ($class) = @_;
- my $self = fields::new($class);
- return $self;
+ my ($class) = @_;
+ my $self = fields::new($class);
+ return $self;
}
sub persist_login {
- my ($self, $user) = @_;
- my $dbh = Bugzilla->dbh;
- my $cgi = Bugzilla->cgi;
- my $input_params = Bugzilla->input_params;
-
- my $ip_addr;
- if ($input_params->{'Bugzilla_restrictlogin'}) {
- $ip_addr = remote_ip();
- # The IP address is valid, at least for comparing with itself in a
- # subsequent login
- trick_taint($ip_addr);
- }
-
- $dbh->bz_start_transaction();
-
- my $login_cookie =
- Bugzilla::Token::GenerateUniqueToken('logincookies', 'cookie');
-
- $dbh->do("INSERT INTO logincookies (cookie, userid, ipaddr, lastused)
- VALUES (?, ?, ?, NOW())",
- undef, $login_cookie, $user->id, $ip_addr);
-
- # Issuing a new cookie is a good time to clean up the old
- # cookies.
- $dbh->do("DELETE FROM logincookies WHERE lastused < "
- . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-',
- MAX_LOGINCOOKIE_AGE, 'DAY'));
-
- $dbh->bz_commit_transaction();
-
- # We do not want WebServices to generate login cookies.
- # All we need is the login token for User.login.
- return $login_cookie if i_am_webservice();
-
- # Prevent JavaScript from accessing login cookies.
- my %cookieargs = ('-httponly' => 1);
-
- # Remember cookie only if admin has told so
- # or admin didn't forbid it and user told to remember.
- if ( Bugzilla->params->{'rememberlogin'} eq 'on' ||
- (Bugzilla->params->{'rememberlogin'} ne 'off' &&
- $input_params->{'Bugzilla_remember'} &&
- $input_params->{'Bugzilla_remember'} eq 'on') )
- {
- # Not a session cookie, so set an infinite expiry
- $cookieargs{'-expires'} = 'Fri, 01-Jan-2038 00:00:00 GMT';
- }
- if (Bugzilla->params->{'ssl_redirect'}) {
- # Make these cookies only be sent to us by the browser during
- # HTTPS sessions, if we're using SSL.
- $cookieargs{'-secure'} = 1;
- }
-
- $cgi->send_cookie(-name => 'Bugzilla_login',
- -value => $user->id,
- %cookieargs);
- $cgi->send_cookie(-name => 'Bugzilla_logincookie',
- -value => $login_cookie,
- %cookieargs);
+ my ($self, $user) = @_;
+ my $dbh = Bugzilla->dbh;
+ my $cgi = Bugzilla->cgi;
+ my $input_params = Bugzilla->input_params;
+
+ my $ip_addr;
+ if ($input_params->{'Bugzilla_restrictlogin'}) {
+ $ip_addr = remote_ip();
+
+ # The IP address is valid, at least for comparing with itself in a
+ # subsequent login
+ trick_taint($ip_addr);
+ }
+
+ $dbh->bz_start_transaction();
+
+ my $login_cookie
+ = Bugzilla::Token::GenerateUniqueToken('logincookies', 'cookie');
+
+ $dbh->do(
+ "INSERT INTO logincookies (cookie, userid, ipaddr, lastused)
+ VALUES (?, ?, ?, NOW())", undef, $login_cookie, $user->id, $ip_addr
+ );
+
+ # Issuing a new cookie is a good time to clean up the old
+ # cookies.
+ $dbh->do("DELETE FROM logincookies WHERE lastused < "
+ . $dbh->sql_date_math('LOCALTIMESTAMP(0)', '-', MAX_LOGINCOOKIE_AGE, 'DAY'));
+
+ $dbh->bz_commit_transaction();
+
+ # We do not want WebServices to generate login cookies.
+ # All we need is the login token for User.login.
+ return $login_cookie if i_am_webservice();
+
+ # Prevent JavaScript from accessing login cookies.
+ my %cookieargs = ('-httponly' => 1);
+
+ # Remember cookie only if admin has told so
+ # or admin didn't forbid it and user told to remember.
+ if (
+ Bugzilla->params->{'rememberlogin'} eq 'on'
+ || ( Bugzilla->params->{'rememberlogin'} ne 'off'
+ && $input_params->{'Bugzilla_remember'}
+ && $input_params->{'Bugzilla_remember'} eq 'on')
+ )
+ {
+ # Not a session cookie, so set an infinite expiry
+ $cookieargs{'-expires'} = 'Fri, 01-Jan-2038 00:00:00 GMT';
+ }
+ if (Bugzilla->params->{'ssl_redirect'}) {
+
+ # Make these cookies only be sent to us by the browser during
+ # HTTPS sessions, if we're using SSL.
+ $cookieargs{'-secure'} = 1;
+ }
+
+ $cgi->send_cookie(-name => 'Bugzilla_login', -value => $user->id, %cookieargs);
+ $cgi->send_cookie(
+ -name => 'Bugzilla_logincookie',
+ -value => $login_cookie,
+ %cookieargs
+ );
}
sub logout {
- my ($self, $param) = @_;
-
- my $dbh = Bugzilla->dbh;
- my $cgi = Bugzilla->cgi;
- my $input = Bugzilla->input_params;
- $param = {} unless $param;
- my $user = $param->{user} || Bugzilla->user;
- my $type = $param->{type} || LOGOUT_ALL;
-
- if ($type == LOGOUT_ALL) {
- $dbh->do("DELETE FROM logincookies WHERE userid = ?",
- undef, $user->id);
- return;
- }
-
- # The LOGOUT_*_CURRENT options require the current login cookie.
- # If a new cookie has been issued during this run, that's the current one.
- # If not, it's the one we've received.
- my @login_cookies;
- my $cookie = first {$_->name eq 'Bugzilla_logincookie'}
- @{$cgi->{'Bugzilla_cookie_list'}};
- if ($cookie) {
- push(@login_cookies, $cookie->value);
- }
- elsif ($cookie = $cgi->cookie('Bugzilla_logincookie')) {
- push(@login_cookies, $cookie);
- }
-
- # If we are a webservice using a token instead of cookie
- # then add that as well to the login cookies to delete
- if (my $login_token = $user->authorizer->login_token) {
- push(@login_cookies, $login_token->{'login_token'});
- }
-
- # Make sure that @login_cookies is not empty to not break SQL statements.
- push(@login_cookies, '') unless @login_cookies;
-
- # These queries use both the cookie ID and the user ID as keys. Even
- # though we know the userid must match, we still check it in the SQL
- # as a sanity check, since there is no locking here, and if the user
- # logged out from two machines simultaneously, while someone else
- # logged in and got the same cookie, we could be logging the other
- # user out here. Yes, this is very very very unlikely, but why take
- # chances? - bbaetz
- map { trick_taint($_) } @login_cookies;
- @login_cookies = map { $dbh->quote($_) } @login_cookies;
- if ($type == LOGOUT_KEEP_CURRENT) {
- $dbh->do("DELETE FROM logincookies WHERE " .
- $dbh->sql_in('cookie', \@login_cookies, 1) .
- " AND userid = ?",
- undef, $user->id);
- } elsif ($type == LOGOUT_CURRENT) {
- $dbh->do("DELETE FROM logincookies WHERE " .
- $dbh->sql_in('cookie', \@login_cookies) .
- " AND userid = ?",
- undef, $user->id);
- } else {
- die("Invalid type $type supplied to logout()");
- }
-
- if ($type != LOGOUT_KEEP_CURRENT) {
- clear_browser_cookies();
- }
+ my ($self, $param) = @_;
+
+ my $dbh = Bugzilla->dbh;
+ my $cgi = Bugzilla->cgi;
+ my $input = Bugzilla->input_params;
+ $param = {} unless $param;
+ my $user = $param->{user} || Bugzilla->user;
+ my $type = $param->{type} || LOGOUT_ALL;
+
+ if ($type == LOGOUT_ALL) {
+ $dbh->do("DELETE FROM logincookies WHERE userid = ?", undef, $user->id);
+ return;
+ }
+
+ # The LOGOUT_*_CURRENT options require the current login cookie.
+ # If a new cookie has been issued during this run, that's the current one.
+ # If not, it's the one we've received.
+ my @login_cookies;
+ my $cookie = first { $_->name eq 'Bugzilla_logincookie' }
+ @{$cgi->{'Bugzilla_cookie_list'}};
+ if ($cookie) {
+ push(@login_cookies, $cookie->value);
+ }
+ elsif ($cookie = $cgi->cookie('Bugzilla_logincookie')) {
+ push(@login_cookies, $cookie);
+ }
+
+ # If we are a webservice using a token instead of cookie
+ # then add that as well to the login cookies to delete
+ if (my $login_token = $user->authorizer->login_token) {
+ push(@login_cookies, $login_token->{'login_token'});
+ }
+
+ # Make sure that @login_cookies is not empty to not break SQL statements.
+ push(@login_cookies, '') unless @login_cookies;
+
+ # These queries use both the cookie ID and the user ID as keys. Even
+ # though we know the userid must match, we still check it in the SQL
+ # as a sanity check, since there is no locking here, and if the user
+ # logged out from two machines simultaneously, while someone else
+ # logged in and got the same cookie, we could be logging the other
+ # user out here. Yes, this is very very very unlikely, but why take
+ # chances? - bbaetz
+ map { trick_taint($_) } @login_cookies;
+ @login_cookies = map { $dbh->quote($_) } @login_cookies;
+ if ($type == LOGOUT_KEEP_CURRENT) {
+ $dbh->do(
+ "DELETE FROM logincookies WHERE "
+ . $dbh->sql_in('cookie', \@login_cookies, 1)
+ . " AND userid = ?",
+ undef, $user->id
+ );
+ }
+ elsif ($type == LOGOUT_CURRENT) {
+ $dbh->do(
+ "DELETE FROM logincookies WHERE "
+ . $dbh->sql_in('cookie', \@login_cookies)
+ . " AND userid = ?",
+ undef, $user->id
+ );
+ }
+ else {
+ die("Invalid type $type supplied to logout()");
+ }
+
+ if ($type != LOGOUT_KEEP_CURRENT) {
+ clear_browser_cookies();
+ }
}
sub clear_browser_cookies {
- my $cgi = Bugzilla->cgi;
- $cgi->remove_cookie('Bugzilla_login');
- $cgi->remove_cookie('Bugzilla_logincookie');
- $cgi->remove_cookie('sudo');
+ my $cgi = Bugzilla->cgi;
+ $cgi->remove_cookie('Bugzilla_login');
+ $cgi->remove_cookie('Bugzilla_logincookie');
+ $cgi->remove_cookie('sudo');
}
1;