1
0
mirror of https://github.com/Yubico/yubikey-val.git synced 2025-01-20 10:52:15 +01:00

Merge branch 'master' of github.com:Yubico/yubikey-val-server-php

This commit is contained in:
Klas Lindfors 2012-06-14 16:44:54 +02:00
commit 0f0a23694a
4 changed files with 36 additions and 110 deletions

View File

@ -47,7 +47,7 @@ function getHttpVal($key, $defaultVal) {
return $v; return $v;
} }
function debug() { function log_format() {
$str = ""; $str = "";
foreach (func_get_args() as $msg) foreach (func_get_args() as $msg)
{ {
@ -59,8 +59,7 @@ function debug() {
$str .= $msg . " "; $str .= $msg . " ";
} }
} }
global $ykval_common_log; return $str;
$ykval_common_log->log(LOG_DEBUG, $str);
} }
// Return eg. 2008-11-21T06:11:55Z0711 // Return eg. 2008-11-21T06:11:55Z0711
@ -86,7 +85,7 @@ function UnixToDbTime($unix)
// Sign a http query string in the array of key-value pairs // Sign a http query string in the array of key-value pairs
// return b64 encoded hmac hash // return b64 encoded hmac hash
function sign($a, $apiKey) { function sign($a, $apiKey, $logger) {
ksort($a); ksort($a);
$qs = urldecode(http_build_query($a)); $qs = urldecode(http_build_query($a));
@ -94,7 +93,7 @@ function sign($a, $apiKey) {
$hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true); $hmac = hash_hmac('sha1', utf8_encode($qs), $apiKey, true);
$hmac = base64_encode($hmac); $hmac = base64_encode($hmac);
debug('SIGN: ' . $qs . ' H=' . $hmac); $logger->log(LOG_DEBUG, 'SIGN: ' . $qs . ' H=' . $hmac);
return $hmac; return $hmac;
@ -117,18 +116,18 @@ function modhex2b64 ($modhex_str) {
// long as one of the URLs given work, data will be returned. If all // long as one of the URLs given work, data will be returned. If all
// URLs fail, data from some URL that did not match parameter $match // URLs fail, data from some URL that did not match parameter $match
// (defaults to ^OK) is returned, or if all URLs failed, false. // (defaults to ^OK) is returned, or if all URLs failed, false.
function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) { function retrieveURLasync ($ident, $urls, $logger, $ans_req=1, $match="^OK", $returl=False, $timeout=10) {
$mh = curl_multi_init(); $mh = curl_multi_init();
$ch = array(); $ch = array();
foreach ($urls as $id => $url) { foreach ($urls as $id => $url) {
$handle = curl_init(); $handle = curl_init();
debug("url is: " . $url); $logger->log($ident . " adding URL : " . $url);
curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL"); curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1); curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_FAILONERROR, true); curl_setopt($handle, CURLOPT_FAILONERROR, true);
curl_setopt($handle, CURLOPT_TIMEOUT, 10); curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);
curl_multi_add_handle($mh, $handle); curl_multi_add_handle($mh, $handle);
@ -144,17 +143,17 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
; ;
while ($info = curl_multi_info_read($mh)) { while ($info = curl_multi_info_read($mh)) {
debug ("YK-KSM multi", $info); $logger->log($ident . " curl multi info : ", $info);
if ($info['result'] == CURLE_OK) { if ($info['result'] == CURLE_OK) {
$str = curl_multi_getcontent($info['handle']); $str = curl_multi_getcontent($info['handle']);
debug($str); $logger->log($ident . " curl multi content : " . $str);
if (preg_match("/".$match."/", $str)) { if (preg_match("/".$match."/", $str)) {
$logger->log($ident . " response matches " . $match);
$error = curl_error ($info['handle']); $error = curl_error ($info['handle']);
$errno = curl_errno ($info['handle']); $errno = curl_errno ($info['handle']);
$cinfo = curl_getinfo ($info['handle']); $cinfo = curl_getinfo ($info['handle']);
debug("YK-KSM errno/error: " . $errno . "/" . $error, $cinfo); $logger->log($ident . " errno/error: " . $errno . "/" . $error, $cinfo);
$ans_count++; $ans_count++;
debug("found entry");
if ($returl) $ans_arr[]="url=" . $cinfo['url'] . "\n" . $str; if ($returl) $ans_arr[]="url=" . $cinfo['url'] . "\n" . $str;
else $ans_arr[]=$str; else $ans_arr[]=$str;
} }
@ -166,8 +165,7 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
} }
curl_multi_close ($mh); curl_multi_close ($mh);
if ($ans_count==1) return $ans_arr[0]; return $ans_arr;
else return $ans_arr;
} }
curl_multi_remove_handle ($mh, $info['handle']); curl_multi_remove_handle ($mh, $info['handle']);
@ -185,6 +183,7 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) {
} }
curl_multi_close ($mh); curl_multi_close ($mh);
if ($ans_count>0) return $ans_arr;
return $str; return $str;
} }
@ -198,17 +197,20 @@ function retrieveURLsimple ($url, $match="^OK") {
} }
// $otp: A yubikey OTP // $otp: A yubikey OTP
function KSMdecryptOTP($urls) { function KSMdecryptOTP($urls, $logger) {
$ret = array(); $ret = array();
if (!is_array($urls)) { if (!is_array($urls)) {
$response = retrieveURLsimple ($urls); $response = retrieveURLsimple ($urls);
} elseif (count($urls) == 1) { } elseif (count($urls) == 1) {
$response = retrieveURLsimple ($urls[0]); $response = retrieveURLsimple ($urls[0]);
} else { } else {
$response = retrieveURLasync ($urls); $response = retrieveURLasync ("YK-KSM", $urls, $logger, $ans_req=1, $match="^OK", $returl=False, $timeout=10);
if (is_array($response)) {
$response = $response[0];
}
} }
if ($response) { if ($response) {
debug("YK-KSM response: " . $response); $logger->log(LOG_DEBUG, log_format("YK-KSM response: ", $response));
} }
if (sscanf ($response, if (sscanf ($response,
"OK counter=%04x low=%04x high=%02x use=%02x", "OK counter=%04x low=%04x high=%02x use=%02x",
@ -229,7 +231,7 @@ function sendResp($status, $logger, $apiKey = '', $extra = null) {
if ($extra){ if ($extra){
foreach ($extra as $param => $value) $a[$param] = $value; foreach ($extra as $param => $value) $a[$param] = $value;
} }
$h = sign($a, $apiKey); $h = sign($a, $apiKey, $logger);
$str = "h=" . $h . "\r\n"; $str = "h=" . $h . "\r\n";
$str .= "t=" . ($a['t']) . "\r\n"; $str .= "t=" . ($a['t']) . "\r\n";

View File

@ -117,15 +117,6 @@ if (!$localParams) {
exit; exit;
} }
if ($localParams['active'] != 1) {
/* The remote server has accepted an OTP from a YubiKey which we would not. We update our
* counters
*/
$myLog->log(LOG_WARNING, 'Received sync-request for de-activated Yubikey ' . $yk_publicname .
' - check database synchronization!!!');
}
/* Conditional update local database */ /* Conditional update local database */
$sync->updateDbCounters($syncParams); $sync->updateDbCounters($syncParams);
@ -172,7 +163,15 @@ if ($sync->countersEqual($localParams, $syncParams)) {
} }
} }
if ($localParams['active'] != 1) {
/* The remote server has accepted an OTP from a YubiKey which we would not.
* We still needed to update our counters with the counters from the OTP though.
*/
$myLog->log(LOG_WARNING, 'Received sync-request for de-activated Yubikey ' . $yk_publicname .
' - check database synchronization!!!');
sendResp(S_BAD_OTP, $apiKey);
exit;
}
$extra=array('modified'=>$localParams['modified'], $extra=array('modified'=>$localParams['modified'],
'nonce'=>$localParams['nonce'], 'nonce'=>$localParams['nonce'],

View File

@ -412,7 +412,7 @@ class SyncLib
/* /*
Send out requests Send out requests
*/ */
$ans_arr=$this->retrieveURLasync($urls, $ans_req, $timeout); $ans_arr=$this->retrieveURLasync_wrap($urls, $ans_req, $timeout);
if (!is_array($ans_arr)) { if (!is_array($ans_arr)) {
$this->log(LOG_WARNING, 'No responses from validation server pool'); $this->log(LOG_WARNING, 'No responses from validation server pool');
@ -516,84 +516,9 @@ class SyncLib
else return 0; else return 0;
} }
function retrieveURLasync_wrap ($urls, $ans_req=1, $timeout=1.0)
/* {
This function takes a list of URLs. It will return the content of return retrieveURLasync("YK-VAL sync", $urls, $this->myLog, $ans_req, $match="status=OK", $returl=True, $timeout);
the first successfully retrieved URL, whose content matches ^OK.
The request are sent asynchronously. Some of the URLs can fail
with unknown host, connection errors, or network timeout, but as
long as one of the URLs given work, data will be returned. If all
URLs fail, data from some URL that did not match parameter $match
(defaults to ^OK) is returned, or if all URLs failed, false.
*/
function retrieveURLasync ($urls, $ans_req=1, $timeout=1.0) {
$mh = curl_multi_init();
$ch = array();
foreach ($urls as $id => $url) {
$this->log(LOG_DEBUG, "url in retrieveURLasync is " . $url);
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_USERAGENT, "YK-VAL");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_FAILONERROR, true);
curl_setopt($handle, CURLOPT_TIMEOUT, $timeout);
curl_multi_add_handle($mh, $handle);
$ch[$handle] = $handle;
}
$str = false;
$ans_count = 0;
$ans_arr = array();
do {
while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM)
;
while ($info = curl_multi_info_read($mh)) {
debug ("YK-KSM multi", $info);
if ($info['result'] == CURLE_OK) {
$str = curl_multi_getcontent($info['handle']);
if (preg_match("/status=OK/", $str)) {
$error = curl_error ($info['handle']);
$errno = curl_errno ($info['handle']);
$cinfo = curl_getinfo ($info['handle']);
debug("YK-KSM errno/error: " . $errno . "/" . $error, $cinfo);
$ans_count++;
$ans_arr[]="url=" . $cinfo['url'] . "\n" . $str;
}
if ($ans_count >= $ans_req) {
foreach ($ch as $h) {
curl_multi_remove_handle ($mh, $h);
curl_close ($h);
}
curl_multi_close ($mh);
return $ans_arr;
}
curl_multi_remove_handle ($mh, $info['handle']);
curl_close ($info['handle']);
unset ($ch[$info['handle']]);
}
curl_multi_select ($mh);
}
} while($active);
foreach ($ch as $h) {
curl_multi_remove_handle ($mh, $h);
curl_close ($h);
}
curl_multi_close ($mh);
if ($ans_count>0) return $ans_arr;
else return $str;
} }
} }

View File

@ -20,7 +20,7 @@ if (preg_match("/\/wsapi\/([0-9]+)\.([0-9]+)\//", $_SERVER['REQUEST_URI'], $out)
$protocol_version=1.0; $protocol_version=1.0;
} }
$myLog->log(LOG_INFO, "found protocol version " . $protocol_version); $myLog->log(LOG_DEBUG, "found protocol version " . $protocol_version);
/* Extract values from HTTP request /* Extract values from HTTP request
*/ */
@ -185,7 +185,7 @@ if ($h != '') {
} }
unset($a['h']); unset($a['h']);
$hmac = sign($a, $apiKey); $hmac = sign($a, $apiKey, $myLog);
// Compare it // Compare it
if ($hmac != $h) { if ($hmac != $h) {
$myLog->log(LOG_DEBUG, 'client hmac=' . $h . ', server hmac=' . $hmac); $myLog->log(LOG_DEBUG, 'client hmac=' . $h . ', server hmac=' . $hmac);
@ -212,7 +212,7 @@ if (!is_array($urls)) {
//// Decode OTP from input //// Decode OTP from input
// //
$otpinfo = KSMdecryptOTP($urls); $otpinfo = KSMdecryptOTP($urls, $myLog);
if (!is_array($otpinfo)) { if (!is_array($otpinfo)) {
sendResp(S_BAD_OTP, $myLog, $apiKey); sendResp(S_BAD_OTP, $myLog, $apiKey);
exit; exit;