public function testCountersEqual() { $sl = new SyncLib(); $localParams = array('yk_counter' => 100, 'yk_use' => 10); $otpParams = array('yk_counter' => 100, 'yk_use' => 10); $this->assertTrue($sl->countersEqual($otpParams, $localParams)); $otpParams['yk_use'] = 8; $this->assertFalse($sl->countersEqual($otpParams, $localParams)); $otpParams['yk_use'] = 9; $this->assertFalse($sl->countersEqual($otpParams, $localParams)); $otpParams['yk_use'] = -11; $this->assertFalse($sl->countersEqual($otpParams, $localParams)); $otpParams['yk_use'] = 10; $otpParams['yk_counter'] = 101; $this->assertFalse($sl->countersEqual($otpParams, $localParams)); }
$myLog->log(LOG_DEBUG, 'Decrypted OTP:', $otpinfo); // get Yubikey from DB $yk_publicname = substr($otp, 0, strlen($otp) - TOKEN_LEN); if (($localParams = $sync->getLocalParams($yk_publicname)) === FALSE) { $myLog->log(LOG_NOTICE, "Invalid Yubikey {$yk_publicname}"); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); } $myLog->log(LOG_DEBUG, 'Auth data:', $localParams); if ($localParams['active'] != 1) { $myLog->log(LOG_NOTICE, "De-activated Yubikey {$yk_publicname}"); sendResp(S_BAD_OTP, $myLog, $apiKey); } /* Build OTP params */ $otpParams = array('modified' => time(), 'otp' => $otp, 'nonce' => $nonce, 'yk_publicname' => $yk_publicname, 'yk_counter' => $otpinfo['session_counter'], 'yk_use' => $otpinfo['session_use'], 'yk_high' => $otpinfo['high'], 'yk_low' => $otpinfo['low']); /* 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']) { $myLog->log(LOG_WARNING, 'Replayed request'); sendResp(S_REPLAYED_REQUEST, $myLog, $apiKey, $extra); } /* Check the OTP counters against local db */ if ($sync->countersHigherThanOrEqual($localParams, $otpParams)) { $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); sendResp(S_REPLAYED_OTP, $myLog, $apiKey, $extra); } /* Valid OTP, update database. */ if (!$sync->updateDbCounters($otpParams)) { $myLog->log(LOG_CRIT, 'Failed to update yubikey counters in database'); sendResp(S_BACKEND_ERROR, $myLog, $apiKey); }
if ($localParams['active'] != 1) { $myLog->log(LOG_NOTICE, 'De-activated Yubikey ' . $yk_publicname); sendResp(S_BAD_OTP, $apiKey); exit; } /* Conditional update local database */ $sync->updateDbCounters($syncParams); $myLog->log(LOG_DEBUG, 'Local params ', $localParams); $myLog->log(LOG_DEBUG, 'Sync request params ', $syncParams); # # Compare sync and local counters and generate warnings according to # # http://code.google.com/p/yubikey-val-server-php/wiki/ServerReplicationProtocol # if ($sync->countersHigherThan($localParams, $syncParams)) { $myLog->log(LOG_WARNING, 'Remote server out of sync.'); } if ($sync->countersEqual($localParams, $syncParams)) { if ($syncParams['modified'] == $localParams['modified'] && $syncParams['nonce'] == $localParams['nonce']) { $myLog->log(LOG_NOTICE, 'Sync request unnessecarily sent'); } if ($syncParams['modified'] != $localParams['modified'] && $syncParams['nonce'] == $localParams['nonce']) { $deltaModified = $syncParams['modified'] - $localParams['modified']; $myLog->log(LOG_WARNING, 'We might have a replay. 2 events at different times have generated the same counters. The time difference is ' . $deltaModified . ' seconds'); } if ($syncParams['nonce'] != $localParams['nonce']) { $myLog->log(LOG_WARNING, 'Remote server has received a request to validate an already validated OTP '); } } $extra = array('modified' => $localParams['modified'], 'nonce' => $localParams['nonce'], 'yk_publicname' => $yk_publicname, 'yk_counter' => $localParams['yk_counter'], 'yk_use' => $localParams['yk_use'], 'yk_high' => $localParams['yk_high'], 'yk_low' => $localParams['yk_low']); sendResp(S_OK, '', $extra);