diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/U2F.pm index 2d69327b0..f4af2cf1a 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/U2F.pm @@ -9,6 +9,7 @@ use strict; use Mouse; use JSON qw(from_json to_json); use Lemonldap::NG::Portal::Main::Constants qw( + PE_BADCREDENTIALS PE_ERROR PE_OK PE_SENDRESPONSE @@ -58,7 +59,9 @@ sub run { return PE_U2FFAILED if ( $res == 0 ); my $challenge = $req->datas->{crypter}->authenticationChallenge; - my $tmp = $self->p->sendHtml( + $self->ott->updateToken( $token, + __ch => JSON::from_json($challenge)->{challenge} ); + my $tmp = $self->p->sendHtml( $req, 'u2fcheck', params => { @@ -88,6 +91,12 @@ sub verify { } $self->logger->debug("Get challenge: $challenge"); + unless ( $session->{__ch} and $session->{__ch} eq $challenge ) { + $self->userLogger->error("U2F challenge changes by user !!! $session->{__ch}/$challenge"); + $req->error(PE_BADCREDENTIALS); + return $self->fail($req); + } + delete $session->{__ch}; if ( not $req->datas->{crypter}->setChallenge($challenge) ) { $self->logger->error( $@ ? $@ : Crypt::U2F::Server::Simple::lastError() ); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm index c93171caa..44e7eb6e6 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Lib/OneTimeToken.pm @@ -112,6 +112,25 @@ sub getToken { } } +sub updateToken { + my ( $self, $id, $k, $v ) = @_; + if ( $self->cache ) { + my $data; + unless ( $data = $self->cache->get($id) ) { + $self->logger->notice("Bad (or expired) token $id"); + return undef; + } + my $h = from_json( $data, { allow_nonref => 1 } ); + $h->{$k} = $v; + $self->cache->set( $id, to_json($h), $self->timeout . ' s' ); + return $id; + } + else { + $self->p->getApacheSession( $id, $k => $v ); + return $id; + } +} + sub setToken { my ( $self, $req, $info ) = @_; $self->logger->debug('Prepare token');