diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Demo.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Demo.pm index b54c31f09..bbdaa6b76 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Demo.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Auth/Demo.pm @@ -33,7 +33,8 @@ sub init { sub authenticate { my ( $self, $req ) = @_; - return PE_BADCREDENTIALS unless ( $req->{user} eq $req->datas->{password} ); + return PE_BADCREDENTIALS + unless ( $req->{user} eq $req->datas->{password} ); PE_OK; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index 08906b190..842fd958b 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -343,8 +343,13 @@ sub updatePersistentSession { # Update current session $self->updateSession( $req, $infos, $id ); - $uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} }; - return () unless ($uid); + $uid ||= $req->{sessionInfo}->{ $self->conf->{whatToTrace} } + || $req->userData->{ $self->conf->{whatToTrace} }; + unless ($uid) { + $self->lmLog( 'No uid found, skipping updatePersistentSession', + 'debug' ); + return (); + } $self->lmLog( "Update $uid persistent session", 'debug' ); my $persistentSession = $self->getPersistentSession($uid); diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/U2F.pm index eec8f0169..6f0863e0a 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/U2F.pm @@ -6,6 +6,11 @@ package Lemonldap::NG::Portal::Plugins::U2F; use strict; use Mouse; +use Lemonldap::NG::Portal::Main::Constants qw( + PE_BADCREDENTIALS + PE_ERROR + PE_OK +); our $VERSION = '2.0.0'; @@ -29,6 +34,7 @@ has ott => ( sub init { my ($self) = @_; + $self->addUnauthRoute( u2fcheck => 'verify', ['POST'] ); return 0 unless $self->SUPER::init; 1; } @@ -37,7 +43,65 @@ sub init { # Main method sub run { - my($self,$req) = @_; + my ( $self, $req ) = @_; + my ( $kh, $uk ); + + # Check if user is registered + if ( my $res = $self->loadUser($req) ) { + return PE_ERROR if ( $res == -1 ); + + # TODO: remove cookie and set token + my $challenge = $self->crypter->authenticationChallenge; + return $self->sendHtml( $req, 'u2fcheck', + params => { CHALLENGE => $challenge } ); + } + return PE_OK; +} + +sub verify { + my ( $self, $req ) = @_; + + # TODO: set sessionInfo with token + if ( my $resp = $req->param('u2fSignature') ) { + unless ( $self->loadUser($req) == 1 ) { + return $self->p->do( $req, [ sub { PE_ERROR } ] ); + } + if ( $self->crypter->authenticationVerify($resp) ) { + + # OK + return [ 200, [ 'Content-Type', 'text/plain' ], ['OK'] ]; + } + else { + return $self->p->do( $req, [ sub { PE_BADCREDENTIALS } ] ); + } + } + else { + $self->p->userNotice( 'No U2F response for user' + . $req->sessionInfo->{ $self->conf->{whatToTrace} } ); + return $self->p->do( $req, [ sub { PE_BADCREDENTIALS } ] ); + } +} + +sub loadUser { + my ( $self, $req ) = @_; + my ( $kh, $uk ); + if ( ( $kh = $req->sessionInfo->{_u2fKeyHandle} ) + and ( $uk = $req->sessionInfo->{_u2fUserKey} ) ) + { + $self->crypter->{keyHandle} = $kh; + $self->crypter->{publicKey} = $uk; + unless ( $self->crypter->setKeyHandle and $self->crypter->setPublicKey ) + { + $self->lmLog( + 'U2F error: ' . Crypt::U2F::Server::u2fclib_getError(), + 'error' ); + return -1; + } + return 1; + } + else { + return 0; + } } 1; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/U2F.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/U2F.pm index ca8a254cb..42b6c60d4 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/U2F.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Register/U2F.pm @@ -33,8 +33,8 @@ sub run { $self->p->updatePersistentSession( $req, { - _u2fHandle => encode_base64( $keyHandle, '' ), - _u2fKey => encode_base64( $userKey, '' ) + _u2fKeyHandle => encode_base64( $keyHandle, '' ), + _u2fUserKey => encode_base64( $userKey, '' ) } ); return $self->p->sendHtml( $req, 'u2fregister',