diff --git a/ykval-common.php b/ykval-common.php index ce4c9ce..6e7395e 100644 --- a/ykval-common.php +++ b/ykval-common.php @@ -47,7 +47,7 @@ function getHttpVal($key, $defaultVal) { return $v; } -function debug() { +function log_format() { $str = ""; foreach (func_get_args() as $msg) { @@ -59,8 +59,7 @@ function debug() { $str .= $msg . " "; } } - global $ykval_common_log; - $ykval_common_log->log(LOG_DEBUG, $str); + return $str; } // 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 // return b64 encoded hmac hash -function sign($a, $apiKey) { +function sign($a, $apiKey, $logger) { ksort($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 = base64_encode($hmac); - debug('SIGN: ' . $qs . ' H=' . $hmac); + $logger->log(LOG_DEBUG, 'SIGN: ' . $qs . ' H=' . $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 // 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, $match="^OK", $returl=False) { +function retrieveURLasync ($ident, $urls, $logger, $ans_req=1, $match="^OK", $returl=False, $timeout=10) { $mh = curl_multi_init(); $ch = array(); foreach ($urls as $id => $url) { $handle = curl_init(); - debug("url is: " . $url); + $logger->log($ident . " adding URL : " . $url); 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, 10); + curl_setopt($handle, CURLOPT_TIMEOUT, $timeout); 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)) { - debug ("YK-KSM multi", $info); + $logger->log($ident . " curl multi info : ", $info); if ($info['result'] == CURLE_OK) { $str = curl_multi_getcontent($info['handle']); - debug($str); + $logger->log($ident . " curl multi content : " . $str); if (preg_match("/".$match."/", $str)) { + $logger->log($ident . " response matches " . $match); $error = curl_error ($info['handle']); $errno = curl_errno ($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++; - debug("found entry"); if ($returl) $ans_arr[]="url=" . $cinfo['url'] . "\n" . $str; else $ans_arr[]=$str; } @@ -166,8 +165,7 @@ function retrieveURLasync ($urls, $ans_req=1, $match="^OK", $returl=False) { } curl_multi_close ($mh); - if ($ans_count==1) return $ans_arr[0]; - else return $ans_arr; + return $ans_arr; } 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); + if ($ans_count>0) return $ans_arr; return $str; } @@ -198,17 +197,20 @@ function retrieveURLsimple ($url, $match="^OK") { } // $otp: A yubikey OTP -function KSMdecryptOTP($urls) { +function KSMdecryptOTP($urls, $logger) { $ret = array(); if (!is_array($urls)) { $response = retrieveURLsimple ($urls); } elseif (count($urls) == 1) { $response = retrieveURLsimple ($urls[0]); } 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) { - debug("YK-KSM response: " . $response); + $logger->log(LOG_DEBUG, log_format("YK-KSM response: ", $response)); } if (sscanf ($response, "OK counter=%04x low=%04x high=%02x use=%02x", @@ -229,7 +231,7 @@ function sendResp($status, $logger, $apiKey = '', $extra = null) { if ($extra){ foreach ($extra as $param => $value) $a[$param] = $value; } - $h = sign($a, $apiKey); + $h = sign($a, $apiKey, $logger); $str = "h=" . $h . "\r\n"; $str .= "t=" . ($a['t']) . "\r\n"; diff --git a/ykval-sync.php b/ykval-sync.php index 55e1a53..c9fe517 100644 --- a/ykval-sync.php +++ b/ykval-sync.php @@ -117,15 +117,6 @@ if (!$localParams) { 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 */ $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'], 'nonce'=>$localParams['nonce'], diff --git a/ykval-synclib.php b/ykval-synclib.php index f990c42..f96e2d9 100644 --- a/ykval-synclib.php +++ b/ykval-synclib.php @@ -412,7 +412,7 @@ class SyncLib /* 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)) { $this->log(LOG_WARNING, 'No responses from validation server pool'); @@ -516,84 +516,9 @@ class SyncLib else return 0; } - - /* - This function takes a list of URLs. It will return the content of - 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; + function retrieveURLasync_wrap ($urls, $ans_req=1, $timeout=1.0) + { + return retrieveURLasync("YK-VAL sync", $urls, $this->myLog, $ans_req, $match="status=OK", $returl=True, $timeout); } } diff --git a/ykval-verify.php b/ykval-verify.php index 58a5cfa..e466190 100644 --- a/ykval-verify.php +++ b/ykval-verify.php @@ -20,7 +20,7 @@ if (preg_match("/\/wsapi\/([0-9]+)\.([0-9]+)\//", $_SERVER['REQUEST_URI'], $out) $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 */ @@ -185,7 +185,7 @@ if ($h != '') { } unset($a['h']); - $hmac = sign($a, $apiKey); + $hmac = sign($a, $apiKey, $myLog); // Compare it if ($hmac != $h) { $myLog->log(LOG_DEBUG, 'client hmac=' . $h . ', server hmac=' . $hmac); @@ -212,7 +212,7 @@ if (!is_array($urls)) { //// Decode OTP from input // -$otpinfo = KSMdecryptOTP($urls); +$otpinfo = KSMdecryptOTP($urls, $myLog); if (!is_array($otpinfo)) { sendResp(S_BAD_OTP, $myLog, $apiKey); exit;