Skip to content

Commit

Permalink
merging 1.2 and bugfixes for auth and login
Browse files Browse the repository at this point in the history
  • Loading branch information
tipaul committed Oct 10, 2002
1 parent c989c92 commit 9d31145
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 240 deletions.
344 changes: 178 additions & 166 deletions C4/Auth.pm
Expand Up @@ -116,146 +116,154 @@ has authenticated.
# table could be removed. # table could be removed.


sub checkauth { sub checkauth {
my $query=shift; my $query=shift;
# $authnotrequired will be set for scripts which will run without authentication # $authnotrequired will be set for scripts which will run without authentication
my $authnotrequired=shift; my $authnotrequired=shift;
if (my $userid=$ENV{'REMOTE_USERNAME'}) { if (my $userid=$ENV{'REMOTE_USERNAME'}) {
# Using Basic Authentication, no cookies required # Using Basic Authentication, no cookies required
my $cookie=$query->cookie(-name => 'sessionID', my $cookie=$query->cookie(-name => 'sessionID',
-value => '', -value => '',
-expires => '+1y'); -expires => '+1y');
return ($userid, $cookie, ''); return ($userid, $cookie, '');
}

# Get session ID from cookie.
my $sessionID=$query->cookie('sessionID');
# FIXME - Error-checking: if the user isn't allowing cookies,
# $sessionID will be undefined. Don't confuse this with an
# expired cookie.

my $message='';

# Make sure the session ID is (still) good.
my $dbh = C4::Context->dbh;
my $sth=$dbh->prepare("select userid,ip,lasttime from sessions where sessionid=?");
$sth->execute($sessionID);
if ($sth->rows) {
my ($userid, $ip, $lasttime) = $sth->fetchrow;
# FIXME - Back door for tonnensen
if ($lasttime<time()-45 && $userid ne 'tonnesen') {
# This session has been inactive for >45 seconds, and
# doesn't belong to user tonnensen. It has expired.
$message="You have been logged out due to inactivity.";

# Remove this session ID from the list of active sessions.
# FIXME - Ought to have a cron job clean this up as well.
my $sti=$dbh->prepare("delete from sessions where sessionID=?");
$sti->execute($sessionID);

# Add an entry to sessionqueries, so that we can restart
# the script once the user has authenticated.
my $scriptname=$ENV{'SCRIPT_NAME'}; # FIXME - Unused
my $selfurl=$query->self_url();
$sti=$dbh->prepare("insert into sessionqueries (sessionID, userid, value) values (?, ?, ?)");
$sti->execute($sessionID, $userid, $selfurl);

# Log the fact that someone tried to use an expired session ID.
# FIXME - Ought to have a better logging mechanism,
# ideally some wrapper that logs either to a
# user-specified file, or to syslog, as determined by
# either an entry in /etc/koha.conf, or a system
# preference.
open L, ">>/tmp/sessionlog";
my $time=localtime(time());
printf L "%20s from %16s logged out at %30s (inactivity).\n", $userid, $ip, $time;
close L;
} elsif ($ip ne $ENV{'REMOTE_ADDR'}) {
# This session is coming from an IP address other than the
# one where it was set. The user might be doing something
# naughty.
my $newip=$ENV{'REMOTE_ADDR'};

$message="ERROR ERROR ERROR ERROR<br>Attempt to re-use a cookie from a different ip address.<br>(authenticated from $ip, this request from $newip)";
} else {
# This appears to be a valid session. Update the time
# stamp on it and return.
my $cookie=$query->cookie(-name => 'sessionID',
-value => $sessionID,
-expires => '+1y');
my $sti=$dbh->prepare("update sessions set lasttime=? where sessionID=?");
$sti->execute(time(), $sessionID);
return ($userid, $cookie, $sessionID);
} }
} warn "passe 1";

# Get session ID from cookie.
# If we get this far, it's because we haven't received a cookie my $sessionID=$query->cookie('sessionID');
# with a valid session ID. Need to start a new session and set a warn "sessionId = $sessionID";
# new cookie. # FIXME - Error-checking: if the user isn't allowing cookies,

# $sessionID will be undefined. Don't confuse this with an
if ($authnotrequired) { # expired cookie.
# This script doesn't require the user to be logged in. Return
# just the cookie, without user ID or session ID information. my $message='';
my $cookie=$query->cookie(-name => 'sessionID',
-value => '', # Make sure the session ID is (still) good.
-expires => '+1y'); my $dbh = C4::Context->dbh;
return('', $cookie, ''); my $sth=$dbh->prepare("select userid,ip,lasttime from sessions where sessionid=?");
} else { $sth->execute($sessionID);
# This script requires authorization. Assume that we were if ($sth->rows) {
# given user and password information; generate a new session. warn "IF 1";

my ($userid, $ip, $lasttime) = $sth->fetchrow;
# Generate a new session ID. # FIXME - Back door for tonnensen
($sessionID) || ($sessionID=int(rand()*100000).'-'.time()); if ($lasttime<time()-45 && $userid ne 'tonnesen') {
my $userid=$query->param('userid'); # This session has been inactive for >45 seconds, and
my $password=$query->param('password'); # doesn't belong to user tonnensen. It has expired.
if (checkpw($dbh, $userid, $password)) { $message="You have been logged out due to inactivity.";
# The given password is valid

# Remove this session ID from the list of active sessions.
# Delete any old copies of this session. # FIXME - Ought to have a cron job clean this up as well.
my $sti=$dbh->prepare("delete from sessions where sessionID=? and userid=?"); my $sti=$dbh->prepare("delete from sessions where sessionID=?");
$sti->execute($sessionID, $userid); $sti->execute($sessionID);


# Add this new session to the 'sessions' table. # Add an entry to sessionqueries, so that we can restart
$sti=$dbh->prepare("insert into sessions (sessionID, userid, ip,lasttime) values (?, ?, ?, ?)"); # the script once the user has authenticated.
$sti->execute($sessionID, $userid, $ENV{'REMOTE_ADDR'}, time()); my $scriptname=$ENV{'SCRIPT_NAME'}; # FIXME - Unused

my $selfurl=$query->self_url();
# See if there's an entry for this session ID and user in $sti=$dbh->prepare("insert into sessionqueries (sessionID, userid, value) values (?, ?, ?)");
# the 'sessionqueries' table. If so, then use that entry $sti->execute($sessionID, $userid, $selfurl);
# to generate an HTTP redirect that'll take the user to
# where ve wanted to go in the first place. # Log the fact that someone tried to use an expired session ID.
$sti=$dbh->prepare("select value from sessionqueries where sessionID=? and userid=?"); # FIXME - Ought to have a better logging mechanism,
# FIXME - There is no sessionqueries.value # ideally some wrapper that logs either to a
$sti->execute($sessionID, $userid); # user-specified file, or to syslog, as determined by
if ($sti->rows) { # either an entry in /etc/koha.conf, or a system
my $stj=$dbh->prepare("delete from sessionqueries where sessionID=?"); # preference.
$stj->execute($sessionID); open L, ">>/tmp/sessionlog";
my ($selfurl) = $sti->fetchrow; my $time=localtime(time());
print $query->redirect($selfurl); printf L "%20s from %16s logged out at %30s (inactivity).\n", $userid, $ip, $time;
exit; close L;
} } elsif ($ip ne $ENV{'REMOTE_ADDR'}) {
open L, ">>/tmp/sessionlog"; warn "ELSE1";
my $time=localtime(time()); # This session is coming from an IP address other than the
printf L "%20s from %16s logged in at %30s.\n", $userid, $ENV{'REMOTE_ADDR'}, $time; # one where it was set. The user might be doing something
close L; # naughty.
my $cookie=$query->cookie(-name => 'sessionID', my $newip=$ENV{'REMOTE_ADDR'};
-value => $sessionID,
-expires => '+1y'); $message="ERROR ERROR ERROR ERROR<br>Attempt to re-use a cookie from a different ip address.<br>(authenticated from $ip, this request from $newip)";
return ($userid, $cookie, $sessionID); } else {
warn "ELSE2";
# This appears to be a valid session. Update the time
# stamp on it and return.
my $cookie=$query->cookie(-name => 'sessionID',
-value => $sessionID,
-expires => '+1y');
my $sti=$dbh->prepare("update sessions set lasttime=? where sessionID=?");
$sti->execute(time(), $sessionID);
return ($userid, $cookie, $sessionID);
}
}
warn "AFTER";
# If we get this far, it's because we haven't received a cookie
# with a valid session ID. Need to start a new session and set a
# new cookie.

if ($authnotrequired) {
warn "authnotrequired";
# This script doesn't require the user to be logged in. Return
# just the cookie, without user ID or session ID information.
my $cookie=$query->cookie(-name => 'sessionID',
-value => '',
-expires => '+1y');
return('', $cookie, '');
} else { } else {
# Either we weren't given a user id and password, or else warn "ELSE3";
# the password was invalid. # This script requires authorization. Assume that we were

# given user and password information; generate a new session.
if ($userid) {
$message="Invalid userid or password entered."; # Generate a new session ID.
} ($sessionID) || ($sessionID=int(rand()*100000).'-'.time());
my $parameters; my $userid=$query->param('userid');
foreach (param $query) { my $password=$query->param('password');
$parameters->{$_}=$query->{$_}; warn "calling checkpw";
} if (checkpw($dbh, $userid, $password)) {
my $cookie=$query->cookie(-name => 'sessionID', # The given password is valid
-value => $sessionID, warn "VALID";
-expires => '+1y'); # Delete any old copies of this session.
print $query->header(-cookie=>$cookie); my $sti=$dbh->prepare("delete from sessions where sessionID=? and userid=?");
print qq| $sti->execute($sessionID, $userid);

# Add this new session to the 'sessions' table.
$sti=$dbh->prepare("insert into sessions (sessionID, userid, ip,lasttime) values (?, ?, ?, ?)");
$sti->execute($sessionID, $userid, $ENV{'REMOTE_ADDR'}, time());

# See if there's an entry for this session ID and user in
# the 'sessionqueries' table. If so, then use that entry
# to generate an HTTP redirect that'll take the user to
# where ve wanted to go in the first place.
$sti=$dbh->prepare("select value from sessionqueries where sessionID=? and userid=?");
# FIXME - There is no sessionqueries.value
$sti->execute($sessionID, $userid);
if ($sti->rows) {
my $stj=$dbh->prepare("delete from sessionqueries where sessionID=?");
$stj->execute($sessionID);
my ($selfurl) = $sti->fetchrow;
print $query->redirect($selfurl);
exit;
}
open L, ">>/tmp/sessionlog";
my $time=localtime(time());
printf L "%20s from %16s logged in at %30s.\n", $userid, $ENV{'REMOTE_ADDR'}, $time;
close L;
my $cookie=$query->cookie(-name => 'sessionID',
-value => $sessionID,
-expires => '+1y');
return ($userid, $cookie, $sessionID);
} else {
# Either we weren't given a user id and password, or else
# the password was invalid.
warn "INVALID";
if ($userid) {
$message="Invalid userid or password entered.";
}
my $parameters;
foreach (param $query) {
$parameters->{$_}=$query->{$_};
}
my $cookie=$query->cookie(-name => 'sessionID',
-value => $sessionID,
-expires => '+1y');
return ("",$cookie,$sessionID);
print $query->header(-cookie=>$cookie);
print qq|
<html> <html>
<body background=/images/kohaback.jpg> <body background=/images/kohaback.jpg>
<center> <center>
Expand All @@ -271,7 +279,7 @@ sub checkauth {
<tr><td>Password:</td><td><input type=password name=password></td></tr> <tr><td>Password:</td><td><input type=password name=password></td></tr>
<tr><td colspan=2 align=center><input type=submit value=login></td></tr> <tr><td colspan=2 align=center><input type=submit value=login></td></tr>
</table> </table>
</td><td align=center valign=top> </td><td align=center valign=top>
<table border=0 bgcolor=#dddddd cellpadding=10 cellspacing=0> <table border=0 bgcolor=#dddddd cellpadding=10 cellspacing=0>
Expand All @@ -295,9 +303,9 @@ sub checkauth {
</body> </body>
</html> </html>
|; |;
exit; exit;
}
} }
}
} }


# checkpw # checkpw
Expand All @@ -307,33 +315,37 @@ sub checkauth {
# Returns 1 if the password is good, or 0 otherwise. # Returns 1 if the password is good, or 0 otherwise.
sub checkpw { sub checkpw {


# This should be modified to allow a select of authentication schemes (ie LDAP) # This should be modified to allow a select of authentication schemes (ie LDAP)
# as well as local authentication through the borrowers tables passwd field # as well as local authentication through the borrowers tables passwd field
# #
my ($dbh, $userid, $password) = @_; my ($dbh, $userid, $password) = @_;
my $sth; my $sth;


# Try the user ID. # Try the user ID.
$sth = $dbh->prepare("select password from borrowers where userid=?"); $sth = $dbh->prepare("select password from borrowers where userid=?");
$sth->execute($userid); $sth->execute($userid);
if ($sth->rows) { if ($sth->rows) {
my ($md5password) = $sth->fetchrow; my ($md5password) = $sth->fetchrow;
if (md5_base64($password) eq $md5password) { if (md5_base64($password) eq $md5password) {
return 1; # The password matches return 1; # The password matches
}
}

# Try the card number.
$sth = $dbh->prepare("select password from borrowers where cardnumber=?");
$sth->execute($userid);
if ($sth->rows) {
my ($md5password) = $sth->fetchrow;
if (md5_base64($password) eq $md5password) {
return 1; # The password matches
}
} }
} if ($userid eq C4::Context->config('user') && $password eq C4::Context->config('pass')) {

# Koha superuser account
# Try the card number. return 2;
$sth = $dbh->prepare("select password from borrowers where cardnumber=?");
$sth->execute($userid);
if ($sth->rows) {
my ($md5password) = $sth->fetchrow;
if (md5_base64($password) eq $md5password) {
return 1; # The password matches
} }
} return 0; # Either there's no such user, or the password
return 0; # Either there's no such user, or the password # doesn't match.
# doesn't match.
} }




Expand Down

0 comments on commit 9d31145

Please sign in to comment.