| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | <?php | 
					
						
							|  |  |  | namespace LAM\TOOLS\WEBAUTHN; | 
					
						
							|  |  |  | use \htmlButton; | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | use \htmlDiv; | 
					
						
							|  |  |  | use \htmlGroup; | 
					
						
							|  |  |  | use htmlHiddenInput; | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | use \htmlOutputText; | 
					
						
							|  |  |  | use \htmlResponsiveRow; | 
					
						
							|  |  |  | use \htmlResponsiveTable; | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | use \htmlSpacer; | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | use \htmlStatusMessage; | 
					
						
							|  |  |  | use \htmlTitle; | 
					
						
							|  |  |  | use \LAM\LOGIN\WEBAUTHN\PublicKeyCredentialSourceRepositorySQLite; | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | use LAM\LOGIN\WEBAUTHN\WebauthnManager; | 
					
						
							|  |  |  | use Webauthn\PublicKeyCredentialCreationOptions; | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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(); | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | validateSecurityToken(); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | checkIfToolIsActive('toolWebauthn'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setlanguage(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | include __DIR__ . '/../../lib/adminHeader.inc'; | 
					
						
							|  |  |  | echo '<div class="user-bright smallPaddingContent">'; | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | echo "<form id='webauthnform' action=\"webauthn.php\" method=\"post\">\n"; | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | $tabindex = 1; | 
					
						
							|  |  |  | $container = new htmlResponsiveRow(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $container->add(new htmlTitle(_("Webauthn devices")), 12); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | $webauthnManager = new WebauthnManager(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | $userDn = $_SESSION['ldap']->getUserName(); | 
					
						
							|  |  |  | $database = new PublicKeyCredentialSourceRepositorySQLite(); | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | showRemoveMessage($container); | 
					
						
							|  |  |  | addNewDevice($container, $webauthnManager); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | $container->addVerticalSpacer('0.5rem'); | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | $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); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | $buttonGroup = new htmlGroup(); | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | $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)); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | $reloadButton = new htmlButton('reload', _('Reload')); | 
					
						
							|  |  |  | $reloadButton->setIconClass('refreshButton'); | 
					
						
							|  |  |  | $buttonGroup->addElement($reloadButton); | 
					
						
							|  |  |  | $container->add($buttonGroup, 12); | 
					
						
							|  |  |  | $container->addVerticalSpacer('2rem'); | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | $results = $database->searchDevices($userDn); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | 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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | addSecurityTokenToMetaHTML($container); | 
					
						
							| 
									
										
										
										
											2020-01-05 18:05:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | parseHtml(null, $container, array(), false, $tabindex, 'user'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | echo '</form>'; | 
					
						
							|  |  |  | echo '</div>'; | 
					
						
							|  |  |  | include __DIR__ . '/../../lib/adminFooter.inc'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-06 11:26:50 +00:00
										 |  |  | /** | 
					
						
							|  |  |  |  * 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); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |