Added timestamp-based verification.
--- a/plugins/Yubikey.php Mon Mar 02 10:56:51 2009 -0500
+++ b/plugins/Yubikey.php Sun Mar 08 00:45:45 2009 -0500
@@ -117,6 +117,7 @@
err_missing_api_key: 'Your OTP could not be validated because no Yubico API key is registered on this site.',
err_http_response_error: 'Your OTP could not be validated because the Yubico authentication server reported an error.',
err_malformed_response: 'Your OTP could not be validated because the Yubico authentication server returned an unexpected response.',
+ err_timestamp_check_failed: 'Your OTP could not be validated because the timestamp of the response from the Yubico authentication server was out of bounds.',
err_response_missing_sig: 'Your OTP could not be validated because the Yubico authentication server did not sign its response.',
err_response_invalid_sig: 'Your OTP could not be validated because the signature of the authentication response was invalid.',
err_response_missing_status: '%this.yubiauth_err_malformed_response%',
--- a/plugins/yubikey/corelib.php Mon Mar 02 10:56:51 2009 -0500
+++ b/plugins/yubikey/corelib.php Sun Mar 08 00:45:45 2009 -0500
@@ -126,9 +126,19 @@
}
if ( $response['status'] === 'OK' )
{
- return array(
- 'success' => true
- );
+ if ( yubikey_verify_timestamp($response['t']) )
+ {
+ return array(
+ 'success' => true
+ );
+ }
+ else
+ {
+ return array(
+ 'success' => false,
+ 'error' => 'timestamp_check_failed'
+ );
+ }
}
else
{
@@ -168,16 +178,56 @@
return $sig;
}
+/**
+ * Validate the timestamp returned in a Yubico API response. Borrowed from Drupal and backported for friendliness with earlier versions of PHP.
+ * @param string Yubico timestamp
+ * @return bool True if valid, false otherwise
+ */
+
+function yubikey_verify_timestamp($timestamp)
+{
+ $tolerance = intval(getConfig('yubikey_api_ts_tolerance', 150));
+
+ $now = time();
+ $timestamp_seconds = strtotime(substr($timestamp, 0, -4));
+
+ if ( !$timestamp || !$now )
+ {
+ return false;
+ }
+
+ if ( ( $timestamp_seconds + $tolerance ) > $now && ( $timestamp_seconds - $tolerance ) < $now )
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
$plugins->attachHook('compile_template', 'yubikey_attach_headers($this);');
function yubikey_attach_headers(&$template)
{
+ global $db, $session, $paths, $template, $plugins; // Common objects
+
if ( getConfig('yubikey_enable', '1') != '1' )
return true;
$template->add_header('<script type="text/javascript" src="' . scriptPath . '/plugins/yubikey/yubikey.js"></script>');
$template->add_header('<link rel="stylesheet" type="text/css" href="' . scriptPath . '/plugins/yubikey/yubikey.css" />');
// config option for all users have yubikey
- $template->add_header('<script type="text/javascript">var yk_reg_require_otp = ' . getConfig('yubikey_reg_require_otp', '0') . '</script>');
+ $user_flags = 0;
+ if ( $session->user_logged_in )
+ {
+ $q = $db->sql_query('SELECT COUNT(yubi_uid) > 0 FROM ' . table_prefix . "yubikey WHERE user_id = {$session->user_id};");
+ if ( !$q )
+ $db->_die();
+
+ list($user_flags) = $db->fetchrow_num();
+ $db->free_result();
+ }
+
+ $template->add_header('<script type="text/javascript">var yk_reg_require_otp = ' . getConfig('yubikey_reg_require_otp', '0') . '; var yk_user_enabled = ' . $user_flags . ';</script>');
}
--- a/plugins/yubikey/yubikey.js Mon Mar 02 10:56:51 2009 -0500
+++ b/plugins/yubikey/yubikey.js Sun Mar 08 00:45:45 2009 -0500
@@ -252,7 +252,7 @@
$('#messageBoxButtons input:button:first').focus();
$('#ajax_login_field_captcha').focus();
});
- if ( window.yk_reg_require_otp )
+ if ( window.yk_reg_require_otp || window.yk_user_enabled )
{
setTimeout(function()
{