[Melbourne-pm] Apache auth and one time passwords.
Rick Measham
rickm at isite.net.au
Wed Mar 9 20:10:07 PST 2005
Daniel Pittman wrote:
> I have a couple of web based systems that I would like to protect with a
> one time password tool, and being lazy, I want to use the work someone
> else has done to achieve this.
As you're the one who introduced me to perl-based apache authentication,
I feel I should reply :)
The attached solution is a simple hack on something I've done here at
work. Normally I select the user from the database. In this case, I
delete them. That way, if they exist I get a positive response from the
delete and I cache them so they can keep accessing the site until their
session expires (you'll notice I refresh the session on each request).
The solution does not rely on cookies, but instead relies on the browser
not forgetting it's auth details for the site :)
N.B. The attached code ran perfectly in my head, but has not been tested
on any other version of perl/apache.
Cheers!
Rick Measham
-------------- next part --------------
package Auth::OTP;
use strict;
use Apache::Constants qw(:common);
use Cache::FileCache;
use DBI;
require '/etc/httpd/lib/perl/config.pm';
my $DBH = DBI->connect(
$config::db_dsn,
$config::db_user,
$config::db_pass
) or die $DBI::errstr;
my $CACHE = Cache::FileCache->new({
namespace => 'namespace',
username => 'otp',
default_expires_in => $config::session_expire,
});
sub handler {
my $r = shift;
# get user's authentication credentials
my($res, $sent_pw) = $r->get_basic_auth_pw;
return $res if $res != OK;
my $user = $r->connection->user;
my $reason = authenticate($r, $user, $sent_pw);
if($reason) {
$r->note_basic_auth_failure;
$r->log_reason($reason, $r->filename);
return AUTH_REQUIRED;
}
return OK;
}
sub authenticate {
my ($r, $user, $password) = @_;
return 'No Database Connection' unless $DBH and $DBH->isa('DBI::db'); # No auth if we can't get to the DB!
# Check the cache for the user:
if ($user eq $CACHE->get($password)) {
$CACHE->set($password => $user);
return '';
}
my ($ok) = $dbh->do(sprintf(
"DELETE FROM OTP WHERE User=%s AND OTP=%s",
$dbh->quote($user),
$dbh->quote($password),
));
return ($dbh->errstr) if $dbh->errstr;
return ("Unknown user") unless $ok > 0;
$CACHE->set($password => $user);
return '';
}
1;
More information about the Melbourne-pm
mailing list