345 if ( $otp['session'] == $session_count && $otp['count'] <= $token_count ) |
345 if ( $otp['session'] == $session_count && $otp['count'] <= $token_count ) |
346 { |
346 { |
347 return 'REPLAYED_OTP'; |
347 return 'REPLAYED_OTP'; |
348 } |
348 } |
349 |
349 |
350 // update DB |
|
351 $q = $db->sql_query("UPDATE " . table_prefix . "yms_yubikeys SET session_count = {$otp['session']}, token_count = {$otp['count']}, access_time = " . time() . ", token_time = {$otp['timestamp']} WHERE id = $yubikey_id;"); |
|
352 if ( !$q ) |
|
353 $db->_die(); |
|
354 |
|
355 // check timestamp |
350 // check timestamp |
356 if ( $otp['session'] == $session_count ) |
351 if ( $otp['session'] == $session_count ) |
357 { |
352 { |
358 $expect_delta = time() - $access_time; |
353 $expect_delta = time() - $access_time; |
359 // 8Hz Yubikey internal clock |
354 // Tolerate up to a 0.5Hz deviance from 8Hz. I've observed Yubikey |
360 $actual_delta = intval(( $otp['timestamp'] - $token_time ) / 8); |
355 // clocks running at 8.32Hz |
361 $fuzz = 150; |
356 $actual_delta = $otp['timestamp'] - $token_time; |
|
357 $fuzz = 150 + round(($actual_delta / 7.5) - ($actual_delta / 8.5)); |
|
358 // Now that we've calculated fuzz, convert the actual delta to quasi-seconds |
|
359 $actual_delta /= 8; |
362 if ( !yms_within($expect_delta, $actual_delta, $fuzz) ) |
360 if ( !yms_within($expect_delta, $actual_delta, $fuzz) ) |
363 { |
361 { |
364 // if we have a likely wraparound, just pass it |
362 // if we have a likely wraparound, just pass it |
365 if ( !($token_time > 0xe80000 && $otp['timestamp'] < 0x800000) ) |
363 if ( !($token_time > 0xe80000 && $otp['timestamp'] < 0x080000) ) |
366 { |
364 { |
367 return 'BAD_OTP'; |
365 return 'BAD_OTP'; |
368 } |
366 } |
369 } |
367 } |
370 // $debug_array = array('ts_debug_delta_expected' => $expect_delta, 'ts_debug_delta_received' => $actual_delta); |
368 // $debug_array = array('ts_debug_delta_expected' => $expect_delta, 'ts_debug_delta_received' => $actual_delta); |
371 } |
369 } |
372 |
370 |
|
371 // update DB |
|
372 $q = $db->sql_query("UPDATE " . table_prefix . "yms_yubikeys SET session_count = {$otp['session']}, token_count = {$otp['count']}, access_time = " . time() . ", token_time = {$otp['timestamp']} WHERE id = $yubikey_id;"); |
|
373 if ( !$q ) |
|
374 $db->_die(); |
|
375 |
373 // looks like we're good |
376 // looks like we're good |
374 return 'OK'; |
377 return 'OK'; |
375 } |
378 } |