Bug 20122 - Bugzilla requires new login if IP changes

r=joel x2
parent 52aac68c
......@@ -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();
......
......@@ -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;
......
......@@ -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>
......@@ -71,8 +69,23 @@
<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"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment