This commit is contained in:
Xavier Guimard 2017-02-16 10:42:22 +00:00
parent 271a30ec28
commit ed748080d1
4 changed files with 89 additions and 80 deletions

View File

@ -0,0 +1,84 @@
package Lemonldap::NG::Handler::Lib::CDA;
use strict;
sub run {
my ( $class, $req, $rule, $protection ) = @_;
my $uri = $class->unparsed_uri;
my $cn = $class->tsv->{cookieName};
my ( $id, $session );
if( $uri =~ s/[\?&;]${cn}cda=(\w+)$//oi ) {
if ( $id = $class->fetchId and $session = $class->retrieveSession($id) ) {
$class->logger->info(
'CDA asked for an already available session, skipping');
}
else {
my $cdaid = $1;
$class->logger->debug("CDA request with id $cdaid");
my $cdaInfos = $class->getCDAInfos($cdaid);
unless ( $cdaInfos->{cookie_value} and $cdaInfos->{cookie_name} ) {
$class->logger->error("CDA request for id $cdaid is not valid");
return $class->FORBIDDEN;
}
my $redirectUrl = $class->_buildUrl($uri);
my $redirectHttps = ( $redirectUrl =~ m/^https/ );
$class->set_header_out(
'Location' => $redirectUrl,
'Set-Cookie' => $cdaInfos->{cookie_name} . "=" . 'c:'
. $class->tsv->{cipher}->encrypt(
$cdaInfos->{cookie_value} . ' ' . $class->resolveAlias
)
. "; path=/"
. ( $redirectHttps ? "; secure" : "" )
. ( $class->tsv->{httpOnly} ? "; HttpOnly" : "" )
. (
$class->tsv->{cookieExpiration}
? "; expires="
. expires( $class->tsv->{cookieExpiration}, 'cookie' )
: ""
)
);
return $class->REDIRECT;
}
}
return $class->SUPER::init( $req, $rule, $protection );
}
## @rmethod protected hash getCDAInfos(id)
# Tries to retrieve the CDA session, get infos and delete session
# @return CDA session infos
sub getCDAInfos {
my ( $class, $id ) = @_;
my $infos = {};
# Get the session
my $cdaSession = Lemonldap::NG::Common::Session->new(
{
storageModule => $class->tsv->{sessionStorageModule},
storageModuleOptions => $class->tsv->{sessionStorageOptions},
cacheModule => $class->tsv->{sessionCacheModule},
cacheModuleOptions => $class->tsv->{sessionCacheOptions},
id => $id,
kind => "CDA",
}
);
unless ( $cdaSession->error ) {
$class->logger->debug("Get CDA session $id");
$infos->{cookie_value} = $cdaSession->data->{cookie_value};
$infos->{cookie_name} = $cdaSession->data->{cookie_name};
$cdaSession->remove;
}
else {
$class->logger->info("CDA Session $id can't be retrieved");
$class->logger->info( $cdaSession->error );
}
return $infos;
}
1;

View File

@ -95,7 +95,6 @@ sub reload {
# - jail
# - defaultValuesInit():
# (scalars for global options)
# - cda
# - cookieExpiration # warning: absent from default Conf
# - cookieName
# - securedCookie,
@ -182,11 +181,10 @@ sub defaultValuesInit {
$class->tsv->{$_} = $conf->{$_} foreach (
qw(
cda cookieExpiration cookieName
customFunctions httpOnly securedCookie
timeout timeoutActivity timeoutActivityInterval
useRedirectOnError useRedirectOnForbidden useSafeJail
whatToTrace
cookieExpiration cookieName customFunctions httpOnly
securedCookie timeout timeoutActivity
timeoutActivityInterval useRedirectOnError useRedirectOnForbidden
useSafeJail whatToTrace
)
);

View File

@ -101,45 +101,6 @@ sub run {
# Cross domain authentication
my $uri = $class->unparsed_uri;
my $cn = $class->tsv->{cookieName};
if ( $class->tsv->{cda}
and $uri =~ s/[\?&;]${cn}cda=(\w+)$//oi )
{
if ( $class->fetchId and $session = $class->retrieveSession($id) ) {
$class->logger->info(
'CDA asked for an already available session, skipping');
}
else {
my $cdaid = $1;
$class->logger->debug("CDA request with id $cdaid");
my $cdaInfos = $class->getCDAInfos($cdaid);
unless ( $cdaInfos->{cookie_value} and $cdaInfos->{cookie_name} ) {
$class->logger->error("CDA request for id $cdaid is not valid");
return $class->FORBIDDEN;
}
my $redirectUrl = $class->_buildUrl($uri);
my $redirectHttps = ( $redirectUrl =~ m/^https/ );
$class->set_header_out(
'Location' => $redirectUrl,
'Set-Cookie' => $cdaInfos->{cookie_name} . "=" . 'c:'
. $class->tsv->{cipher}->encrypt(
$cdaInfos->{cookie_value} . ' ' . $class->resolveAlias
)
. "; path=/"
. ( $redirectHttps ? "; secure" : "" )
. ( $class->tsv->{httpOnly} ? "; HttpOnly" : "" )
. (
$class->tsv->{cookieExpiration}
? "; expires="
. expires( $class->tsv->{cookieExpiration}, 'cookie' )
: ""
)
);
return $class->REDIRECT;
}
}
$uri = $class->uri_with_args;
my ($cond);
@ -494,41 +455,6 @@ sub retrieveSession {
}
}
## @rmethod protected hash getCDAInfos(id)
# Tries to retrieve the CDA session, get infos and delete session
# @return CDA session infos
sub getCDAInfos {
my ( $class, $id ) = @_;
my $infos = {};
# Get the session
my $cdaSession = Lemonldap::NG::Common::Session->new(
{
storageModule => $class->tsv->{sessionStorageModule},
storageModuleOptions => $class->tsv->{sessionStorageOptions},
cacheModule => $class->tsv->{sessionCacheModule},
cacheModuleOptions => $class->tsv->{sessionCacheOptions},
id => $id,
kind => "CDA",
}
);
unless ( $cdaSession->error ) {
$class->logger->debug("Get CDA session $id");
$infos->{cookie_value} = $cdaSession->data->{cookie_value};
$infos->{cookie_name} = $cdaSession->data->{cookie_name};
$cdaSession->remove;
}
else {
$class->logger->info("CDA Session $id can't be retrieved");
$class->logger->info( $cdaSession->error );
}
return $infos;
}
## @cmethod private string _buildUrl(string s)
# Transform /<s> into http(s?)://<host>:<port>/s
# @param $s path

View File

@ -1110,6 +1110,7 @@ sub attributes {
{ k => 'Zimbra', v => 'ZimbraPreAuth' },
{ k => 'AuthBasic', v => 'AuthBasic' },
{ k => 'SecureToken', v => 'SecureToken' },
{ k => 'CDA', v => 'CDA' },
],
default => 'Main',
documentation => 'Handler type',