175 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php
 | |
| namespace LAM\TOOLS\WEBAUTHN;
 | |
| use \htmlButton;
 | |
| use \htmlDiv;
 | |
| use \htmlGroup;
 | |
| use htmlHiddenInput;
 | |
| use \htmlOutputText;
 | |
| use \htmlResponsiveRow;
 | |
| use \htmlResponsiveTable;
 | |
| use \htmlSpacer;
 | |
| use \htmlStatusMessage;
 | |
| use \htmlTitle;
 | |
| use \LAM\LOGIN\WEBAUTHN\PublicKeyCredentialSourceRepositorySQLite;
 | |
| use LAM\LOGIN\WEBAUTHN\WebauthnManager;
 | |
| use Webauthn\PublicKeyCredentialCreationOptions;
 | |
| 
 | |
| /*
 | |
| 
 | |
|   This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | |
|   Copyright (C) 2020  Roland Gruber
 | |
| 
 | |
|   This program is free software; you can redistribute it and/or modify
 | |
|   it under the terms of the GNU General Public License as published by
 | |
|   the Free Software Foundation; either version 2 of the License, or
 | |
|   (at your option) any later version.
 | |
| 
 | |
|   This program is distributed in the hope that it will be useful,
 | |
|   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|   GNU General Public License for more details.
 | |
| 
 | |
|   You should have received a copy of the GNU General Public License
 | |
|   along with this program; if not, write to the Free Software
 | |
|   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 
 | |
| */
 | |
| 
 | |
| /**
 | |
| * Allows webauthn device management.
 | |
| *
 | |
| * @author Roland Gruber
 | |
| * @package tools
 | |
| */
 | |
| 
 | |
| /** security functions */
 | |
| include_once(__DIR__ . "/../../lib/security.inc");
 | |
| /** access to configuration options */
 | |
| include_once(__DIR__ . "/../../lib/config.inc");
 | |
| /** webauthn */
 | |
| include_once __DIR__ . '/../../lib/webauthn.inc';
 | |
| 
 | |
| // start session
 | |
| startSecureSession();
 | |
| enforceUserIsLoggedIn();
 | |
| validateSecurityToken();
 | |
| 
 | |
| checkIfToolIsActive('toolWebauthn');
 | |
| 
 | |
| setlanguage();
 | |
| 
 | |
| include __DIR__ . '/../../lib/adminHeader.inc';
 | |
| echo '<div class="user-bright smallPaddingContent">';
 | |
| echo "<form id='webauthnform' action=\"webauthn.php\" method=\"post\">\n";
 | |
| $tabindex = 1;
 | |
| $container = new htmlResponsiveRow();
 | |
| 
 | |
| $container->add(new htmlTitle(_("Webauthn devices")), 12);
 | |
| 
 | |
| $webauthnManager = new WebauthnManager();
 | |
| 
 | |
| $userDn = $_SESSION['ldap']->getUserName();
 | |
| $database = new PublicKeyCredentialSourceRepositorySQLite();
 | |
| showRemoveMessage($container);
 | |
| addNewDevice($container, $webauthnManager);
 | |
| $container->addVerticalSpacer('0.5rem');
 | |
| $container->add(new htmlHiddenInput('registrationData', ''), 12);
 | |
| $errorMessageDiv = new htmlDiv('generic-webauthn-error', new htmlOutputText(''));
 | |
| $errorMessageDiv->addDataAttribute('button', _('Ok'));
 | |
| $errorMessageDiv->addDataAttribute('title', _('Webauthn failed'));
 | |
| $container->add($errorMessageDiv, 12);
 | |
| $buttonGroup = new htmlGroup();
 | |
| $registerButton = new htmlButton('register', _('Register new device'));
 | |
| $registerButton->addDataAttribute('dn', $userDn);
 | |
| $registerButton->addDataAttribute('sec_token_value', getSecurityTokenValue());
 | |
| $registerButton->addDataAttribute('sec_token_name', getSecurityTokenName());
 | |
| $registration = $webauthnManager->getRegistrationObject($userDn, false);
 | |
| $registrationJson = json_encode($registration);
 | |
| $_SESSION['webauthn_registration'] = $registrationJson;
 | |
| $registerButton->addDataAttribute('publickey', $registrationJson);
 | |
| $registerButton->setIconClass('createButton');
 | |
| $registerButton->setOnClick('window.lam.webauthn.registerOwnDevice(event);');
 | |
| $buttonGroup->addElement($registerButton);
 | |
| $buttonGroup->addElement(new htmlSpacer('1rem', null));
 | |
| $reloadButton = new htmlButton('reload', _('Reload'));
 | |
| $reloadButton->setIconClass('refreshButton');
 | |
| $buttonGroup->addElement($reloadButton);
 | |
| $container->add($buttonGroup, 12);
 | |
| $container->addVerticalSpacer('2rem');
 | |
| $results = $database->searchDevices($userDn);
 | |
| if (empty($results)) {
 | |
| 	$container->add(new htmlStatusMessage('INFO', _('No devices found.')), 12);
 | |
| }
 | |
| else {
 | |
| 	$titles = array(
 | |
| 		_('Registration'),
 | |
| 		_('Last use'),
 | |
| 		_('Delete')
 | |
| 	);
 | |
| 	$data = array();
 | |
| 	$id = 0;
 | |
| 	foreach ($results as $result) {
 | |
| 		$delButton = new htmlButton('deleteDevice' . $id, 'delete.png', true);
 | |
| 		$delButton->addDataAttribute('credential', $result['credentialId']);
 | |
| 		$delButton->addDataAttribute('dn', $result['dn']);
 | |
| 		$delButton->addDataAttribute('dialogtitle', _('Remove device'));
 | |
| 		$delButton->addDataAttribute('oktext', _('Ok'));
 | |
| 		$delButton->addDataAttribute('canceltext', _('Cancel'));
 | |
| 		$delButton->setOnClick('window.lam.webauthn.removeOwnDevice(event);');
 | |
| 		$data[] = array(
 | |
| 			new htmlOutputText(date('Y-m-d H:i:s', $result['registrationTime'])),
 | |
| 			new htmlOutputText(date('Y-m-d H:i:s', $result['lastUseTime'])),
 | |
| 			$delButton
 | |
| 		);
 | |
| 		$id++;
 | |
| 	}
 | |
| 	$table = new htmlResponsiveTable($titles, $data);
 | |
| 	$tableDiv = new htmlDiv('webauthn_results', $table);
 | |
| 	$tableDiv->addDataAttribute('sec_token_value', getSecurityTokenValue());
 | |
| 	$container->add($tableDiv, 12);
 | |
| }
 | |
| $container->addVerticalSpacer('2rem');
 | |
| 
 | |
| $confirmationDiv = new htmlDiv('webauthnDeleteConfirm', new htmlOutputText(_('Do you really want to remove this device?')), array('hidden'));
 | |
| $container->add($confirmationDiv, 12);
 | |
| 
 | |
| addSecurityTokenToMetaHTML($container);
 | |
| 
 | |
| parseHtml(null, $container, array(), false, $tabindex, 'user');
 | |
| 
 | |
| echo '</form>';
 | |
| echo '</div>';
 | |
| include __DIR__ . '/../../lib/adminFooter.inc';
 | |
| 
 | |
| /**
 | |
|  * Checks if a new device should be registered and adds it.
 | |
|  *
 | |
|  * @param htmlResponsiveRow $container row
 | |
|  * @param WebauthnManager $webauthnManager webauthn manager
 | |
|  */
 | |
| function addNewDevice($container, $webauthnManager) {
 | |
| 	if (empty($_POST['registrationData'])) {
 | |
| 		return;
 | |
| 	}
 | |
| 	$registrationData = base64_decode($_POST['registrationData']);
 | |
| 	$registrationObject = PublicKeyCredentialCreationOptions::createFromString($_SESSION['webauthn_registration']);
 | |
| 	$success = $webauthnManager->storeNewRegistration($registrationObject, $registrationData);
 | |
| 	if ($success) {
 | |
| 		$container->add(new htmlStatusMessage('INFO', _('The device was registered.')), 12);
 | |
| 	}
 | |
| 	else {
 | |
| 		$container->add(new htmlStatusMessage('ERROR', _('The device failed to register.')), 12);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Shows the message if a device was removed.
 | |
|  *
 | |
|  * @param htmlResponsiveRow $container row
 | |
|  */
 | |
| function showRemoveMessage($container) {
 | |
| 	if (!empty($_POST['removed']) && ($_POST['removed'] === 'true')) {
 | |
| 		$container->add(new htmlStatusMessage('INFO', _('The device was deleted.')), 12);
 | |
| 	}
 | |
| }
 |