Test 2F TTL (#1782)
This commit is contained in:
parent
bbe18393a5
commit
e3c2766809
|
@ -3524,6 +3524,9 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
|||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'totp2fTTL' => {
|
||||
'type' => 'int'
|
||||
},
|
||||
'totp2fUserCanChangeKey' => {
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
|
@ -3563,6 +3566,9 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
|||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'u2fTTL' => {
|
||||
'type' => 'int'
|
||||
},
|
||||
'u2fUserCanRemoveKey' => {
|
||||
'default' => 1,
|
||||
'type' => 'bool'
|
||||
|
@ -3764,6 +3770,9 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
|||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'yubikey2fTTL' => {
|
||||
'type' => 'int'
|
||||
},
|
||||
'yubikey2fUrl' => {
|
||||
'type' => 'text'
|
||||
},
|
||||
|
|
|
@ -1369,7 +1369,10 @@ sub attributes {
|
|||
default => 1,
|
||||
documentation => 'Authorize users to remove existing U2F key',
|
||||
},
|
||||
|
||||
u2fTTL => {
|
||||
type => 'int',
|
||||
documentation => 'U2F device time to live',
|
||||
},
|
||||
# TOTP second factor
|
||||
totp2fActivation => {
|
||||
type => 'boolOrExpr',
|
||||
|
@ -1421,6 +1424,10 @@ sub attributes {
|
|||
default => 1,
|
||||
documentation => 'Authorize users to remove existing TOTP secret',
|
||||
},
|
||||
totp2fTTL => {
|
||||
type => 'int',
|
||||
documentation => 'TOTP device time to live ',
|
||||
},
|
||||
|
||||
# UTOTP 2F
|
||||
utotp2fActivation => {
|
||||
|
@ -1578,6 +1585,10 @@ sub attributes {
|
|||
default => 1,
|
||||
documentation => 'Authorize users to remove existing Yubikey',
|
||||
},
|
||||
yubikey2fTTL => {
|
||||
type => 'int',
|
||||
documentation => 'Yubikey device time to live',
|
||||
},
|
||||
|
||||
# Single session
|
||||
notifyDeleted => {
|
||||
|
|
|
@ -689,6 +689,7 @@ sub tree {
|
|||
'totp2fDisplayExistingSecret',
|
||||
'totp2fUserCanChangeKey',
|
||||
'totp2fUserCanRemoveKey',
|
||||
'totp2fTTL',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -698,6 +699,7 @@ sub tree {
|
|||
nodes => [
|
||||
'u2fActivation', 'u2fSelfRegistration',
|
||||
'u2fAuthnLevel', 'u2fUserCanRemoveKey',
|
||||
'u2fTTL',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -745,6 +747,7 @@ sub tree {
|
|||
'yubikey2fUrl',
|
||||
'yubikey2fPublicIDSize',
|
||||
'yubikey2fUserCanRemoveKey',
|
||||
'yubikey2fTTL',
|
||||
],
|
||||
},
|
||||
'sfRequired',
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -20,7 +20,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_TOKENEXPIRED
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.2';
|
||||
our $VERSION = '2.0.5';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
@ -126,7 +126,6 @@ sub init {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -137,7 +136,6 @@ sub init {
|
|||
# run() is called at each authentication, just after sessionInfo populated
|
||||
sub run {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
my $checkLogins = $req->param('checkLogins');
|
||||
my $spoofId = $req->param('spoofId') || '';
|
||||
$self->logger->debug("2F checkLogins set") if ($checkLogins);
|
||||
|
@ -145,6 +143,71 @@ sub run {
|
|||
# Skip 2F unless a module has been registered
|
||||
return PE_OK unless ( @{ $self->sfModules } );
|
||||
|
||||
# Remove expired 2F devices
|
||||
my $session = $req->sessionInfo;
|
||||
if ( $session->{_2fDevices} ) {
|
||||
$self->logger->debug("Loading 2F Devices ...");
|
||||
|
||||
# Read existing 2FDevices
|
||||
my $_2fDevices =
|
||||
eval { from_json( $session->{_2fDevices}, { allow_nonref => 1 } ); };
|
||||
if ($@) {
|
||||
$self->logger->error("Bad encoding in _2fDevices: $@");
|
||||
return PE_ERROR;
|
||||
}
|
||||
$self->logger->debug(" -> 2F Device(s) found");
|
||||
|
||||
my $u2fTTL = $self->conf->{u2fTTL}
|
||||
&& $self->conf->{u2fTTL} > 0 ? $self->conf->{u2fTTL} : 0;
|
||||
my $totpTTL = $self->conf->{totp2fTTL}
|
||||
&& $self->conf->{totp2fTTL} > 0 ? $self->conf->{totp2fTTL} : 0;
|
||||
my $ubkTTL = $self->conf->{yubikey2fTTL}
|
||||
&& $self->conf->{yubikey2fTTL} > 0 ? $self->conf->{yubikey2fTTL} : 0;
|
||||
|
||||
if ( $u2fTTL || $totpTTL || $ubkTTL ) {
|
||||
my $now = time();
|
||||
my $removed = 0;
|
||||
$self->logger->debug("Looking for expired 2F device(s)...");
|
||||
foreach (@$_2fDevices) {
|
||||
if ( $_->{type} eq 'U2F' ) {
|
||||
if ( $u2fTTL && $now - $_->{epoch} > $u2fTTL ) {
|
||||
$self->logger->debug(
|
||||
"Remove U2F -> $_->{name} / $_->{epoch}");
|
||||
$self->userLogger->info("Remove expired U2F");
|
||||
$_->{type} = 'EXPIRED';
|
||||
$removed++;
|
||||
}
|
||||
}
|
||||
if ( $_->{type} eq 'UBK' ) {
|
||||
if ( $ubkTTL && $now - $_->{epoch} > $ubkTTL ) {
|
||||
$self->logger->debug(
|
||||
"Remove Yubikey -> $_->{name} / $_->{epoch}");
|
||||
$self->userLogger->info("Remove expired Yubiked");
|
||||
$_->{type} = 'EXPIRED';
|
||||
$removed++;
|
||||
}
|
||||
}
|
||||
if ( $_->{type} eq 'TOTP' ) {
|
||||
if ( $totpTTL && $now - $_->{epoch} > $totpTTL ) {
|
||||
$self->logger->debug(
|
||||
"Remove TOTP -> $_->{name} / $_->{epoch}");
|
||||
$self->userLogger->info("Remove expired TOTP");
|
||||
$_->{type} = 'EXPIRED';
|
||||
$removed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($removed) {
|
||||
$self->logger->debug(
|
||||
"Found EXPIRED 2F device(s) => Update persistent session");
|
||||
@$_2fDevices =
|
||||
map { $_->{type} =~ /\bEXPIRED\b/ ? () : $_ } @$_2fDevices;
|
||||
$self->p->updatePersistentSession( $req,
|
||||
{ _2fDevices => to_json($_2fDevices) } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Search for authorized modules for this user
|
||||
my @am;
|
||||
foreach my $m ( @{ $self->sfModules } ) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user