refactoring
This commit is contained in:
parent
27a4234634
commit
de19770211
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace LAM\LIB\TWO_FACTOR;
|
namespace LAM\LIB\TWO_FACTOR;
|
||||||
|
use LAM\LOGIN\WEBAUTHN\WebauthnManager;
|
||||||
use \selfServiceProfile;
|
use \selfServiceProfile;
|
||||||
use \LAMConfig;
|
use \LAMConfig;
|
||||||
use \htmlScript;
|
use \htmlScript;
|
||||||
|
@ -551,7 +552,8 @@ class WebauthnProvider extends BaseProvider {
|
||||||
$row->add(new htmlDiv(null, $errorMessage, array('hidden webauthn-error')), 12);
|
$row->add(new htmlDiv(null, $errorMessage, array('hidden webauthn-error')), 12);
|
||||||
if ($this->config->twoFactorAuthenticationOptional === true) {
|
if ($this->config->twoFactorAuthenticationOptional === true) {
|
||||||
include_once __DIR__ . '/webauthn.inc';
|
include_once __DIR__ . '/webauthn.inc';
|
||||||
$hasTokens = hasTokensRegistered($userDn);
|
$webauthnManager = new WebauthnManager();
|
||||||
|
$hasTokens = $webauthnManager->isRegistered($userDn);
|
||||||
if (!$hasTokens) {
|
if (!$hasTokens) {
|
||||||
$skipButton = new htmlButton('skip_webauthn', _('Skip'));
|
$skipButton = new htmlButton('skip_webauthn', _('Skip'));
|
||||||
$skipButton->setCSSClasses(array('fullwidth'));
|
$skipButton->setCSSClasses(array('fullwidth'));
|
||||||
|
@ -572,7 +574,8 @@ class WebauthnProvider extends BaseProvider {
|
||||||
public function verify2ndFactor($user, $password, $serial, $twoFactorInput) {
|
public function verify2ndFactor($user, $password, $serial, $twoFactorInput) {
|
||||||
logNewMessage(LOG_DEBUG, 'WebauthnProvider: Checking 2nd factor for ' . $user);
|
logNewMessage(LOG_DEBUG, 'WebauthnProvider: Checking 2nd factor for ' . $user);
|
||||||
include_once __DIR__ . '/webauthn.inc';
|
include_once __DIR__ . '/webauthn.inc';
|
||||||
if ($this->config->twoFactorAuthenticationOptional && !hasTokensRegistered($user) && ($_POST['sig_response'] === 'skip')) {
|
$webauthnManager = new WebauthnManager();
|
||||||
|
if ($this->config->twoFactorAuthenticationOptional && !$webauthnManager->isRegistered($user) && ($_POST['sig_response'] === 'skip')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$response = base64_decode($_POST['sig_response']);
|
$response = base64_decode($_POST['sig_response']);
|
||||||
|
|
|
@ -72,28 +72,38 @@ use \LAMException;
|
||||||
include_once __DIR__ . '/3rdParty/composer/autoload.php';
|
include_once __DIR__ . '/3rdParty/composer/autoload.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Manages Webauthn registrations and authentications.
|
||||||
|
*
|
||||||
|
* @package LAM\LOGIN\WEBAUTHN
|
||||||
|
*/
|
||||||
|
class WebauthnManager {
|
||||||
|
|
||||||
|
/**
|
||||||
* Returns if the given DN is registered for webauthn.
|
* Returns if the given DN is registered for webauthn.
|
||||||
*
|
*
|
||||||
* @param string $dn DN
|
* @param string $dn DN
|
||||||
* @return boolean is registered
|
* @return boolean is registered
|
||||||
*/
|
*/
|
||||||
function isRegistered($dn) {
|
public function isRegistered($dn) {
|
||||||
return false;
|
$database = $this->getDatabase();
|
||||||
}
|
$userEntity = $this->getUserEntity($dn);
|
||||||
|
$results = $database->findAllForUserEntity($userEntity);
|
||||||
|
return !empty($results);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a challenge for a new token.
|
* Returns a challenge for a new token.
|
||||||
*
|
*
|
||||||
* @param string $dn DN
|
* @param string $dn DN
|
||||||
* @param bool $isSelfService is executed in self service
|
* @param bool $isSelfService is executed in self service
|
||||||
* @return PublicKeyCredentialCreationOptions registration object
|
* @return PublicKeyCredentialCreationOptions registration object
|
||||||
*/
|
*/
|
||||||
function getRegistrationObject($dn, $isSelfService) {
|
public function getRegistrationObject($dn, $isSelfService) {
|
||||||
$rpEntity = createRpEntry($isSelfService);
|
$rpEntity = $this->createRpEntry($isSelfService);
|
||||||
$userEntity = getUserEntity($dn);
|
$userEntity = $this->getUserEntity($dn);
|
||||||
$challenge = generateRandomPassword(32);
|
$challenge = generateRandomPassword(32);
|
||||||
$credentialParameters = getCredentialParameters();
|
$credentialParameters = $this->getCredentialParameters();
|
||||||
$excludedKeys = getExcludedKeys($userEntity);
|
$excludedKeys = $this->getExcludedKeys($userEntity);
|
||||||
$timeout = 20000;
|
$timeout = 20000;
|
||||||
$registrationObject = new PublicKeyCredentialCreationOptions(
|
$registrationObject = new PublicKeyCredentialCreationOptions(
|
||||||
$rpEntity,
|
$rpEntity,
|
||||||
|
@ -107,15 +117,30 @@ function getRegistrationObject($dn, $isSelfService) {
|
||||||
new AuthenticationExtensionsClientInputs());
|
new AuthenticationExtensionsClientInputs());
|
||||||
logNewMessage(LOG_DEBUG, 'Webauthn registration: ' . json_encode($registrationObject));
|
logNewMessage(LOG_DEBUG, 'Webauthn registration: ' . json_encode($registrationObject));
|
||||||
return $registrationObject;
|
return $registrationObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the user entity for the registration.
|
||||||
|
*
|
||||||
|
* @param $dn DN
|
||||||
|
* @return PublicKeyCredentialUserEntity user entity
|
||||||
|
*/
|
||||||
|
private function getUserEntity($dn) {
|
||||||
|
return new PublicKeyCredentialUserEntity(
|
||||||
|
$dn,
|
||||||
|
$dn,
|
||||||
|
extractRDNValue($dn),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Returns the part that identifies the server and application.
|
* Returns the part that identifies the server and application.
|
||||||
*
|
*
|
||||||
* @param bool $isSelfService is executed in self service
|
* @param bool $isSelfService is executed in self service
|
||||||
* @return PublicKeyCredentialRpEntity relying party entry
|
* @return PublicKeyCredentialRpEntity relying party entry
|
||||||
*/
|
*/
|
||||||
function createRpEntry($isSelfService) {
|
private function createRpEntry($isSelfService) {
|
||||||
$pathPrefix = $isSelfService ? '../' : '';
|
$pathPrefix = $isSelfService ? '../' : '';
|
||||||
$icon = $pathPrefix . '../graphics/logo136.png';
|
$icon = $pathPrefix . '../graphics/logo136.png';
|
||||||
if (!$isSelfService) {
|
if (!$isSelfService) {
|
||||||
|
@ -126,49 +151,45 @@ function createRpEntry($isSelfService) {
|
||||||
$domain,
|
$domain,
|
||||||
$icon
|
$icon
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the user entity for the registration.
|
|
||||||
*
|
|
||||||
* @param $dn DN
|
|
||||||
* @return PublicKeyCredentialUserEntity user entity
|
|
||||||
*/
|
|
||||||
function getUserEntity($dn) {
|
|
||||||
return new PublicKeyCredentialUserEntity(
|
|
||||||
$dn,
|
|
||||||
$dn,
|
|
||||||
extractRDNValue($dn),
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the supported credential algorithms.
|
* Returns the supported credential algorithms.
|
||||||
*
|
*
|
||||||
* @return array algorithms
|
* @return array algorithms
|
||||||
*/
|
*/
|
||||||
function getCredentialParameters() {
|
private function getCredentialParameters() {
|
||||||
return array(
|
return array(
|
||||||
new PublicKeyCredentialParameters('public-key', Algorithms::COSE_ALGORITHM_ES256),
|
new PublicKeyCredentialParameters('public-key', Algorithms::COSE_ALGORITHM_ES256),
|
||||||
new PublicKeyCredentialParameters('public-key', Algorithms::COSE_ALGORITHM_RS256),
|
new PublicKeyCredentialParameters('public-key', Algorithms::COSE_ALGORITHM_RS256),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all credential ids that are already registered.
|
* Returns a list of all credential ids that are already registered.
|
||||||
*
|
*
|
||||||
* @param PublicKeyCredentialUserEntity $user user data
|
* @param PublicKeyCredentialUserEntity $user user data
|
||||||
* @return PublicKeyCredentialDescriptor[] credential ids
|
* @return PublicKeyCredentialDescriptor[] credential ids
|
||||||
*/
|
*/
|
||||||
function getExcludedKeys($user) {
|
private function getExcludedKeys($user) {
|
||||||
$keys = array();
|
$keys = array();
|
||||||
$repository = new PublicKeyCredentialSourceRepositorySQLite();
|
$repository = $this->getDatabase();
|
||||||
$credentialSources = $repository->findAllForUserEntity($user);
|
$credentialSources = $repository->findAllForUserEntity($user);
|
||||||
foreach ($credentialSources as $credentialSource) {
|
foreach ($credentialSources as $credentialSource) {
|
||||||
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $credentialSource->getPublicKeyCredentialId());
|
$keys[] = new PublicKeyCredentialDescriptor(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $credentialSource->getPublicKeyCredentialId());
|
||||||
}
|
}
|
||||||
return $keys;
|
return $keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the webauthn database.
|
||||||
|
*
|
||||||
|
* @return PublicKeyCredentialSourceRepositorySQLite database
|
||||||
|
*/
|
||||||
|
public function getDatabase() {
|
||||||
|
return new PublicKeyCredentialSourceRepositorySQLite();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,19 +296,6 @@ function getExtensionOutputChecker() {
|
||||||
return new ExtensionOutputCheckerHandler();
|
return new ExtensionOutputCheckerHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if there are any tokens registered for the given DN.
|
|
||||||
*
|
|
||||||
* @param string $dn user DN
|
|
||||||
* @return bool at least one token is registered
|
|
||||||
*/
|
|
||||||
function hasTokensRegistered($dn) {
|
|
||||||
$repository = new PublicKeyCredentialSourceRepositorySQLite();
|
|
||||||
$userEntity = getUserEntity($dn);
|
|
||||||
$tokens = $repository->findAllForUserEntity($userEntity);
|
|
||||||
return !empty($tokens);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the public key credentials in the SQLite database.
|
* Stores the public key credentials in the SQLite database.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,8 +7,7 @@ use \htmlResponsiveRow;
|
||||||
use \htmlLink;
|
use \htmlLink;
|
||||||
use \htmlOutputText;
|
use \htmlOutputText;
|
||||||
use \htmlButton;
|
use \htmlButton;
|
||||||
use function LAM\LOGIN\WEBAUTHN\getRegistrationObject;
|
use LAM\LOGIN\WEBAUTHN\WebauthnManager;
|
||||||
use function LAM\LOGIN\WEBAUTHN\isRegistered;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -193,9 +192,10 @@ class Ajax {
|
||||||
private function manageWebauthn($isSelfService) {
|
private function manageWebauthn($isSelfService) {
|
||||||
include_once __DIR__ . '/../../lib/webauthn.inc';
|
include_once __DIR__ . '/../../lib/webauthn.inc';
|
||||||
$userDN = $_SESSION['ldap']->getUserName();
|
$userDN = $_SESSION['ldap']->getUserName();
|
||||||
$isRegistered = isRegistered($userDN);
|
$webauthnManager = new WebauthnManager();
|
||||||
|
$isRegistered = $webauthnManager->isRegistered($userDN);
|
||||||
if (!$isRegistered) {
|
if (!$isRegistered) {
|
||||||
$registrationObject = getRegistrationObject($userDN, $isSelfService);
|
$registrationObject = $webauthnManager->getRegistrationObject($userDN, $isSelfService);
|
||||||
$_SESSION['webauthn_registration'] = json_encode($registrationObject);
|
$_SESSION['webauthn_registration'] = json_encode($registrationObject);
|
||||||
echo json_encode(
|
echo json_encode(
|
||||||
array(
|
array(
|
||||||
|
|
Loading…
Reference in New Issue