From cb0fed8e1320f74ab83c0d8249e939d49c6d8cc2 Mon Sep 17 00:00:00 2001 From: Christophe Maudoux Date: Sat, 3 Oct 2020 11:58:49 +0200 Subject: [PATCH] Prevent to update SFA if impersonation is in progress (#2337) --- .../Lemonldap/NG/Portal/2F/Register/TOTP.pm | 7 +++++- .../Lemonldap/NG/Portal/2F/Register/U2F.pm | 7 +++++- .../NG/Portal/2F/Register/Yubikey.pm | 13 ++++++++++- .../lib/Lemonldap/NG/Portal/Main/Plugin.pm | 23 ++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm index c973f6735..21cf47743 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/TOTP.pm @@ -148,6 +148,10 @@ sub run { 400 ); } + # Check if TOTP can be stored + return $self->p->sendError( $req, 'notAuthorized', 400 ) + unless $self->allowedUpdateSfa($req); + # Store TOTP secret push @keep, { @@ -259,7 +263,8 @@ sub run { # Check if unregistration is allowed return $self->p->sendError( $req, 'notAuthorized', 400 ) - unless $self->conf->{totp2fUserCanRemoveKey}; + unless ( $self->conf->{totp2fUserCanRemoveKey} + && $self->allowedUpdateSfa($req) ); my $epoch = $req->param('epoch') or return $self->p->sendError( $req, '"epoch" parameter is missing', diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm index e0ad21ebb..8fbb32ff9 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/U2F.pm @@ -117,6 +117,10 @@ sub run { $_2fDevices = []; } + # Check if U2F key can be stored + return $self->p->sendError( $req, 'notAuthorized', 400 ) + unless $self->allowedUpdateSfa($req); + my $keyName = $req->param('keyName'); my $epoch = time(); @@ -246,7 +250,8 @@ sub run { # Check if unregistration is allowed return $self->p->sendError( $req, 'notAuthorized', 200 ) - unless $self->conf->{u2fUserCanRemoveKey}; + unless ( $self->conf->{u2fUserCanRemoveKey} + && $self->allowedUpdateSfa($req) ); my $epoch = $req->param('epoch') or return $self->p->sendError( $req, '"epoch" parameter is missing', diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm index d2f451206..d85721d24 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Register/Yubikey.pm @@ -73,6 +73,16 @@ sub run { $_2fDevices = []; } + # Check if UBK key can be stored + return $self->p->sendHtml( + $req, 'error', + params => { + MAIN_LOGO => $self->conf->{portalMainLogo}, + RAW_ERROR => 'notAuthorized', + AUTH_ERROR_TYPE => 'warning', + } + ) unless $self->allowedUpdateSfa($req); + # Search if the Yubikey is already registered my $SameUBKFound = 0; foreach (@$_2fDevices) { @@ -151,7 +161,8 @@ sub run { # Check if unregistration is allowed return $self->p->sendError( $req, 'notAuthorized', 400 ) - unless $self->conf->{yubikey2fUserCanRemoveKey}; + unless ( $self->conf->{yubikey2fUserCanRemoveKey} + && $self->allowedUpdateSfa($req) ); my $epoch = $req->param('epoch') or return $self->p->sendError( $req, '"epoch" parameter is missing', diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm index 4f656a0a8..af5f06138 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Plugin.pm @@ -11,7 +11,7 @@ use Lemonldap::NG::Portal::Main::Constants qw( PE_ERROR ); -our $VERSION = '2.0.6'; +our $VERSION = '2.0.10'; extends 'Lemonldap::NG::Common::Module'; @@ -104,6 +104,27 @@ sub createNotification { } } +sub allowedUpdateSfa { + my ( $self, $req ) = @_; + my $res = 1; + if ( $self->conf->{impersonationRule} ) { + $self->logger->debug('Impersonation plugin is enabled!'); + if ( $req->userData->{"$self->{conf}->{impersonationPrefix}_user"} + && $req->userData->{"$self->{conf}->{impersonationPrefix}_user"} ne + $req->userData->{_user} ) + { + $self->userLogger->warn( + 'Impersonation in progress! User is not allowed to update SFA.' + ); + undef $res; + } + else { + $self->userLogger->info('User is allowed to update SFA'); + } + } + return $res; +} + 1; __END__