Apache2-AuthCookieLDAP
view release on metacpan or search on metacpan
lib/Apache2/AuthCookieLDAP.pm view on Meta::CPAN
package Apache2::AuthCookieLDAP;
# Apache2::AuthCookieLDAP
#
# An Apache2::AuthCookie backend for LDAP based authentication
#
# Author: Kirill Solomko <ksolomko@cpan.org>
use strict;
use warnings;
use 5.010_000;
our $VERSION = '1.15';
use Apache2::AuthCookie;
use base qw(Apache2::AuthCookie);
use Apache2::Connection;
use Apache2::RequestRec;
use Apache2::Log;
use Apache2::Const -compile => qw(:log);
use APR::Const -compile => qw(:error ENOTIME SUCCESS);
use English qw(-no_match_vars);
use Digest::MD5 qw(md5_hex);
use Crypt::CBC;
use Crypt::DES;
use Net::LDAP;
use constant CIPHER_TYPES => qw(DES IDEA Blowfish Blowfish_PP);
use constant LOG_LEVELS => {
emerg => Apache2::Const::LOG_EMERG,
alert => Apache2::Const::LOG_ALERT,
crit => Apache2::Const::LOG_CRIT,
err => Apache2::Const::LOG_ERR,
warn => Apache2::Const::LOG_WARNING,
notice => Apache2::Const::LOG_NOTICE,
info => Apache2::Const::LOG_INFO,
debug => Apache2::Const::LOG_DEBUG
};
use constant NULL => q{};
use constant C_SECRET_KEY => '_SecretKey';
use constant C_SESSION_LIFETIME => '_SessionLifetime';
use constant C_LDAPURI => '_LDAPURI';
use constant C_BASE => '_Base';
use constant C_BINDDN => '_BindDN';
use constant C_BINDPW => '_BindPW';
use constant C_FILTER => '_Filter';
use constant C_CIPHER => '_Cipher';
use constant C_DEBUG => '_Debug';
use constant C_DEBUG_LOGLEVEL => '_DebugLogLevel';
use constant C_ERROR_LOGLEVEL => '_ErrorLogLevel';
my %CONFIG_DEFAULT = (
C_SECRET_KEY, undef, C_SESSION_LIFETIME, '00-24-00-00',
C_LDAPURI, undef, C_BASE, undef,
C_BINDDN, undef, C_BINDPW, undef,
C_FILTER, '(uid=%USER%)', C_CIPHER, 'des',
C_DEBUG_LOGLEVEL, 'alert', C_ERROR_LOGLEVEL, 'err',
C_DEBUG, 0,
);
my $ldap_handler;
my %config_data;
my %ciphers;
my $DEBUG = C_DEBUG;
#----------------------------------------------------------------------
sub cipher {
my ( $self, $r ) = @_;
my $auth_name = $r->auth_name;
my $cipher = $self->config( $r, C_CIPHER );
my $cipher_key = $auth_name . ':' . lc($cipher);
unless ( exists $ciphers{$cipher_key} ) {
my $secret_key = $self->config( $r, C_SECRET_KEY );
foreach my $cipher_type (CIPHER_TYPES) {
next unless lc($cipher_type) eq $cipher;
$ciphers{$cipher_key} = Crypt::CBC->new(
-key => $secret_key,
-cipher => $cipher_type
);
}
}
exists $ciphers{$cipher_key}
? return $ciphers{$cipher_key}
: $self->fatal( $r, "Wrong cipher $cipher" );
return NULL;
}
sub config {
my ( $self, $r, $req_key ) = @_;
return unless defined $req_key;
if ( keys %config_data ) {
exists $config_data{$req_key}
? return $config_data{$req_key}
: return NULL;
}
my $auth_name = $r->auth_name;
foreach my $key ( keys %CONFIG_DEFAULT ) {
my $default = $CONFIG_DEFAULT{$key};
my $var = $r->dir_config( $auth_name . $key );
$config_data{$key} = defined $var ? $var : $default;
if ( $key eq C_DEBUG ) {
$DEBUG = $config_data{$key};
}
}
foreach my $key ( ( C_DEBUG_LOGLEVEL, C_ERROR_LOGLEVEL ) ) {
my $value = $config_data{$key};
my $replace = $key eq C_DEBUG_LOGLEVEL ? 'alert' : 'err';
unless ( exists LOG_LEVELS->{$value} ) {
$self->fatal( $r,
"Loglevel '$value' does not exist, using '$replace' instead" );
}
}
my %use_files;
foreach my $c_key ( C_BASE, C_BINDDN, C_BINDPW ) {
my $c_var = $config_data{$c_key};
if ( $c_var && $c_var =~ /^file:(.+):(.+)$/ ) {
-f $1
? push @{ $use_files{$1} }, [ $c_key, $2 ]
: $self->fatal( $r, "$c_key: check your file access: $1" );
}
}
foreach my $file ( keys %use_files ) {
open( my $lp_fh, $file )
|| $self->fatal( $r, "Cannot open $file: $!" );
my $search_data = $use_files{$file};
if ( $#$search_data != 1 ) { # to be safe
$self->fatal( $r, "Wrong regex pattern for file $file" );
}
while ( my $row = <$lp_fh> ) {
( run in 0.899 second using v1.01-cache-2.11-cpan-df04353d9ac )