Merge branch 'crypto-improvements'
This commit is contained in:
commit
1a1ccd7568
|
@ -133,7 +133,7 @@
|
|||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "llng-fastcgi-server 1"
|
||||
.TH llng-fastcgi-server 1 "2019-06-13" "perl v5.28.1" "User Contributed Perl Documentation"
|
||||
.TH llng-fastcgi-server 1 "2019-06-27" "perl v5.28.1" "User Contributed Perl Documentation"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
|
||||
],
|
||||
"dynamic_config" : 1,
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
||||
"license" : [
|
||||
"open_source"
|
||||
],
|
||||
"meta-spec" : {
|
||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
||||
"version" : "2"
|
||||
"version" : 2
|
||||
},
|
||||
"name" : "Lemonldap-NG-Common",
|
||||
"no_index" : {
|
||||
|
@ -41,7 +41,8 @@
|
|||
"DBI" : "0",
|
||||
"LWP::Protocol::https" : "0",
|
||||
"Net::LDAP" : "0",
|
||||
"SOAP::Lite" : "0"
|
||||
"SOAP::Lite" : "0",
|
||||
"String::Random" : "0"
|
||||
},
|
||||
"requires" : {
|
||||
"Apache::Session" : "0",
|
||||
|
|
|
@ -9,7 +9,7 @@ build_requires:
|
|||
configure_requires:
|
||||
ExtUtils::MakeMaker: '0'
|
||||
dynamic_config: 1
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
||||
license: open_source
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||
|
@ -28,6 +28,7 @@ recommends:
|
|||
LWP::Protocol::https: '0'
|
||||
Net::LDAP: '0'
|
||||
SOAP::Lite: '0'
|
||||
String::Random: '0'
|
||||
requires:
|
||||
Apache::Session: '0'
|
||||
Cache::Cache: '0'
|
||||
|
|
|
@ -34,6 +34,7 @@ WriteMakefile(
|
|||
'Convert::Base32' => 0,
|
||||
'Cookie::Baker::XS' => 0,
|
||||
'Crypt::URandom' => 0,
|
||||
'String::Random' => 0,
|
||||
'DBI' => 0,
|
||||
'Net::LDAP' => 0,
|
||||
'SOAP::Lite' => 0,
|
||||
|
|
|
@ -31,6 +31,9 @@ sub info {
|
|||
my $conf =
|
||||
$self->confAccess->getConf( { cfgNum => $self->cfgNum, raw => 1 } )
|
||||
or die $Lemonldap::NG::Common::Conf::msg;
|
||||
$conf->{cfgAuthorIP} ||= "No IP provided";
|
||||
$conf->{cfgDate} ||= 0;
|
||||
$conf->{cfgLog} ||= "No log provided";
|
||||
print qq{
|
||||
Num : $conf->{cfgNum}
|
||||
Author : $conf->{cfgAuthor}
|
||||
|
|
|
@ -12,9 +12,27 @@ use strict;
|
|||
use Crypt::Rijndael;
|
||||
use MIME::Base64;
|
||||
use Digest::MD5 qw(md5);
|
||||
use String::Random;
|
||||
use bytes;
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
my ( $newIv, $randG );
|
||||
|
||||
BEGIN {
|
||||
eval { require Crypt::URandom; Crypt::URandom::urandom(16) };
|
||||
if ($@) {
|
||||
$newIv = sub { return md5( rand() . time . {} ) };
|
||||
$randG = sub {
|
||||
my $a = 256;
|
||||
$a = unpack( "C", Crypt::URandom::urandom(1) ) while ( $a > $_[0] );
|
||||
return $a;
|
||||
};
|
||||
}
|
||||
else {
|
||||
$newIv = sub { return Crypt::URandom::urandom(16) };
|
||||
$randG = sub { return int( rand( $_[0] ) ) };
|
||||
}
|
||||
}
|
||||
|
||||
our $msg;
|
||||
|
||||
|
@ -41,11 +59,11 @@ sub new {
|
|||
# @param key that secondary key
|
||||
# @return Crypt::Rijndael object
|
||||
sub _getCipher {
|
||||
my ( $self, $key ) = @_;
|
||||
my ( $self, $key, $iv ) = @_;
|
||||
$key ||= "";
|
||||
$self->{ciphers}->{$key} ||=
|
||||
my $cipher =
|
||||
Crypt::Rijndael->new( md5( $self->{key}, $key ), $self->{mode} );
|
||||
return $self->{ciphers}->{$key};
|
||||
return $cipher;
|
||||
}
|
||||
|
||||
## @method string encrypt(string data)
|
||||
|
@ -53,13 +71,19 @@ sub _getCipher {
|
|||
# @param data data to encrypt
|
||||
# @return encrypted data in Base64 format
|
||||
sub encrypt {
|
||||
my ( $self, $data ) = @_;
|
||||
my ( $self, $data, $low ) = @_;
|
||||
|
||||
# pad $data so that its length be multiple of 16 bytes
|
||||
my $l = bytes::length($data) % 16;
|
||||
$data .= "\0" x ( 16 - $l ) unless ( $l == 0 );
|
||||
|
||||
eval { $data = encode_base64( $self->_getCipher->encrypt($data), '' ); };
|
||||
my $iv = $low ? md5( rand() . time . {} ) : $newIv->();
|
||||
my $hmac = md5($data);
|
||||
eval {
|
||||
$data =
|
||||
encode_base64(
|
||||
$iv . $hmac . $self->_getCipher->set_iv($iv)->encrypt($data), '' );
|
||||
};
|
||||
if ($@) {
|
||||
$msg = "Crypt::Rijndael error : $@";
|
||||
return undef;
|
||||
|
@ -81,11 +105,21 @@ sub decrypt {
|
|||
$data =~ s/%2F/\//ig;
|
||||
$data =~ s/%3D/=/ig;
|
||||
$data =~ s/%0A/\n/ig;
|
||||
eval { $data = $self->_getCipher->decrypt( decode_base64($data) ); };
|
||||
$data = decode_base64($data);
|
||||
my $iv;
|
||||
$iv = bytes::substr( $data, 0, 16 );
|
||||
my $hmac = bytes::substr( $data, 16, 16 );
|
||||
$data = bytes::substr( $data, 32 );
|
||||
eval { $data = $self->_getCipher->set_iv($iv)->decrypt($data); };
|
||||
|
||||
if ($@) {
|
||||
$msg = "Crypt::Rijndael error : $@";
|
||||
return undef;
|
||||
}
|
||||
if ( md5($data) ne $hmac ) {
|
||||
$msg = "Bad MAC";
|
||||
return undef;
|
||||
}
|
||||
else {
|
||||
$msg = '';
|
||||
|
||||
|
@ -141,15 +175,30 @@ sub _cryptHex {
|
|||
"Lemonldap::NG::Common::Crypto::${sub}Hex error : data length must be multiple of 32";
|
||||
return undef;
|
||||
}
|
||||
my $iv;
|
||||
if ( $sub eq 'encrypt' ) {
|
||||
$iv = $newIv->();
|
||||
}
|
||||
$data = pack "H*", $data;
|
||||
eval { $data = $self->_getCipher($key)->$sub($data); };
|
||||
if ( $sub eq 'decrypt' ) {
|
||||
$iv = bytes::substr( $data, 0, 16 );
|
||||
$data = bytes::substr( $data, 16 );
|
||||
}
|
||||
eval { $data = $self->_getCipher($key)->set_iv($iv)->$sub($data); };
|
||||
if ($@) {
|
||||
$msg = "Crypt::Rijndael error : $@";
|
||||
return undef;
|
||||
}
|
||||
if ( $sub eq 'encrypt' ) {
|
||||
$data = $iv . $data;
|
||||
}
|
||||
$msg = "";
|
||||
$data = unpack "H*", $data;
|
||||
return $data;
|
||||
}
|
||||
|
||||
sub srandom {
|
||||
return String::Random->new( rand_gen => $randG );
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||
|
||||
use Test::More tests => 21;
|
||||
use Test::More tests => 22;
|
||||
use Digest::MD5 qw(md5 md5_hex md5_base64);
|
||||
use strict;
|
||||
|
||||
|
@ -30,7 +30,11 @@ foreach my $i ( 1 .. 17 ) {
|
|||
my $s = '';
|
||||
$s = join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. $i ) );
|
||||
ok( $c->decrypt( $c->encrypt($s) ) eq $s,
|
||||
"Test of base64 encrypting with $i characters string" );
|
||||
"Test of base64 encrypting with $i characters string" )
|
||||
or diag "Source: $s\nCypher: "
|
||||
. $c->encrypt($s)
|
||||
. "\nUncipher:"
|
||||
. $c->decrypt( $c->encrypt($s) );
|
||||
}
|
||||
|
||||
my $data = md5_hex(rand);
|
||||
|
@ -42,6 +46,9 @@ ok(
|
|||
|
||||
# Test a long value, and replace carriage return by %0A
|
||||
my $long = "f5a1f72e7ab2f7712855a068af0066f36bfcf2c87e6feb9cf4200da1868e1dfe";
|
||||
my $cryptedlong =
|
||||
"Da6sYxp9NCXv8+8TirqHmPWwTQHyEGmkCBGCLCX/81dPSMwIQVQNV7X9KG3RrKZfyRmzJR6DZYdU%0Ab75+VH3+CA==";
|
||||
ok( $c->decrypt($cryptedlong) eq $long, "Test of long value encrypting" );
|
||||
ok( $c->decrypt( $c->encrypt($long) ) eq $long,
|
||||
"Test of long value encrypting" );
|
||||
ok(
|
||||
$c->decryptHex( $c->encryptHex($long) ) eq $long,
|
||||
"Test of long value encrypting (hex)"
|
||||
);
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
|
||||
],
|
||||
"dynamic_config" : 1,
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
||||
"license" : [
|
||||
"open_source"
|
||||
],
|
||||
"meta-spec" : {
|
||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
||||
"version" : "2"
|
||||
"version" : 2
|
||||
},
|
||||
"name" : "Lemonldap-NG-Handler",
|
||||
"no_index" : {
|
||||
|
|
|
@ -11,7 +11,7 @@ build_requires:
|
|||
configure_requires:
|
||||
ExtUtils::MakeMaker: '0'
|
||||
dynamic_config: 1
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
||||
license: open_source
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||
|
|
|
@ -103,7 +103,7 @@ sub build_jail {
|
|||
|
||||
# Import crypto methods for jail
|
||||
sub encrypt {
|
||||
return &Lemonldap::NG::Handler::Main::tsv->{cipher}->encrypt(@_);
|
||||
return &Lemonldap::NG::Handler::Main::tsv->{cipher}->encrypt( $_[0], 1 );
|
||||
}
|
||||
|
||||
sub token {
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
|
||||
],
|
||||
"dynamic_config" : 1,
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
||||
"license" : [
|
||||
"open_source"
|
||||
],
|
||||
"meta-spec" : {
|
||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
||||
"version" : "2"
|
||||
"version" : 2
|
||||
},
|
||||
"name" : "Lemonldap-NG-Manager",
|
||||
"no_index" : {
|
||||
|
|
|
@ -9,7 +9,7 @@ build_requires:
|
|||
configure_requires:
|
||||
ExtUtils::MakeMaker: '0'
|
||||
dynamic_config: 1
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
||||
license: open_source
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||
|
|
|
@ -11,7 +11,7 @@ sub perlExpr {
|
|||
[ '&encrypt', '&token' ] );
|
||||
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
|
||||
$Lemonldap::NG::Common::Safelib::functions );
|
||||
$cpt->reval("BEGIN { warnings->unimport; } $val");
|
||||
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
|
||||
my $err = join(
|
||||
'',
|
||||
grep( { $_ =~ /Undefined subroutine/ ? () : $_; } split( /\n/, $@, 0 ) )
|
||||
|
|
|
@ -18,7 +18,7 @@ sub perlExpr {
|
|||
[ '&encrypt', '&token' ] );
|
||||
$cpt->share_from( 'Lemonldap::NG::Common::Safelib',
|
||||
$Lemonldap::NG::Common::Safelib::functions );
|
||||
$cpt->reval("BEGIN { warnings->unimport; } $val");
|
||||
$cpt->reval("BEGIN { 'warnings'->unimport; } $val");
|
||||
my $err = join( '',
|
||||
grep { $_ =~ /Undefined subroutine/ ? () : $_ } split( /\n/, $@ ) );
|
||||
return $err ? ( 1, "__badExpression__: $err" ) : (1);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use Lemonldap::NG::Common::Conf;
|
||||
use Lemonldap::NG::Common::Conf::Constants;
|
||||
use Lemonldap::NG::Manager::Conf::Parser;
|
||||
use Lemonldap::NG::Handler::Main::Jail;
|
||||
use Data::Dumper;
|
||||
use English qw(-no_match_vars);
|
||||
use File::Temp;
|
||||
|
|
|
@ -301,7 +301,7 @@
|
|||
"hideTree":"Masquer l'arbre",
|
||||
"httpOnly":"Protection contre javascript",
|
||||
"https":"HTTPS",
|
||||
"impersonation":"Usurpation d'identité",
|
||||
"impersonation":"Simulation d'identité",
|
||||
"impersonationRule":"Règle d'utilisation",
|
||||
"impersonationIdRule":"Règle d'utilisation des identités",
|
||||
"impersonationHiddenAttributes":"Attributs masqués",
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
|
||||
],
|
||||
"dynamic_config" : 1,
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010",
|
||||
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
|
||||
"license" : [
|
||||
"open_source"
|
||||
],
|
||||
"meta-spec" : {
|
||||
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
|
||||
"version" : "2"
|
||||
"version" : 2
|
||||
},
|
||||
"name" : "Lemonldap-NG-Portal",
|
||||
"no_index" : {
|
||||
|
@ -57,7 +57,6 @@
|
|||
"Net::OpenID::Consumer" : "0",
|
||||
"Net::OpenID::Server" : "0",
|
||||
"SOAP::Lite" : "0",
|
||||
"String::Random" : "0",
|
||||
"Unicode::String" : "0",
|
||||
"Web::ID" : "0"
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@ build_requires:
|
|||
configure_requires:
|
||||
ExtUtils::MakeMaker: '0'
|
||||
dynamic_config: 1
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150010'
|
||||
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
|
||||
license: open_source
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||
|
@ -43,7 +43,6 @@ recommends:
|
|||
Net::OpenID::Consumer: '0'
|
||||
Net::OpenID::Server: '0'
|
||||
SOAP::Lite: '0'
|
||||
String::Random: '0'
|
||||
Unicode::String: '0'
|
||||
Web::ID: '0'
|
||||
requires:
|
||||
|
|
|
@ -28,7 +28,6 @@ WriteMakefile(
|
|||
'Net::OpenID::Consumer' => 0,
|
||||
'Net::OpenID::Server' => 0,
|
||||
'SOAP::Lite' => 0,
|
||||
'String::Random' => 0,
|
||||
'Unicode::String' => 0,
|
||||
'Web::ID' => 0,
|
||||
},
|
||||
|
|
|
@ -2,7 +2,6 @@ package Lemonldap::NG::Portal::2F::Ext2F;
|
|||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use String::Random;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
|
@ -38,7 +37,7 @@ sub init {
|
|||
$self->error("Missing 'ext2FSendCommand' parameter, aborting");
|
||||
return 0;
|
||||
}
|
||||
$self->random( String::Random->new );
|
||||
$self->random( Lemonldap::NG::Common::Crypto::srandom() );
|
||||
$self->logo( $self->conf->{ext2fLogo} )
|
||||
if ( $self->conf->{ext2fLogo} );
|
||||
return $self->SUPER::init();
|
||||
|
|
|
@ -2,7 +2,6 @@ package Lemonldap::NG::Portal::2F::Mail2F;
|
|||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use String::Random;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_BADCREDENTIALS
|
||||
PE_ERROR
|
||||
|
@ -23,7 +22,7 @@ has prefix => ( is => 'ro', default => 'mail' );
|
|||
has random => (
|
||||
is => 'rw',
|
||||
default => sub {
|
||||
return String::Random->new;
|
||||
return Lemonldap::NG::Common::Crypto::srandom();
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_ERROR
|
||||
PE_LOGOUT_OK
|
||||
PE_OK
|
||||
PE_BADURL
|
||||
PE_SENDRESPONSE
|
||||
);
|
||||
|
||||
|
@ -55,6 +56,18 @@ sub init {
|
|||
},
|
||||
['GET']
|
||||
);
|
||||
|
||||
# Add CAS Services, so we can check service= parameter on logout
|
||||
foreach my $casSrv ( keys %{ $self->conf->{casAppMetaDataOptions} } ) {
|
||||
if ( my $serviceUrl =
|
||||
$self->conf->{casAppMetaDataOptions}->{$casSrv}
|
||||
->{casAppMetaDataOptionsService} )
|
||||
{
|
||||
push @{ $self->p->{additionalTrustedDomains} }, $serviceUrl;
|
||||
$self->logger->debug(
|
||||
"CAS Service $serviceUrl added in trusted domains");
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -265,6 +278,19 @@ sub run {
|
|||
$logout_service = ''
|
||||
if ( $self->p->checkXSSAttack( 'service', $logout_service ) );
|
||||
|
||||
# If we use access control, check that the service URL is trusted
|
||||
if ( $self->conf->{casAccessControlPolicy} =~ /^(error|faketicket)$/i )
|
||||
{
|
||||
if ( $logout_service
|
||||
and not $self->p->isTrustedUrl($logout_service) )
|
||||
{
|
||||
$self->userLogger->error(
|
||||
"Untrusted service URL $logout_service"
|
||||
. "specified for CAS Logout" );
|
||||
return PE_BADURL;
|
||||
}
|
||||
}
|
||||
|
||||
# Delete linked CAS sessions
|
||||
$self->deleteCasSecondarySessions($session_id);
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ use Lemonldap::NG::Common::UserAgent;
|
|||
use Lemonldap::NG::Common::FormEncode;
|
||||
use XML::Simple;
|
||||
use MIME::Base64;
|
||||
use String::Random;
|
||||
use HTTP::Request; # SOAP call
|
||||
use POSIX qw(strftime); # Convert SAML2 date into timestamp
|
||||
use Time::Local; # Convert SAML2 date into timestamp
|
||||
|
|
|
@ -8,7 +8,6 @@ package Lemonldap::NG::Portal::Lib::SMTP;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use JSON qw(from_json);
|
||||
use String::Random;
|
||||
use MIME::Entity;
|
||||
use Email::Sender::Simple qw(sendmail);
|
||||
use Email::Sender::Transport::SMTP qw();
|
||||
|
@ -24,7 +23,7 @@ our $transport;
|
|||
has random => (
|
||||
is => 'rw',
|
||||
default => sub {
|
||||
return String::Random->new;
|
||||
return Lemonldap::NG::Common::Crypto::srandom();
|
||||
}
|
||||
);
|
||||
has charset => (
|
||||
|
|
|
@ -39,6 +39,7 @@ has _jsRedirect => ( is => 'rw' );
|
|||
|
||||
# TrustedDomain regexp
|
||||
has trustedDomainsRe => ( is => 'rw' );
|
||||
has additionalTrustedDomains => ( is => 'rw', default => sub { [] } );
|
||||
|
||||
# Lists to store plugins entry-points
|
||||
my @entryPoints;
|
||||
|
@ -269,53 +270,6 @@ sub reloadConf {
|
|||
unless $self->{_sfEngine} =
|
||||
$self->loadPlugin( $self->conf->{'sfEngine'} );
|
||||
|
||||
# Initialize trusted domain regexp
|
||||
if ( $self->conf->{trustedDomains}
|
||||
and $self->conf->{trustedDomains} =~ /^\s*\*\s*$/ )
|
||||
{
|
||||
$self->trustedDomainsRe(qr#^https?://#);
|
||||
}
|
||||
else {
|
||||
my $re = Regexp::Assemble->new();
|
||||
if ( my $td = $self->conf->{trustedDomains} ) {
|
||||
$td =~ s/^\s*(.*?)\s*/$1/;
|
||||
foreach ( split( /\s+/, $td ) ) {
|
||||
next unless ($td);
|
||||
s#^\.#([^/]+\.)?#;
|
||||
$self->logger->debug("Domain $_ added in trusted domains");
|
||||
s/\./\\./g;
|
||||
|
||||
# This regexp is valid for the followings hosts:
|
||||
# - $td
|
||||
# - $domainlabel.$td
|
||||
# $domainlabel is build looking RFC2396
|
||||
# (see Regexp::Common::URI::RFC2396)
|
||||
$_ =~
|
||||
s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g;
|
||||
$re->add("$_");
|
||||
}
|
||||
}
|
||||
my $p = $self->conf->{portal};
|
||||
$p =~ s#https?://([^/]*).*$#$1#;
|
||||
$re->add( quotemeta($p) );
|
||||
foreach my $vhost ( keys %{ $self->conf->{locationRules} } ) {
|
||||
$self->logger->debug("Vhost $vhost added in trusted domains");
|
||||
$re->add( quotemeta($vhost) );
|
||||
$self->conf->{vhostOptions} ||= {};
|
||||
if ( my $tmp =
|
||||
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
{
|
||||
foreach my $alias ( split /\s+/, $tmp ) {
|
||||
$self->logger->debug(
|
||||
"Alias $alias added in trusted domains");
|
||||
$re->add( quotemeta($alias) );
|
||||
}
|
||||
}
|
||||
}
|
||||
my $tmp = 'https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
|
||||
$self->trustedDomainsRe(qr/$tmp/);
|
||||
}
|
||||
|
||||
# Compile macros in _macros, groups in _groups
|
||||
foreach my $type (qw(macros groups)) {
|
||||
$self->{"_$type"} = {};
|
||||
|
@ -344,6 +298,59 @@ sub reloadConf {
|
|||
$self->loadPlugin($plugin) or return $self->fail;
|
||||
}
|
||||
|
||||
# Initialize trusted domain regexp
|
||||
if ( $self->conf->{trustedDomains}
|
||||
and $self->conf->{trustedDomains} =~ /^\s*\*\s*$/ )
|
||||
{
|
||||
$self->trustedDomainsRe(qr#^https?://#);
|
||||
}
|
||||
else {
|
||||
my $re = Regexp::Assemble->new();
|
||||
if ( my $td = $self->conf->{trustedDomains} ) {
|
||||
$td =~ s/^\s*(.*?)\s*/$1/;
|
||||
foreach ( split( /\s+/, $td ) ) {
|
||||
next unless ($td);
|
||||
s#^\.#([^/]+\.)?#;
|
||||
$self->logger->debug("Domain $_ added in trusted domains");
|
||||
s/\./\\./g;
|
||||
|
||||
# This regexp is valid for the followings hosts:
|
||||
# - $td
|
||||
# - $domainlabel.$td
|
||||
# $domainlabel is build looking RFC2396
|
||||
# (see Regexp::Common::URI::RFC2396)
|
||||
$_ =~
|
||||
s/\*\\\./(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9]\\.)*/g;
|
||||
$re->add("$_");
|
||||
}
|
||||
}
|
||||
foreach ( @{ $self->{additionalTrustedDomains} },
|
||||
$self->conf->{portal} )
|
||||
{
|
||||
my $p = $_;
|
||||
$p =~ s#https?://([^/]*).*$#$1#;
|
||||
$re->add( quotemeta($p) );
|
||||
}
|
||||
foreach my $vhost ( keys %{ $self->conf->{locationRules} } ) {
|
||||
$self->logger->debug("Vhost $vhost added in trusted domains");
|
||||
$re->add( quotemeta($vhost) );
|
||||
$self->conf->{vhostOptions} ||= {};
|
||||
if ( my $tmp =
|
||||
$self->conf->{vhostOptions}->{$vhost}->{vhostAliases} )
|
||||
{
|
||||
foreach my $alias ( split /\s+/, $tmp ) {
|
||||
$self->logger->debug(
|
||||
"Alias $alias added in trusted domains");
|
||||
$re->add( quotemeta($alias) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $tmp = 'https?://' . $re->as_string . '(?::\d+)?(?:/|$)';
|
||||
$self->trustedDomainsRe(qr/$tmp/);
|
||||
|
||||
}
|
||||
|
||||
# Clean $req->pdata after authentication
|
||||
push @{ $self->endAuth }, sub {
|
||||
unless ( $_[0]->pdata->{keepPdata} ) {
|
||||
|
|
|
@ -152,7 +152,7 @@ ok( $res->{cn} eq 'Frédéric Accents', 'UTF-8 values' )
|
|||
or explain( $res, 'cn => Frédéric Accents' );
|
||||
count(3);
|
||||
|
||||
# Logout initiated by CAS
|
||||
# Logout initiated by CAS, try with invalid service URL first
|
||||
switch ('issuer');
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
|
@ -164,7 +164,22 @@ ok(
|
|||
'Query SP for logout'
|
||||
);
|
||||
count(1);
|
||||
expectRedirection( $res, 'http://url.test/' );
|
||||
ok( $res->[2]->[0] =~ m%<span trmsg="37"></span>%, ' PE37 found' );
|
||||
count(1);
|
||||
|
||||
# Logout initiated by CAS, try with valid service URL
|
||||
ok(
|
||||
$res = $issuer->_get(
|
||||
'/cas/logout',
|
||||
query => 'service=http://auth.sp.com/',
|
||||
cookie => "lemonldap=$idpId,llngcasserver=idp",
|
||||
accept => 'text/html'
|
||||
),
|
||||
'Query SP for logout'
|
||||
);
|
||||
count(1);
|
||||
|
||||
expectRedirection( $res, 'http://auth.sp.com/' );
|
||||
|
||||
# Verify that user has been disconnected
|
||||
ok( $res = $issuer->_get( '/', cookie => "lemonldap=$idpId" ), 'Query IdP' );
|
||||
|
@ -192,8 +207,13 @@ sub issuer {
|
|||
issuerDBCASActivation => 1,
|
||||
casAttr => 'uid',
|
||||
casAttributes => { cn => 'cn', uid => 'uid', },
|
||||
casAccessControlPolicy => 'none',
|
||||
casAccessControlPolicy => 'error',
|
||||
multiValuesSeparator => ';',
|
||||
casAppMetaDataOptions => {
|
||||
sp => {
|
||||
casAppMetaDataOptionsService => 'http://auth.sp.com',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -44,8 +44,8 @@ my $id1 = expectCookie($res);
|
|||
my $id2 = expectCookie( $res, 'lemonldaphttp' );
|
||||
|
||||
# Check lemonldap Cookie
|
||||
ok( $id1 =~ /^\w{64}$/, " -> Get cookie : lemonldap=something" )
|
||||
or explain( $res->[1], "Set-Cookie: lemonldap=$id1" );
|
||||
ok( $id1 =~ /^\w{64}$/, " -> https cookie is 64 char long" )
|
||||
or explain( $id1, '64-char string' );
|
||||
ok( ${ $res->[1] }[3] =~ /HttpOnly=1/, " -> Cookie 'lemonldap' is HttpOnly" )
|
||||
or explain( $res->[1] );
|
||||
ok( ${ $res->[1] }[3] =~ /secure/, " -> Cookie 'lemonldap' is secure" )
|
||||
|
@ -53,8 +53,8 @@ ok( ${ $res->[1] }[3] =~ /secure/, " -> Cookie 'lemonldap' is secure" )
|
|||
count(3);
|
||||
|
||||
# Check lemonldaphttp Cookie
|
||||
ok( $id2 =~ /^\w{64}$/, " -> Get cookie lemonldaphttp=something" )
|
||||
or explain( $res->[1], "Set-Cookie: lemonldaphttp=$id2" );
|
||||
ok( length($id2) % 32 == 0, " -> http cookie is 96 byte long" )
|
||||
or explain( $id2, '\w x 32 string' );
|
||||
ok(
|
||||
${ $res->[1] }[5] =~ /HttpOnly=1/,
|
||||
" -> Cookie 'lemonldaphttp' is HttpOnly"
|
||||
|
|
Loading…
Reference in New Issue