[682] in Kerberos-V5-bugs

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

KDCREP_MODIFIED error code over-used (at least in beta 2)

daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Mon Aug 29 12:53:34 1994

Date: Mon, 29 Aug 1994 12:54:21 -0400
From: "Jonathan I. Kamens" <jik@cam.ov.com>
To: krb5-bugs@MIT.EDU

In MIT krb5 beta 2, the KRB5_KDCREP_MODIFIED error code is used in two
situations where I believe more specific error codes should be
returned:

1) When the clock skew in a reply from the KDC is too great to be
   permitted.
2) When krb5_get_in_tkt is called with client and server principals
   whose realms are different.

Two fix these problems, I've made the following changes:

1) Added a KRB5_KDCREP_SKEW error code, whose error string is "Clock
   skew too great in KDC reply".
2) Added a KRB5_IN_TKT_REALM_MISMATCH error code, whose error string
   is "Client/server realm mismatch in initial ticket request".
3) Added a krb5_realm_compare function, which takes two principals and
   compares their realms, returning TRUE if they are the same and
   FALSE if they are different.
4) Modified gc_via_tgt.c and get_in_tkt.c to return KRB5_KDCREP_SKEW
   when appropriate instead of KRB5_KDCREP_MODIFIED.
5) Modified get_in_tkt.c to compare the client and server realms and
   return KRb5_IN_TKT_REALM_MISMATCH if they do not match.
6) Added KRB5_KDCREP_SKEW to 425error.c.

Note that my realm-mismatch fix for krb5_get_in_tkt is one of two
possible options for fixing this bug.  The other one is modifying
krb5_get_in_tkt so that if the client and server passed into it have
different realms, it gets a TGT for the local realm and then uses
krb5_get_cred (or whatever) to get a ticket for the server in the
remote realm.  I chose not to make this change because it would change
the current behavior (rather than just changing the error code
returned in the case of one particular failure) and would make the API
diverge more significantly from the protocol internals.

The patches below are mostly against beta 2, except for the
krb5_err.et patch, which is against the beta 4 version of krb5_err.et.
Some of the patches may not apply because of changes between beta 2
and beta 4; others won't apply cleanly because of local debugging
changes we've made that crept into the patches.  It should be obvious
how to apply them by hand.

  jik

*** krb5/include/krb5/func-proto.h	1993/10/27 18:05:08	1.3
--- krb5/include/krb5/func-proto.h	1994/08/26 19:49:47
***************
*** 130,135 ****
--- 130,138 ----
  int krb5_address_order
  	PROTOTYPE((const krb5_address *,
  		   const krb5_address *));
+ krb5_boolean krb5_realm_compare
+ 	PROTOTYPE((krb5_const_principal,
+ 		   krb5_const_principal));
  krb5_boolean krb5_principal_compare
  	PROTOTYPE((krb5_const_principal,
  		   krb5_const_principal));
*** krb5/lib/error_tables/krb5_err.et	1994/08/25 21:02:11	1.4
--- krb5/lib/error_tables/krb5_err.et	1994/08/26 19:47:16
***************
*** 189,194 ****
--- 189,196 ----
  
  error_code KRB5_PRINC_NOMATCH,		"Requested principal and ticket don't match"
  error_code KRB5_KDCREP_MODIFIED,	"KDC reply did not match expectations"
+ error_code KRB5_KDCREP_SKEW,		"Clock skew too great in KDC reply"
+ error_code KRB5_IN_TKT_REALM_MISMATCH,	"Client/server realm mismatch in initial ticket request"
  
  error_code KRB5_PROG_ETYPE_NOSUPP,	"Program lacks support for encryption type"
  error_code KRB5_PROG_KEYTYPE_NOSUPP,	"Program lacks support for key type"
*** krb5/lib/krb/gc_via_tgt.c	1994/03/25 00:01:01	1.2
--- krb5/lib/krb/gc_via_tgt.c	1994/08/29 16:46:06
***************
*** 225,232 ****
  	|| (request.nonce != dec_rep->enc_part2->nonce)
  	/* XXX check for extraneous flags */
  	/* XXX || (!krb5_addresses_compare(addrs, dec_rep->enc_part2->caddrs)) */
- 	|| ((request.from == 0) &&
- 	    !in_clock_skew(dec_rep->enc_part2->times.starttime))
  	|| ((request.from != 0) &&
  	    (request.from != dec_rep->enc_part2->times.starttime))
  	|| ((request.till != 0) &&
--- 225,230 ----
***************
*** 238,244 ****
  	    (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) &&
  	    (request.till != 0) &&
  	    (dec_rep->enc_part2->times.renew_till > request.till))
! 	) {
  	cleanup();
  #ifdef OVSEC_DEBUG
  	{
--- 236,249 ----
  	    (dec_rep->enc_part2->flags & KDC_OPT_RENEWABLE) &&
  	    (request.till != 0) &&
  	    (dec_rep->enc_part2->times.renew_till > request.till))
! 	)
! 	retval = KRB5_KDCREP_MODIFIED;
! 
!     if 	((request.from == 0) &&
! 	 !in_clock_skew(dec_rep->enc_part2->times.starttime))
! 	retval = KRB5_KDCREP_SKEW;
! 
!     if (retval) {
  	cleanup();
  #ifdef OVSEC_DEBUG
  	{
***************
*** 369,375 ****
  	    }
  	}
  #endif /* OVSEC_DEBUG */
! 	return KRB5_KDCREP_MODIFIED;
      }
  #endif
  
--- 374,380 ----
  	    }
  	}
  #endif /* OVSEC_DEBUG */
! 	return retval;
      }
  #endif
  
*** krb5/lib/krb/get_in_tkt.c	1994/08/25 21:07:36	1.2
--- krb5/lib/krb/get_in_tkt.c	1994/08/26 19:49:00
***************
*** 118,126 ****
      krb5_timestamp time_now;
      krb5_pa_data	*padata;
  
      if (ret_as_reply)
  	*ret_as_reply = 0;
!     
      request.msg_type = KRB5_AS_REQ;
  
      if (pre_auth_type == KRB5_PADATA_NONE) {
--- 118,129 ----
      krb5_timestamp time_now;
      krb5_pa_data	*padata;
  
+     if (! krb5_realm_compare(creds->client, creds->server))
+ 	return KRB5_IN_TKT_REALM_MISMATCH;
+ 
      if (ret_as_reply)
  	*ret_as_reply = 0;
! 
      request.msg_type = KRB5_AS_REQ;
  
      if (pre_auth_type == KRB5_PADATA_NONE) {
***************
*** 310,317 ****
  	|| (request.nonce != as_reply->enc_part2->nonce)
  	/* XXX check for extraneous flags */
  	/* XXX || (!krb5_addresses_compare(addrs, as_reply->enc_part2->caddrs)) */
- 	|| ((request.from == 0) &&
- 	    !in_clock_skew(as_reply->enc_part2->times.starttime))
  	|| ((request.from != 0) &&
  	    (request.from != as_reply->enc_part2->times.starttime))
  	|| ((request.till != 0) &&
--- 313,318 ----
***************
*** 323,335 ****
  	    (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) &&
  	    (request.till != 0) &&
  	    (as_reply->enc_part2->times.renew_till > request.till))
! 	) {
  #ifdef OVSEC_DEBUG
  	{
  	  char *client1, *client2;
  	  fprintf(stderr, "FUNCTION: krb5_get_in_tkt\n");
  	  
! 	  /* (1) !krb5_principal_compare(as_reply->client, request.client) */
  	  
  	  if (!krb5_principal_compare(as_reply->client, request.client)) {
  	      krb5_unparse_name(as_reply->client, &client1);
--- 324,343 ----
  	    (as_reply->enc_part2->flags & KDC_OPT_RENEWABLE) &&
  	    (request.till != 0) &&
  	    (as_reply->enc_part2->times.renew_till > request.till))
! 	)
! 	retval = KRB5_KDCREP_MODIFIED;
!     
!     if ((request.from == 0) &&
! 	!in_clock_skew(as_reply->enc_part2->times.starttime))
! 	retval = KRB5_KDCREP_SKEW;
! 
!     if (retval) {
  #ifdef OVSEC_DEBUG
  	{
  	  char *client1, *client2;
  	  fprintf(stderr, "FUNCTION: krb5_get_in_tkt\n");
  	  
! /* (1) !krb5_principal_compare(as_reply->client, request.client) */
  	  
  	  if (!krb5_principal_compare(as_reply->client, request.client)) {
  	      krb5_unparse_name(as_reply->client, &client1);
***************
*** 451,457 ****
  	memset((char *)as_reply->enc_part2->session->contents, 0,
  	       as_reply->enc_part2->session->length);
  	krb5_free_kdc_rep(as_reply);
! 	return KRB5_KDCREP_MODIFIED;
      }
  
      /* XXX issue warning if as_reply->enc_part2->key_exp is nearby */
--- 459,465 ----
  	memset((char *)as_reply->enc_part2->session->contents, 0,
  	       as_reply->enc_part2->session->length);
  	krb5_free_kdc_rep(as_reply);
! 	return retval;
      }
  
      /* XXX issue warning if as_reply->enc_part2->key_exp is nearby */
*** krb5/lib/krb/princ_comp.c	1993/09/20 20:19:48	1.1
--- krb5/lib/krb/princ_comp.c	1994/08/29 15:44:27
***************
*** 35,40 ****
--- 35,53 ----
  #include <krb5/ext-proto.h>
  
  krb5_boolean
+ krb5_realm_compare(princ1, princ2)
+ krb5_const_principal princ1;
+ krb5_const_principal princ2;
+ {
+     if (krb5_princ_realm(princ1)->length != krb5_princ_realm(princ2)->length ||
+ 	memcmp (krb5_princ_realm(princ1)->data, krb5_princ_realm(princ2)->data,
+ 		krb5_princ_realm(princ2)->length))
+ 	return FALSE;
+ 
+     return TRUE;
+ }
+ 
+ krb5_boolean
  krb5_principal_compare(princ1, princ2)
  krb5_const_principal princ1;
  krb5_const_principal princ2;
***************
*** 45,53 ****
      if (nelem != krb5_princ_size(princ2))
  	return FALSE;
  
!     if (krb5_princ_realm(princ1)->length != krb5_princ_realm(princ2)->length ||
! 	memcmp (krb5_princ_realm(princ1)->data, krb5_princ_realm(princ2)->data,
! 		krb5_princ_realm(princ2)->length))
  	return FALSE;
  
      for (i = 0; i < nelem; i++) {
--- 58,64 ----
      if (nelem != krb5_princ_size(princ2))
  	return FALSE;
  
!     if (! krb5_realm_compare(princ1, princ2))
  	return FALSE;
  
      for (i = 0; i < nelem; i++) {
*** krb5/lib/krb425/425error.c	1994/08/25 21:21:29	1.1
--- krb5/lib/krb425/425error.c	1994/08/25 21:22:05
***************
*** 80,85 ****
--- 80,86 ----
  	case KRB5KDC_ERR_BADOPTION:	/* KDC can't do requested opt. */
  	case KRB5KDC_ERR_ETYPE_NOSUPP:	/* No support for encryption type */
  	case KRB5_KDCREP_MODIFIED:	/* KDC reply did not match expectations */
+ 	case KRB5_KDCREP_SKEW:		/* Clock skew too greate in KDC reply */
  		return(KDC_GEN_ERR);
  	case KRB5_KDC_UNREACH:		/* Cannot contact any KDC for requested realm */
  	case KRB5_REALM_UNKNOWN:	/* Cannot find KDC for requested realm */

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