Merge branch 'v2.0'

This commit is contained in:
Xavier Guimard 2020-04-12 20:40:24 +02:00
commit 5dc1bc0a49
30 changed files with 104 additions and 63 deletions

View File

@ -1,4 +1,4 @@
.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35)
.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
@ -54,16 +54,20 @@
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.if !\nF .nr F 0
.if \nF>0 \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
@ -129,15 +133,7 @@
.\" ========================================================================
.\"
.IX Title "llng-fastcgi-server 8"
<<<<<<< HEAD
<<<<<<< HEAD
.TH llng-fastcgi-server 8 "2020-04-03" "perl v5.26.1" "User Contributed Perl Documentation"
=======
.TH llng-fastcgi-server 8 "2020-04-01" "perl v5.26.1" "User Contributed Perl Documentation"
>>>>>>> v2.0
=======
.TH llng-fastcgi-server 8 "2020-04-05" "perl v5.26.1" "User Contributed Perl Documentation"
>>>>>>> v2.0
.TH llng-fastcgi-server 8 "2020-04-12" "perl v5.30.0" "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

View File

@ -236,6 +236,8 @@ other engines can be used:
It uses L<FCGI::ProcManager> as manager. Other managers:
=over
=item L<FCGI::ProcManager::Dynamic>
llng-fastcgi-server -u nobody -g nobody -s /run/llng.sock -e FCGI -n 10 \

View File

@ -286,7 +286,7 @@ languages = en, fr, vi, it, ar, de, fi, tr, pl
; If you want to hide this, just protect "/index.fcgi/notification" in
; your Apache configuration file
; XSS protection bypass
; By default, the portal refuse redirections that comes from sites not
; By default, the portal refuses redirections that come from sites not
; registered in the configuration (manager) except for those coming
; from trusted domains. By default, trustedDomains contains the domain
; declared in the manager. You can set trustedDomains to empty value so

View File

@ -340,7 +340,10 @@ sub grant {
# @return Constant $class->FORBIDDEN
sub forbidden {
my ( $class, $req, $session, $vhost ) = @_;
my $uri = $req->{env}->{REQUEST_URI};
my $uri = $req->{env}->{REQUEST_URI};
my $portal = $class->tsv->{portal}->();
$portal = ( $portal =~ m#^https?://([^/]*).*# )[0];
$portal =~ s/:\d+$//;
$vhost ||= $class->resolveAlias($req);
if ( $session->{_logout} ) {
@ -363,11 +366,12 @@ sub forbidden {
$session->{ $class->tsv->{whatToTrace} } );
# Redirect or Forbidden?
if ( $class->tsv->{useRedirectOnForbidden} ) {
$class->logger->debug("Use redirect for forbidden access");
if ( $class->tsv->{useRedirectOnForbidden} && $vhost ne $portal ) {
$class->logger->debug("Use redirect for forbidden access ");
return $class->goToError( $req, $uri, 403 );
}
else {
$class->logger->debug("Self protected Portal URL") if $vhost eq $portal;
$class->logger->debug("Return forbidden access");
return $class->FORBIDDEN;
}
@ -448,7 +452,7 @@ sub fetchId {
my $value =
$lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );

View File

@ -1301,6 +1301,9 @@ qr/^(?:\*\.)?(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][
'default' => 120,
'type' => 'int'
},
'globalLogoutCustomParam' => {
'type' => 'text'
},
'globalLogoutRule' => {
'default' => 0,
'type' => 'boolOrExpr'

View File

@ -506,6 +506,11 @@ sub attributes {
documentation => 'Display favorite applications tab in portal',
flags => 'p',
},
globalLogoutCustomParam => {
type => 'text',
documentation => 'Custom session parameter to display',
flags => 'p',
},
impersonationMergeSSOgroups => {
default => 0,
type => 'boolOrExpr',

View File

@ -721,7 +721,7 @@ sub tree {
help => 'globallogout.html',
form => 'simpleInputContainer',
nodes =>
[ 'globalLogoutRule', 'globalLogoutTimer', ],
[ 'globalLogoutRule', 'globalLogoutTimer','globalLogoutCustomParam' ],
},
{
title => 'stateCheck',

View File

@ -680,7 +680,7 @@ sub _scanNodes {
}
# Create new apps
else {
if ( $leaf->{type} eq 'menuApp' ) {
hdebug(' new app');
$knownCat->{__id}++;
$cn->{$newapp} = {

View File

@ -25,7 +25,7 @@
<div class="row">
<div class="col-md-1">
<button class="btn btn-default" ng-click="showModal('logoChoice.html')">
<img ng-src="{{portal.data}}static/common/apps/{{currentNode.data.logo}}" />
<img ng-src="{{portal.data}}static/common/apps/{{currentNode.data.logo}}" height="30px" width="30px"/>
</button>
</div>
<div class="col-md-11">

View File

@ -320,6 +320,7 @@
"friendlyName":"اسم مألوف",
"generalParameters":"المعاييرالعامة",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"تفعيل",
"globalLogoutTimer":"قبول تلقائي للوقت",
"globalStorage":"أباتشي :: وحدة الجلسة",

View File

@ -320,6 +320,7 @@
"friendlyName":"Friendly name",
"generalParameters":"General Parameters",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Activation",
"globalLogoutTimer":"Auto accept time",
"globalStorage":"Apache::Session module",

View File

@ -320,6 +320,7 @@
"friendlyName":"Friendly name",
"generalParameters":"General Parameters",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Activation",
"globalLogoutTimer":"Auto accept time",
"globalStorage":"Apache::Session module",

View File

@ -320,6 +320,7 @@
"friendlyName":"Nom alternatif",
"generalParameters":"Paramètres généraux",
"globalLogout":"Déconnexion globale",
"globalLogoutCustomParam":"Paramètre personnalisé",
"globalLogoutRule":"Activation",
"globalLogoutTimer":"Délai d'acceptation automatique",
"globalStorage":"Module Apache::Session",

View File

@ -320,6 +320,7 @@
"friendlyName":"Nome amichevole",
"generalParameters":"Parametri generali",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Attivazione",
"globalLogoutTimer":"Auto accettazione tempo",
"globalStorage":"Modulo Apache::Session",

View File

@ -320,6 +320,7 @@
"friendlyName":"Kolay ad",
"generalParameters":"Genel Parametreler",
"globalLogout":"Global çıkış",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Aktivasyon",
"globalLogoutTimer":"Otomatik kabul süresi",
"globalStorage":"Apache::Session modülü",

View File

@ -320,6 +320,7 @@
"friendlyName":"Tên thân thiện",
"generalParameters":"Thông số chung",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Activation",
"globalLogoutTimer":"Tự động chấp nhận thời gian",
"globalStorage":"Mô đun Apache :: Session",

View File

@ -320,6 +320,7 @@
"friendlyName":"Friendly name",
"generalParameters":"通用参数",
"globalLogout":"Global logout",
"globalLogoutCustomParam":"Custom parameter",
"globalLogoutRule":"Activation",
"globalLogoutTimer":"自动接收时间",
"globalStorage":"Apache::Session 模块",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -98,7 +98,8 @@
</table>
</div>
<div ng-if="!node.nodes">
<th ng-if="node.td!='1' && node.td!='2'"><span title="{{node.title}}">{{translate(node.title)}}</span></th>
<th ng-if="node.title=='type'"><span title="{{node.title}}">{{translate(node.title)}}</span></th>
<th ng-if="node.td!='1' && node.td!='2' && node.title!='type'"><span title="{{node.title}}">{{node.title}}</span></th>
<td class="data-{{node.epoch}}" ng-if="node.td>='1'">{{node.title}}</td>
<th ng-if="node.title=='type' || node.title=='rp'">{{translate(node.value)}}</th>
<td id="v-{{node.title}}" class="col-md-4 data-{{node.epoch}}" ng-if="node.title!='type' && node.title!='rp'">{{node.value}}</td>

View File

@ -34,7 +34,10 @@ sub extractFormInfo {
}
my $res = $req->data->{enabledMods0}->[0]->extractFormInfo($req);
delete $req->pdata->{_choice} if ( $res > 0 );
if ( $res > 0 ) {
$self->setSecurity($req);
delete $req->pdata->{_choice};
}
return $res;
}

View File

@ -37,8 +37,11 @@ sub extractFormInfo {
$field = $tmp;
}
}
$self->logger->debug("Using SSL environment variable $field");
if ( $req->user( $req->env->{$field} ) ) {
$req->env->{$field}
? $self->logger->debug("Using SSL environment variable $field")
: $self->logger->notice(
"No name found in certificate, check your configuration");
if ( $req->env->{$field} and $req->user( $req->env->{$field} ) ) {
$self->userLogger->notice( "GoodSSL authentication for " . $req->user );
return PE_OK;
}

View File

@ -55,7 +55,7 @@ sub init {
}
# RUNNING METHODS
# Look for user active SSO sessions and propose to close them
# Look for user active SSO sessions and suggest to close them
sub run {
my ( $self, $req ) = @_;
my $user = $req->{userData}->{ $self->conf->{whatToTrace} };
@ -102,6 +102,7 @@ sub run {
SESSIONS => $sessions,
TOKEN => $token,
LOGIN => $user,
CUSTOMPRM => $self->conf->{globalLogoutCustomParam}
}
);
$req->response($tmp);
@ -168,10 +169,12 @@ sub activeSessions {
my ( $self, $req ) = @_;
my $activeSessions = [];
my $sessions = {};
my $regex = '^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$';
my $user = $req->{userData}->{ $self->conf->{whatToTrace} };
my $customParam = $self->conf->{globalLogoutCustomParam} || '';
# Try to retrieve session from sessions DB
$self->logger->debug('Try to retrieve session from DB');
# Try to retrieve sessions from sessions DB
$self->logger->debug('Try to retrieve sessions from DB');
my $moduleOptions = $self->conf->{globalStorageOptions} || {};
$moduleOptions->{backend} = $self->conf->{globalStorage};
$self->logger->debug("Looking for \"$user\" sessions...");
@ -181,12 +184,18 @@ sub activeSessions {
$self->logger->debug("Building array ref with sessions info...");
@$activeSessions = map { {
id => $_,
UA => $sessions->{$_}->{'UA'},
ipAddr => $sessions->{$_}->{'ipAddr'},
authLevel => $sessions->{$_}->{'authenticationLevel'},
startTime => $sessions->{$_}->{'_startTime'},
updateTime => $sessions->{$_}->{'_updateTime'},
id => $_,
customParam => $sessions->{$_}->{$customParam},
ipAddr => $sessions->{$_}->{'ipAddr'},
authLevel => $sessions->{$_}->{'authenticationLevel'},
startTime => $sessions->{$_}->{'_startTime'} =~
s/$regex/$1-$2-$3 $4:$5:$6/ro,
updateTime => (
$sessions->{$_}->{'_updateTime'}
? $sessions->{$_}->{'_updateTime'} =~
s/$regex/$1-$2-$3 $4:$5:$6/ro
: ''
),
};
} keys %$sessions;

View File

@ -35,7 +35,7 @@
"PE42":"Confirmation required",
"PE43":"Your mail address is mandatory",
"PE44":"Confirmation key is invalid or too old",
"PE45":"An error occurs when sending mail",
"PE45":"An error occurred when sending mail",
"PE46":"A mail has been sent",
"PE48":"Undefined SAML error",
"PE49":"Unable to load SAML service",

View File

@ -7,14 +7,16 @@
<TMPL_IF NAME="SESSIONS">
<div class="card col border-secondary">
<div class="text-center bg-light text-dark"><b><span trspan="activeSessions">ACTIVE SSO SESSIONS</span>: <u><TMPL_VAR NAME="LOGIN"></u></b></div>
<table class="table table-sm table-hover">
<table class="table table-sm table-hover text-center">
<thead>
<tr>
<th scope="col"><span trspan="startTime">startTime</span></th>
<th scope="col"><span trspan="updateTime">updateTime</span></th>
<th scope="col"><span trspan="authLevel">authLevel</span></th>
<th scope="col"><span trspan="ipAddr">ipAddr</span></th>
<th scope="col"><span trspan="UA">UA</span></th>
<th scope="col"><span trspan="authLevel">authLevel</span></th>
<TMPL_IF NAME="CUSTOMPRM">
<th scope="col"><TMPL_VAR NAME="CUSTOMPRM"></th>
</TMPL_IF>
</tr>
</thead>
<tbody>
@ -22,9 +24,11 @@
<tr>
<td scope="row"><TMPL_VAR NAME="startTime"></td>
<td scope="row"><TMPL_VAR NAME="updateTime"></td>
<td scope="row"><TMPL_VAR NAME="authLevel"></td>
<td scope="row"><TMPL_VAR NAME="ipAddr"></td>
<td scope="row"><TMPL_VAR NAME="UA"></td>
<td scope="row"><TMPL_VAR NAME="authLevel"></td>
<TMPL_IF NAME="CUSTOMPRM">
<td scope="row"><TMPL_VAR NAME="customParam"></td>
</TMPL_IF>
</tr>
</TMPL_LOOP>
</tbody>

View File

@ -11,14 +11,15 @@ my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
loginHistoryEnabled => 0,
bruteForceProtection => 0,
requireToken => 0,
restSessionServer => 1,
globalLogoutRule => '$uid eq "dwho"',
logLevel => 'error',
authentication => 'Demo',
userDB => 'Same',
loginHistoryEnabled => 0,
bruteForceProtection => 0,
requireToken => 0,
restSessionServer => 1,
globalLogoutRule => '$uid eq "dwho"',
globalLogoutCustomParam => 'authMode'
}
}
);
@ -138,15 +139,17 @@ my ( $host, $url, $query ) =
ok( $res->[2]->[0] =~ m%<span trspan="globalLogout">%,
'Found trspan="globalLogout"' )
or explain( $res->[2]->[0], 'trspan="globalLogout"' );
ok( $res->[2]->[0] =~ m%<td scope="row">DEMO</td>%, 'CustomParam found "DEMO"' )
or explain( $res->[2]->[0], 'CustomParam DEMO' );
my @c = ( $res->[2]->[0] =~ m%<td scope="row">127.0.0.1</td>%gs );
my @d = ( $res->[2]->[0] =~ m%<th scope="col"><span trspan="%gs );
my @d = ( $res->[2]->[0] =~ m%<th scope="col">%gs );
## Three entries found
ok( @c == 3, ' -> Three entries found' )
or explain( $res->[2]->[0], "Number of session(s) found = " . scalar @c );
ok( @d == 5, ' -> Five <th> found' )
or explain( $res->[2]->[0], "Number of <th> found = " . scalar @d );
count(3);
count(4);
## GlobalLogout request for 'dwho'
$query .= '&all=1';

View File

@ -12,7 +12,7 @@ my $client = LLNG::Manager::Test->new( {
userDB => 'Same',
autoSigninRules => {
rtyler => '$env->{REMOTE_ADDR} =~ /^127',
dwho => '$env->{REMOTE_ADDR =~ /^127/',
dwho => '$env->{REMOTE_ADDR} =~ /^127/',
msmith => '$env->{REMOTE_ADDR} =~ /^127/',
},
}

View File

@ -288,14 +288,14 @@ qr%<input type="hidden" name="reference1x1" value="RemoveSF-(\d{10})">%,
'Notification reference found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 120 <= $1 && $1 <= time() + 125, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] );
or print STDERR Dumper( $res->[2]->[0] ), time(), $1;
ok(
$res->[2]->[0] =~
qr%<input type="hidden" name="reference1x2" value="RemoveSF-(\d{10})">%,
'Notification reference found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 300 <= $1 && $1 <= time() + 305, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] );
or print STDERR Dumper( $res->[2]->[0] ), time(), $1;;
my @notifs =
( $res->[2]->[0] =~
m%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%gs

View File

@ -149,8 +149,8 @@ SKIP: {
qr%<input type="hidden" name="reference1x1" value="Remov-e-TOTP-(\d{10})">%,
'Notification reference found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 300 <= $1 && $1 <= time() + 305, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 290 <= $1 && $1 <= time() + 310, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] ), time(), $1;
ok(
$res->[2]->[0] =~
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%,

View File

@ -153,8 +153,8 @@ SKIP: {
qr%<input type="hidden" name="reference1x1" value="Remove-TOTP-(\d{10})">%,
'Notification reference found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 300 <= $1 && $1 <= time() + 305, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] );
ok( time() + 290 <= $1 && $1 <= time() + 310, 'Right reference found' )
or print STDERR Dumper( $res->[2]->[0] ), time(), $1;
ok(
$res->[2]->[0] =~
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%,