]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 20122 - Bugzilla requires new login if IP changes
authorbbaetz%student.usyd.edu.au <>
Wed, 2 Oct 2002 18:57:23 +0000 (18:57 +0000)
committerbbaetz%student.usyd.edu.au <>
Wed, 2 Oct 2002 18:57:23 +0000 (18:57 +0000)
r=joel x2

CGI.pl
defparams.pl
template/en/default/account/login.html.tmpl

diff --git a/CGI.pl b/CGI.pl
index f4a9813f03a9954d9fe2a2159717ae6c63136808..1e534b384025aa1b5374ca9cd70ff2a7343b2703 100644 (file)
--- a/CGI.pl
+++ b/CGI.pl
@@ -412,12 +412,31 @@ sub PasswordForLogin {
     return $result;
 }
 
+sub get_netaddr {
+    my ($ipaddr) = @_;
+
+    # Check for a valid IPv4 addr which we know how to parse
+    if ($ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+        return undef;
+    }
+
+    my $addr = unpack("N", pack("CCCC", split(/\./, $ipaddr)));
+
+    my $maskbits = Param('loginnetmask');
+
+    $addr >>= (32-$maskbits);
+    $addr <<= (32-$maskbits);
+    return join(".", unpack("CCCC", pack("N", $addr)));
+}
+
 sub quietly_check_login() {
     $::disabledreason = '';
     my $userid = 0;
+    my $ipaddr = $ENV{'REMOTE_ADDR'};
+    my $netaddr = get_netaddr($ipaddr);
     if (defined $::COOKIE{"Bugzilla_login"} &&
         defined $::COOKIE{"Bugzilla_logincookie"}) {
-        SendSQL("SELECT profiles.userid," .
+        my $query = "SELECT profiles.userid," .
                 " profiles.login_name, " .
                 " profiles.disabledtext " .
                 " FROM profiles, logincookies WHERE logincookies.cookie = " .
@@ -425,8 +444,14 @@ sub quietly_check_login() {
                 " AND profiles.userid = logincookies.userid AND" .
                 " profiles.login_name = " .
                 SqlQuote($::COOKIE{"Bugzilla_login"}) .
-                " AND logincookies.ipaddr = " .
-                SqlQuote($ENV{"REMOTE_ADDR"}));
+                " AND (logincookies.ipaddr = " .
+                SqlQuote($ipaddr);
+        if (defined $netaddr) {
+            $query .= " OR logincookies.ipaddr = " . SqlQuote($netaddr);
+        }
+        $query .= ")";
+        SendSQL($query);
+
         my @row;
         if (MoreSQLData()) {
             ($userid, my $loginname, my $disabledtext) = FetchSQLData();
@@ -728,7 +753,16 @@ sub confirm_login {
      # the cookies.
      if($enteredlogin ne "") {
        $::COOKIE{"Bugzilla_login"} = $enteredlogin;
-       SendSQL("insert into logincookies (userid,ipaddr) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($ENV{'REMOTE_ADDR'})]})");
+       my $ipaddr = $ENV{'REMOTE_ADDR'};
+
+       # Unless we're restricting the login, or restricting would have no
+       # effect, loosen the IP which we record in the table
+       unless ($::FORM{'Bugzilla_restrictlogin'} ||
+               Param('loginnetmask') == 32) {
+           $ipaddr = get_netaddr($ipaddr);
+           $ipaddr = $ENV{'REMOTE_ADDR'} unless defined $ipaddr;
+       }
+       SendSQL("insert into logincookies (userid,ipaddr) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($ipaddr)]})");
        SendSQL("select LAST_INSERT_ID()");
        my $logincookie = FetchOneColumn();
 
index 8e931006febb9a152be0a5011a89554a079e8015..232b6c346569b2f801657d13ec4d6a8444afffff 100644 (file)
@@ -111,6 +111,21 @@ sub check_webdotbase {
     return "";
 }
 
+sub check_netmask {
+    my ($mask) = @_;
+    my $res = check_numeric($mask);
+    return $res if $res;
+    if ($mask < 0 || $mask > 32) {
+        return "an IPv4 netmask must be between 0 and 32 bits";
+    }
+    # Note that if we changed the netmask from anything apart from 32, then
+    # existing logincookies which aren't for a single IP won't work
+    # any more. We can't know which ones they are, though, so they'll just
+    # take space until they're preiodically cleared, later.
+
+    return "";
+}
+
 # OK, here are the parameter definitions themselves.
 #
 # Each definition is a hash with keys:
@@ -845,6 +860,17 @@ Reason: %reason%
    type => 't',
    default => ''
   },
+
+  {
+   name => 'loginnetmask',
+   desc => 'The number of bits for the netmask used if a user chooses to ' .
+           'allow a login to be valid for more than a single IP. Setting ' .
+           'this to 32 disables this feature.<br>' .
+           'Note that enabling this may decrease the security of your system.',
+   type => 't',
+   default => '32',
+   checker => \&check_netmask
+  },
 );
 
 1;
index 29b5b1aee22b57c9cdd1d64c9767da6ffc1d33f7..16a49580f4f2455ebcf33a71570e7ec057738397 100644 (file)
@@ -38,8 +38,8 @@
 
 <form action="[% target %]" method="POST">
   <table>
-    [% IF Param("useLDAP") %]
-      <tr>
+    <tr>
+      [% IF Param("useLDAP") %]
         <td align="right">
           <b>Username:</b>
         </td>
@@ -54,9 +54,7 @@
         <td>
           <input type="password" size="10" name="LDAP_password">
         </td>
-      </tr>
-    [% ELSE %]
-      <tr>
+      [% ELSE %]
         <td align="right">
           <b>E-mail address:</b>
         </td>
         <td>
           <input type="password" size="35" name="Bugzilla_password">
         </td>
+      [% END %]
+    [% IF Param('loginnetmask') < 32 %]
+      <tr>
+        <td align="right">
+          <b>
+             Restrict this session<br>
+             to this IP address:
+          </b>
+        </td>
+        <td>
+          <input type="checkbox" name="Bugzilla_restrictlogin"
+                 checked="checked">
+          (Using this option increases security)
+        </td>
       </tr>
     [% END %]
+    </tr>
   </table>
   
   [% PROCESS "global/hidden-fields.html.tmpl"