AP-REP KRB5_MUTUAL_FAILED (-1765328226L) and Leap Seconds

Tom Yu tlyu at MIT.EDU
Wed May 25 17:53:49 EDT 2011

Dave Daugherty <dave.daugherty at centrify.com> writes:

> We recently stumbled upon a problem with a CentOS version 5 library that appears to factor 24 leap seconds into gmttime_r function. This may have to do with timezone settings http://old.nabble.com/Seeking-clarifaction-of-tai64nlocal-and-leap-seconds-td31298116.html

Are there systems where the "right/*" timezones are the default?  They
are arguably not POSIX-conforming and could run into all sorts of
other problems.  If they're sufficiently common, we might need a
workaround.  (POSIX defines "Seconds Since the Epoch" in a way that
ignores the existence of leap seconds, i.e. every calendar day
consists of exactly 86400 seconds.)

> This leads to a AP-REQ/AP-REP failure because of the following
> AP-REQ reads gmtime_r and converts it to an ASCII time string to be sent to the service - the gmtime_r includes leap seconds
> The AP-REP that comes back  and the returned time string (which is correct) eventually is given to krb5int_gmt_mktime (or gmt_mktime in older releases) where the time string is converted back into a time structure without factoring in the leap seconds
> Now the mutual authentication fails because the two values - the gmttime_r sent and the gmt_mktime value are off by 24 seconds.

This is not the first time I've heard of this problem (thanks to Love
Hörnquist Åstrand for pointing it out before, along with a possible
solution), but I'd like to have more information about how common it

> Questions:
> Why not just save the time string and then compare it against the return time string to avoid this problem?

Overall, this does not appear to be an easy problem to solve.

The interfaces used in the mk_req/rd_rep code path deal in time_t
values, not struct tm values or ASN.1 GeneralizedTime strings, so it
would not be easy to save the time string.  Attempting to solve this
by using the platform's native time conversion functions runs into
problems because there is no standard inverse to gmtime() (some
platforms might have timegm(), a GNU extension), and changing global
timezone state in a library isn't very friendly or thread-safe.

We might try Love's approach, which involves a replacement gmtime()
that ignores leap seconds.  On a system with a "right" timezone, that
approach won't encode the correct value of UTC time into the protocol
messages, as the time_t values will count leap seconds while the
replacement gmtime() will ignore them.  This may not matter right now,
as the offset is currently only 24 seconds, but it might cause
auditing issues or confusion when interpreting log files.  In the
future, it might exceed the permissible clockskew.

> Are there other places in the code base where this might be a problem?

It might possibly be a problem anywhere else that deals with reading
GeneralizedTime values and converting them to time_t values.

More information about the krbdev mailing list