⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgi.pm

📁 bugzilla 项目缺陷管理工具源码
💻 PM
字号:
# -*- 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>#                 Erik Stambaugh <erik@dasbistro.com>package Bugzilla::Auth::Login::WWW::CGI;use strict;use Bugzilla::Config;use Bugzilla::Constants;use Bugzilla::Error;use Bugzilla::Util;use Bugzilla::Token;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;    my $dbh = Bugzilla->dbh;    # First, try the actual login method against form variables    my $username = $cgi->param("Bugzilla_login");    my $passwd = $cgi->param("Bugzilla_password");        $cgi->delete('Bugzilla_login', 'Bugzilla_password');    # Perform the actual authentication, get the method name from the class name    my ($authmethod, $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 = Bugzilla::Auth::get_netaddr($ipaddr);        }        # The IP address is valid, at least for comparing with itself in a        # subsequent login        trick_taint($ipaddr);        my $logincookie = Bugzilla::Token::GenerateUniqueToken('logincookies', 'cookie');        $dbh->do("INSERT INTO logincookies (cookie, userid, ipaddr, lastused)                 VALUES (?, ?, ?, NOW())",                 undef,                 $logincookie, $userid, $ipaddr);        # Remember cookie only if admin has told so        # or admin didn't forbid it and user told to remember.        if ((Param('rememberlogin') eq 'on') ||            ((Param('rememberlogin') ne 'off') &&             $cgi->param('Bugzilla_remember') &&             ($cgi->param('Bugzilla_remember') eq 'on'))) {            $cgi->send_cookie(-name => 'Bugzilla_login',                              -value => $userid,                              -expires => 'Fri, 01-Jan-2038 00:00:00 GMT');            $cgi->send_cookie(-name => 'Bugzilla_logincookie',                              -value => $logincookie,                              -expires => 'Fri, 01-Jan-2038 00:00:00 GMT');        }        else {            $cgi->send_cookie(-name => 'Bugzilla_login',                              -value => $userid);            $cgi->send_cookie(-name => 'Bugzilla_logincookie',                              -value => $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::Login::WWW::CGI::Cookie;        my $authmethod = "Cookie";        ($authres, $userid, $extra) =          Bugzilla::Auth::Login::WWW::CGI::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) {        ThrowCodeError("auth_err",                       { authmethod => lc($authmethod),                         userid => $userid,                         auth_err_tag => $extra,                         info => $info                       });    }    # 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) {        # Redirect to SSL if required        if (Param('sslbase') ne '' and Param('ssl') ne 'never') {            $cgi->require_https(Param('sslbase'));        }            # Throw up the login page        print Bugzilla->cgi->header();        my $template = Bugzilla->template;        $template->process("account/auth/login.html.tmpl",                           { 'target' => $cgi->url(-relative=>1),                             'caneditaccount' => Bugzilla::Auth->can_edit('new'),                             'has_db' => Bugzilla::Auth->has_db,                           }                          )          || 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.        $dbh->do("DELETE FROM logincookies WHERE " .                 $dbh->sql_to_days('NOW()') . " - " .                 $dbh->sql_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_browser_cookies();        # 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 });}# This auth style allows the user to log out.sub can_logout { return 1; }# Logs user out, according to the option provided; this consists of# removing entries from logincookies for the specified $user.sub logout {    my ($class, $user, $option) = @_;    my $dbh = Bugzilla->dbh;    my $cgi = Bugzilla->cgi;    $option = LOGOUT_ALL unless defined $option;    if ($option == 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 $cookie;    foreach (@{$cgi->{'Bugzilla_cookie_list'}}) {        if ($_->name() eq 'Bugzilla_logincookie') {            $cookie = $_->value();            last;        }    }    $cookie ||= $cgi->cookie("Bugzilla_logincookie");    trick_taint($cookie);    # 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    if ($option == LOGOUT_KEEP_CURRENT) {        $dbh->do("DELETE FROM logincookies WHERE cookie != ? AND userid = ?",                 undef, $cookie, $user->id);    } elsif ($option == LOGOUT_CURRENT) {        $dbh->do("DELETE FROM logincookies WHERE cookie = ? AND userid = ?",                 undef, $cookie, $user->id);    } else {        die("Invalid option $option supplied to logout()");    }    if ($option != LOGOUT_KEEP_CURRENT) {        clear_browser_cookies();        Bugzilla->logout_request();    }}sub clear_browser_cookies {    my $cgi = Bugzilla->cgi;    $cgi->remove_cookie('Bugzilla_login');    $cgi->remove_cookie('Bugzilla_logincookie');}1;__END__=head1 NAMEBugzilla::Auth::Login::WWW::CGI - CGI-based logins for Bugzilla=head1 SUMMARYThis is a L<login module|Bugzilla::Auth/"LOGIN"> for Bugzilla. Users connectingfrom a CGI script use this module to authenticate. Logouts are also handled here.=head1 BEHAVIOURUsers 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, usingL<Bugzilla::Auth::Login::WWW::CGI::Cookie>.=head1 SEE ALSOL<Bugzilla::Auth>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -