Apache-AutoLogin
view release on metacpan or search on metacpan
AutoLogin.pm view on Meta::CPAN
# Else write the credentials within the cookie into the http header
else {
# But only if there IS something in the cookie!
if ($decrypted_string ne '' and $c_user ne '' and $c_password ne '') {
my $credentials=MIME::Base64::encode(join(":",$c_user,$c_password));
$r->headers_in->set(Authorization => "Basic $credentials");
}
}
# Return DECLINED
return DECLINED;
}
## sets the cookie
sub setCookie {
my ($r,$user,$password,$client_identifier,$cookie_lifetime,$encryption_key)=@_;
my $auth_name=$r->dir_config('AutoLoginAuthName');
my $log=$r->server->log;
my $auth_cookie = Apache::Cookie->new ($r,
-name => $auth_name,
-value => {Basic => encode_base64(encrypt_aes(join (":",$user,$password,$client_identifier,(time()+60*60*24*$cookie_lifetime)),$encryption_key))},
-path => "/",
-expires => "+".$cookie_lifetime."d"
);
$auth_cookie->bake;
}
sub encrypt_aes {
my ($string, $key)=@_;
# keysize() is 32, but 24 and 16 are also possible
# blocksize() is 16
# So we fill the string with some random data to the next 16 byte boundary.
# Like this we have a valid block size AND oracle attacks get very difficult.
my $fillup=16-(length($string) % 16);
if ($fillup==0)
{
$fillup=16;
}
# The : is the boundary of the random data.
$string=$string . ":";
--$fillup;
while ($fillup>0)
{
$string.=int(rand(10));
--$fillup;
}
## a a md5_hex checksum to the string.
$string.=md5_hex($string);
my $cipher = new Crypt::Rijndael $key, Crypt::Rijndael::MODE_CBC;
# encrypt the string.
$string=$cipher->encrypt($string);
return $string;
}
sub decrypt_aes {
my ($string, $key)=@_;
# keysize() is 32, but 24 and 16 are also possible
# blocksize() is 16
## The string must have 16 bytes blocks.
if (length($string) % 16 !=0)
{
return "";
}
my $cipher = new Crypt::Rijndael $key, Crypt::Rijndael::MODE_CBC;
# decrypt it
my $decrypted=$cipher->decrypt($string);
# Chop of the last 32 bytes (this is the md5 checksum)
# and calculate checksum
## Check if the string is longer than 32 bytes
if (length ($decrypted)<32)
{
return "";
}
## Alter the string (chop of the last 32 bytes
my $checksum=substr($decrypted,-32);
$decrypted=substr($decrypted,0,(length($decrypted)-32));
## If the checksum is invalid return this
if ($checksum ne md5_hex($decrypted))
{
return "";
}
## chop of the random data
my $char=" ";
while($char ne ':' and $char ne '')
{
$char=chop($decrypted);
}
## If char is eq to '' then there were no credentials, etc. in the string...
if ($char eq '')
{
return '';
}
return $decrypted;
}
1;
__END__
# Below is stub documentation for your module. You better edit it!
=head1 NAME
Apache::AutoLogin - Automatic login module based on encrypted cookies for sites using basic authentication.
=head1 SYNOPSIS
# In httpd.conf or .htaccess put it just
# before your basic authentication module
# It has the be invoked as a PerlAccessHandler,
# because this is just the phase
# before authentication!
<Location />
PerlModule Apache::AutoLogin
PerlAccessHandler Apache::AutoLogin
( run in 1.378 second using v1.01-cache-2.11-cpan-e1769b4cff6 )