From 48ac5bd591b06e4be35cf4a8239504d6e7df2a0b Mon Sep 17 00:00:00 2001 From: Xavier Guimard Date: Wed, 23 Sep 2009 12:42:34 +0000 Subject: [PATCH] * New authentication scheme : Relay (queries by SOAP another portal) * syslog facility was not taken in account * Missing HTTP::Headers dependency * lmConfigEditor must not display reVHosts and cipher which are calculated by Conf.pm * bad Apache security in Debian configuration files --- build/lemonldap-ng/debian/portal-apache.conf | 2 +- build/lemonldap-ng/debian/portal-apache2.conf | 2 +- modules/lemonldap-ng-common/Makefile.PL | 1 + .../lib/Lemonldap/NG/Common/CGI.pm | 2 +- .../lib/Lemonldap/NG/Handler/Simple.pm | 2 +- .../example/scripts/lmConfigEditor | 5 +- modules/lemonldap-ng-portal/MANIFEST | 3 + .../lib/Lemonldap/NG/Portal/AuthRelay.pm | 72 +++++++++++++++ .../lib/Lemonldap/NG/Portal/UserDBRelay.pm | 29 ++++++ .../lib/Lemonldap/NG/Portal/_Relay.pm | 91 +++++++++++++++++++ 10 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthRelay.pm create mode 100644 modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDBRelay.pm create mode 100644 modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_Relay.pm diff --git a/build/lemonldap-ng/debian/portal-apache.conf b/build/lemonldap-ng/debian/portal-apache.conf index f18598b87..a5d845fdc 100644 --- a/build/lemonldap-ng/debian/portal-apache.conf +++ b/build/lemonldap-ng/debian/portal-apache.conf @@ -20,7 +20,7 @@ # SOAP functions for sessions management (disabled by default) - + Order deny,allow Deny from all diff --git a/build/lemonldap-ng/debian/portal-apache2.conf b/build/lemonldap-ng/debian/portal-apache2.conf index 885a2a6d7..662df35d9 100644 --- a/build/lemonldap-ng/debian/portal-apache2.conf +++ b/build/lemonldap-ng/debian/portal-apache2.conf @@ -20,7 +20,7 @@ # SOAP functions for sessions management (disabled by default) - + Order deny,allow Deny from all diff --git a/modules/lemonldap-ng-common/Makefile.PL b/modules/lemonldap-ng-common/Makefile.PL index 3251cf209..1e0b19788 100644 --- a/modules/lemonldap-ng-common/Makefile.PL +++ b/modules/lemonldap-ng-common/Makefile.PL @@ -30,6 +30,7 @@ WriteMakefile( 'IO::String' => 0, 'SOAP::Lite' => 0, 'Crypt::Rijndael' => 0, + 'HTTP::Headers' => 0, }, # e.g., Module::Name => 1.1 #EXE_FILES => [ 'scripts/lmConfig_File2MySQL', ], ( diff --git a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm index f159d0e65..4df563c8c 100644 --- a/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm +++ b/modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/CGI.pm @@ -221,7 +221,7 @@ sub startSyslog { return if ( $self->{_syslog} ); eval { use Sys::Syslog; - openlog( 'lemonldap-ng', 'ndelay', '$self->{syslog}' ); + openlog( 'lemonldap-ng', 'ndelay', $self->{syslog} ); }; $self->abort( "Unable to use syslog", $@ ) if ($@); $self->{_syslog} = 1; diff --git a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm index 045700441..daac6a7ee 100644 --- a/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm +++ b/modules/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Simple.pm @@ -880,7 +880,7 @@ sub run ($$) { . ( $https ? 's' : '' ) . "://$host:$portString" . $apacheRequest->uri - . ( $apacheRequest->args ? "?" . $apacheRequest->args : "" ) ); + . ( $args ? "?" . $args : "" ) ); $host =~ s/^[^\.]+\.(.*\..*$)/$1/; lmSetErrHeaderOut( $apacheRequest, 'Set-Cookie' => "$str; domain=$host; path=/" diff --git a/modules/lemonldap-ng-manager/example/scripts/lmConfigEditor b/modules/lemonldap-ng-manager/example/scripts/lmConfigEditor index 2cf1025db..86bff4be0 100644 --- a/modules/lemonldap-ng-manager/example/scripts/lmConfigEditor +++ b/modules/lemonldap-ng-manager/example/scripts/lmConfigEditor @@ -15,7 +15,10 @@ my $conf = Lemonldap::NG::Common::Conf->new(); open F1, ">$refFile" or quit($!); open F2, ">$editFile" or quit($!); -my $tmp = Dumper($conf->getConf); +my $tmp = $conf->getConf(); +delete $tmp->{reVHosts}; +delete $tmp->{cipher}; +$tmp = Dumper($tmp); print F1 $tmp; print F2 $tmp; close F1; diff --git a/modules/lemonldap-ng-portal/MANIFEST b/modules/lemonldap-ng-portal/MANIFEST index 6af30a132..265235f8d 100644 --- a/modules/lemonldap-ng-portal/MANIFEST +++ b/modules/lemonldap-ng-portal/MANIFEST @@ -79,6 +79,7 @@ lib/Lemonldap/NG/Portal.pm lib/Lemonldap/NG/Portal/_i18n.pm lib/Lemonldap/NG/Portal/_LDAP.pm lib/Lemonldap/NG/Portal/_Multi.pm +lib/Lemonldap/NG/Portal/_Relay.pm lib/Lemonldap/NG/Portal/_Remote.pm lib/Lemonldap/NG/Portal/_SAML.pm lib/Lemonldap/NG/Portal/_SOAP.pm @@ -88,6 +89,7 @@ lib/Lemonldap/NG/Portal/AuthCAS.pm lib/Lemonldap/NG/Portal/AuthLA.pm lib/Lemonldap/NG/Portal/AuthLDAP.pm lib/Lemonldap/NG/Portal/AuthMulti.pm +lib/Lemonldap/NG/Portal/AuthRelay.pm lib/Lemonldap/NG/Portal/AuthRemote.pm lib/Lemonldap/NG/Portal/AuthSAML.pm lib/Lemonldap/NG/Portal/AuthSSL.pm @@ -104,6 +106,7 @@ lib/Lemonldap/NG/Portal/Simple.pm lib/Lemonldap/NG/Portal/UserDBLDAP.pm lib/Lemonldap/NG/Portal/UserDBMulti.pm lib/Lemonldap/NG/Portal/UserDBNull.pm +lib/Lemonldap/NG/Portal/UserDBRelay.pm lib/Lemonldap/NG/Portal/UserDBRemote.pm lib/Lemonldap/NG/Portal/UserDBSAML.pm Makefile.PL diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthRelay.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthRelay.pm new file mode 100644 index 000000000..0a8c0bbcf --- /dev/null +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/AuthRelay.pm @@ -0,0 +1,72 @@ +## @file +# Relay authentication module + +## @class +# Relay authentication module: It simply call another Lemonldap::NG portal by +# SOAP using credentials +package Lemonldap::NG::Portal::AuthRelay; + +use strict; +use Lemonldap::NG::Portal::_Relay; +use Lemonldap::NG::Portal::_WebForm; +use Lemonldap::NG::Portal::Simple; +use base qw(Lemonldap::NG::Portal::_WebForm Lemonldap::NG::Portal::_Relay); + +our $VERSION = '0.1'; + +## @apmethod int authInit() +# Call Lemonldap::NG::Portal::_Relay::relayInit(); +# @return Lemonldap::NG::Portal constant +*authInit = *Lemonldap::NG::Portal::_Relay::relayInit; + +## @apmethod int authenticate() +# Call Lemonldap::NG::Portal::_Relay::relayQuery() +# @return Lemonldap::NG::Portal constant +*authenticate = *Lemonldap::NG::Portal::_Relay::relayQuery; + +## @apmethod int setAuthSessionInfo() +# Call Lemonldap::NG::Portal::_Relay::setSessionInfo() +# @return Lemonldap::NG::Portal constant +*setAuthSessionInfo = *Lemonldap::NG::Portal::_Relay::setSessionInfo; + +1; + +__END__ + +=head1 NAME + +Lemonldap::NG::Portal::AuthRelay - Authentication module for Lemonldap::NG +that delegates authentication to a remote Lemonldap::NG portal. + +=head1 SYNOPSIS + + use Lemonldap::NG::Portal::Simple; + my $portal = new Lemonldap::NG::Portal::Simple( + + # AUTHENTICATION PART + authentication => 'Relay', + ); + +=head1 DESCRIPTION + +Authentication module for Lemonldap::NG portal that forward credentials to a +remote portal using SOAP. + +=head1 SEE ALSO + +L +L + +=head1 AUTHOR + +Xavier Guimard, Ex.guimard@free.frE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2009 by Xavier Guimard + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.10.0 or, +at your option, any later version of Perl 5 you may have available. + +=cut diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDBRelay.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDBRelay.pm new file mode 100644 index 000000000..4f5fb014c --- /dev/null +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/UserDBRelay.pm @@ -0,0 +1,29 @@ +## @file +# Relay userDB mechanism + +## @class +# Relay userDB mechanism class +package Lemonldap::NG::Portal::UserDBRelay; + +use strict; +use Lemonldap::NG::Portal::_Relay; +use Lemonldap::NG::Portal::Simple; +use base qw(Lemonldap::NG::Portal::_Relay); + +our $VERSION = '0.1'; + +## @apmethod int userDBInit() +# Call Lemonldap::NG::Portal::_Relay::relayInit(); +# @return Lemonldap::NG::Portal constant +*userDBInit = *Lemonldap::NG::Portal::_Relay::relayInit; + +## @apmethod int getUser() +# Call Lemonldap::NG::Portal::_Relay::relayQuery() +# @return Lemonldap::NG::Portal constant +*getUser = *Lemonldap::NG::Portal::_Relay::relayQuery; + +sub setGroups { + PE_OK; +} +1; + diff --git a/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_Relay.pm b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_Relay.pm new file mode 100644 index 000000000..1bebd08b7 --- /dev/null +++ b/modules/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/_Relay.pm @@ -0,0 +1,91 @@ +## @file +# Relay authentication and userDB base. + +## @class +# Relay authentication and userDB base class. +package Lemonldap::NG::Portal::_Relay; + +use strict; +use Lemonldap::NG::Portal::Simple; +use MIME::Base64; +use SOAP::Lite; + +our $VERSION = '0.1'; + +## @apmethod int relayInit() +# Checks if remote portal parameters are set. +# @return Lemonldap::NG::Portal constant +sub relayInit { + my $self = shift; + return PE_OK if ( $self->{_relayInitDone} ); + my @missing = (); + foreach (qw(soapAuthService)) { + push @missing, $_ unless ( defined( $self->{$_} ) ); + } + $self->{soapSessionService} ||= + $self->{soapAuthService} . 'index.pl/sessions'; + $self->{soapSessionService} =~ s/\.plindex.pl/\.pl/; + $self->{remoteCookieName} ||= $self->{cookieName}; + $self->abort( "Missing parameters", + "Required parameters: " . join( ', ', @missing ) ) + if (@missing); + $self->{_relayInitDone}++; + PE_OK; +} + +## @apmethod int relayQuery() +# Queries the remote portal to authenticate users using given credentials +sub relayQuery { + my $self = shift; + return PE_OK if ( $self->{_relayQueryDone} ); + my $soap = + SOAP::Lite->proxy( $self->{soapAuthService} ) + ->uri('urn:Lemonldap::NG::Common::CGI::SOAPService'); + my $r = $soap->getCookies( $self->{user}, $self->{password} ); + if ( $r->fault ) { + $self->abort( "Unable to query authentication service", + $r->fault->{faultstring} ); + } + my $res = $r->result(); + + # If authentication failed, display error + if ( $res->{error} ) { + $self->_sub( 'userError', + "Authentication failed for $self->{user} " + . $soap->error( 'fr', $res->{error} )->result() ); + return PE_BADCREDENTIALS; + } + $self->{remoteId} = $res->{cookies}->{ $self->{remoteCookieName} } + or $self->abort("No cookie named $self->{remoteCookieName}"); + $self->{_relayQueryDone}++; + PE_OK; +} + +## @apmethod int setSessionInfo() +# Queries the remote portal to get users attributes and +# store them in local session +sub setSessionInfo { + my $self = shift; + return PE_OK if ( $self->{_setSessionInfoDone} ); + my $soap = + SOAP::Lite->proxy( $self->{soapSessionService} ) + ->uri('urn:Lemonldap::NG::Common::CGI::SOAPService'); + my $r = $soap->getAttributes( $self->{remoteId} ); + if ( $r->fault ) { + $self->abort( "Unable to query authentication service", + $r->fault->{faultstring} ); + } + my $res = $r->result(); + if ( $res->{error} ) { + $self->_sub( 'userError', + "Unable to get attributes for $self->{user} " ); + return PE_ERROR; + } + $self->{sessionInfo}->{$_} ||= $res->{attributes}->{$_} + foreach ( keys %{ $res->{attributes} } ); + $self->{_setSessionInfoDone}++; + PE_OK; +} + +1; +