From 20fd1b9f6f15f7864620ff91ff1eb257ad5ccb5a Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Mon, 15 Feb 2010 17:25:06 +0000 Subject: import version 0.01 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10b5458 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +META.yml +Makefile +/blib +/pm_to_blib diff --git a/Changes b/Changes new file mode 100644 index 0000000..88f37e9 --- /dev/null +++ b/Changes @@ -0,0 +1,5 @@ +Revision history for DJabberd-Authen-LDAP + +0.01 2007-07-26 + Initial Revision. Only supports rebinding + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..58085bd --- /dev/null +++ b/MANIFEST @@ -0,0 +1,9 @@ +Changes +MANIFEST +Makefile.PL +README +lib/DJabberd/Authen/LDAP.pm +t/00-load.t +t/boilerplate.t +t/pod-coverage.t +t/pod.t diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..2f0ffed --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,18 @@ +use strict; +use warnings; +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'DJabberd::Authen::LDAP', + AUTHOR => 'Edward Rudd ', + VERSION_FROM => 'lib/DJabberd/Authen/LDAP.pm', + ABSTRACT_FROM => 'lib/DJabberd/Authen/LDAP.pm', + PL_FILES => {}, + PREREQ_PM => { + 'Test::More' => 0, + 'DJabberd' => 0.83, + 'Net::LDAP' => 0.34 + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'DJabberd-Authen-LDAP-*' }, +); diff --git a/README b/README new file mode 100644 index 0000000..34586d0 --- /dev/null +++ b/README @@ -0,0 +1,41 @@ +DJabberd-Authen-LDAP + +This is an LDAP Authentication for the DJabberd XMPP Server. This module +depends on DJabberd of course (version 0.83 or newer) and Net::LDAP. + +INSTALLATION + +To install this module, run the following commands: + + perl Makefile.PL + make + make test + make install + + +SUPPORT AND DOCUMENTATION + +After installing, you can find documentation for this module with the perldoc command. + + perldoc DJabberd::Authen::LDAP + +You can also look for information at: + + Search CPAN + http://search.cpan.org/dist/DJabberd-Authen-LDAP + + CPAN Request Tracker: + http://rt.cpan.org/NoAuth/Bugs.html?Dist=DJabberd-Authen-LDAP + + AnnoCPAN, annotated CPAN documentation: + http://annocpan.org/dist/DJabberd-Authen-LDAP + + CPAN Ratings: + http://cpanratings.perl.org/d/DJabberd-Authen-LDAP + +COPYRIGHT AND LICENCE + +Copyright (C) 2007 Edward Rudd + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. diff --git a/lib/DJabberd/Authen/LDAP.pm b/lib/DJabberd/Authen/LDAP.pm new file mode 100644 index 0000000..9808fa8 --- /dev/null +++ b/lib/DJabberd/Authen/LDAP.pm @@ -0,0 +1,171 @@ +package DJabberd::Authen::LDAP; + +use warnings; +use strict; +use base 'DJabberd::Authen'; + +use DJabberd::Log; +our $logger = DJabberd::Log->get_logger; +use Net::LDAP; + +sub log { + $logger; +} + +=head1 NAME + +DJabberd::Authen::LDAP - An LDAP authentication module for DJabberd + +=head1 VERSION + +Version 0.01 +=cut + +our $VERSION = '0.01'; + +=head1 SYNOPSIS + + + + [...] + + + LDAPURI ldap://localhost/ + LDAPBindDN cn=reader + LDAPBindPW pass + LDAPBaseDN ou=people + LDAPFilter (&(inetAuthorizedServices=jabber)(uid=%u)) + LDAPMethod rebind + + + +LDAPURI , LDAPBaseDN, and LDAPFilter are required +Everything else is optional. + +The Only LDAPMethod supported at the moment is rebind which performs a bind as LDAPBindDN + or does anonymous bind, then searches for the user using LDAPFilter and then will rebind + as the found DN to verify the password. + +LDAPFilter is an LDAP filter with a %u that will be substituted with the incoming userid + +=head1 AUTHOR + +Edward Rudd, C<< >> + +=cut + +sub set_config_ldapuri { + my ($self, $ldapuri) = @_; + if ( $ldapuri =~ /((?:ldap[si]?\:\/\/)?[\w\.%\d]+\/?)/ ) { + $self->{'ldap_uri'} = $ldapuri; + } +} + +sub set_config_ldapbinddn { + my ($self, $ldapbinddn) = @_; + $self->{'ldap_binddn'} = $ldapbinddn; +} + +sub set_config_ldapbindpw { + my ($self, $ldapbindpw) = @_; + $self->{'ldap_bindpw'} = $ldapbindpw; +} + +sub set_config_ldapbasedn { + my ($self, $ldapbasedn) = @_; + $self->{'ldap_basedn'} = $ldapbasedn; +} + +sub set_config_ldapfilter { + my ($self, $ldapfilter) = @_; + $self->{'ldap_filter'} = $ldapfilter; +} + +sub set_config_ldapmethod { + my ($self, $ldapmethod) = @_; + if ( $ldapmethod =~ /^(?:rebind)$/ ) { + $self->{'ldap_method'} = $ldapmethod; + } else { + $self->{'ldap_method'} = 'unknown'; + } +} + +sub finalize { + my $self = shift; + $logger->error_die("Invalid LDAP URI") unless $self->{ldap_uri}; + $logger->error_die("No LDAP BaseDN Specified") unless $self->{ldap_basedn}; + if (not defined $self->{'ldap_method'}) { $self->{'ldap_type'} = 'rebind'; } + for ($self->{ldap_type}) { + if (/^rebind$/) { + # check additional required params + $logger->error_die("Must specify filter with userid as %u") unless $self->{ldap_filter}; + } else { + $logger->error_die("Invalid LDAP Authentication Method"); + } + } + # Initialize ldap connection + $self->{'ldap_conn'} = Net::LDAP->new($self->{ldap_uri}) + or $logger->error_die("Could not connect to LDAP Server ".$self->{ldap_uri}); +} + +sub can_retrieve_cleartext { 0 } + +sub check_cleartext { + my ($self, $cb, %args) = @_; + my $username = $args{username}; + my $password = $args{password}; + my $conn = $args{conn}; + unless ($username =~ /^\w+$/) { + $cb->reject; + return; + } + + my $ldap = $self->{'ldap_conn'}; + + if (defined $self->{'ldap_binddn'}) { + if (not $ldap->bind($self->{'ldap_binddn'}, + password=>$self->{'ldap_bindpw'})) { + $logger->info("Could not bind to ldap server"); + $cb->decline; + } + } else { + $ldap->unbind; + } + + my $filter = $self->{'ldap_filter'}; + $filter =~ s/%u/$username/; + $logger->info("Searching $filter on ".$self->{'ldap_basedn'}); + my $srch = $ldap->search( + base=>$self->{'ldap_basedn'}, + filter=>$filter, + attrs=>['dn']); + if ($srch->code || $srch->count != 1) { + $logger->info("Account $username not found."); + $cb->decline; + } else { + my $entry = $srch->entry(0); + my $DN = $entry->dn(); + undef($entry); + undef($srch); + + my $res = $ldap->bind($DN,password=>$password); + + if ($res->code == 0) { + $cb->accept; + } else { + $cb->reject; + } + } +} + +=head1 COPYRIGHT & LICENSE + +Original work Copyright 2006 Alexander Karelas, Martin Atkins, Brad Fitzpatrick and Aleksandar Milanov. All rights reserved. +Copyright 2007 Edward Rudd. All rights reserved. + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=cut + +1; diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..5ae63ed --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,9 @@ +#!perl -T + +use Test::More tests => 1; + +BEGIN { + use_ok( 'DJabberd::Authen::LDAP' ); +} + +diag( "Testing DJabberd::Authen::LDAP $DJabberd::Authen::LDAP::VERSION, Perl $], $^X" ); diff --git a/t/boilerplate.t b/t/boilerplate.t new file mode 100644 index 0000000..090be99 --- /dev/null +++ b/t/boilerplate.t @@ -0,0 +1,48 @@ +#!perl -T + +use strict; +use warnings; +use Test::More tests => 3; + +sub not_in_file_ok { + my ($filename, %regex) = @_; + open my $fh, "<", $filename + or die "couldn't open $filename for reading: $!"; + + my %violated; + + while (my $line = <$fh>) { + while (my ($desc, $regex) = each %regex) { + if ($line =~ $regex) { + push @{$violated{$desc}||=[]}, $.; + } + } + } + + if (%violated) { + fail("$filename contains boilerplate text"); + diag "$_ appears on lines @{$violated{$_}}" for keys %violated; + } else { + pass("$filename contains no boilerplate text"); + } +} + +not_in_file_ok(README => + "The README is used..." => qr/The README is used/, + "'version information here'" => qr/to provide version information/, +); + +not_in_file_ok(Changes => + "placeholder date/time" => qr(Date/time) +); + +sub module_boilerplate_ok { + my ($module) = @_; + not_in_file_ok($module => + 'the great new $MODULENAME' => qr/ - The great new /, + 'boilerplate description' => qr/Quick summary of what the module/, + 'stub function definition' => qr/function[12]/, + ); +} + +module_boilerplate_ok('lib/DJabberd/Authen/LDAP.pm'); diff --git a/t/pod-coverage.t b/t/pod-coverage.t new file mode 100644 index 0000000..703f91d --- /dev/null +++ b/t/pod-coverage.t @@ -0,0 +1,6 @@ +#!perl -T + +use Test::More; +eval "use Test::Pod::Coverage 1.04"; +plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; +all_pod_coverage_ok(); diff --git a/t/pod.t b/t/pod.t new file mode 100644 index 0000000..976d7cd --- /dev/null +++ b/t/pod.t @@ -0,0 +1,6 @@ +#!perl -T + +use Test::More; +eval "use Test::Pod 1.14"; +plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; +all_pod_files_ok(); -- cgit v0.9.2