plugins/yubikey/corelib.php
changeset 37 5e946a3f405b
parent 36 f2aa4bc50d2f
--- a/plugins/yubikey/corelib.php	Sat May 29 04:35:49 2010 -0400
+++ b/plugins/yubikey/corelib.php	Fri Nov 11 00:30:49 2011 -0500
@@ -10,222 +10,222 @@
 
 function generate_yubikey_field($name = 'yubikey_otp', $value = false)
 {
-  global $lang;
-  
-  $fid = substr(sha1(microtime() . mt_rand()), 0, 12);
-  $class = $value ? 'wasfull' : 'wasempty';
-  $html = '<input id="yubifield' . $fid . '" class="' . $class . '" type="hidden" name="' . $name . '" value="' . ( is_string($value) ? $value : '' ) . '" />';
-  $html .= '<noscript><input type="text" name="' . $name . '" class="yubikey_noscript" value="' . ( is_string($value) ? $value : '' ) . '" /> </noscript>';
-  if ( $value )
-  {
-    $html .= '<span id="yubistat' . $fid . '" class="yubikey_status enrolled">' . $lang->get('yubiauth_ctl_status_enrolled') . '</span>';
-    $atext = $lang->get('yubiauth_ctl_btn_change_key');
-    $classadd = ' abutton_green';
-  }
-  else
-  {
-    $html .= '<span id="yubistat' . $fid . '" class="yubikey_status empty">' . $lang->get('yubiauth_ctl_status_empty') . '</span>';
-    $atext = $lang->get('yubiauth_ctl_btn_enroll');
-    $classadd = '';
-  }
-  
-  $html .= ' <span class="yubikey_pubkey">';
-  if ( !empty($value) )
-    $html .= htmlspecialchars(substr($value, 0, 12));
-  $html .= '</span> ';
-  
-  $html .= ' <a class="abutton' . $classadd . ' yubikey_enroll" onclick="yk_mb_init(\'yubifield' . $fid . '\', \'yubistat' . $fid . '\'); return false;" href="#enroll">' . $atext . '</a>';
-  if ( $value )
-  {
-    $html .= ' <a class="abutton abutton_red yubikey_enroll" onclick="yk_clear(\'yubifield' . $fid . '\', \'yubistat' . $fid . '\'); return false;" href="#enroll">'
-             . $lang->get('yubiauth_ctl_btn_clear') .
-             '</a>';
-  }
-  
-  return $html;
+	global $lang;
+	
+	$fid = substr(sha1(microtime() . mt_rand()), 0, 12);
+	$class = $value ? 'wasfull' : 'wasempty';
+	$html = '<input id="yubifield' . $fid . '" class="' . $class . '" type="hidden" name="' . $name . '" value="' . ( is_string($value) ? $value : '' ) . '" />';
+	$html .= '<noscript><input type="text" name="' . $name . '" class="yubikey_noscript" value="' . ( is_string($value) ? $value : '' ) . '" /> </noscript>';
+	if ( $value )
+	{
+		$html .= '<span id="yubistat' . $fid . '" class="yubikey_status enrolled">' . $lang->get('yubiauth_ctl_status_enrolled') . '</span>';
+		$atext = $lang->get('yubiauth_ctl_btn_change_key');
+		$classadd = ' abutton_green';
+	}
+	else
+	{
+		$html .= '<span id="yubistat' . $fid . '" class="yubikey_status empty">' . $lang->get('yubiauth_ctl_status_empty') . '</span>';
+		$atext = $lang->get('yubiauth_ctl_btn_enroll');
+		$classadd = '';
+	}
+	
+	$html .= ' <span class="yubikey_pubkey">';
+	if ( !empty($value) )
+		$html .= htmlspecialchars(substr($value, 0, 12));
+	$html .= '</span> ';
+	
+	$html .= ' <a class="abutton' . $classadd . ' yubikey_enroll" onclick="yk_mb_init(\'yubifield' . $fid . '\', \'yubistat' . $fid . '\'); return false;" href="#enroll">' . $atext . '</a>';
+	if ( $value )
+	{
+		$html .= ' <a class="abutton abutton_red yubikey_enroll" onclick="yk_clear(\'yubifield' . $fid . '\', \'yubistat' . $fid . '\'); return false;" href="#enroll">'
+ 						. $lang->get('yubiauth_ctl_btn_clear') .
+ 						'</a>';
+	}
+	
+	return $html;
 }
 
 function yubikey_validate_otp($otp)
 {
-  $api_key = getConfig('yubikey_api_key');
-  $api_id  = getConfig('yubikey_api_key_id');
-  // Don't require an API key or user ID to be installed if we're using local YMS
-  if ( !(getConfig('yubikey_use_local_yms', 0) && defined('YMS_INSTALLED')) && (!$api_key || !$api_id) )
-  {
-    return array(
-        'success' => false,
-        'error' => 'missing_api_key'
-      );
-  }
-  if ( !preg_match('/^[cbdefghijklnrtuv]{44}$/', $otp) )
-  {
-    return array(
-        'success' => false,
-        'error' => 'otp_invalid_chars'
-      );
-  }
-  // are we using local YMS?
-  if ( getConfig('yubikey_use_local_yms', 0) && defined('YMS_INSTALLED') )
-  {
-    $result = yms_validate_otp($otp, $api_id);
-    if ( $result == 'OK' )
-    {
-      return array(
-          'success' => true
-        );
-    }
-    else
-    {
-      return array(
-        'success' => false,
-        'error' => strtolower("response_{$result}")
-      );
-    }
-  }
-  // make HTTP request
-  require_once( ENANO_ROOT . '/includes/http.php' );
-  $auth_url = getConfig('yubikey_auth_server', YK_DEFAULT_VERIFY_URL);
-  $auth_url = preg_replace('#^https?://#i', '', $auth_url);
-  if ( !preg_match('#^(\[?[a-z0-9-:]+(?:\.[a-z0-9-:]+\]?)*)(?::([0-9]+))?(/.*)$#U', $auth_url, $match) )
-  {
-    return array(
-        'success' => false,
-        'error' => 'invalid_auth_url'
-      );
-  }
-  $auth_server =& $match[1];
-  $auth_port = ( !empty($match[2]) ) ? intval($match[2]) : 80;
-  $auth_uri =& $match[3];
-  try
-  {
-    $req = new Request_HTTP($auth_server, $auth_uri, 'GET', $auth_port);
-    $req->add_get('id', strval($api_id));
-    $req->add_get('otp', $otp);
-    $req->add_get('h', yubikey_sign($req->parms_get));
-  
-    $response = $req->get_response_body();
-  }
-  catch ( Exception $e )
-  {
-    return array(
-        'success' => false,
-        'error' => 'http_failed',
-        'http_error' => $e->getMessage()
-      );
-  }
-  
-  if ( $req->response_code != HTTP_OK )
-  {
-    return array(
-        'success' => false,
-        'error' => 'http_response_error'
-      );
-  }
-  $response = trim($response);
-  if ( !preg_match_all('/^([a-z0-9_]+)=(.*?)\r?$/m', $response, $matches) )
-  {
-    return array(
-        'success' => false,
-        'error' => 'malformed_response'
-      );
-  }
-  $response = array();
-  foreach ( $matches[0] as $i => $_ )
-  {
-    $response[$matches[1][$i]] = $matches[2][$i];
-  }
-  // make sure we have a status
-  if ( !isset($response['status']) )
-  {
-    return array(
-        'success' => false,
-        'error' => 'response_missing_status'
-      );
-  }
-  // verify response signature
-  // MISSING_PARAMETER is the ONLY situation under which an unsigned response is acceptable
-  if ( $response['status'] !== 'MISSING_PARAMETER' )
-  {
-    if ( !isset($response['h']) )
-    {
-      return array(
-          'success' => false,
-          'error' => 'response_missing_sig'
-        );
-    }
-    if ( yubikey_sign($response) !== $response['h'] )
-    {
-      return array(
-          'success' => false,
-          'error' => 'response_invalid_sig'
-        );
-    }
-  }
-  if ( $response['status'] === 'OK' )
-  {
-    if ( yubikey_verify_timestamp($response['t']) )
-    {
-      return array(
-          'success' => true
-        );
-    }
-    else
-    {
-      return array(
-          'success' => false,
-          'error' => 'timestamp_check_failed'
-        );
-    }
-  }
-  else
-  {
-    return array(
-        'success' => false,
-        'error' => strtolower("response_{$response['status']}")
-      );
-  }
+	$api_key = getConfig('yubikey_api_key');
+	$api_id  = getConfig('yubikey_api_key_id');
+	// Don't require an API key or user ID to be installed if we're using local YMS
+	if ( !(getConfig('yubikey_use_local_yms', 0) && defined('YMS_INSTALLED')) && (!$api_key || !$api_id) )
+	{
+		return array(
+				'success' => false,
+				'error' => 'missing_api_key'
+			);
+	}
+	if ( !preg_match('/^[cbdefghijklnrtuv]{44}$/', $otp) )
+	{
+		return array(
+				'success' => false,
+				'error' => 'otp_invalid_chars'
+			);
+	}
+	// are we using local YMS?
+	if ( getConfig('yubikey_use_local_yms', 0) && defined('YMS_INSTALLED') )
+	{
+		$result = yms_validate_otp($otp, $api_id);
+		if ( $result == 'OK' )
+		{
+			return array(
+					'success' => true
+				);
+		}
+		else
+		{
+			return array(
+				'success' => false,
+				'error' => strtolower("response_{$result}")
+			);
+		}
+	}
+	// make HTTP request
+	require_once( ENANO_ROOT . '/includes/http.php' );
+	$auth_url = getConfig('yubikey_auth_server', YK_DEFAULT_VERIFY_URL);
+	$auth_url = preg_replace('#^https?://#i', '', $auth_url);
+	if ( !preg_match('#^(\[?[a-z0-9-:]+(?:\.[a-z0-9-:]+\]?)*)(?::([0-9]+))?(/.*)$#U', $auth_url, $match) )
+	{
+		return array(
+				'success' => false,
+				'error' => 'invalid_auth_url'
+			);
+	}
+	$auth_server =& $match[1];
+	$auth_port = ( !empty($match[2]) ) ? intval($match[2]) : 80;
+	$auth_uri =& $match[3];
+	try
+	{
+		$req = new Request_HTTP($auth_server, $auth_uri, 'GET', $auth_port);
+		$req->add_get('id', strval($api_id));
+		$req->add_get('otp', $otp);
+		$req->add_get('h', yubikey_sign($req->parms_get));
+	
+		$response = $req->get_response_body();
+	}
+	catch ( Exception $e )
+	{
+		return array(
+				'success' => false,
+				'error' => 'http_failed',
+				'http_error' => $e->getMessage()
+			);
+	}
+	
+	if ( $req->response_code != HTTP_OK )
+	{
+		return array(
+				'success' => false,
+				'error' => 'http_response_error'
+			);
+	}
+	$response = trim($response);
+	if ( !preg_match_all('/^([a-z0-9_]+)=(.*?)\r?$/m', $response, $matches) )
+	{
+		return array(
+				'success' => false,
+				'error' => 'malformed_response'
+			);
+	}
+	$response = array();
+	foreach ( $matches[0] as $i => $_ )
+	{
+		$response[$matches[1][$i]] = $matches[2][$i];
+	}
+	// make sure we have a status
+	if ( !isset($response['status']) )
+	{
+		return array(
+				'success' => false,
+				'error' => 'response_missing_status'
+			);
+	}
+	// verify response signature
+	// MISSING_PARAMETER is the ONLY situation under which an unsigned response is acceptable
+	if ( $response['status'] !== 'MISSING_PARAMETER' )
+	{
+		if ( !isset($response['h']) )
+		{
+			return array(
+					'success' => false,
+					'error' => 'response_missing_sig'
+				);
+		}
+		if ( yubikey_sign($response) !== $response['h'] )
+		{
+			return array(
+					'success' => false,
+					'error' => 'response_invalid_sig'
+				);
+		}
+	}
+	if ( $response['status'] === 'OK' )
+	{
+		if ( yubikey_verify_timestamp($response['t']) )
+		{
+			return array(
+					'success' => true
+				);
+		}
+		else
+		{
+			return array(
+					'success' => false,
+					'error' => 'timestamp_check_failed'
+				);
+		}
+	}
+	else
+	{
+		return array(
+				'success' => false,
+				'error' => strtolower("response_{$response['status']}")
+			);
+	}
 }
 
 function yubikey_sign($arr, $use_api_key = false)
 {
-  static $api_key = false;
-  
-  ksort($arr);
-  
-  if ( !$use_api_key )
-  {
-    if ( !$api_key )
-    {
-      $api_key = getConfig('yubikey_api_key');
-      $api_key = hexencode(base64_decode($api_key), '', '');
-    }
-    $use_api_key = $api_key;
-  }
-  /*
-  else
-  {
-    $use_api_key = hexencode(base64_decode($use_api_key), '', '');
-  }
-  */
-  
-  foreach ( array('h', 'title', 'auth', 'do') as $key )
-  {
-    if ( isset($arr[$key]) )
-      unset($arr[$key]);
-  }
-  
-  $req = array();
-  foreach ( $arr as $key => $val )
-  {
-    $req[] = "$key=$val";
-  }
-  $req = implode('&', $req);
-  
-  $sig = hmac_sha1($req, $use_api_key);
-  $sig = hexdecode($sig);
-  $sig = base64_encode($sig);
-  
-  return $sig;
+	static $api_key = false;
+	
+	ksort($arr);
+	
+	if ( !$use_api_key )
+	{
+		if ( !$api_key )
+		{
+			$api_key = getConfig('yubikey_api_key');
+			$api_key = hexencode(base64_decode($api_key), '', '');
+		}
+		$use_api_key = $api_key;
+	}
+	/*
+	else
+	{
+		$use_api_key = hexencode(base64_decode($use_api_key), '', '');
+	}
+	*/
+	
+	foreach ( array('h', 'title', 'auth', 'do') as $key )
+	{
+		if ( isset($arr[$key]) )
+			unset($arr[$key]);
+	}
+	
+	$req = array();
+	foreach ( $arr as $key => $val )
+	{
+		$req[] = "$key=$val";
+	}
+	$req = implode('&', $req);
+	
+	$sig = hmac_sha1($req, $use_api_key);
+	$sig = hexdecode($sig);
+	$sig = base64_encode($sig);
+	
+	return $sig;
 }
 
 /**
@@ -236,65 +236,65 @@
 
 function yubikey_verify_timestamp($timestamp)
 {
-  $tolerance = intval(getConfig('yubikey_api_ts_tolerance', 150));
-  
-  $now = time();
-  $timestamp_seconds = yk_strtotime($timestamp);
+	$tolerance = intval(getConfig('yubikey_api_ts_tolerance', 150));
+	
+	$now = time();
+	$timestamp_seconds = yk_strtotime($timestamp);
 
-  if ( !$timestamp || !$now || !$timestamp_seconds )
-  {
-    return false;
-  }
+	if ( !$timestamp || !$now || !$timestamp_seconds )
+	{
+		return false;
+	}
 
-  if ( ( $timestamp_seconds + $tolerance ) > $now && ( $timestamp_seconds - $tolerance ) < $now )
-  {
-    return true;
-  }
+	if ( ( $timestamp_seconds + $tolerance ) > $now && ( $timestamp_seconds - $tolerance ) < $now )
+	{
+		return true;
+	}
 
-  return false;
+	return false;
 }
 
 function yk_strtotime($timestamp)
 {
-  if ( !preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:Z[0-9]+)?$/', $timestamp, $match) )
-    return 0;
-  
-  $hour = intval($match[4]);
-  $minute = intval($match[5]);
-  $second = intval($match[6]);
-  $month = intval($match[2]);
-  $day = intval($match[3]);
-  $year = intval($match[1]);
-  
-  return gmmktime($hour, $minute, $second, $month, $day, $year);
+	if ( !preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:Z[0-9]+)?$/', $timestamp, $match) )
+		return 0;
+	
+	$hour = intval($match[4]);
+	$minute = intval($match[5]);
+	$second = intval($match[6]);
+	$month = intval($match[2]);
+	$day = intval($match[3]);
+	$year = intval($match[1]);
+	
+	return gmmktime($hour, $minute, $second, $month, $day, $year);
 }
 
 $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
-  $user_flags = 0;
-  $yk_enabled = 0;
-  if ( $session->user_logged_in )
-  {
-    $q = $db->sql_query('SELECT COUNT(y.yubi_uid) > 0, u.user_yubikey_flags FROM ' . table_prefix . "yubikey AS y LEFT JOIN " . table_prefix . "users AS u ON ( u.user_id = y.user_id ) WHERE y.user_id = {$session->user_id} GROUP BY u.user_id, u.user_yubikey_flags;");
-    if ( !$q )
-      $db->_die();
-    
-    list($yk_enabled, $user_flags) = $db->fetchrow_num();
-    $db->free_result();
-  }
-  $yk_enabled = intval($yk_enabled);
-  $user_flags = intval($user_flags);
-  
-  $template->add_header('<script type="text/javascript">var yk_reg_require_otp = ' . getConfig('yubikey_reg_require_otp', '0') . '; var yk_user_enabled = ' . $yk_enabled . '; var yk_user_flags = ' . $user_flags . ';</script>');
+	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
+	$user_flags = 0;
+	$yk_enabled = 0;
+	if ( $session->user_logged_in )
+	{
+		$q = $db->sql_query('SELECT COUNT(y.yubi_uid) > 0, u.user_yubikey_flags FROM ' . table_prefix . "yubikey AS y LEFT JOIN " . table_prefix . "users AS u ON ( u.user_id = y.user_id ) WHERE y.user_id = {$session->user_id} GROUP BY u.user_id, u.user_yubikey_flags;");
+		if ( !$q )
+			$db->_die();
+		
+		list($yk_enabled, $user_flags) = $db->fetchrow_num();
+		$db->free_result();
+	}
+	$yk_enabled = intval($yk_enabled);
+	$user_flags = intval($user_flags);
+	
+	$template->add_header('<script type="text/javascript">var yk_reg_require_otp = ' . getConfig('yubikey_reg_require_otp', '0') . '; var yk_user_enabled = ' . $yk_enabled . '; var yk_user_flags = ' . $user_flags . ';</script>');
 }