0) { $row = mysql_fetch_assoc($r); mysql_free_result($r); $modified=DbTimeToUnix($row['accessed']); } else { $modified=0; } //// Queue sync requests $sl = new SyncLib(); // We need the modifed value from the DB $stmp = 'SELECT accessed FROM yubikeys WHERE id=' . $ad['id']; query($conn, $stmt); $otpParams=array('modified'=>$modified, 'otp'=>$otp, 'yk_identity'=>$devId, 'yk_counter'=>$otpinfo['session_counter'], 'yk_use'=>$otpinfo['session_use'], 'yk_high'=>$otpinfo['high'], 'yk_low'=>$otpinfo['low']); $localParams=array('modified'=>DbTimeToUnix($ad['accessed']), 'otp'=>'', 'yk_identity'=>$devId, 'yk_counter'=>$ad['counter'], 'yk_use'=>$ad['sessionUse'], 'yk_high'=>$ad['high'], 'yk_low'=>$ad['low']); if (!$sl->queue($otpParams, $localParams)) { debug("ykval-verify:critical:failed to queue sync requests"); sendResp(S_BACKEND_ERROR, $apiKey); exit; } $required_answers=$sl->getNumberOfServers(); $syncres=$sl->sync($required_answers); $answers=$sl->getNumberOfAnswers(); $valid_answers=$sl->getNumberOfValidAnswers(); debug("ykval-verify:notice:number of servers=" . $required_answers); debug("ykval-verify:notice:number of answers=" . $answers); debug("ykval-verify:notice:number of valid answers=" . $valid_answers); if($syncres==False) { # sync returned false, indicating that # either at least 1 answer marked OTP as invalid or # there were not enough answers debug("ykval-verify:notice:Sync failed"); if ($valid_answers!=$answers) { sendResp(S_REPLAYED_OTP, $apiKey); exit; } else { sendResp(S_NOT_ENOUGH_ANSWERS, $apiKey); exit; } } //// Check the time stamp // if ($sessionCounter == $seenSessionCounter && $sessionUse > $seenSessionUse) { $ts = ($otpinfo['high'] << 16) + $otpinfo['low']; $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); // 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; } debug("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) . '%'); if ($deviation > TS_ABS_TOLERANCE && $percent > TS_REL_TOLERANCE) { debug("OTP failed phishing test"); if (0) { sendResp(S_DELAYED_OTP, $apiKey); exit; } } } if ($timestamp==1){ $extra['timestamp'] = ($otpinfo['high'] << 16) + $otpinfo['low']; $extra['sessioncounter'] = $sessionCounter; $extra['sessionuse'] = $sessionUse; sendResp(S_OK, $apiKey, $extra); } else { sendResp(S_OK, $apiKey); } ?>