[210] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

problems with short-lifetime tickets (with fix)

daemon@ATHENA.MIT.EDU (Bill Sommerfeld)
Wed Nov 6 16:08:33 1991

Date: Wed, 6 Nov 91 16:02:22 EST
From: sommerfeld@apollo.com (Bill Sommerfeld)
To: tytso@Athena.MIT.EDU
Cc: krb5-bugs@Athena.MIT.EDU, Gregory Carpenter <greg@apollo.com>,

I promised that I'd send this down to Ted a couple of weeks ago, but
I've been swamped with work.

For DCE, we are attempting to implement revocation by using short
lifetime service tickets.  By default, we set service ticket lifetimes
in the KDC database to ~2 hours, while ticket granting tickets are
somewhat longer lived.

There is a problem with the current implementation: unless the
application handles ticket directly with extreme care, it is likely
that the presence of expired service tickets in the ccache will
prevent the application from fetching a new "fresh" ticket from the
KDC.

There is a "TIMES_MATCH" flag which attempts to implement this by
comparing the lifetimes of tickets listed in the cache with a
timestamp passed in via the cred structure, but it doesn't get it
quite right in the current code -- the caller would have to fill in
the timestamp itself, and the same timestamp would also be used to cap
the maximum lifetime -- so if I said "I want a ticket that will be
good for at least five minutes", I got a ticket which was good for
*exactly* five minutes.

This patch changes the semantics of the "TIMES_MATCH" flag to means
"compare against the current local time" if the passed-in time is
zero; there is an additional patch to gc_frm_kdc.c which causes it to
set the TIMES_MATCH flag when fetching ticket-granting-tickets from
the credential cache.

						- Bill


*** fcc_retrv.c/MIT-beta1	Thu Jun  6 09:42:14 1991
--- fcc_retrv.c	Thu Oct 31 16:11:18 1991
***************
*** 37,43 ****
  #define flags_match(a,b) (a & b == a)
  #define times_match_exact(t1,t2) (memcmp((char *)(t1), (char *)(t2), sizeof(*(t1))) == 0)
  
! static krb5_boolean times_match PROTOTYPE((const krb5_ticket_times *,
  					   const krb5_ticket_times *));
  static krb5_boolean standard_fields_match
      PROTOTYPE((const krb5_creds *,
--- 37,44 ----
  #define flags_match(a,b) (a & b == a)
  #define times_match_exact(t1,t2) (memcmp((char *)(t1), (char *)(t2), sizeof(*(t1))) == 0)
  
! static krb5_boolean times_match PROTOTYPE((krb5_int32 now,
!                                            const krb5_ticket_times *,
  					   const krb5_ticket_times *));
  static krb5_boolean standard_fields_match
      PROTOTYPE((const krb5_creds *,
***************
*** 102,108 ****
--- 103,114 ----
       krb5_cc_cursor cursor;
       krb5_error_code kret;
       krb5_creds fetchcreds;
+      krb5_timestamp now;
  
+      kret = krb5_timeofday(&now);
+      if (kret != KRB5_OK)
+ 	 return kret;
+ 	 
       kret = krb5_fcc_start_seq_get(id, &cursor);
       if (kret != KRB5_OK)
  	  return kret;
***************
*** 125,131 ****
  	       times_match_exact(&mcreds->times, &fetchcreds.times))
  	      &&
  	      (! set(KRB5_TC_MATCH_TIMES) ||
! 	       times_match(&mcreds->times, &fetchcreds.times))
  	      &&
  	      ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
  	       authdata_match(mcreds->authdata, fetchcreds.authdata))
--- 131,137 ----
  	       times_match_exact(&mcreds->times, &fetchcreds.times))
  	      &&
  	      (! set(KRB5_TC_MATCH_TIMES) ||
! 	       times_match(now, &mcreds->times, &fetchcreds.times))
  	      &&
  	      ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
  	       authdata_match(mcreds->authdata, fetchcreds.authdata))
***************
*** 149,166 ****
  }
  
  static krb5_boolean
! times_match(t1, t2)
  register const krb5_ticket_times *t1;
  register const krb5_ticket_times *t2;
  {
      if (t1->renew_till) {
  	if (t1->renew_till > t2->renew_till)
! 	    return FALSE;		/* this one expires too late */
      }
      if (t1->endtime) {
  	if (t1->endtime > t2->endtime)
! 	    return FALSE;		/* this one expires too late */
      }
      /* only care about expiration on a times_match */
      return TRUE;
  }
--- 155,182 ----
  }
  
  static krb5_boolean
! times_match(now, t1, t2)
! krb5_int32 now;    
  register const krb5_ticket_times *t1;
  register const krb5_ticket_times *t2;
  {
      if (t1->renew_till) {
  	if (t1->renew_till > t2->renew_till)
! 	    return FALSE;		/* this one expires too soon */
      }
+ 
+     if (t2->renew_till) {
+ 	if (now > t2->renew_till)
+ 	    return FALSE;
+     }
+ 
      if (t1->endtime) {
  	if (t1->endtime > t2->endtime)
! 	    return FALSE;		/* this one expires too soon */
      }
+     if (now > t2->endtime)
+ 	return FALSE;
+ 
      /* only care about expiration on a times_match */
      return TRUE;
  }


*** gc_frm_kdc.c/MIT-beta1	Thu Jun  6 09:36:02 1991
--- gc_frm_kdc.c	Thu Oct 31 15:05:38 1991
***************
*** 114,120 ****
  
      /* try to fetch it directly */
      retval = krb5_cc_retrieve_cred (ccache,
! 				    KRB5_TC_MATCH_SRV_NAMEONLY,
  				    &tgtq,
  				    &tgt);
  
--- 114,121 ----
  
      /* try to fetch it directly */
      retval = krb5_cc_retrieve_cred (ccache,
! 				    KRB5_TC_MATCH_SRV_NAMEONLY
!                                     | KRB5_TC_MATCH_TIMES,
  				    &tgtq,
  				    &tgt);
  
***************
*** 141,147 ****
  	for (; next_server >= tgs_list; next_server--) {
  	    tgtq.server = *next_server;
  	    retval = krb5_cc_retrieve_cred (ccache,
! 					    KRB5_TC_MATCH_SRV_NAMEONLY,
  					    &tgtq,
  					    &tgt);
  	    if (retval) {
--- 142,149 ----
  	for (; next_server >= tgs_list; next_server--) {
  	    tgtq.server = *next_server;
  	    retval = krb5_cc_retrieve_cred (ccache,
! 					    KRB5_TC_MATCH_SRV_NAMEONLY
!                                             | KRB5_TC_MATCH_TIMES,
  					    &tgtq,
  					    &tgt);
  	    if (retval) {

home help back first fref pref prev next nref lref last post