Apache-AutoLogin

 view release on metacpan or  search on metacpan

AutoLogin.pm  view on Meta::CPAN

package Apache::AutoLogin;

use 5.006;
use strict;
use warnings;

use Apache::Constants qw(OK DECLINED SERVER_ERROR);
use Crypt::Rijndael;
use MIME::Base64;
use Digest::MD5 qw(md5_hex md5);
use Apache::Cookie;
use Apache::Request;
use Apache::Log;

our $VERSION = '0.1';


## This is the handler that gets called by mod_perl

sub handler {
    

AutoLogin.pm  view on Meta::CPAN

    $r->no_cache(1);
    
    ## Get some information on the client as the IP, the User-Agent and the host name.
    my $conn=$r->connection;
    my $client_identifier=$conn->remote_ip;
    $client_identifier=$client_identifier."-".md5_hex($r->headers_in->get('User-Agent')).
                "-".md5_hex($r->headers_in->get('Host'));
    
    ## Now read the configuration variable from the httpd.conf
    
    my $cookie_lifetime=$r->dir_config('AutoLoginCookieLifetimeInDays');
    my $encryption_key=$r->dir_config('AutoLoginEncryptionKey');
    my $logout_uri=$r->dir_config('AutoLoginLogoutPage');
    my $auth_name=$r->dir_config('AutoLoginAuthName');
    
    ## lets make an md5 hash out of the encryption key.
    ## This should make things more secure
    
    $encryption_key=md5($encryption_key).md5($encryption_key.md5($encryption_key));
    
    ## enable logging to apache's error log

AutoLogin.pm  view on Meta::CPAN

    if (defined $auth_header)
    {
        $credentials =(split / /, $auth_header)[-1];
        ($user, $password) = split /:/, MIME::Base64::decode($credentials),2;
    }
    
    $log->info("header $user from $client_identifier");
    
    # Look for any cookies
    
    my %cookiejar = Apache::Cookie->new($r)->parse;
    
    
    ## If the user has called the predefined logout page,
    ## invalidate the cookie
    if ($r->uri() eq $logout_uri)
    {
        $log->info("User from $client_identifier logged out (".$r->uri().")");
        
        my $i=0;
        my $temp_key="";

AutoLogin.pm  view on Meta::CPAN

        my $temp_key3="";
        
        while ($i<32)
        {
            $temp_key.=int(rand(10));
            $temp_key2.=int(rand(10));
            $temp_key3.=int(rand(10));
            ++$i;
        }
        
        setCookie($r,$temp_key2,$temp_key3,0,1,$temp_key);
       
        $r->uri($logout_uri);
        return OK;
    }
    
    # If there is no cookie at all, generate one
    
    unless ($cookiejar{$auth_name}) {
        
        $log->info("Client $client_identifier has no cookie");
    
        setCookie($r,$user,$password,$client_identifier,$cookie_lifetime,$encryption_key);
        
        # DECLINED zur?ckgeben, damit Apache weitermacht.
        return DECLINED;
    }
    
        
    # Get the credentials out of the cookie
    
    my %auth_cookie=$cookiejar{$auth_name}->value;
    my $decrypted_string=decrypt_aes(decode_base64($auth_cookie{Basic}),$encryption_key);

AutoLogin.pm  view on Meta::CPAN

    if ($decrypted_string ne '')
    {
        $log->info("Data from cookie $c_user, $c_date, $c_client_ip");
        
        ## Some checks on the validity of the cookie
        
        # Check if the cookie hasn't expired
        
        if (time()>$c_date)
        {
            $log->info("Cookie has expired");
            setCookie($r,$user,$password,$client_identifier,$cookie_lifetime,$encryption_key);
            return DECLINED;
        }
        
        # Check if the cookie comes from the host it was issued to
        
        if ($client_identifier ne $c_client_ip)
        {
            $log->info("Cookie for $c_user has not been set for $client_identifier but for $c_client_ip");
            setCookie($r,$user,$password,$client_identifier,$cookie_lifetime,$encryption_key);
            return DECLINED;
        }
    }
    else
    {
        $log->info("Client $client_identifier has furnished an invalid cookie.");
    }
    
    # If the client sent any http authentication credentials lets write them to a cookie
    
    if ($user ne '' && $password ne '') {
        setCookie($r,$user,$password,$client_identifier,$cookie_lifetime,$encryption_key);
    }
    
    # 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 {

AutoLogin.pm  view on Meta::CPAN

  # It has the be invoked as a PerlAccessHandler,
  # because this is just the phase
  # before authentication!
  
  <Location />
        PerlModule Apache::AutoLogin
        PerlAccessHandler Apache::AutoLogin
        
        # Set the lifetime of the cookie in days
        
        PerlSetVar AutoLoginCookieLifetimeInDays "3"
        
        # The encryption key can have any length, but the longer the better
        
        PerlSetVar AutoLoginEncryptionKey "abcdefghijklmnopqrstuvwxyz123456"
        
        # set the logout page: Important, make
        # sure that you specify something
        # that gets not cached by proxies, or
        # else the cookie won't be invalidated.
        

AutoLogin.pm  view on Meta::CPAN

        require valid-user

  </Location>
  
  # In this example make sure logout.php
  # can be viewed by the client without authentication!
  
  <Location /logout.php>
        PerlModule Apache::AutoLogin
        PerlAccessHandler Apache::AutoLogin
        PerlSetVar AutoLoginCookieLifetimeInDays "3"
        ## Anything as a key, is not important, cause it will by a random key
        PerlSetVar AutoLoginEncryptionKey "abcdefghijklmnopqrstuvwxyz123456"
        PerlSetVar AutoLoginLogoutPage "/logout.php"
        PerlSetVar AutoLoginAuthName "AutoLogin rulez"

        Order allow,deny
        allow from all
        satisfy any
  </Location>

AutoLogin.pm  view on Meta::CPAN


Anyways, although cracking of the cookie is almost unfeasable with todays computing powers, be aware that this module is for convenience only. It does not give you any additional security (well a bit perhaps) over traditional basic authentication, wh...

Although the cookie can be regarded as secure, the security of it's use stands and falls with the security of the computer it is stored on. If your users do not have personal accounts on their computers, forget about using it.


=head1 Apache configuration directives

All directives are passed in PerlSetVar.
        
=head2 AutoLoginCookieLifetimeInDays "3"

    Lifetime of the cookie in days.

=head2 AutoLoginEncryptionKey "abcdefghijklmnopqrstuvwxyz123456"

    The encryption key to use. Based on this key via md5 some fairly random 256 bit key will be generated. You may change it regularly.

=head2 AutoLoginLogoutPage "/logout.php"

    The logout URI. Make sure, that it does not get cached by any proxies or else the cookie cannot be invalidated and that this URI can be accessed without authentication!

Makefile.PL  view on Meta::CPAN

use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'		=> 'Apache::AutoLogin',
    'VERSION_FROM'	=> 'AutoLogin.pm', # finds $VERSION
    'PREREQ_PM'		=> {Apache::Constants => 1.09,
                            Crypt::Rijndael => 0.04,
                            MIME::Base64 => 2.12,
                            Digest::MD5 => 2.13,
                            Apache::Cookie => 0.01,
                            Apache::Request => 0.33,
                            Apache::Log => 1.01}, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM => 'AutoLogin.pm', # retrieve abstract from module
       AUTHOR     => 'Marcel M. Weber <mmweber@ncpro.com>') : ()),
);

README  view on Meta::CPAN

   make install

DEPENDENCIES

This module requires these other modules and libraries:

    Apache::Constants => 1.09
    Crypt::Rijndael => 0.04
    MIME::Base64 => 2.16
    Digest::MD5 => 2.13
    Apache::Cookie => 0.01
    Apache::Request => 0.33
    Apache::Log => 1.01

COPYRIGHT AND LICENCE

Artistic licence as in perl.

Copyright (C) 2004 Marcel M. Weber <mmweber@ncpro.com>



( run in 1.165 second using v1.01-cache-2.11-cpan-e9199f4ba4c )