Commit 09d9608f authored by Christophe Maudoux's avatar Christophe Maudoux 🐛
Browse files

Modify Handler internal cache timeout & code order & Append debug mgs (#1509)

parent e6c034a3
......@@ -57,10 +57,10 @@ sub updateStatus {
$user ||= Lemonldap::NG::Handler::API->remote_ip;
$url ||= Lemonldap::NG::Handler::API->uri_with_args;
eval {
print $statusPipe "$user => "
. Lemonldap::NG::Handler::API->hostname
. "$url $action\n"
if ($statusPipe);
print $statusPipe "$user => "
. Lemonldap::NG::Handler::API->hostname
. "$url $action\n"
if ($statusPipe);
};
}
......@@ -84,8 +84,8 @@ sub forbidden {
my $vhost = $class->resolveAlias;
Lemonldap::NG::Handler::Main::Logger->lmLog(
"User "
. $datas->{ $tsv->{whatToTrace} }
. " was forbidden to access to $vhost$uri",
. $datas->{ $tsv->{whatToTrace} }
. " was forbidden to access to $vhost$uri",
"notice"
);
$class->updateStatus( 'REJECT', $datas->{ $tsv->{whatToTrace} } );
......@@ -97,8 +97,8 @@ sub forbidden {
return $class->goToPortal( $uri, 'lmError=403' );
}
else {
Lemonldap::NG::Handler::Main::Logger->lmLog( "Return forbidden access",
'debug' );
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Return forbidden access", 'debug' );
return FORBIDDEN;
}
}
......@@ -138,14 +138,14 @@ sub goToPortal {
my $urlc_init = $class->encodeUrl($url);
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Redirect "
. Lemonldap::NG::Handler::API->remote_ip
. " to portal (url was $url)",
. Lemonldap::NG::Handler::API->remote_ip
. " to portal (url was $url)",
'debug'
);
Lemonldap::NG::Handler::API->set_header_out(
'Location' => &{ $tsv->{portal} }()
. "?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
'Location' => &{ $tsv->{portal} }()
. "?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
return REDIRECT;
}
......@@ -157,18 +157,18 @@ sub fetchId {
my $t = Lemonldap::NG::Handler::API->header_in('Cookie');
my $vhost = $class->resolveAlias;
my $lookForHttpCookie = $tsv->{securedCookie} =~ /^(2|3)$/
&& !(
&& !(
defined( $tsv->{https}->{$vhost} )
? $tsv->{https}->{$vhost}
: $tsv->{https}->{_}
);
my $value =
$lookForHttpCookie
? ( $t =~ /$tsv->{cookieName}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$tsv->{cookieName}=([^,; ]+)/o ? $1 : 0 );
);
my $value
= $lookForHttpCookie
? ( $t =~ /$tsv->{cookieName}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$tsv->{cookieName}=([^,; ]+)/o ? $1 : 0 );
$value = $tsv->{cipher}->decryptHex( $value, "http" )
if ( $value && $lookForHttpCookie && $tsv->{securedCookie} == 3 );
if ( $value && $lookForHttpCookie && $tsv->{securedCookie} == 3 );
return $value;
}
......@@ -179,11 +179,11 @@ sub retrieveSession {
my ( $class, $id ) = @_;
my $now = time();
# 1. Search if the user was the same as previous (very efficient in
# persistent connection).
# 1. Search if the user was the same as previous (very efficient in
# persistent connection). Timeout is same value as current HTTP/1.1 Keep-Alive timeout
if ( defined $datas->{_session_id}
and $id eq $datas->{_session_id}
and ( $now - $datasUpdate < 60 ) )
and ( $now - $datasUpdate < 15 ) )
{
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Get session $id from Handler internal cache", 'debug' );
......@@ -192,8 +192,7 @@ sub retrieveSession {
# 2. Get the session from cache or backend
$session = Lemonldap::NG::Common::Session->new(
{
storageModule => $tsv->{sessionStorageModule},
{ storageModule => $tsv->{sessionStorageModule},
storageModuleOptions => $tsv->{sessionStorageOptions},
cacheModule => $tsv->{sessionCacheModule},
cacheModuleOptions => $tsv->{sessionCacheOptions},
......@@ -209,6 +208,35 @@ sub retrieveSession {
Lemonldap::NG::Handler::Main::Logger->lmLog( "Get session $id",
'debug' );
# Verify that session is valid
Lemonldap::NG::Handler::Main::Logger->lmLog(
"_utime is not defined. This should not happen. Verify it is transmitted correctly to handler",
'error'
) unless $datas->{_utime};
Lemonldap::NG::Handler::Main::Logger->lmLog( "now -> $now", 'debug' );
Lemonldap::NG::Handler::Main::Logger->lmLog(
"_lastSeen -> " . $datas->{_lastSeen}, 'debug' )
if ( $datas->{_lastSeen} );
my $delta = $now - $datas->{_lastSeen} if ( $datas->{_lastSeen} );
Lemonldap::NG::Handler::Main::Logger->lmLog(
"now - _lastSeen = $delta", 'debug' )
if ( $datas->{_lastSeen} );
if ($now - $datas->{_utime} > $tsv->{timeout}
or ( $tsv->{timeoutActivity}
and $datas->{_lastSeen}
and $now - $datas->{_lastSeen} > $tsv->{timeoutActivity} )
)
{
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Session $id expired", 'info' );
# Clean cached data
$datas = {};
return 0;
}
# Update the session to notify activity, if necessary
if ( $tsv->{timeoutActivity}
and
......@@ -225,37 +253,17 @@ sub retrieveSession {
}
else {
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Update _lastSeen with $now", 'debug' );
"Update _lastSeen with $now from Handler", 'debug' );
}
}
# Verify that session is valid
Lemonldap::NG::Handler::Main::Logger->lmLog(
"_utime is not defined. This should not happen. Verify it is transmitted correctly to handler",
'error'
) unless $datas->{_utime};
if (
$now - $datas->{_utime} > $tsv->{timeout}
or ( $tsv->{timeoutActivity}
and $datas->{_lastSeen}
and $now - $datas->{_lastSeen} > $tsv->{timeoutActivity} )
)
{
Lemonldap::NG::Handler::Main::Logger->lmLog( "Session $id expired",
'info' );
# Clean cached data
$datas = {};
return 0;
}
$datasUpdate = $now;
return 1;
}
else {
Lemonldap::NG::Handler::Main::Logger->lmLog(
"Session $id can't be retrieved", 'info' );
Lemonldap::NG::Handler::Main::Logger->lmLog( $session->error, 'info' );
Lemonldap::NG::Handler::Main::Logger->lmLog( $session->error,
'info' );
return 0;
}
......@@ -270,8 +278,7 @@ sub getCDAInfos {
# Get the session
my $cdaSession = Lemonldap::NG::Common::Session->new(
{
storageModule => $tsv->{sessionStorageModule},
{ storageModule => $tsv->{sessionStorageModule},
storageModuleOptions => $tsv->{sessionStorageOptions},
cacheModule => $tsv->{sessionCacheModule},
cacheModuleOptions => $tsv->{sessionCacheOptions},
......@@ -317,7 +324,7 @@ sub getCDAInfos {
sub run {
my ( $class, $cond, $protection ) = @_;
return DECLINED
unless ( Lemonldap::NG::Handler::API->is_initial_req );
unless ( Lemonldap::NG::Handler::API->is_initial_req );
# Direct return if maintenance mode is active
if ( $class->checkMaintenanceMode ) {
......@@ -355,22 +362,22 @@ sub run {
Lemonldap::NG::Handler::API->set_header_out(
'Location' => $redirectUrl,
'Set-Cookie' => $cdaInfos->{cookie_name} . "="
. $cdaInfos->{cookie_value}
. "; path=/"
. ( $redirectHttps ? "; secure" : "" )
. ( $tsv->{httpOnly} ? "; HttpOnly" : "" )
. (
. $cdaInfos->{cookie_value}
. "; path=/"
. ( $redirectHttps ? "; secure" : "" )
. ( $tsv->{httpOnly} ? "; HttpOnly" : "" )
. (
$tsv->{cookieExpiration}
? "; expires=" . expires( $tsv->{cookieExpiration}, 'cookie' )
: ""
)
)
);
return REDIRECT;
}
$uri = Lemonldap::NG::Handler::API->uri_with_args;
$protection = $class->isUnprotected($uri)
unless ( defined $protection );
unless ( defined $protection );
if ( $protection == SKIP ) {
Lemonldap::NG::Handler::Main::Logger->lmLog( "Access control skipped",
......@@ -417,8 +424,8 @@ sub run {
# Log access granted
Lemonldap::NG::Handler::Main::Logger->lmLog(
"User "
. $datas->{ $tsv->{whatToTrace} }
. " was granted to access to $uri",
. $datas->{ $tsv->{whatToTrace} }
. " was granted to access to $uri",
'debug'
);
......@@ -443,12 +450,14 @@ sub run {
else {
# Redirect user to the portal
Lemonldap::NG::Handler::Main::Logger->lmLog( "No cookie found", 'info' )
unless ($id);
Lemonldap::NG::Handler::Main::Logger->lmLog( "No cookie found",
'info' )
unless ($id);
# if the cookie was fetched, a log is sent by retrieveSession()
$class->updateStatus( $id ? 'EXPIRED' : 'REDIRECT' );
return $class->goToPortal( Lemonldap::NG::Handler::API->unparsed_uri );
return $class->goToPortal(
Lemonldap::NG::Handler::API->unparsed_uri );
}
}
......@@ -458,10 +467,10 @@ sub run {
sub checkMaintenanceMode {
my $class = shift;
my $vhost = $class->resolveAlias;
my $_maintenance =
( defined $tsv->{maintenance}->{$vhost} )
? $tsv->{maintenance}->{$vhost}
: $tsv->{maintenance}->{_};
my $_maintenance
= ( defined $tsv->{maintenance}->{$vhost} )
? $tsv->{maintenance}->{$vhost}
: $tsv->{maintenance}->{_};
if ($_maintenance) {
Lemonldap::NG::Handler::Main::Logger->lmLog(
......@@ -509,12 +518,12 @@ sub grant {
return &{$cond}() if ($cond);
my $vhost = $class->resolveAlias;
for ( my $i = 0 ; $i < $tsv->{locationCount}->{$vhost} ; $i++ ) {
for ( my $i = 0; $i < $tsv->{locationCount}->{$vhost}; $i++ ) {
if ( $uri =~ $tsv->{locationRegexp}->{$vhost}->[$i] ) {
Lemonldap::NG::Handler::Main::Logger->lmLog(
'Regexp "'
. $tsv->{locationConditionText}->{$vhost}->[$i]
. '" match',
. $tsv->{locationConditionText}->{$vhost}->[$i]
. '" match',
'debug'
);
return &{ $tsv->{locationCondition}->{$vhost}->[$i] }();
......@@ -540,19 +549,19 @@ sub _buildUrl {
my ( $class, $s ) = @_;
my $realvhost = Lemonldap::NG::Handler::API->hostname;
my $vhost = $class->resolveAlias;
my $portString =
$tsv->{port}->{$vhost}
|| $tsv->{port}->{_}
|| Lemonldap::NG::Handler::API->get_server_port;
my $portString
= $tsv->{port}->{$vhost}
|| $tsv->{port}->{_}
|| Lemonldap::NG::Handler::API->get_server_port;
my $_https = (
defined( $tsv->{https}->{$vhost} )
? $tsv->{https}->{$vhost}
: $tsv->{https}->{_}
);
$portString =
( $_https && $portString == 443 ) ? ''
: ( !$_https && $portString == 80 ) ? ''
: ':' . $portString;
$portString
= ( $_https && $portString == 443 ) ? ''
: ( !$_https && $portString == 80 ) ? ''
: ':' . $portString;
my $url = "http" . ( $_https ? "s" : "" ) . "://$realvhost$portString$s";
Lemonldap::NG::Handler::Main::Logger->lmLog( "Build URL $url", 'debug' );
return $url;
......@@ -597,13 +606,13 @@ sub status($$) {
Lemonldap::NG::Handler::Main::Logger->lmLog( "Request for status",
'debug' );
return $class->abort("$class: status page can not be displayed")
unless ( $statusPipe and $statusOut );
unless ( $statusPipe and $statusOut );
print $statusPipe "STATUS"
. (
. (
Lemonldap::NG::Handler::API->args
? " " . Lemonldap::NG::Handler::API->args
: ''
) . "\n";
) . "\n";
my $buf;
while (<$statusOut>) {
last if (/^END$/);
......@@ -648,7 +657,7 @@ sub redirectFilter {
sub isUnprotected {
my ( $class, $uri ) = @_;
my $vhost = $class->resolveAlias;
for ( my $i = 0 ; $i < $tsv->{locationCount}->{$vhost} ; $i++ ) {
for ( my $i = 0; $i < $tsv->{locationCount}->{$vhost}; $i++ ) {
if ( $uri =~ $tsv->{locationRegexp}->{$vhost}->[$i] ) {
return $tsv->{locationProtection}->{$vhost}->[$i];
}
......@@ -749,32 +758,32 @@ sub postJavascript {
foreach my $name ( keys %$data ) {
use bytes;
my $value = "x" x bytes::length( $data->{$name} );
$filler .=
"form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
$filler
.= "form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
}
my $submitter =
$formParams->{buttonSelector} eq "none" ? ""
: $formParams->{buttonSelector}
? "form.find('$formParams->{buttonSelector}').click();\n"
: "form.submit();\n";
my $submitter
= $formParams->{buttonSelector} eq "none" ? ""
: $formParams->{buttonSelector}
? "form.find('$formParams->{buttonSelector}').click();\n"
: "form.submit();\n";
my $jqueryUrl = $formParams->{jqueryUrl} || "";
$jqueryUrl = &{ $tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
if ( $jqueryUrl eq "default" );
if ( $jqueryUrl eq "default" );
$jqueryUrl = "<script type='text/javascript' src='$jqueryUrl'></script>\n"
if ($jqueryUrl);
if ($jqueryUrl);
return
$jqueryUrl
. "<script type='text/javascript'>\n"
. "/* script added by Lemonldap::NG */\n"
. "jQuery(window).on('load', function() {\n"
. "var form = jQuery('$form');\n"
. "form.attr('autocomplete', 'off');\n"
. $filler
. $submitter . "})\n"
. "</script>\n";
$jqueryUrl
. "<script type='text/javascript'>\n"
. "/* script added by Lemonldap::NG */\n"
. "jQuery(window).on('load', function() {\n"
. "var form = jQuery('$form');\n"
. "form.attr('autocomplete', 'off');\n"
. $filler
. $submitter . "})\n"
. "</script>\n";
}
1;
......@@ -8,12 +8,12 @@ sub types {
'authParamsText' => {
'test' => sub {
1;
}
}
},
'blackWhiteList' => {
'test' => sub {
1;
}
}
},
'bool' => {
'msgFail' => '__notABoolean__',
......@@ -34,8 +34,8 @@ sub types {
push @cf, defined $conf->{'customFunctions'}
? map( {
my $f = $_;
$f =~ s/\w+:://g;
$f, $_;
$f =~ s/\w+:://g;
$f, $_;
} split( /\s+/, $conf->{'customFunctions'}, 0 ) )
: ();
foreach my $f (@cf) {
......@@ -44,21 +44,21 @@ sub types {
BEGIN {
${^WARNING_BITS} =
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x01";
"\x54\x55\x55\x55\x15\x55\x55\x55\x55\x55\x51\x55\x55\x55\x55\x55\x55\x05";
}
eval "$s $val";
return $@ ? ( 1, "__badExpression__: $@" ) : 1;
}
}
},
'catAndAppList' => {
'test' => sub {
1;
}
}
},
'file' => {
'test' => sub {
1;
}
}
},
'hostname' => {
'form' => 'text',
......@@ -92,48 +92,48 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
}
return 1, "__unknownAttrOrMacro__: $val";
}
}
},
'longtext' => {
'test' => sub {
1;
}
}
},
'menuApp' => {
'test' => sub {
1;
}
}
},
'menuCat' => {
'test' => sub {
1;
}
}
},
'oidcmetadatajson' => {
'test' => sub {
1;
}
}
},
'oidcmetadatajwks' => {
'test' => sub {
1;
}
}
},
'oidcOPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'oidcRPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'password' => {
'msgFail' => '__malformedValue__',
'test' => sub {
1;
}
}
},
'pcre' => {
'form' => 'text',
......@@ -144,7 +144,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
}
};
return $@ ? ( 0, "__badRegexp__: $@" ) : 1;
}
}
},
'PerlModule' => {
'form' => 'text',
......@@ -154,17 +154,17 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'portalskin' => {
'test' => sub {
1;
}
}
},
'portalskinbackground' => {
'test' => sub {
1;
}
}
},
'post' => {
'test' => sub {
1;
}
}
},
'RSAPrivateKey' => {
'test' => sub {
......@@ -172,7 +172,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'RSAPublicKey' => {
'test' => sub {
......@@ -180,7 +180,7 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\n
m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'RSAPublicKeyOrCertificate' => {
'test' => sub {
......@@ -188,37 +188,37 @@ m[^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\
m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$]s
? 1
: ( 1, '__badPemEncoding__' );
}
}
},
'rule' => {
'test' => sub {
1;
}
}
},
'samlAssertion' => {
'test' => sub {
1;
}
}
},
'samlAttribute' => {
'test' => sub {
1;
}
}
},
'samlIDPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'samlService' => {
'test' => sub {
1;
}
}
},
'samlSPMetaDataNode' => {
'test' => sub {
1;
}
}
},
'select' => {
'test' => sub {
......@@ -228,19 +228,19 @@ m[^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9/\+\r\
return $test
? 1
: ( 0, "Invalid value '$_[0]' for this select" );
}
}
},
'subContainer' => {