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