#!/usr/local/bin/perl -w BEGIN { our $no_session_check = 1; require "preface.pl"; } use OTP qw(authenticate challenge); if (!param('userid')) { #stage 1, user must supply his login print header; $template->process("login.html", {title => "Login", stage => 1}) || die $template->error(); } else { if (!param('pass')) { #stage 2, user sees the challenge and supplies his password my $sth = $conn->prepare("SELECT runs, seed FROM web_otp WHERE user_id = '" . param('userid') . "'") || die $conn->errstr; $sth->execute() || die $sth->errstr; my ($runs, $seed) = $sth->fetchrow(); $sth->finish(); die "no otp-infos for " . param("userid") unless $runs && $seed; print header; $template->process("login.html", {title => "Login", stage => 2, userid => param("userid"), challenge => challenge($runs, $seed)}) || die $template->error(); } else { #stage 3, password is verified and Pronto WebMail is loaded my $sth = $conn->prepare("SELECT last_otp FROM web_otp WHERE user_id = '" . param('userid') . "'") || die $conn->errstr; $sth->execute() || die $sth->errstr; my ($last_pass) = $sth->fetchrow(); $sth->finish(); die "no last otp for " . param("userid") unless $last_pass; my $pass = authenticate(param('pass'), $last_pass); die "I was unable to authenticate you!" unless $pass; my $sql = "UPDATE web_otp SET last_otp = '$pass', runs = runs - 1 WHERE user_id = '" . param("userid") . "'"; $conn->do($sql) || die $conn->errstr; $sql = "DELETE FROM web_session WHERE user_id = '" . param("userid") . "'"; $conn->do($sql) || die $conn->errstr; my $session = int(rand(1000000000)); $sql = "INSERT INTO web_session (user_id, session, valid_till) " . "VALUES ('" . param("userid") . "', $session, " . (time() + $session_timeout) . ")"; $conn->do($sql) || die $conn->errstr; print redirect("/cgi-bin/frames.pl?session=$session"); } }