Updates to authentications cripts. userpage.pl is the page for authenticated
[koha.git] / C4 / Auth.pm
1 package C4::Auth;
2
3 use strict;
4 use Digest::MD5 qw(md5_base64);
5
6
7 require Exporter;
8 use C4::Database;
9
10 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
11
12 # set the version for version checking
13 $VERSION = 0.01;
14
15 @ISA = qw(Exporter);
16 @EXPORT = qw(
17              &checkauth
18 );
19
20
21
22 sub checkauth {
23     my $query=shift;
24     # $authnotrequired will be set for scripts which will run without authentication
25     my $authnotrequired=shift;
26     if (my $userid=$ENV{'REMOTE_USERNAME'}) {
27         # Using Basic Authentication, no cookies required
28         my $cookie=$query->cookie(-name => 'sessionID',
29                                   -value => '',
30                                   -expires => '+1y');
31         return ($userid, $cookie, '');
32     }
33     my $sessionID=$query->cookie('sessionID');
34     my $message='';
35
36     my $dbh=C4Connect();
37     my $sth=$dbh->prepare("select userid,ip,lasttime from sessions where sessionid=?");
38     $sth->execute($sessionID);
39     if ($sth->rows) {
40         my ($userid, $ip, $lasttime) = $sth->fetchrow;
41         if ($lasttime<time()-45 && $userid ne 'tonnesen') {
42             # timed logout
43             $message="You have been logged out due to inactivity.";
44             my $sti=$dbh->prepare("delete from sessions where sessionID=?");
45             $sti->execute($sessionID);
46             my $scriptname=$ENV{'SCRIPT_NAME'};
47             my $selfurl=$query->self_url();
48             $sti=$dbh->prepare("insert into sessionqueries (sessionID, userid, value) values (?, ?, ?)");
49             $sti->execute($sessionID, $userid, $selfurl);
50             open L, ">>/tmp/sessionlog";
51             my $time=localtime(time());
52             printf L "%20s from %16s logged out at %30s (inactivity).\n", $userid, $ip, $time;
53             close L;
54         } elsif ($ip ne $ENV{'REMOTE_ADDR'}) {
55             # Different ip than originally logged in from
56             my $newip=$ENV{'REMOTE_ADDR'};
57
58             $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)";
59         } else {
60             my $cookie=$query->cookie(-name => 'sessionID',
61                                       -value => $sessionID,
62                                       -expires => '+1y');
63             my $sti=$dbh->prepare("update sessions set lasttime=? where sessionID=?");
64             $sti->execute(time(), $sessionID);
65             return ($userid, $cookie, $sessionID);
66         }
67     }
68
69
70
71     if ($authnotrequired) {
72         my $cookie=$query->cookie(-name => 'sessionID',
73                                   -value => '',
74                                   -expires => '+1y');
75         return('', $cookie, '');
76     } else {
77         ($sessionID) || ($sessionID=int(rand()*100000).'-'.time());
78         my $userid=$query->param('userid');
79         my $password=$query->param('password');
80         if (checkpw($dbh, $userid, $password)) {
81             my $sti=$dbh->prepare("delete from sessions where sessionID=? and userid=?");
82             $sti->execute($sessionID, $userid);
83             $sti=$dbh->prepare("insert into sessions (sessionID, userid, ip,lasttime) values (?, ?, ?, ?)");
84             $sti->execute($sessionID, $userid, $ENV{'REMOTE_ADDR'}, time());
85             $sti=$dbh->prepare("select value from sessionqueries where sessionID=? and userid=?");
86             $sti->execute($sessionID, $userid);
87             if ($sti->rows) {
88                 my $stj=$dbh->prepare("delete from sessionqueries where sessionID=?");
89                 $stj->execute($sessionID);
90                 my ($selfurl) = $sti->fetchrow;
91                 print $query->redirect($selfurl);
92                 exit;
93             }
94             open L, ">>/tmp/sessionlog";
95             my $time=localtime(time());
96             printf L "%20s from %16s logged in  at %30s.\n", $userid, $ENV{'REMOTE_ADDR'}, $time;
97             close L;
98             my $cookie=$query->cookie(-name => 'sessionID',
99                                       -value => $sessionID,
100                                       -expires => '+1y');
101             return ($userid, $cookie, $sessionID);
102         } else {
103             if ($userid) {
104                 $message="Invalid userid or password entered.";
105             }
106             my $parameters;
107             foreach (param $query) {
108                 $parameters->{$_}=$query->{$_};
109             }
110             my $cookie=$query->cookie(-name => 'sessionID',
111                                       -value => $sessionID,
112                                       -expires => '+1y');
113             print $query->header(-cookie=>$cookie);
114             print qq|
115 <html>
116 <body background=/images/kohaback.jpg>
117 <center>
118 <h2>$message</h2>
119
120 <form method=post>
121 <table border=0 cellpadding=10 cellspacing=0 width=60%>
122     <tr><td align=center valign=top>
123
124     <table border=0 bgcolor=#dddddd cellpadding=10 cellspacing=0>
125     <tr><th colspan=2 background=/images/background-mem.gif><font size=+2>Koha Login</font></th></tr>
126     <tr><td>Name:</td><td><input name=userid></td></tr>
127     <tr><td>Password:</td><td><input type=password name=password></td></tr>
128     <tr><td colspan=2 align=center><input type=submit value=login></td></tr>
129     </table>
130     
131     </td><td align=center valign=top>
132
133     <table border=0 bgcolor=#dddddd cellpadding=10 cellspacing=0>
134     <tr><th background=/images/background-mem.gif><font size=+2>Demo Information</font></th></tr>
135     <td>
136     Log in as librarian/koha or patron/koha.  The timeout is set to 40 seconds of
137     inactivity for the purposes of this demo.  You can navigate to the Circulation
138     or Acquisitions modules and you should see an indicator in the upper left of
139     the screen saying who you are logged in as.  If you want to try it out with
140     a longer timout period, log in as tonnesen/koha and there will be no
141     timeout period.
142     <p>
143     You can also log in using a patron cardnumber.   Try V10000008 and
144     V1000002X with password koha.
145     </td>
146     </tr>
147     </table>
148     </td></tr>
149 </table>
150 </form>
151 </body>
152 </html>
153 |;
154             exit;
155         }
156     }
157 }
158
159
160 sub checkpw {
161
162 # This should be modified to allow a select of authentication schemes (ie LDAP)
163 # as well as local authentication through the borrowers tables passwd field
164 #
165     my ($dbh, $userid, $password) = @_;
166     my $sth=$dbh->prepare("select password from borrowers where userid=?");
167     $sth->execute($userid);
168     if ($sth->rows) {
169         my ($md5password) = $sth->fetchrow;
170         if (md5_base64($password) eq $md5password) {
171             return 1;
172         }
173     }
174     my $sth=$dbh->prepare("select password from borrowers where cardnumber=?");
175     $sth->execute($userid);
176     if ($sth->rows) {
177         my ($md5password) = $sth->fetchrow;
178         if (md5_base64($password) eq $md5password) {
179             return 1;
180         }
181     }
182     return 0;
183 }
184
185
186 END { }       # module clean-up code here (global destructor)