Fix some little bugs

This commit is contained in:
Xavier Guimard 2010-02-08 10:06:21 +00:00
parent 434f8ea286
commit fad774f41b
2 changed files with 143 additions and 164 deletions

View File

@ -22,69 +22,70 @@ sub authInit {
return PE_ERROR unless $self->loadLasso();
# Activate SOAP
$self->{Soap} = 1;
$self->abort( 'To use SAML, you must set "Soap => 1"', 'error' )
unless ( $self->{Soap} );
# Check presence of private key in configuration
unless ( $self->{samlServicePrivateKey} ) {
$self->lmLog( "SAML private key not found in configuration", 'error' );
return PE_ERROR;
}
return PE_ERROR;
}
# Get metadata from configuration
$self->lmLog( "Get Metadata for this service", 'debug' );
# Get metadata from configuration
$self->lmLog( "Get Metadata for this service", 'debug' );
my $service_metadata = Lemonldap::NG::Common::Conf::SAML::Metadata->new();
# Create Lasso server with service metadata
my $server = $self->createServer(
# Create Lasso server with service metadata
my $server = $self->createServer(
$service_metadata->serviceToXML(
$ENV{DOCUMENT_ROOT} . "/skins/common/saml2-metadata.tpl", $self
),
$self->{samlServicePrivateKey},
);
$self->{samlServicePrivateKey},
);
unless ($server) {
$self->lmLog( 'Unable to create Lasso server', 'error' );
return PE_ERROR;
}
unless ($server) {
$self->lmLog( 'Unable to create Lasso server', 'error' );
return PE_ERROR;
}
$self->lmLog( "Service created", 'debug' );
$self->lmLog( "Service created", 'debug' );
# Check presence of at least one identity provider in configuration
unless ( $self->{samlIDPMetaData}
and keys %{ $self->{samlIDPMetaData} } )
{
$self->lmLog( "No IDP found in configuration", 'error' );
return PE_ERROR;
}
# Check presence of at least one identity provider in configuration
unless ( $self->{samlIDPMetaData}
and keys %{ $self->{samlIDPMetaData} } )
{
$self->lmLog( "No IDP found in configuration", 'error' );
return PE_ERROR;
}
# Load identity provider metadata
# IDP are listed in $self->{samlIDPMetaData}
# Each key is the IDP name and value is the metadata
# Build IDP list for later use in extractFormInfo
foreach ( keys %{ $self->{samlIDPMetaData} } ) {
# Load identity provider metadata
# IDP are listed in $self->{samlIDPMetaData}
# Each key is the IDP name and value is the metadata
# Build IDP list for later use in extractFormInfo
foreach ( keys %{ $self->{samlIDPMetaData} } ) {
$self->lmLog( "Get Metadata for IDP $_", 'debug' );
$self->lmLog( "Get Metadata for IDP $_", 'debug' );
# Get metadata from configuration
# Get metadata from configuration
my $idp_metadata = Lemonldap::NG::Common::Conf::SAML::Metadata->new();
unless (
$idp_metadata->initializeFromConfHash(
$self->{samlIDPMetaData}->{$_}
)
)
{
$self->lmLog( "Fail to read IDP $_ Metadata from configuration",
'error' );
return PE_ERROR;
}
unless (
$idp_metadata->initializeFromConfHash(
$self->{samlIDPMetaData}->{$_}
)
)
{
$self->lmLog( "Fail to read IDP $_ Metadata from configuration",
'error' );
return PE_ERROR;
}
# Add this IDP to Lasso::Server
my $result = $self->addIDP( $server, $idp_metadata->toXML() );
# Add this IDP to Lasso::Server
my $result = $self->addIDP( $server, $idp_metadata->toXML() );
unless ($result) {
$self->lmLog( "Fail to use IDP $_ Metadata", 'error' );
return PE_ERROR;
}
unless ($result) {
$self->lmLog( "Fail to use IDP $_ Metadata", 'error' );
return PE_ERROR;
}
# Store IDP entityID and Organization Name
my $entityID = $idp_metadata->{entityID};
@ -93,8 +94,8 @@ sub authInit {
$self->{_idpList}->{$_}->{entityID} = $entityID;
$self->{_idpList}->{$_}->{name} = $name;
$self->lmLog( "IDP $_ added", 'debug' );
}
$self->lmLog( "IDP $_ added", 'debug' );
}
# Store Lasso::Server object
$self->{_lassoServer} = $server;
@ -106,7 +107,7 @@ sub authInit {
# Check authentication statement or create authentication request
# @return Lemonldap::NG::Portal error code
sub extractFormInfo {
my $self = shift;
my $self = shift;
my $server = $self->{_lassoServer};
my $idp;
@ -114,16 +115,16 @@ sub extractFormInfo {
# if ( authnStatement ) ...
# TODO - check authstatement
# else
# 2. IDP resolution
# Get IDP resolution cookie
my %cookies = fetch CGI::Cookie;
my %cookies = fetch CGI::Cookie;
my $idp_cookie = $cookies{ $self->{samlIdPResolveCookie} };
if ($idp_cookie) {
$idp = $idp_cookie->value;
$idp = $idp_cookie->value;
$self->lmLog( "IDP $idp found in IDP resolution cookie", 'debug' );
}
}
# If no IDP resolve cookie, find another way to get it
# Case 1: IDP was choosen from portal IDP list
@ -139,37 +140,28 @@ sub extractFormInfo {
$self->lmLog( "No IDP found, redirecting user to IDP list", 'debug' );
# IDP list
my $html = "<h3>";
$html .=
&Lemonldap::NG::Portal::_i18n::msg( PM_SAML_IDPSELECT,
$ENV{HTTP_ACCEPT_LANGUAGE} );
$html .= "</h3>\n";
my $html = "<h3>"
. &Lemonldap::NG::Portal::_i18n::msg( PM_SAML_IDPSELECT,
$ENV{HTTP_ACCEPT_LANGUAGE} )
. "</h3>\n<table>\n";
$html .= "<table>\n";
foreach ( keys %{ $self->{_idpList} } ) {
$html .= "<tr><td>";
$html .=
"<input type=\"radio\" name=\"idp\" value=\""
'<tr><td><input type="radio" name="idp" value="'
. $self->{_idpList}->{$_}->{entityID}
. "\" />\n";
$html .= "</td><td>";
$html .= $self->{_idpList}->{$_}->{name};
$html .= "</td></tr>";
. '" /></td><td>'
. $self->{_idpList}->{$_}->{name}
. '</td></tr>';
}
$html .=
"<tr><td><input type=\"checkbox\" name=\"cookie_type\" value=\"1\"></td>";
$html .= "<td>";
$html .=
&Lemonldap::NG::Portal::_i18n::msg( PM_REMEMBERCHOICE,
$ENV{HTTP_ACCEPT_LANGUAGE} );
$html .= "</td></tr>\n";
'<tr><td><input type="checkbox" name="cookie_type" value="1"></td><td>'
. &Lemonldap::NG::Portal::_i18n::msg( PM_REMEMBERCHOICE,
$ENV{HTTP_ACCEPT_LANGUAGE} )
. "</td></tr></table>\n"
$html .= "</table>\n";
# Script to autoselect first choice
$html .=
"<script>\$('[type=radio]:first').attr('checked','checked');</script>\n";
# Script to autoselect first choice
. '<script>$("[type=radio]:first").attr("checked","checked");</script>';
$self->info($html);
@ -184,48 +176,43 @@ sub extractFormInfo {
-expires => '-1d',
);
return PE_CONFIRM;
return PE_CONFIRM;
}
# If IDP is found but not confirmed, let the user confirm it
if ( $confirm_flag != 1 ) {
$self->lmLog( "IDP $idp selected, need user confirmation", 'debug' );
# Choosen IDP
my $html = "<h3>";
$html .=
&Lemonldap::NG::Portal::_i18n::msg( PM_SAML_IDPCHOOSEN,
$ENV{HTTP_ACCEPT_LANGUAGE} );
$html .= "</h3>\n";
$html .= "<h4>$idp</h4>\n";
$html .= "<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n";
my $html = '<h3>'
. &Lemonldap::NG::Portal::_i18n::msg( PM_SAML_IDPCHOOSEN,
$ENV{HTTP_ACCEPT_LANGUAGE} )
. "</h3>\n<h4>$idp</h4>\n<input type=\"hidden\" name=\"idp\" value=\"$idp\" />\n";
$self->info($html);
return PE_CONFIRM;
return PE_CONFIRM;
}
# Here confirmation is OK (confirm_flag == 1), store choosen IDP in cookie
unless ( $idp_cookie and ( $idp eq $idp_cookie->value ) ) {
$self->lmLog( "Build cookie to remember $idp as IDP choice", 'debug' );
# User can choose temporary (0) or persistent cookie (1)
my $cookie_type = $self->param("cookie_type") || "0";
# User can choose temporary (0) or persistent cookie (1)
my $cookie_type = $self->param("cookie_type") || "0";
push @{ $self->{cookie} },
$self->cookie(
-name => $self->{samlIdPResolveCookie},
-value => $idp,
-domain => $self->{domain},
-path => "/",
-secure => $self->{securedCookie},
-httponly => $self->{httpOnly},
-expires => $cookie_type ? "+365d" : "",
);
push @{ $self->{cookie} },
$self->cookie(
-name => $self->{samlIdPResolveCookie},
-value => $idp,
-domain => $self->{domain},
-path => "/",
-secure => $self->{securedCookie},
-httponly => $self->{httpOnly},
-expires => $cookie_type ? "+365d" : "",
);
}
# 3. Build authentication request
my $login = $self->createAuthnRequest( $server, $idp );

View File

@ -17,6 +17,42 @@ our @EXPORT = qw(
our $VERSION = '0.01';
BEGIN {
# Load Glib if available
eval 'use Glib;';
if ($@) {
print STDERR
"Glib Lasso messages will not be catched (require Glib module)\n";
eval "use constant GLIB => 0";
}
else {
eval "use constant GLIB => 0";
}
# Load Lasso.pm
eval 'use Lasso;';
if ($@) {
print STDERR "Lasso.pm not loaded :$@";
eval 'use constant LASSO => 0;use constant BADLASSO => 0;';
}
else {
no strict 'subs';
eval 'use constant LASSO => 1';
my $lasso_check_version_mode = Lasso::Constants::CHECK_VERSION_NUMERIC;
my $check_version =
Lasso::check_version( 2, 2, 91, $lasso_check_version_mode );
unless ($check_version) {
eval 'use constant BADLASSO => 1';
}
else {
eval 'use constant BADLASSO => 0';
}
}
# Check Lasso version >= 2.2.91
}
## @method boolean loadLasso()
# Load Lasso module
# @return boolean result
@ -27,8 +63,7 @@ sub loadLasso {
return 1 if $self->{_lasso};
# Catch GLib Lasso messages (require Glib)
eval { use Glib; };
unless ($@) {
if (GLIB) {
Glib::Log->set_handler(
"Lasso",
[qw/ error critical warning message info debug /],
@ -38,35 +73,15 @@ sub loadLasso {
}
);
}
else {
$self->lmLog(
"Glib Lasso messages will not be catched (require Glib module)",
'info' );
}
# Load Lasso.pm
eval { use Lasso; };
if ($@) {
$self->lmLog( "Module Lasso not found in @INC", 'error' );
$self->lmLog( "$@", 'debug' );
unless (LASSO) {
$self->lmLog( "Module Lasso not loaded (see bellow)", 'error' );
return 0;
}
# Check Lasso version >= 2.2.91
my $lasso_check_version_mode = Lasso::Constants::CHECK_VERSION_NUMERIC;
my $check_version =
Lasso::check_version( 2, 2, 91, $lasso_check_version_mode );
unless ($check_version) {
if (BADLASSO) {
$self->lmLog( 'Lasso version >= 2.2.91 required', 'error' );
return 0;
}
$self->lmLog( "Module Lasso loaded", 'debug' );
# Remember we have loaded Lasso
$self->{_lasso} = 1;
return 1;
}
@ -76,9 +91,8 @@ sub loadLasso {
# @param string optional log level (debug by default)
# @return 1 if no error
sub checkLassoError {
my $self = shift;
my $error = shift;
my $level = shift || 'debug';
my ( $self, $error, $level ) = splice @_;
my $level ||= 'debug';
# If $error is not a Lasso::Error object, display error string
unless ( ref($error) and $error->isa("Lasso::Error") ) {
@ -106,16 +120,12 @@ sub checkLassoError {
# @param string optional certificate
# @return Lasso::Server object
sub createServer {
my $self = shift;
my $metadata = shift;
my $private_key = shift;
my $private_key_password = shift;
my $certificate = shift;
my ( $self, $metadata, $private_key, $private_key_password, $certificate) = splice @_;
my $server;
eval {
$server = Lasso::Server::new_from_buffers( $metadata, $private_key,
$private_key_password, $certificate );
$private_key_password, $certificate );
};
return unless $self->checkLassoError($@);
@ -131,14 +141,11 @@ sub createServer {
# @param string optional ca cert chain
# @return boolean result
sub addIDP {
my $self = shift;
my $server = shift;
my $metadata = shift;
my $public_key = shift;
my $ca_cert_chain = shift;
my ( $self, $server, $metadata, $public_key, $ca_cert_chain ) = splice @_;
return 0 unless ( $server->isa("Lasso::Server") and defined $metadata );
no strict 'subs';
return $self->addProvider( $server, Lasso::Constants::PROVIDER_ROLE_IDP,
$metadata, $public_key, $ca_cert_chain );
}
@ -152,12 +159,8 @@ sub addIDP {
# @param string optional ca cert chain
# @return boolean result
sub addProvider {
my $self = shift;
my $server = shift;
my $role = shift;
my $metadata = shift;
my $public_key = shift;
my $ca_cert_chain = shift;
my ( $self, $server, $role, $metadata, $public_key, $ca_cert_chain ) =
splice @_;
return 0
unless ( $server->isa("Lasso::Server")
@ -179,11 +182,8 @@ sub addProvider {
#@param string entityID
#@return string organization name
sub getOrganizationName {
my $self = shift;
my $server = shift;
my $idp = shift;
my $provider;
my $node;
my ( $self, $server, $idp ) = splice @_;
my ( $provider, $node );
# Get provider from server
eval { $provider = Lasso::Server::get_provider( $server, $idp ); };
@ -205,9 +205,7 @@ sub getOrganizationName {
# @param string entityID
# @return Lasso::Login object
sub createAuthnRequest {
my $self = shift;
my $server = shift;
my $idp = shift;
my ( $self, $server, $idp ) = splice @_;
# Create Lasso Login
my $login = $self->createLogin($server);
@ -244,8 +242,7 @@ sub createAuthnRequest {
# @param Lasso::Server server
# @return Lasso::Login object
sub createLogin {
my $self = shift;
my $server = shift;
my ( $self, $server ) = splice @_;
my $login;
eval { $login = Lasso::Login->new($server); };
@ -261,13 +258,12 @@ sub createLogin {
# @param string entityID
# @return int HTTP method
sub getHttpMethod {
my $self = shift;
my $server = shift;
my $idp = shift;
my ( $self, $server, $idp ) = splice @_;
# TODO
# By default, use HTTP REDIRECT
no strict;
return Lasso::Constants::HTTP_METHOD_REDIRECT;
}
@ -278,10 +274,7 @@ sub getHttpMethod {
# @param int HTTP method
# @return boolean result
sub initAuthnRequest {
my $self = shift;
my $login = shift;
my $idp = shift;
my $method = shift;
my ( $self, $login, $idp, $method ) = splice @_;
eval { Lasso::Login::init_authn_request( $login, $idp, $method ); };
@ -293,8 +286,7 @@ sub initAuthnRequest {
# @param Lasso::Login login
# @return boolean result
sub buildAuthnRequestMsg {
my $self = shift;
my $login = shift;
my ( $self, $login ) = splice @_;
eval { Lasso::Login::build_authn_request_msg($login); };