#!/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");
  }
}


syntax highlighted by Code2HTML, v. 0.9.1