#!/usr/bin/perl
#
# Copyright 2007-2009 Kees Cook <kees@outflux.net>
# License: GPLv3
#
#
package SQL_Good;
use base 'CGI::Application';
use strict;
use warnings;
use CGI qw/:standard/;
use DBI;

sub setup {
    my $self = shift;
    $self->start_mode('get_password');
    $self->run_modes(
        'get_password' => 'do_get_password',
        'check_password' => 'do_check_password',
    );

    $self->{'dbh'} = DBI->connect("dbi:SQLite:./sql-demo.dbl");
    $self->{'dbh'}->do("PRAGMA synchronous = ON") if ($self->{'dbh'});
}

sub teardown {
    my $self = shift;

    $self->{'dbh'}->disconnect if ($self->{'dbh'});
}

sub do_get_password
{
    my $self = shift;
    my $output = '';
    my $q = $self->query();

    my $title = "Enter Password";
    $output .= $q->start_html(-title => $title );
    $output .= $q->h1($title)."\n";
    $output .= $q->start_form();
    # This really should be $q->password_field, but this is a demo...
    $output .= $q->textfield(-name => 'password', -size => 50);
    $output .= $q->hidden(-name => 'rm', -value => 'check_password');
    $output .= $q->submit(-name => 'Get Secret');
    $output .= $q->end_form();
    $output .= $q->end_html();

    return $output;
}

sub do_check_password
{
    my $self = shift;
    my $output = '';
    my $q = $self->query();

    my $password = $q->param("password");

    my $query = $self->{'dbh'}->prepare(
        "SELECT secret FROM users
         WHERE password = ?");
    $query->execute($password);
    my $report = $query->fetchrow_hashref;

    my $secret = $report->{'secret'};

    if (defined($secret)) {
        my $title = "Authenticated";
        $output .= $q->start_html(-title => $title );
        $output .= $q->h1($title)."\n";
        $output .= "Your secret is '".escapeHTML($secret)."'!";
    }
    else {
        my $title = "Bad Password";
        $output .= $q->start_html(-title => $title );
        $output .= $q->h1($title)."\n";
        # Good software should not print out password attempts...
        $output .= "Your password '".escapeHTML($password)."' was invalid!";
    }

    $output .= $q->end_html();
    return $output;
}

package main;
use strict;
use warnings;

my $webapp = SQL_Good->new();
$webapp->run();
