Add delete function to TOTP & Yubikey - TODO : Verify if user is authorized to delete (#1386)

This commit is contained in:
Christophe Maudoux 2018-04-03 00:01:01 +02:00
parent 6b27054603
commit 0637601d8b
3 changed files with 99 additions and 50 deletions

View File

@ -66,17 +66,15 @@ sub run {
my $code = $req->param('code'); my $code = $req->param('code');
my $TOTPName = $req->param('TOTPName'); my $TOTPName = $req->param('TOTPName');
unless ($code) { unless ($code) {
$self->logger->userInfo('TOTP registration: empty validation form'); $self->logger->userInfo('TOTP registration: empty validation form');
return $self->p->sendError( $req, 'missingCode', 200 ); return $self->p->sendError( $req, 'missingCode', 200 );
} }
#unless ( $code and $TOTPName ) { #unless ( $code and $TOTPName ) {
#$self->logger->userInfo( #$self->logger->userInfo(
#'TOTP registration: empty code or name in validation form'); #'TOTP registration: empty code or name in validation form');
#return $self->p->sendError( $req, 'missingCode', 200 ); #return $self->p->sendError( $req, 'missingCode', 200 );
#} #}
my $r = $self->verifyCode( my $r = $self->verifyCode(
$self->conf->{totp2fInterval}, $self->conf->{totp2fInterval},
@ -111,13 +109,14 @@ sub run {
} }
push @{$list2FDevices}, push @{$list2FDevices},
{ {
type => 'totp', type => 'TOTP',
name => $TOTPName, name => $TOTPName,
_secret => $token->{_totp2fSecret}, _secret => $token->{_totp2fSecret},
epoch => time() epoch => time()
}; };
#$self->logger->debug( #$self->logger->debug(
#"Append 2F Device : { type => 'totp', name => $TOTPName }"); #"Append 2F Device : { type => 'totp', name => $TOTPName }");
$self->p->updatePersistentSession( $req, $self->p->updatePersistentSession( $req,
{ list2FDevices => to_json($list2FDevices) } ); { list2FDevices => to_json($list2FDevices) } );
@ -190,6 +189,33 @@ sub run {
} }
} }
elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
};
my @keep = ();
while (@$list2FDevices) {
my $element = shift @$list2FDevices;
$self->logger->debug("Looking for 2F Device to delete ...");
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'TOTP', epoch => $epoch }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json( \@keep ) } );
$self->userLogger->notice('TOTP deletion succeed');
return [ 200, [ 'Content-Type' => 'application/json' ],
['{"result":1}'] ];
}
} }
1; 1;

View File

@ -66,12 +66,14 @@ sub run {
my $list2FDevices = eval { my $list2FDevices = eval {
$self->logger->debug("Looking for 2F Devices ..."); $self->logger->debug("Looking for 2F Devices ...");
# Read existing 2FDevices # Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, from_json( $req->userData->{list2FDevices},
{ allow_nonref => 1 } ); { allow_nonref => 1 } );
}; };
unless ($list2FDevices) { unless ($list2FDevices) {
$self->logger->debug("No 2F Device found"); $self->logger->debug("No 2F Device found");
# Set default value # Set default value
$list2FDevices = []; $list2FDevices = [];
} }
@ -80,27 +82,23 @@ sub run {
# Select U2F Devices only # Select U2F Devices only
#my @listU2FKeys = map { #my @listU2FKeys = map {
#( $_->{type} eq "U2F" ) ? return $_ : return (); #( $_->{type} eq "U2F" ) ? return $_ : return ();
#} @{$list2FDevices}; #} @{$list2FDevices};
#$self->logger->debug("Select U2F Devices only ..."); #$self->logger->debug("Select U2F Devices only ...");
# Search if U2F Key has been already registered # Search if U2F Key has been already registered
my $SameU2FKeyFound = 0; my $SameU2FKeyFound = 0;
foreach ( @$list2FDevices ) { foreach (@$list2FDevices) {
$self->logger->debug("Reading U2F Keys ..."); $self->logger->debug("Reading U2F Keys ...");
$SameU2FKeyFound ||= 1 if ( ( $_->{name} eq $keyName ) ); $SameU2FKeyFound ||= 1 if ( ( $_->{name} eq $keyName ) );
}; }
$self->logger->debug("Same 2F Device found ? $SameU2FKeyFound");
$self->logger->debug("Same 2F Device found ? $SameU2FKeyFound");
if ($SameU2FKeyFound) { if ($SameU2FKeyFound) {
$self->userLogger->error("U2F Key already registered !"); $self->userLogger->error("U2F Key already registered !");
return $self->p->sendError( $req, 'Bad challenge', 400 ); return $self->p->sendError( $req, 'Bad challenge', 400 );
} }
push @{$list2FDevices}, push @{$list2FDevices},
{ {
@ -218,32 +216,26 @@ sub run {
return $self->p->sendError( $req, $err, 200 ); return $self->p->sendError( $req, $err, 200 );
} }
elsif ( $action eq 'delete' ) { elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch'); my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
my $list2FDevices = eval {
$self->logger->debug("Looking for 2F Devices ...");
# Read existing 2FDevices # Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
{ allow_nonref => 1 } );
}; };
my @keep = (); my @keep = ();
while ( @$list2FDevices ) { while (@$list2FDevices) {
my $element = shift @$list2FDevices; my $element = shift @$list2FDevices;
push @keep, $element unless ( $element->{epoch} eq $epoch ); $self->logger->debug("Looking for 2F Device to delete ...");
} push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'U2F', epoch => $epoch }");
$self->logger->debug(
"Delete 2F Device : { type => 'U2F', epoch => $epoch }");
$self->p->updatePersistentSession( $req, $self->p->updatePersistentSession( $req,
{ list2FDevices => to_json(\@keep) } ); { list2FDevices => to_json( \@keep ) } );
$self->p->updatePersistentSession( $self->p->updatePersistentSession(
$req, $req,

View File

@ -85,6 +85,37 @@ sub run {
); );
} }
} }
elsif ( $action eq 'delete' ) {
my $epoch = $req->param('epoch');
my $list2FDevices = eval {
$self->logger->debug("Loading 2F Devices ...");
# Read existing 2FDevices
from_json( $req->userData->{list2FDevices}, { allow_nonref => 1 } );
};
my @keep = ();
while (@$list2FDevices) {
my $element = shift @$list2FDevices;
$self->logger->debug("Looking for 2F Device to delete ...");
push @keep, $element unless ( $element->{epoch} eq $epoch );
}
$self->logger->debug(
"Delete 2F Device : { type => 'UBK', epoch => $epoch }");
$self->p->updatePersistentSession( $req,
{ list2FDevices => to_json( \@keep ) } );
$self->userLogger->notice('Yubikey deletion succeed');
return [
200,
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
['{"result":1}']
];
}
else { else {
$self->userLogger->error("Unknown Yubikey action $action"); $self->userLogger->error("Unknown Yubikey action $action");
return $self->p->sendHtml( return $self->p->sendHtml(