Skip to content
Snippets Groups Projects
Commit 6b745354 authored by Andreas Åkre Solberg's avatar Andreas Åkre Solberg
Browse files

Improvements to the YubiKey authentication module. Removed the username field,...

Improvements to the YubiKey authentication module. Removed the username field, added dictionaries and templates etc.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1155 44740490-163a-0410-bde0-09ae8108e29a
parent 01ec5be1
No related branches found
No related tags found
No related merge requests found
......@@ -40,13 +40,29 @@
* @package simpleSAMLphp
* @version $Id$
*/
class sspmod_authYubiKey_Auth_Source_YubiKey extends sspmod_core_Auth_UserPassBase {
class sspmod_authYubiKey_Auth_Source_YubiKey extends SimpleSAML_Auth_Source {
/**
* The client id/key for use with the Auth_Yubico PHP module.
*/
private $yubi_id;
private $yubi_key;
/**
* The string used to identify our states.
*/
const STAGEID = 'sspmod_authYubiKey_Auth_Source_YubiKey.state';
/**
* The number of characters of the OTP that is the secure token.
* The rest is the user id.
*/
const TOKENSIZE = 32;
/**
* The key of the AuthId field in the state.
*/
const AUTHID = 'sspmod_authYubiKey_Auth_Source_YubiKey.AuthId';
/**
* The client id/key for use with the Auth_Yubico PHP module.
*/
private $yubi_id;
private $yubi_key;
/**
* Constructor for this authentication source.
......@@ -71,6 +87,84 @@ class sspmod_authYubiKey_Auth_Source_YubiKey extends sspmod_core_Auth_UserPassBa
}
/**
* Initialize login.
*
* This function saves the information about the login, and redirects to a
* login page.
*
* @param array &$state Information about the current authentication.
*/
public function authenticate(&$state) {
assert('is_array($state)');
/* We are going to need the authId in order to retrieve this authentication source later. */
$state[self::AUTHID] = $this->authId;
$id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
$url = SimpleSAML_Module::getModuleURL('authYubiKey/yubikeylogin.php');
SimpleSAML_Utilities::redirect($url, array('AuthState' => $id));
}
/**
* Handle login request.
*
* This function is used by the login form (core/www/loginuserpass.php) when the user
* enters a username and password. On success, it will not return. On wrong
* username/password failure, it will return the error code. Other failures will throw an
* exception.
*
* @param string $authStateId The identifier of the authentication state.
* @param string $otp The one time password entered-
* @return string Error code in the case of an error.
*/
public static function handleLogin($authStateId, $otp) {
assert('is_string($authStateId)');
assert('is_string($otp)');
/* Retrieve the authentication state. */
$state = SimpleSAML_Auth_State::loadState($authStateId, self::STAGEID);
/* Find authentication source. */
assert('array_key_exists(self::AUTHID, $state)');
$source = SimpleSAML_Auth_Source::getById($state[self::AUTHID]);
if ($source === NULL) {
throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
}
try {
/* Attempt to log in. */
$attributes = $source->login($otp);
} catch (SimpleSAML_Error_Error $e) {
/* An error occured during login. Check if it is because of the wrong
* username/password - if it is, we pass that error up to the login form,
* if not, we let the generic error handler deal with it.
*/
if ($e->getErrorCode() === 'WRONGUSERPASS') {
return 'WRONGUSERPASS';
}
/* Some other error occured. Rethrow exception and let the generic error
* handler deal with it.
*/
throw $e;
}
$state['Attributes'] = $attributes;
SimpleSAML_Auth_Source::completeAuth($state);
}
/**
* Return the user id part of a one time passord
*/
public static function getYubiKeyPrefix($otp) {
$uid = substr ($otp, 0, strlen ($otp) - self::TOKENSIZE);
return $uid;
}
/**
* Attempt to log in using the given username and password.
*
......@@ -84,9 +178,8 @@ class sspmod_authYubiKey_Auth_Source_YubiKey extends sspmod_core_Auth_UserPassBa
* @param string $password The password the user wrote.
* @return array Associative array with the users attributes.
*/
protected function login($username, $password) {
assert('is_string($username)');
assert('is_string($password)');
protected function login($otp) {
assert('is_string($otp)');
require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/libextinc/Yubico.php';
......@@ -94,16 +187,16 @@ class sspmod_authYubiKey_Auth_Source_YubiKey extends sspmod_core_Auth_UserPassBa
try {
$yubi = &new Auth_Yubico($this->yubi_id, $this->yubi_key);
$auth = $yubi->verify($password);
$attributes = array('uid' => array($username), 'otp' => array($password));
$auth = $yubi->verify($otp);
$uid = self::getYubiKeyPrefix($otp);
$attributes = array('uid' => array($uid));
} catch (Exception $e) {
SimpleSAML_Logger::info('YubiKey:' . $this->authId . ': Validation error (user ' . $username . ' otp ' . $password . '), debug output: ' . $yubi->getLastResponse());
SimpleSAML_Logger::info('YubiKey:' . $this->authId . ': Validation error (otp ' . $otp . '), debug output: ' . $yubi->getLastResponse());
throw new SimpleSAML_Error_Error('WRONGUSERPASS', $e);
}
SimpleSAML_Logger::info('YubiKey:' . $this->authId . ': YubiKey otp ' . $password . ' for user ' . $username . ' validated successfully: ' . $yubi->getLastResponse());
SimpleSAML_Logger::info('YubiKey:' . $this->authId . ': YubiKey otp ' . $password . ' validated successfully: ' . $yubi->getLastResponse());
return $attributes;
}
......
<?php
$this->data['icon'] = 'lock.png';
$this->data['header'] = $this->t('{authYubiKey:yubikey:header}');
$this->data['autofocus'] = 'otp';
$this->includeAtTemplateBase('includes/header.php');
?>
<div id="content">
<?php
if ($this->data['errorcode'] !== NULL) {
?>
<div style="border-left: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8; background: #f5f5f5">
<img src="/<?php echo $this->data['baseurlpath']; ?>resources/icons/bomb.png" style="float: left; margin: 15px " />
<h2><?php echo $this->t('{login:error_header}'); ?></h2>
<p><b><?php echo $this->t('{errors:title_' . $this->data['errorcode'] . '}'); ?></b></p>
<p><?php echo $this->t('{errors:descr_' . $this->data['errorcode'] . '}'); ?></p>
</div>
<?php
}
?>
<img style="float: right" src="<?php echo(SimpleSAML_Module::getModuleURL('authYubiKey/resources/logo.jpg')); ?>" />
<img style="clear: right; float: right" src="<?php echo(SimpleSAML_Module::getModuleURL('authYubiKey/resources/yubikey.jpg')); ?>" />
<h2 style=""><?php echo $this->t('{authYubiKey:yubikey:header}'); ?></h2>
<form action="?" method="post" name="f">
<p><?php echo $this->t('{authYubiKey:yubikey:intro}'); ?></p>
<p><input id="otp" style="border: 1px solid #ccc; background: #eee; padding: .5em; font-size: medium; width: 70%; color: #aaa" type="text" tabindex="2" name="otp" /></p>
<?php
foreach ($this->data['stateparams'] as $name => $value) {
echo('<input type="hidden" name="' . htmlspecialchars($name) . '" value="' . htmlspecialchars($value) . '" />');
}
?>
</form>
<?php
$this->includeAtTemplateBase('includes/footer.php');
?>
\ No newline at end of file
modules/authYubiKey/www/resources/logo.jpg

7.56 KiB

modules/authYubiKey/www/resources/yubikey.jpg

3.24 KiB

<?php
/**
* This page shows a username/password login form, and passes information from it
* to the sspmod_core_Auth_UserPassBase class, which is a generic class for
* username/password authentication.
*
* @author Olav Morken, UNINETT AS.
* @package simpleSAMLphp
* @version $Id$
*/
if (!array_key_exists('AuthState', $_REQUEST)) {
throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.');
}
$authStateId = $_REQUEST['AuthState'];
if (array_key_exists('otp', $_REQUEST)) {
$otp = $_REQUEST['otp'];
} else {
$otp = '';
}
if (!empty($otp)) {
/* attempt to log in. */
$errorCode = sspmod_authYubiKey_Auth_Source_YubiKey::handleLogin($authStateId, $otp);
} else {
$errorCode = NULL;
}
$globalConfig = SimpleSAML_Configuration::getInstance();
$t = new SimpleSAML_XHTML_Template($globalConfig, 'authYubiKey:yubikeylogin.php');
$t->data['stateparams'] = array('AuthState' => $authStateId);
$t->data['errorcode'] = $errorCode;
$t->show();
exit();
?>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment