by: Nik Conwell <nik@bu.edu>
krb5_set_real_time() accepts as input the time of the KDC
or an application server as a combination of seconds and
microseconds. Often it is the case that the time source
does not provide the real time with less than one second
granularity. Up until this patch such a caller would fill
in the microseconds parameter as zero. krb5_set_real_time()
would treat the zero microseconds as the actual reported
time and compute a microsecond based offset.
During a one second window subsequent calls to
krb5_set_real_time() would have an ever increasing offset
size until the number of seconds is incremented. This
in turn produces a side effect in which the microseconds
value of the local clock is effectively erased.
If there are multiple processes or threads on the same
machine each requesting service tickets using the same
client principal for the same service principal where
the number of seconds reported by the KDC are equivalent,
then they will now all create authenticators with
exactly the same timestamp. As a result, the authenticating
service will detect a replay attack even though the
authenticators are actually unique. The replay cache
only maintains a tuple of client, server and timestamp.
This patch modifies the interpretation of the microseconds
parameter. If -1 is specified, the microseconds offset is
ignored.
ticket: 5924
tags: pullup
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20413
dc483132-0cff-0310-8789-
dd5450dbe970
if (context->library_options & KRB5_LIBOPT_SYNC_KDCTIME) {
retval = krb5_set_real_time(context,
- as_reply->enc_part2->times.authtime, 0);
+ as_reply->enc_part2->times.authtime, -1);
if (retval)
return retval;
} else {
* routines will return the correct time as corrected by difference
* between the system time and the "real time" as passed to this
* routine
+ *
+ * If the real time microseconds are given as -1 the caller doesn't
+ * know the microseconds value so the usec offset is always zero.
*/
krb5_error_code KRB5_CALLCONV
krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)
retval = krb5_crypto_us_timeofday(&sec, &usec);
if (retval)
return retval;
+
os_ctx->time_offset = seconds - sec;
- os_ctx->usec_offset = microseconds - usec;
+ os_ctx->usec_offset = (microseconds > -1) ? microseconds - usec : 0;
+
os_ctx->os_flags = ((os_ctx->os_flags & ~KRB5_OS_TOFFSET_TIME) |
KRB5_OS_TOFFSET_VALID);
return 0;