U2F registration works (#1148)

This commit is contained in:
Xavier Guimard 2017-02-03 17:14:13 +00:00
parent e8fec72141
commit 41da50b8ca
14 changed files with 48 additions and 43 deletions

View File

@ -243,7 +243,6 @@ sub defaultValues {
'timeoutActivityInterval' => 60,
'trustedProxies' => '',
'twitterAuthnLevel' => 1,
'u2fAppId' => 'Lemonldap::NG',
'userControl' => '^[\\w\\.\\-@]+$',
'userDB' => 'Demo',
'useRedirectOnError' => 1,

View File

@ -123,12 +123,7 @@ sub sendError {
);
# SOAP responses
if (
$req->accept =~ m#(?:application|text)/xml#
or ( $req->content_type
and $req->content_type =~ m#(?:application|text)/xml# )
)
{
if ( $req->env->{HTTP_SOAPACTION} ) {
my $s = '<soapenv:Body>
<soapenv:Fault>
<Faultcode>soapenv:Client</Faultcode>

View File

@ -2830,9 +2830,9 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'default' => 0,
'type' => 'bool'
},
'u2fAppId' => {
'default' => 'Lemonldap::NG',
'type' => 'text'
'u2fSelfRegistration' => {
'default' => 0,
'type' => 'bool'
},
'userControl' => {
'default' => '^[\\w\\.\\-@]+$',

View File

@ -954,10 +954,10 @@ sub attributes {
default => 0,
documentation => 'U2F activation',
},
u2fAppId => {
default => 'Lemonldap::NG',
type => 'text',
documentation => 'U2F application ID',
u2fSelfRegistration => {
type => 'bool',
default => 0,
documentation => 'U2F self registration activation',
},
# Single session

View File

@ -582,7 +582,7 @@ sub tree {
{
title => 'u2f',
form => 'simpleInputContainer',
nodes => [ 'u2fActivation', 'u2fAppId', ]
nodes => [ 'u2fActivation', 'u2fSelfRegistration', ]
},
{
title => 'security',

View File

@ -631,7 +631,7 @@
"twitterSecret": "API secret",
"u2f": "U2F",
"u2fActivation": "Activation",
"u2fAppId": "Application ID",
"u2fSelfRegistration": "Self registration",
"uid": "Identifier",
"unknownAttrOrMacro": "Unknown attribute or macro",
"unknownError": "Unknown error",

View File

@ -631,7 +631,7 @@
"twitterSecret": "Secret de l'API",
"u2f": "U2F",
"u2fActivation": "Activation",
"u2fAppId": "Identifiant de l'application",
"u2fSelfRegistration": "Activation de l'enregistrement",
"uid": "Identifiant",
"unknownAttrOrMacro": "Attribut ou macro inconnu",
"unknownError": "Erreur inconnue",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -76,7 +76,10 @@ sub enabledPlugins {
# U2F
if ( $self->conf->{u2fActivation} ) {
push @res, '::Register::U2F', '::Plugins::U2F';
push @res, '::Plugins::U2F';
}
if ( $self->conf->{u2fSelfRegistration} ) {
push @res, '::Register::U2F';
}
# Check if custom plugins are required

View File

@ -9,6 +9,15 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
has crypter => ( is => 'rw' );
has origin => (
is => 'rw',
default => sub {
my $p = $_[0]->{conf}->{portal};
$p =~ s#^(https?://[^/]+).*$#$1#;
return $p;
}
);
sub init {
my ($self) = @_;
eval 'use Crypt::U2F::Server::Simple';
@ -19,8 +28,8 @@ sub init {
unless (
$self->crypter(
Crypt::U2F::Server::Simple->new(
appId => $self->conf->{u2fAppId},
origin => $self->conf->{portal},
appId => $self->origin,
origin => $self->origin,
)
)
)
@ -36,30 +45,24 @@ sub run {
my ( $self, $req ) = @_;
# Check for registration response
if ( my $rd = $req->param('registration') ) {
$self->lmLog( "Get registration data $rd", 'debug' );
my ( $keyHandle, $userKey ) = $self->crypter->registrationVerify($rd);
if ( my $response = $req->param('registration') ) {
$self->lmLog( "Get registration data $response", 'debug' );
my ( $keyHandle, $userKey ) =
$self->crypter->registrationVerify($response);
if ( $keyHandle and $userKey ) {
$self->lmLog( "Handle: $keyHandle, Key: $userKey", 'debug' );
$self->p->updatePersistentSession( $req,
{ _u2fHandle => $keyHandle, _u2fKey => $userKey } );
return $self->p->sendHtml( $req, 'u2fregister',
params => { SUCCESS => 1 } );
}
else {
$self->lmLog(
'U2F Registration failed: '
. Crypt::U2F::Server::Simple::lastError(),
'notice'
);
return $self->p->sendHtml( $req, 'u2fregister',
params => { FAILED => 1 } );
}
$self->p->userError( 'U2F Registration failed: '
. Crypt::U2F::Server::Simple::lastError() );
return $self->p->sendHtml( $req, 'u2fregister',
params => { FAILED => 1 } );
}
my $challenge = $self->crypter->registrationChallenge;
return $self->p->sendHtml( $req, 'u2fregister',
params =>
{ CHALLENGE => $challenge, APPID => $self->conf->{u2fAppId} } );
params => { CHALLENGE => $challenge, APPID => $self->origin } );
}
1;

View File

@ -3,9 +3,11 @@ LemonLDAP::NG U2F registration script
###
register = ->
request =
request = [
challenge: window.datas.challenge
version: 'U2F_V2'
]
console.log 'Register: ', request
u2f.register window.datas.appId, request, [], (data) ->
$('#bind-data').val JSON.stringify data
$('#bind-form').submit()

View File

@ -9,10 +9,13 @@ LemonLDAP::NG U2F registration script
register = function() {
var request;
request = {
challenge: window.datas.challenge,
version: 'U2F_V2'
};
request = [
{
challenge: window.datas.challenge,
version: 'U2F_V2'
}
];
console.log('Register: ', request);
return u2f.register(window.datas.appId, request, [], function(data) {
$('#bind-data').val(JSON.stringify(data));
return $('#bind-form').submit();

View File

@ -1 +1 @@
(function(){var a;a=function(){var b;b={challenge:window.datas.challenge,version:"U2F_V2"};return u2f.register(window.datas.appId,b,[],function(c){$("#bind-data").val(JSON.stringify(c));return $("#bind-form").submit()})};$(document).ready(function(){return setTimeout(a,1000)})}).call(this);
(function(){var a;a=function(){var b;b=[{challenge:window.datas.challenge,version:"U2F_V2"}];console.log("Register: ",b);return u2f.register(window.datas.appId,b,[],function(c){$("#bind-data").val(JSON.stringify(c));return $("#bind-form").submit()})};$(document).ready(function(){return setTimeout(a,1000)})}).call(this);