Apache-AutoLogin

 view release on metacpan or  search on metacpan

AutoLogin.pm  view on Meta::CPAN

    
    # Check if the client has furnished any valid information
    
    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 {

    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);
    



( run in 2.266 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )