V4 tickets expiring too soon
Peter DiCamillo
Peter_DiCamillo at brown.edu
Sat Nov 20 01:46:20 EST 2004
We recently upgraded from Kerberos 1.2.7 to 1.3.5, and we now have a
problem with v4 tickets expiring too soon. We have an application
which gets a v4 TGT, then immediately uses it to get a service
ticket. Usually it works ok, but at times the krb_mk_req call fails
with a ticket expired error (RD_AP_EXP). When we started to
investigate it, we discovered we could reliably reproduce the problem
by just requesting tickets that way in a loop. It always fails
within in a short time.
We verified that the problem does not exist in 1.2.7, and then traced
the source of it in 1.3.5. It's happening when the KDC executes the
code which checks for ticket expiration in rd_req.c:
/* Now check for expiration of ticket */
ret = RD_AP_NYV;
#ifdef KRB_CRYPT_DEBUG
tkt_age = t_local - ad->time_sec;
if (krb_ap_req_debug)
log("Time: %d Issue Date: %d Diff: %d Life %x",
time_secs, ad->time_sec, tkt_age, ad->life);
#endif
if (t_local < ad->time_sec) {
if ((ad->time_sec - t_local) > CLOCK_SKEW)
goto cleanup;
} else if (krb_life_to_time((KRB4_32)ad->time_sec, ad->life)
< t_local + CLOCK_SKEW) {
ret = RD_AP_EXP;
goto cleanup;
}
The TGT was requested with a lifetime of 1 (which makes sense for
this application.) Tracing showed that the TGT was accepted when the
current time was the same as the TGT issue time. But occasionally
the time had incremented by one since the TGT was issued. In that
case, since the ticket lifetime is the same as the clock skew, the
ticket is treated as expired.
At first I thought there was a bug in this code, and that the test
with "t_local + CLOCK_SKEW" should have been "t_local - CLOCK_SKEW".
But when I checked for fixes in the CVS tree, I found this comment
had been added:
/*
* This calculation is different than the same expiration
* calculation in krb5. In krb5 the ticket lasts for
* clock_skew seconds longer than its expiration; in krb4 it
* lasts clock_skew seconds less. This difference is
* necessary to avoid using an almost expired tgt to get a new
* tgt that will last for another 5 minutes. This code
* interacts with the login in src/kdc/kerberos_v4.c to
* back-date tickets to avoid them expiring late. The
* combination may be overly conservative, but I'm fairly sure
* either removing the kerberos_v4 backdating or replacing
* this check with the krb5 check is sufficient to create a
* security problem.
*/
Is the back-dating intended to have the end result of making a krb4
ticket also last clock_skew seconds longer than its expiration? If
so, then it doesn't seem to be working correctly. Otherwise, it
seems like with this change, a TGT must have a lifetime of at least 2
to be able to use it reliably. That would seem to be a security
issue itself when a lifetime of 1 would be sufficient.
The problem we're having is in a production application, so that I
need at least a temporary fix right away. I can think of several
ways to do that, but I'd like to know what the experts recommend as
the best solution.
Peter
More information about the krbdev
mailing list