Merge branch 'v2.0'

This commit is contained in:
Xavier Guimard 2019-06-07 17:48:32 +02:00
commit f59681e80e
13 changed files with 203 additions and 55 deletions

View File

@ -37,6 +37,19 @@ sub addUnauthRoute {
return $self->SUPER::addRoute(@_);
}
sub addAuthRouteWithRedirect {
my $self = shift;
$self->logger->debug("Route with redirect to $_[0]");
$self->addAuthRoute(@_);
$self->addUnauthRoute( $_[0] => '_auth_and_redirect', [ 'GET', 'POST' ] );
}
sub _auth_and_redirect {
my ( $self, $req ) = @_;
$self->api->goToPortal( $req, $req->{env}->{REQUEST_URI} );
return [ 302, $req->respHeaders, [] ];
}
sub defaultAuthRoute {
my $self = shift;
$self->routes( $self->authRoutes );

View File

@ -28,8 +28,14 @@ sub types {
'msgFail' => '__notAValidPerlExpression__',
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -664,8 +670,14 @@ sub attributes {
'casAppMetaDataOptionsRule' => {
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -793,8 +805,14 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'default' => 1,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1110,8 +1128,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'keyTest' => qr/^(?=[^\-])[\w\-]+(?<=[^-])$/,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = $val;
'Safe'->new->reval("BEGIN { warnings->unimport; } $s");
my $s = $val;
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1210,8 +1234,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'grantSessionRules' => {
'keyTest' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1228,8 +1258,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'default' => {},
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1271,8 +1307,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'default' => 1,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1624,7 +1666,13 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
: ( 0, '__badUrl__' );
}
$s =~ s/\b(accept|deny|unprotect|skip)\b/1/g;
'Safe'->new->reval("BEGIN { warnings->unimport; } $s");
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -1664,8 +1712,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'keyTest' => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -2054,8 +2108,14 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'oidcRPMetaDataOptionsRule' => {
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -2403,8 +2463,14 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'keyMsgFail' => '__badSkinRule__',
'keyTest' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }
@ -3146,8 +3212,14 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'samlSPMetaDataOptionsRule' => {
'test' => sub {
my ( $val, $conf ) = @_;
my $s = '';
'Safe'->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = 'Safe'->new;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join(
'',
grep( { $_ =~ /Undefined subroutine/ ? () : $_; }

View File

@ -12,8 +12,14 @@ use Regexp::Common qw/URI/;
my $perlExpr = sub {
my ( $val, $conf ) = @_;
my $s = '';
Safe->new->reval("BEGIN { warnings->unimport; } $s $val");
my $s = '';
my $cpt = new Safe;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s $val");
my $err = join( '',
grep { $_ =~ /Undefined subroutine/ ? () : $_ } split( /\n/, $@ ) );
return $err ? ( 1, "__badExpression__: $err" ) : (1);
@ -511,6 +517,7 @@ sub attributes {
documentation => 'Handler ServiceToken timeout',
flags => 'hp',
},
# Loggers (ini only)
logLevel => {
type => 'text',
@ -754,9 +761,8 @@ sub attributes {
},
corsMax_Age => {
type => 'text',
default => '86400', # 24 hours
documentation =>
'MAx-age for Cross-Origin Resource Sharing',
default => '86400', # 24 hours
documentation => 'MAx-age for Cross-Origin Resource Sharing',
},
cspDefault => {
type => 'text',
@ -1692,7 +1698,13 @@ sub attributes {
: ( 0, '__badUrl__' );
}
$s =~ s/\b(accept|deny|unprotect|skip)\b/1/g;
Safe->new->reval("BEGIN { warnings->unimport; } $s");
my $cpt = new Safe;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s");
my $err = join( '',
grep { $_ =~ /Undefined subroutine/ ? () : $_ }
split( /\n/, $@ ) );
@ -1716,8 +1728,14 @@ sub attributes {
keyMsgFail => '__badHeaderName__',
test => sub {
my ( $val, $conf ) = @_;
my $s = $val;
Safe->new->reval("BEGIN { warnings->unimport; } $s");
my $s = $val;
my $cpt = new Safe;
$cpt->share_from( 'MIME::Base64', ['&encode_base64'] );
$cpt->share_from( 'Lemonldap::NG::Handler::Main::Jail',
[ '&encrypt', '&token' ] );
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
$Lemonldap::NG::Common::Safelib::functions );
$cpt->reval("BEGIN { warnings->unimport; } $s");
my $err = join( '',
grep { $_ =~ /Undefined subroutine/ ? () : $_ }
split( /\n/, $@ ) );

View File

@ -149,12 +149,12 @@
"cspFont":"Sources des polices",
"crossOrigineResourceSharing":"Partage des ressources entre origines multiples",
"corsEnabled":"Activation",
"corsAllow_Credentials":"Informations d'authentification autorisées",
"corsAllow_Headers":"Entêtes autorisés",
"corsAllow_Methods":"Méthodes autorisées",
"corsAllow_Origin":"Origine autorisée",
"corsExpose_Headers":"Entêtes en liste blanche",
"corsMax_Age":"Durée de mise en cache de la requête préliminaire",
"corsAllow_Credentials":"Access-Control-Allow-Credentials",
"corsAllow_Headers":"Access-Control-Allow-Headers",
"corsAllow_Methods":"Access-Control-Allow-Methods",
"corsAllow_Origin":"Access-Control-Allow-Origin",
"corsExpose_Headers":"Access-Control-Expose-Headers",
"corsMax_Age":"Access-Control-Max-Age",
"cfgLog":"Résumé",
"cfgVersion":"Version de la configuration",
"checkXSS":"Contrôler les attaques XSS",

View File

@ -148,7 +148,7 @@
"cspConnect":"Destinazioni Ajax",
"cspFont":"Origine carattere",
"crossOrigineResourceSharing":"Cross-Origin Resource Sharing",
"corsEnabled":"Activation",
"corsEnabled":"Attivazione",
"corsAllow_Credentials":"Access-Control-Allow-Credentials",
"corsAllow_Headers":"Access-Control-Allow-Headers",
"corsAllow_Methods":"Access-Control-Allow-Methods",

View File

@ -38,8 +38,8 @@ foreach my $i ( 0 .. 1 ) {
}
ok(
@{ $resBody->{details}->{__changes__} } == 20,
'JSON response contains 20 changes'
@{ $resBody->{details}->{__changes__} } == 22,
'JSON response contains 22 changes'
) or print STDERR Dumper($resBody);
#print STDERR Dumper($resBody);
@ -193,6 +193,16 @@ sub changes {
'old' => undef,
'new' => '$uid'
},
{
'key' => 'exportedHeaders, test3.example.com, cipherId',
'old' => undef,
'new' => 'encrypt($uid)'
},
{
'key' => 'exportedHeaders, test3.example.com, encodeId',
'old' => undef,
'new' => 'encode_base64($uid)'
},
{
'new' => 'test3.example.com',
'key' => 'exportedHeaders'

View File

@ -1870,6 +1870,16 @@
"type": "keyText",
"title": "Auth-User",
"data": "$uid"
},{
"id": "virtualHosts/test2.example.com/exportedHeaders/2",
"type": "keyText",
"title": "cipherId",
"data": "encrypt($uid)"
},{
"id": "virtualHosts/test2.example.com/exportedHeaders/3",
"type": "keyText",
"title": "encodeId",
"data": "encode_base64($uid)"
}]
}, {
"id": "virtualHosts/test2.example.com/post",

View File

@ -70,6 +70,7 @@ sub authenticate {
my $res =
$self->userBind( $req, $req->data->{dn},
password => $req->data->{password} );
$self->setSecurity($req) if ( $res > PE_OK );
# Remember password if password reset needed
if (

View File

@ -30,6 +30,11 @@ sub addUnauthRoute {
return $self->_addRoute( 'addUnauthRoute', @_ );
}
sub addAuthRouteWithRedirect {
my $self = shift;
return $self->_addRoute( 'addAuthRouteWithRedirect', @_ );
}
sub _addRoute {
my ( $self, $type, $word, $subName, $methods, $transform ) = @_;
$transform //= sub {
@ -146,6 +151,11 @@ Example:
return $self->p->sendHtml($req, 'template', params => { WELLCOME => 1 });
}
If you want to get a "protected application" behavior, you can use
B<addAuthRouteWithRedirect>. This methods calls B<addAuthRoute> with given
arguments and build a "unAuth" route that build a redirection after
authentication.
=head3 Entry point in auth process
A plugin which wants to be inserted in authentication process has to declare

View File

@ -38,8 +38,8 @@ sub hAttr {
sub init {
my ($self) = @_;
my $hd = $self->p->HANDLER;
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRoute( checkuser => 'display', ['GET'] );
$self->addAuthRoute( checkuser => 'check', ['POST'] );
$self->addAuthRouteWithRedirect( checkuser => 'display', ['GET'] );
# Parse identity rule
$self->logger->debug(
@ -153,9 +153,8 @@ sub check {
$req->{user} = $user;
$self->userLogger->notice(
"NO session found in DB. Compute userData...");
$self->logger->debug(
"NO session found in DB. Compute userData...");
$attrs = $self->_userData($req);
$self->logger->debug("NO session found in DB. Compute userData...");
$attrs = $self->_userData($req);
$compute = 1;
}
}
@ -203,11 +202,13 @@ sub check {
# User is allowed ?
$self->logger->debug(
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url");
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url"
);
$auth = $self->_authorization( $req, $url, $attrs );
if ( $auth >= 0 ) {
$auth = $auth ? "allowed" : "forbidden";
$self->userLogger->notice( "checkUser -> $attrs->{ $self->{conf}->{whatToTrace} } is "
$self->userLogger->notice(
"checkUser -> $attrs->{ $self->{conf}->{whatToTrace} } is "
. uc($auth)
. " to access: $url" );
@ -379,10 +380,10 @@ sub _authorization {
}
}
$self->logger->debug("Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" authorization");
$self->logger->debug(
"Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" authorization");
return $exist
? $self->p->HANDLER->grant( $req, $attrs, $appuri,
undef, $vhost )
? $self->p->HANDLER->grant( $req, $attrs, $appuri, undef, $vhost )
: -1;
}
@ -393,7 +394,8 @@ sub _headers {
$vhost =~ s/:\d+$//;
$req->{env}->{HTTP_HOST} = $vhost;
$self->p->HANDLER->headersInit( $self->{conf} );
$self->logger->debug("Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" headers");
$self->logger->debug(
"Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" headers");
return $self->p->HANDLER->checkHeaders( $req, $attrs );
}

View File

@ -77,7 +77,7 @@
"PE85":"Le site souhaite une authentification plus récente (et le plugin UpgradeSession n'est pas chargé). Déconnectez-vous et réessayez",
"PE86":"Votre compte est verrouillé. Vous devez attendre 30s avant de vous ré-authentifier.",
"PE87":"Vous devez vous ré-authentifier pour pouvoir accéder au Portail",
"PE88":"une adresse email doit être renseignée pour pouvoir utiliser l'authentification à double facteurs.",
"PE88":"Une adresse email doit être renseignée pour pouvoir utiliser l'authentification à double facteurs.",
"PE89":"Accès non autorisé au service SAML",
"PE90":"Accès non autorisé au service OIDC",
"PE91":"Accès non autorisé au service OID",

View File

@ -25,6 +25,13 @@ my $client = LLNG::Manager::Test->new( {
}
);
ok( $res = $client->_get( '/checkuser', accept => 'text/html' ),
'Test unauth redirection' );
expectRedirection( $res,
'http://auth.example.com/?url=aHR0cDovL2F1dGguZXhhbXBsZS5jb20vY2hlY2t1c2Vy'
);
count(1);
## Try to authenticate
ok(
$res = $client->_post(
@ -36,7 +43,6 @@ ok(
'Auth query'
);
count(1);
my $id = expectCookie($res);
expectRedirection( $res, 'http://auth.example.com/' );
@ -146,7 +152,8 @@ count(3);
# Request with bad VH
$query =~ s/user=dwho/user=rtyler/;
$query =~ s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Ftry.example.com/;
$query =~
s/url=http%3A%2F%2Ftest1.example.com/url=http%3A%2F%2Ftry.example.com/;
ok(
$res = $client->_post(
'/checkuser',
@ -166,7 +173,8 @@ ok( $res->[2]->[0] =~ m%<span trspan="VHnotFound">%,
count(1);
# Request with forbidden URL
$query =~ s#url=http%3A%2F%2Ftry.example.com#url=http%3A%2F%2Fauth.example.com/checkuser#;
$query =~
s#url=http%3A%2F%2Ftry.example.com#url=http%3A%2F%2Fauth.example.com/checkuser#;
ok(
$res = $client->_post(
'/checkuser',

View File

@ -57,6 +57,7 @@ URL: http://lemonldap-ng.org
Source0: https://release.ow2.org/lemonldap/%{name}-%{version}%{?pre_release:~%{pre_release}}.tar.gz
BuildArch: noarch
BuildRequires: gnupg
BuildRequires: perl-generators
BuildRequires: perl-interpreter
BuildRequires: perl(Apache2::Connection)
@ -661,6 +662,9 @@ fi
# Changelog
#==============================================================================
%changelog
* Fri Jun 07 2019 Xavier Bachelot <xavier@bachelot.org> - 2.0.4-2
- BR: gnupg to fix test 29-AuthGPG.t failure in manager.
* Sun May 12 2019 Clement Oudot <clem.oudot@gmail.com> - 2.0.4-1
- Update to 2.0.4