summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Auth/CGI.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Auth/CGI.pm')
-rw-r--r--Bugzilla/Auth/CGI.pm195
1 files changed, 195 insertions, 0 deletions
diff --git a/Bugzilla/Auth/CGI.pm b/Bugzilla/Auth/CGI.pm
new file mode 100644
index 000000000..b7c2e6c42
--- /dev/null
+++ b/Bugzilla/Auth/CGI.pm
@@ -0,0 +1,195 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Terry Weissman <terry@mozilla.org>
+# Dan Mosedale <dmose@mozilla.org>
+# Joe Robins <jmrobins@tgix.com>
+# Dave Miller <justdave@syndicomm.com>
+# Christopher Aillon <christopher@aillon.com>
+# Gervase Markham <gerv@gerv.net>
+# Christian Reis <kiko@async.com.br>
+# Bradley Baetz <bbaetz@acm.org>
+
+package Bugzilla::Auth::CGI;
+
+use strict;
+
+use Bugzilla::Config;
+use Bugzilla::Constants;
+use Bugzilla::Util;
+
+sub login {
+ my ($class, $type) = @_;
+
+ # 'NORMAL' logins depend on the 'requirelogin' param
+ if ($type == LOGIN_NORMAL) {
+ $type = Param('requirelogin') ? LOGIN_REQUIRED : LOGIN_OPTIONAL;
+ }
+
+ my $cgi = Bugzilla->cgi;
+
+ # First, try the actual login method against form variables
+ my $username = $cgi->param("Bugzilla_login");
+ my $passwd = $cgi->param("Bugzilla_password");
+
+ my $authmethod = Param("loginmethod");
+ my ($authres, $userid, $extra, $info) =
+ Bugzilla::Auth->authenticate($username, $passwd);
+
+ if ($authres == AUTH_OK) {
+ # Login via username/password was correct and valid, so create
+ # and send out the login cookies
+ my $ipaddr = $cgi->remote_addr;
+ unless ($cgi->param('Bugzilla_restrictlogin') ||
+ Param('loginnetmask') == 32) {
+ $ipaddr = get_netaddr($ipaddr);
+ }
+
+ # The IP address is valid, at least for comparing with itself in a
+ # subsequent login
+ trick_taint($ipaddr);
+
+ my $dbh = Bugzilla->dbh;
+ $dbh->do("INSERT INTO logincookies (userid, ipaddr) VALUES (?, ?)",
+ undef,
+ $userid, $ipaddr);
+ my $logincookie = $dbh->selectrow_array("SELECT LAST_INSERT_ID()");
+ my $cookiepath = Param("cookiepath");
+ print "Set-Cookie: Bugzilla_login=$userid ; path=$cookiepath; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
+ print "Set-Cookie: Bugzilla_logincookie=$logincookie ; path=$cookiepath; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
+
+ # compat code. The cookie value is used for logouts, and that
+ # isn't generic yet.
+ $::COOKIE{'Bugzilla_logincookie'} = $logincookie;
+ } elsif ($authres == AUTH_NODATA) {
+ # No data from the form, so try to login via cookies
+ $username = $cgi->cookie("Bugzilla_login");
+ $passwd = $cgi->cookie("Bugzilla_logincookie");
+
+ require Bugzilla::Auth::Cookie;
+ my $authmethod = "Cookie";
+
+ ($authres, $userid, $extra) =
+ Bugzilla::Auth::Cookie->authenticate($username, $passwd);
+
+ # If the data for the cookie was incorrect, then treat that as
+ # NODATA. This could occur if the user's IP changed, for example.
+ # Give them un-loggedin access if allowed (checked below)
+ $authres = AUTH_NODATA if $authres == AUTH_LOGINFAILED;
+ }
+
+ # Now check the result
+
+ # An error may have occurred with the login mechanism
+ if ($authres == AUTH_ERROR) {
+ $::vars->{'authmethod'} = lc($authmethod);
+ $::vars->{'userid'} = $userid;
+ $::vars->{'auth_err_tag'} = $extra;
+ $::vars->{'info'} = $info;
+
+ &::ThrowCodeError("auth_err");
+ }
+
+ # We can load the page if the login was ok, or there was no data
+ # but a login wasn't required
+ if ($authres == AUTH_OK ||
+ ($authres == AUTH_NODATA && $type == LOGIN_OPTIONAL)) {
+
+ # login succeded, so we're done
+ return $userid;
+ }
+
+ # No login details were given, but we require a login if the
+ # page does
+ if ($authres == AUTH_NODATA && $type == LOGIN_REQUIRED) {
+ # Throw up the login page
+
+ print "Content-Type: text/html\n\n";
+
+ my $template = Bugzilla->template;
+ $template->process("account/auth/login.html.tmpl",
+ { 'target' => $cgi->url(-relative=>1),
+ 'form' => \%::FORM,
+ 'mform' => \%::MFORM,
+ 'caneditaccount' => Bugzilla::Auth->can_edit,
+ }
+ )
+ || &::ThrowTemplateError($template->error());
+
+ # This seems like as good as time as any to get rid of old
+ # crufty junk in the logincookies table. Get rid of any entry
+ # that hasn't been used in a month.
+ Bugzilla->dbh->do("DELETE FROM logincookies " .
+ "WHERE TO_DAYS(NOW()) - TO_DAYS(lastused) > 30");
+
+ exit;
+ }
+
+ # The username/password may be wrong
+ # Don't let the user know whether the username exists or whether
+ # the password was just wrong. (This makes it harder for a cracker
+ # to find account names by brute force)
+ if ($authres == AUTH_LOGINFAILED) {
+ &::ThrowUserError("invalid_username_or_password");
+ }
+
+ # The account may be disabled
+ if ($authres == AUTH_DISABLED) {
+ # Clear the cookie
+ my $cookiepath = Param("cookiepath");
+ print "Set-Cookie: Bugzilla_login= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
+ print "Set-Cookie: Bugzilla_logincookie= ; path=$cookiepath; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
+ # and throw a user error
+ &::ThrowUserError("account_disabled",
+ {'disabled_reason' => $extra});
+ }
+
+ # If we get here, then we've run out of options, which shouldn't happen
+ &::ThrowCodeError("authres_unhandled",
+ { authres => $authres,
+ type => $type,
+ }
+ );
+
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bugzilla::Auth::CGI - CGI-based logins for Bugzilla
+
+=head1 SUMMARY
+
+This is a L<login module|Bugzilla::Auth/"LOGIN"> for Bugzilla. Users connecting
+from a CGI script use this module to authenticate.
+
+=head1 BEHAVIOUR
+
+Users are first authenticated against the default authentication handler,
+using the CGI parameters I<Bugzilla_login> and I<Bugzilla_password>.
+
+If no data is present for that, then cookies are tried, using
+L<Bugzilla::Auth::Cookie>.
+
+=head1 SEE ALSO
+
+L<Bugzilla::Auth>