Apache-AppSamurai
view release on metacpan or search on metacpan
lib/Apache/AppSamurai.pm view on Meta::CPAN
sub handle_cache {
my ($self, $r) = @_;
my $auth_name = $r->auth_name;
return unless $auth_name;
unless ($r->dir_config("${auth_name}Cache")) {
$r->no_cache(1);
if (!$r->headers_out->{'Pragma'}) {
$r->err_headers_out->{'Pragma'} = 'no-cache';
}
}
}
# Backdate cookie to attempt to clear from web browser cookie store
sub remove_cookie {
my ($self, $r) = @_;
my $cookie_name = $self->cookie_name($r);
my $str = $self->cookie_string( request => $r,
key => $cookie_name,
value => '',
expires => 'Mon, 21-May-1971 00:00:00 GMT' );
$r->err_headers_out->add("Set-Cookie" => "$str");
$self->Log($r, ('debug', "remove_cookie(): removed_cookie \"$cookie_name\""));
}
# Convert current POST request to GET
# Note - The use of this is questionable now that Apache::Request is being
# used. May go away in the future.
sub _convert_to_get {
my ($self, $r) = @_;
return unless $r->method eq 'POST';
$self->Log($r, ('debug', "Converting POST -> GET"));
# Use Apache::Request for immediate access to all arguments.
my $ar = ($MP eq 1) ?
Apache::Request->instance($r) :
Apache2::Request->new($r);
# Pull list if GET and POST args
my @params = $ar->param;
my ($name, @values, $value);
my @pairs = ();
foreach $name (@params) {
# we don't want to copy login data, only extra data.
$name =~ /^(destination|credential_\d+)$/ and next;
# Pull list of values for this key
@values = $ar->param($name);
# Make sure there is at least one value, which can be empty
(scalar(@values)) or ($values[0] = '');
foreach $value (@values) {
if ($MP eq 1) {
push(@pairs, Apache::Util::escape_uri($name) . '=' .
Apache::Util::escape_uri($value));
} else {
# Assume mod_perl 2 behaviour
push(@pairs, Apache2::Util::escape_path($name, $r->pool) .
'=' . Apache2::Util::escape_path($value, $r->pool));
}
}
}
$r->args(join '&', @pairs) if scalar(@pairs) > 0;
$r->method('GET');
$r->method_number(M_GET);
$r->headers_in->unset('Content-Length');
}
# Handle regular (form based) login
sub login_mp1 ($$) { &login_real }
sub login_mp2 : method { &login_real }
*login = ($MP eq 1) ? \&login_mp1 : \&login_mp2;
sub login_real {
my ($self, $r) = @_;
my ($auth_type, $auth_name) = ($r->auth_type, $r->auth_name);
# Use the magic of Apache::Request to ditch POST handling code
# and cut to the args.
my $ar = ($MP eq 1) ?
Apache::Request->instance($r) :
Apache2::Request->new($r);
my ($ses_key, $tc, $destination, $nonce, $sig, $serverkey);
my @credentials = ();
# Get the hard set destination, or setup to just reload
if ($r->dir_config("${auth_name}LoginDestination")) {
$destination = $r->dir_config("${auth_name}LoginDestination");
} elsif ($ar->param("destination")) {
$destination = $ar->param("destination");
} else {
# Someday something slick could hold the URL, then cut through
# to it. Someday. Today we die.
$self->Log($r, ('warn', "No key 'destination' found in form data"));
$r->subprocess_env('AuthCookieReason', 'no_cookie');
return $auth_type->login_form($r);
}
# Check form nonce and signature
if (defined($ar->param("nonce")) and defined($ar->param("sig"))) {
unless (($nonce = CheckSidFormat($ar->param("nonce"))) and
($sig = CheckSidFormat($ar->param("sig")))) {
$self->Log($r, ('warn', "Missing/invalid form nonce or sig"));
$r->subprocess_env('AuthCookieReason', 'no_cookie');
$r->err_headers_out->{'Location'} = $self->URLErrorCode($destination, 'bad_credentials');
$r->status(REDIRECT);
return REDIRECT;
}
$serverkey = $self->GetServerKey($r) or die("FATAL: Could not fetch valid server key\n");
# Now check!
unless ($sig eq ComputeSessionId($nonce, $serverkey)) {
# Failed!
$self->Log($r, ('warn', "Bad signature on posted form (Possible scripted attack)"));
$r->subprocess_env('AuthCookieReason', 'no_cookie');
( run in 1.171 second using v1.01-cache-2.11-cpan-df04353d9ac )