2009-03-10 23:20:56 +01:00
|
|
|
<?php
|
2009-05-04 16:41:18 +02:00
|
|
|
require_once 'ykval-common.php';
|
|
|
|
require_once 'ykval-config.php';
|
2009-12-02 18:32:20 +01:00
|
|
|
require_once 'ykval-synclib.php';
|
2008-09-17 19:11:16 +02:00
|
|
|
|
2009-05-06 17:07:05 +02:00
|
|
|
$apiKey = '';
|
|
|
|
|
2009-03-10 23:20:56 +01:00
|
|
|
header("content-type: text/plain");
|
2008-09-17 19:11:16 +02:00
|
|
|
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog = new Log('ykval-verify');
|
2010-01-14 12:25:17 +01:00
|
|
|
$myLog->addField('ip', $_SERVER['REMOTE_ADDR']);
|
2010-08-22 15:27:46 +02:00
|
|
|
$myLog->log(LOG_INFO, "Request: " . $_SERVER['QUERY_STRING'] .
|
2010-08-22 16:38:26 +02:00
|
|
|
" (at " . date("c") . " " . microtime() . ") " .
|
2011-10-25 10:08:31 +02:00
|
|
|
(isset($_SERVER["HTTPS"]) == TRUE ? ($_SERVER["HTTPS"] == "on" ? "HTTPS" : "HTTP") : "HTTP"));
|
2010-01-08 17:35:25 +01:00
|
|
|
|
2010-01-14 15:15:17 +01:00
|
|
|
/* Detect protocol version */
|
|
|
|
if (preg_match("/\/wsapi\/([0-9]+)\.([0-9]+)\//", $_SERVER['REQUEST_URI'], $out)) {
|
|
|
|
$protocol_version=$out[1]+$out[2]*0.1;
|
|
|
|
} else {
|
|
|
|
$protocol_version=1.0;
|
2009-12-15 11:17:51 +01:00
|
|
|
}
|
2009-03-11 02:42:23 +01:00
|
|
|
|
2010-01-19 13:45:31 +01:00
|
|
|
$myLog->log(LOG_INFO, "found protocol version " . $protocol_version);
|
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
/* Extract values from HTTP request
|
|
|
|
*/
|
2009-03-18 15:39:32 +01:00
|
|
|
$h = getHttpVal('h', '');
|
2009-03-10 23:20:56 +01:00
|
|
|
$client = getHttpVal('id', 0);
|
|
|
|
$otp = getHttpVal('otp', '');
|
|
|
|
$otp = strtolower($otp);
|
2010-09-21 10:13:36 +02:00
|
|
|
if (preg_match("/^[jxe.uidchtnbpygk]+$/", $otp)) {
|
|
|
|
$new_otp = strtr($otp, "jxe.uidchtnbpygk", "cbdefghijklnrtuv");
|
|
|
|
$myLog->log(LOG_INFO, 'Dvorak OTP converting ' . $otp . ' to ' . $new_otp);
|
|
|
|
$otp = $new_otp;
|
|
|
|
}
|
2009-10-05 16:53:28 +02:00
|
|
|
$timestamp = getHttpVal('timestamp', 0);
|
2010-01-14 12:25:17 +01:00
|
|
|
|
2010-01-20 11:37:21 +01:00
|
|
|
/* Construct response parameters */
|
|
|
|
$extra=array();
|
|
|
|
if ($protocol_version>=2.0) {
|
|
|
|
$extra['otp']=$otp;
|
2012-05-21 08:49:42 +02:00
|
|
|
}
|
2010-01-20 11:37:21 +01:00
|
|
|
|
|
|
|
|
2010-01-14 12:25:17 +01:00
|
|
|
/* We have the OTP now, so let's add it to the logging */
|
|
|
|
$myLog->addField('otp', $otp);
|
|
|
|
|
2009-12-07 20:13:20 +01:00
|
|
|
if ($protocol_version>=2.0) {
|
|
|
|
$sl = getHttpVal('sl', '');
|
|
|
|
$timeout = getHttpVal('timeout', '');
|
2009-12-15 11:17:51 +01:00
|
|
|
$nonce = getHttpVal('nonce', '');
|
2009-12-07 20:13:20 +01:00
|
|
|
|
2010-01-20 11:37:21 +01:00
|
|
|
/* Add nonce to response parameters */
|
|
|
|
$extra['nonce']= $nonce;
|
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
/* Nonce is required from protocol 2.0 */
|
2010-04-23 22:32:39 +02:00
|
|
|
if(!$nonce) {
|
|
|
|
$myLog->log(LOG_NOTICE, 'Nonce is missing and protocol version >= 2.0');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2009-12-15 11:17:51 +01:00
|
|
|
exit;
|
|
|
|
}
|
2012-05-21 08:49:42 +02:00
|
|
|
}
|
2009-03-10 23:20:56 +01:00
|
|
|
|
2010-01-13 16:32:57 +01:00
|
|
|
|
2010-01-14 10:39:48 +01:00
|
|
|
/* Sanity check HTTP parameters
|
|
|
|
|
|
|
|
* otp: one-time password
|
|
|
|
* id: client id
|
|
|
|
* timeout: timeout in seconds to wait for external answers, optional: if absent the server decides
|
2012-05-08 13:43:21 +02:00
|
|
|
* nonce: random alphanumeric string, 16 to 40 characters long. Must be non-predictable and changing for each request, but need not be cryptographically strong
|
2010-01-14 10:39:48 +01:00
|
|
|
* sl: "sync level", percentage of external servers that needs to answer (integer 0 to 100), or "fast" or "secure" to use server-configured values
|
|
|
|
* h: signature (optional)
|
|
|
|
* timestamp: requests timestamp/counters in response
|
|
|
|
|
|
|
|
*/
|
2010-01-13 16:32:57 +01:00
|
|
|
|
2012-02-22 14:27:24 +01:00
|
|
|
/* Change default protocol "strings" to numeric values */
|
2012-05-21 08:49:42 +02:00
|
|
|
if (isset($sl) && strcasecmp($sl, 'fast')==0) {
|
|
|
|
$sl=$baseParams['__YKVAL_SYNC_FAST_LEVEL__'];
|
|
|
|
}
|
|
|
|
if (isset($sl) && strcasecmp($sl, 'secure')==0) {
|
|
|
|
$sl=$baseParams['__YKVAL_SYNC_SECURE_LEVEL__'];
|
|
|
|
}
|
|
|
|
if (!isset($sl)) {
|
|
|
|
$sl=$baseParams['__YKVAL_SYNC_DEFAULT_LEVEL__'];
|
|
|
|
}
|
|
|
|
if (!isset($timeout)) {
|
|
|
|
$timeout=$baseParams['__YKVAL_SYNC_DEFAULT_TIMEOUT__'];
|
|
|
|
}
|
2012-02-22 14:27:24 +01:00
|
|
|
|
2010-09-12 12:39:23 +02:00
|
|
|
if ($otp == '') {
|
|
|
|
$myLog->log(LOG_NOTICE, 'OTP is missing');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-09-12 12:39:23 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2010-09-12 12:42:32 +02:00
|
|
|
if (strlen($otp) < TOKEN_LEN || strlen ($otp) > OTP_MAX_LEN) {
|
2010-09-12 12:39:23 +02:00
|
|
|
$myLog->log(LOG_NOTICE, 'Incorrect OTP length: ' . $otp);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BAD_OTP);
|
2010-09-12 12:39:23 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (preg_match("/^[cbdefghijklnrtuv]+$/", $otp)==0) {
|
|
|
|
$myLog->log(LOG_NOTICE, 'Invalid OTP: ' . $otp);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BAD_OTP);
|
2010-09-12 12:39:23 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2010-01-14 15:15:17 +01:00
|
|
|
if (preg_match("/^[0-9]+$/", $client)==0){
|
2010-01-13 16:32:57 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'id provided in request must be an integer');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-01-13 16:32:57 +01:00
|
|
|
exit;
|
2011-08-18 14:19:15 +02:00
|
|
|
}
|
2010-01-13 16:32:57 +01:00
|
|
|
|
2010-01-14 15:19:20 +01:00
|
|
|
if ($timeout && preg_match("/^[0-9]+$/", $timeout)==0) {
|
2010-01-14 10:39:48 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'timeout is provided but not correct');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-01-14 10:39:48 +01:00
|
|
|
exit;
|
2011-08-18 14:19:15 +02:00
|
|
|
}
|
2010-01-14 10:39:48 +01:00
|
|
|
|
2012-05-21 08:49:42 +02:00
|
|
|
if (isset($nonce) && preg_match("/^[A-Za-z0-9]+$/", $nonce)==0) {
|
2010-01-14 10:39:48 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'NONCE is provided but not correct');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-01-14 10:39:48 +01:00
|
|
|
exit;
|
2011-08-18 14:19:15 +02:00
|
|
|
}
|
2010-04-23 22:32:39 +02:00
|
|
|
|
2012-05-21 08:49:42 +02:00
|
|
|
if (isset($nonce) && (strlen($nonce) < 16 || strlen($nonce) > 40)) {
|
2010-04-23 22:32:39 +02:00
|
|
|
$myLog->log(LOG_NOTICE, 'Nonce too short or too long');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-04-23 22:32:39 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2010-01-14 15:19:20 +01:00
|
|
|
if ($sl && (preg_match("/^[0-9]+$/", $sl)==0 || ($sl<0 || $sl>100))) {
|
2010-01-14 10:39:48 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'SL is provided but not correct');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2010-01-14 10:39:48 +01:00
|
|
|
exit;
|
2011-08-18 14:19:15 +02:00
|
|
|
}
|
2010-01-14 10:39:48 +01:00
|
|
|
|
|
|
|
// NOTE: Timestamp parameter is not checked since current protocol says that 1 means request timestamp
|
|
|
|
// and anything else is discarded.
|
|
|
|
|
2009-03-10 23:20:56 +01:00
|
|
|
//// Get Client info from DB
|
|
|
|
//
|
2009-05-06 17:07:05 +02:00
|
|
|
if ($client <= 0) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'Client ID is missing');
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_MISSING_PARAMETER);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2010-01-20 11:37:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* Initialize the sync library. Strive to use this instead of custom
|
|
|
|
DB requests, custom comparisons etc */
|
|
|
|
$sync = new SyncLib('ykval-verify:synclib');
|
|
|
|
$sync->addField('ip', $_SERVER['REMOTE_ADDR']);
|
|
|
|
$sync->addField('otp', $otp);
|
|
|
|
|
|
|
|
if (! $sync->isConnected()) {
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BACKEND_ERROR);
|
2010-01-20 11:37:21 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
$cd=$sync->getClientData($client);
|
|
|
|
if(!$cd) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'Invalid client id ' . $client);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_NO_SUCH_CLIENT);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
2009-12-15 11:17:51 +01:00
|
|
|
}
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_DEBUG,"Client data:", $cd);
|
2009-03-10 23:20:56 +01:00
|
|
|
|
|
|
|
//// Check client signature
|
|
|
|
//
|
|
|
|
$apiKey = base64_decode($cd['secret']);
|
|
|
|
|
2009-03-18 16:05:59 +01:00
|
|
|
if ($h != '') {
|
2009-05-06 17:07:05 +02:00
|
|
|
// Create the signature using the API key
|
2012-05-16 13:45:08 +02:00
|
|
|
$a;
|
|
|
|
if($_GET) {
|
|
|
|
$a = $_GET;
|
|
|
|
} elseif($_POST) {
|
|
|
|
$a = $_POST;
|
|
|
|
} else {
|
|
|
|
sendRest(S_BACKEND_ERROR);
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
unset($a['h']);
|
2009-12-15 11:17:51 +01:00
|
|
|
|
2009-05-06 17:07:05 +02:00
|
|
|
$hmac = sign($a, $apiKey);
|
|
|
|
// Compare it
|
|
|
|
if ($hmac != $h) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_DEBUG, 'client hmac=' . $h . ', server hmac=' . $hmac);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BAD_SIGNATURE, $apiKey);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
|
|
|
}
|
2009-03-10 23:20:56 +01:00
|
|
|
}
|
|
|
|
|
2010-01-19 13:45:31 +01:00
|
|
|
/* We need to add necessary parameters not available at earlier protocols after signature is computed.
|
|
|
|
*/
|
|
|
|
if ($protocol_version<2.0) {
|
|
|
|
/* We need to create a nonce manually here */
|
|
|
|
$nonce = md5(uniqid(rand()));
|
|
|
|
$myLog->log(LOG_INFO, 'protocol version below 2.0. Created nonce ' . $nonce);
|
|
|
|
}
|
|
|
|
|
2009-04-27 19:57:24 +02:00
|
|
|
//// Which YK-KSM should we talk to?
|
|
|
|
//
|
|
|
|
$urls = otp2ksmurls ($otp, $client);
|
|
|
|
if (!is_array($urls)) {
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BACKEND_ERROR, $apiKey);
|
2009-04-27 19:57:24 +02:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2009-03-10 23:20:56 +01:00
|
|
|
//// Decode OTP from input
|
|
|
|
//
|
2009-04-27 19:57:24 +02:00
|
|
|
$otpinfo = KSMdecryptOTP($urls);
|
2009-03-11 01:19:59 +01:00
|
|
|
if (!is_array($otpinfo)) {
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BAD_OTP, $apiKey);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
2009-03-10 23:20:56 +01:00
|
|
|
}
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_DEBUG, "Decrypted OTP:", $otpinfo);
|
2009-03-10 23:20:56 +01:00
|
|
|
|
2009-03-11 12:02:55 +01:00
|
|
|
//// Get Yubikey from DB
|
|
|
|
//
|
2009-03-18 12:00:48 +01:00
|
|
|
$devId = substr($otp, 0, strlen ($otp) - TOKEN_LEN);
|
2010-01-08 14:54:33 +01:00
|
|
|
$yk_publicname=$devId;
|
|
|
|
$localParams = $sync->getLocalParams($yk_publicname);
|
2009-12-15 11:17:51 +01:00
|
|
|
if (!$localParams) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'Invalid Yubikey ' . $yk_publicname);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BACKEND_ERROR, $apiKey);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
2009-12-15 11:17:51 +01:00
|
|
|
}
|
2009-03-10 23:20:56 +01:00
|
|
|
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_DEBUG, "Auth data:", $localParams);
|
2009-12-15 11:17:51 +01:00
|
|
|
if ($localParams['active'] != 1) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_NOTICE, 'De-activated Yubikey ' . $devId);
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BAD_OTP, $apiKey);
|
2009-05-06 17:07:05 +02:00
|
|
|
exit;
|
2009-03-10 23:20:56 +01:00
|
|
|
}
|
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
/* Build OTP params */
|
2009-12-04 12:57:49 +01:00
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
$otpParams=array('modified'=>time(),
|
2009-12-04 12:57:49 +01:00
|
|
|
'otp'=>$otp,
|
2009-12-15 11:17:51 +01:00
|
|
|
'nonce'=>$nonce,
|
2010-01-08 14:54:33 +01:00
|
|
|
'yk_publicname'=>$devId,
|
2009-12-04 12:57:49 +01:00
|
|
|
'yk_counter'=>$otpinfo['session_counter'],
|
|
|
|
'yk_use'=>$otpinfo['session_use'],
|
|
|
|
'yk_high'=>$otpinfo['high'],
|
|
|
|
'yk_low'=>$otpinfo['low']);
|
|
|
|
|
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
/* First check if OTP is seen with the same nonce, in such case we have an replayed request */
|
|
|
|
if ($sync->countersEqual($localParams, $otpParams) &&
|
|
|
|
$localParams['nonce']==$otpParams['nonce']) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_WARNING, 'Replayed request');
|
2010-01-20 15:06:57 +01:00
|
|
|
sendResp(S_REPLAYED_REQUEST, $apiKey, $extra);
|
2009-12-15 11:17:51 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check the OTP counters against local db */
|
|
|
|
if ($sync->countersHigherThanOrEqual($localParams, $otpParams)) {
|
2010-01-12 16:24:38 +01:00
|
|
|
$sync->log(LOG_WARNING, 'replayed OTP: Local counters higher');
|
|
|
|
$sync->log(LOG_WARNING, 'replayed OTP: Local counters ', $localParams);
|
|
|
|
$sync->log(LOG_WARNING, 'replayed OTP: Otp counters ', $otpParams);
|
2010-01-20 11:37:21 +01:00
|
|
|
sendResp(S_REPLAYED_OTP, $apiKey, $extra);
|
2009-12-15 11:17:51 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Valid OTP, update database. */
|
|
|
|
|
|
|
|
if(!$sync->updateDbCounters($otpParams)) {
|
2010-01-12 14:00:28 +01:00
|
|
|
$myLog->log(LOG_CRIT, "Failed to update yubikey counters in database");
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BACKEND_ERROR, $apiKey);
|
2009-12-15 11:17:51 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Queue sync requests */
|
2009-12-04 12:57:49 +01:00
|
|
|
|
2009-12-07 20:13:20 +01:00
|
|
|
if (!$sync->queue($otpParams, $localParams)) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_CRIT, "ykval-verify:critical:failed to queue sync requests");
|
2011-08-18 14:19:15 +02:00
|
|
|
sendResp(S_BACKEND_ERROR, $apiKey);
|
2009-12-04 12:57:49 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2009-12-07 20:13:20 +01:00
|
|
|
$nr_servers=$sync->getNumberOfServers();
|
2009-12-08 17:07:08 +01:00
|
|
|
$req_answers=ceil($nr_servers*$sl/100.0);
|
2009-12-07 20:13:20 +01:00
|
|
|
if ($req_answers>0) {
|
|
|
|
$syncres=$sync->sync($req_answers, $timeout);
|
|
|
|
$nr_answers=$sync->getNumberOfAnswers();
|
|
|
|
$nr_valid_answers=$sync->getNumberOfValidAnswers();
|
2009-12-08 17:07:08 +01:00
|
|
|
$sl_success_rate=floor(100.0 * $nr_valid_answers / $nr_servers);
|
2009-12-07 20:13:20 +01:00
|
|
|
|
|
|
|
} else {
|
2010-05-17 15:06:06 +02:00
|
|
|
$syncres=true;
|
2009-12-07 20:13:20 +01:00
|
|
|
$nr_answers=0;
|
|
|
|
$nr_valid_answers=0;
|
|
|
|
$sl_success_rate=0;
|
|
|
|
}
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_INFO, "ykval-verify:notice:synclevel=" . $sl .
|
|
|
|
" nr servers=" . $nr_servers .
|
|
|
|
" req answers=" . $req_answers .
|
|
|
|
" answers=" . $nr_answers .
|
|
|
|
" valid answers=" . $nr_valid_answers .
|
|
|
|
" sl success rate=" . $sl_success_rate .
|
|
|
|
" timeout=" . $timeout);
|
2009-12-02 18:32:20 +01:00
|
|
|
|
|
|
|
if($syncres==False) {
|
2009-12-07 20:13:20 +01:00
|
|
|
/* sync returned false, indicating that
|
|
|
|
either at least 1 answer marked OTP as invalid or
|
|
|
|
there were not enough answers */
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_WARNING, "ykval-verify:notice:Sync failed");
|
2009-12-07 20:13:20 +01:00
|
|
|
if ($nr_valid_answers!=$nr_answers) {
|
2010-01-20 11:37:21 +01:00
|
|
|
sendResp(S_REPLAYED_OTP, $apiKey, $extra);
|
2009-12-02 18:32:20 +01:00
|
|
|
exit;
|
|
|
|
} else {
|
2010-01-20 11:37:21 +01:00
|
|
|
$extra['sl']=$sl_success_rate;
|
2009-12-08 11:26:27 +01:00
|
|
|
sendResp(S_NOT_ENOUGH_ANSWERS, $apiKey, $extra);
|
2009-12-02 18:32:20 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
2009-03-10 23:20:56 +01:00
|
|
|
|
2009-12-15 11:17:51 +01:00
|
|
|
/* Recreate parameters to make phising test work out
|
|
|
|
TODO: use timefunctionality in deltatime library instead */
|
|
|
|
$sessionCounter = $otpParams['yk_counter'];
|
|
|
|
$sessionUse = $otpParams['yk_use'];
|
|
|
|
$seenSessionCounter = $localParams['yk_counter'];
|
|
|
|
$seenSessionUse = $localParams['yk_use'];
|
|
|
|
|
|
|
|
$ad['high']=$localParams['yk_high'];
|
|
|
|
$ad['low']=$localParams['yk_low'];
|
|
|
|
$ad['accessed']=$sync->unixToDbTime($localParams['modified']);
|
2009-12-07 20:13:20 +01:00
|
|
|
|
2009-03-11 01:19:59 +01:00
|
|
|
//// Check the time stamp
|
2009-03-10 23:20:56 +01:00
|
|
|
//
|
2009-03-11 01:19:59 +01:00
|
|
|
if ($sessionCounter == $seenSessionCounter && $sessionUse > $seenSessionUse) {
|
2009-03-11 02:37:07 +01:00
|
|
|
$ts = ($otpinfo['high'] << 16) + $otpinfo['low'];
|
2009-03-11 01:19:59 +01:00
|
|
|
$seenTs = ($ad['high'] << 16) + $ad['low'];
|
|
|
|
$tsDiff = $ts - $seenTs;
|
|
|
|
$tsDelta = $tsDiff * TS_SEC;
|
|
|
|
|
|
|
|
//// Check the real time
|
|
|
|
//
|
|
|
|
$lastTime = strtotime($ad['accessed']);
|
|
|
|
$now = time();
|
|
|
|
$elapsed = $now - $lastTime;
|
|
|
|
$deviation = abs($elapsed - $tsDelta);
|
2009-10-05 16:53:28 +02:00
|
|
|
|
|
|
|
// Time delta server might verify multiple OTPS in a row. In such case validation server doesn't
|
|
|
|
// have time to tick a whole second and we need to avoid division by zero.
|
|
|
|
if ($elapsed != 0) {
|
|
|
|
$percent = $deviation/$elapsed;
|
|
|
|
} else {
|
|
|
|
$percent = 1;
|
|
|
|
}
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_INFO, "Timestamp seen=" . $seenTs . " this=" . $ts .
|
|
|
|
" delta=" . $tsDiff . ' secs=' . $tsDelta .
|
|
|
|
' accessed=' . $lastTime .' (' . $ad['accessed'] . ') now='
|
|
|
|
. $now . ' (' . strftime("%Y-%m-%d %H:%M:%S", $now)
|
|
|
|
. ') elapsed=' . $elapsed .
|
|
|
|
' deviation=' . $deviation . ' secs or '.
|
|
|
|
round(100*$percent) . '%');
|
2009-03-11 01:26:57 +01:00
|
|
|
if ($deviation > TS_ABS_TOLERANCE && $percent > TS_REL_TOLERANCE) {
|
2010-01-11 13:06:00 +01:00
|
|
|
$myLog->log(LOG_NOTICE, "OTP failed phishing test");
|
2009-05-06 15:20:40 +02:00
|
|
|
if (0) {
|
2010-01-20 11:37:21 +01:00
|
|
|
sendResp(S_DELAYED_OTP, $apiKey, $extra);
|
2009-03-11 01:19:59 +01:00
|
|
|
exit;
|
|
|
|
}
|
|
|
|
}
|
2009-03-10 23:20:56 +01:00
|
|
|
}
|
|
|
|
|
2010-01-20 11:37:21 +01:00
|
|
|
/* Fill up with more respone parameters */
|
2009-12-07 20:13:20 +01:00
|
|
|
if ($protocol_version>=2.0) {
|
|
|
|
$extra['sl'] = $sl_success_rate;
|
|
|
|
}
|
2009-10-05 16:53:28 +02:00
|
|
|
if ($timestamp==1){
|
|
|
|
$extra['timestamp'] = ($otpinfo['high'] << 16) + $otpinfo['low'];
|
|
|
|
$extra['sessioncounter'] = $sessionCounter;
|
|
|
|
$extra['sessionuse'] = $sessionUse;
|
2009-12-07 20:13:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sendResp(S_OK, $apiKey, $extra);
|
|
|
|
|
2008-09-17 19:11:16 +02:00
|
|
|
?>
|