This is irking me.

$state preserves information about the request and so on.  Now,
$r->whatever_method works just fine.. EXCEPT for sending headers.  When I
visit my site, I get my nifty login page, and that is all.  Always the login
page.

I telnetted into the thing to see what kinds of cookie strings I was getting
back and... NO HEADERS!  No Content-type: 's or nothing.

$r->send_http_header; must be broken, eh?  How to fix?? =P

I'll spare all of your eyes by not sending complete source, but here's the
basic idea.


#!/usr/bin/perl

package RequestHandler;
use strict;

# snipped out a lot of use vars qw();'s and $val = blah.

sub handler {
        my $r = shift;
        my $result = undef;

        eval { $result = inner_handler($r) };
        return $result unless $@;

        warn "Uncaught Exception: $@";

        return SERVER_ERROR;
}

sub inner_handler {
        my $r = shift;

        my %q = ($r->args, $r->content);
        my %state = (r => $r, q => \%q);

        $state{login_user} = '';
        $state{login_pass} = '';
        $state{title} = '';
        $state{template} = '';
        $state{auth_status} = password_boxes(\%state);

        validate_auth_cookie(\%state);

        my $function = $r->uri;
        $function = '/login.html' if $state{login_user} eq '';
        my $func = $Dispatch{$function} || $Dispatch{DEFAULT};

        return $func->(\%state);
}

sub output_html {
        my $state = shift;
        my %args = @_;
        my $title = $state->{title};
        my $r = $state->{r};

        $r->status(200);

        my $template = HTML::Template->new(
                filename                =>
"$Template_Dir/$state->{template}",
                die_on_bad_params       => 0,
        );

        $template->param(TITLE => $title);
        eval { foreach (keys %args) {
                $template->param($_ => $args{$_});
        }};
        $template->param(ERRORS => $@) if $@;

        $r->header_out( 'Set-Cookie' => $state->{cookie_out} ) if
$state->{cookie_out};
        $r->send_http_header('text/html');
        print $template->output();
}

sub get_password {
        my $state = shift;

        my $row = $Sql->select_hashref('DECODE(PWORD,\'blah\')', 'techs',
"TECH=\"$state->{
q}->{login_user}\"");
        return $row->{"DECODE(PWORD,'blah')"};
}

sub build_auth_string {
        my $state = shift;
        my $ip = shift || $ENV{REMOTE_ADDR};
        my $time = shift || time;

        my $login = $state->{login_user};
        my $password = $state->{login_pass};
        my $val = join "::", $login, $ip, $password, $time;

        # Iterate thru by 8 byte hunks.
        # with the added 8 spaces, do not do the last hunk
        # which will be all spaces
        my $blown;
        my $pos;
        for ( $pos = 0;  (($pos + 8) < length($val) ) ; $pos+=8 ) {
                $blown .= $cipher->encrypt(substr($val, $pos, 8));
                # encrypt this without temp vars
        }

        my $enc  = encode_base64($blown,"");

        $enc;
}

sub parse_auth_string {
        my $state  = shift;
        my $cookie = shift;

        return unless $cookie;
        return if $cookie =~ /logged_out/;

        my $unenc= decode_base64($cookie);
        my $unblown;

        # start at 8, take 8 bytes at a time
        # $unenc should be exactly a multiple of 8 bytes.

        my $pos;
        for ( $pos = 0; $pos<length($unenc); $pos += 8) {
                $unblown .= $cipher->decrypt(substr($unenc, $pos, 8));
        }
        my ($login, $ip, $password, $time)=split ( /::/, $unblown, 4);
}

sub get_auth_cookie {
        my $state=shift;
        my $cookie = TTMSCGI->parse_cookie($ENV{HTTP_COOKIE})->{ttms_user};
        my($login, $ip, $password, $time) = parse_auth_string($state,
$cookie);
        ($login, $ip, $password, $time);
}

sub set_auth_cookie {
        my $state = shift;

        my $val = build_auth_string($state);
        my $c = TTMSCGI->build_cookie(
                name    => 'ttms_user',
                value   => $val,
                expires => time + 86400*30*7,
                domain  => $Cookie_Domain,
                path    => '/',
        );
        $state->{cookie_out} = $c;
}

sub build_logout_cookie {
        TTMSCGI->build_cookie(
                name   => 'ttms_user',
                value  => "logged_out",
                expires=> time - 86400,
                domain => $Cookie_Domain,
                path   => '/'
        );
}

sub set_logout_cookie {
        my $state = shift;
        $state->{cookie_out} = build_logout_cookie($state);
}

sub validate_auth_cookie {
        my $state = shift;
        my ($login, $ip, $pass, $time) = get_auth_cookie($state);
        return unless $login && $pass;

        my $checkpass = get_password($state);
        if ($pass eq $checkpass) {
                $state->{login_user} = $login;
                $state->{login_pass} = $pass;
                $state->{auth_status} = "Logged in as $state->{login_user}";
                return;
        }
        return;
}

Reply via email to