From 3e01c3e73d85977a24f28dd636c6013ea9ea8ded Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Sat, 4 Aug 2007 00:30:48 +0000 Subject: [PATCH] back-port r19748 from trunk Based on Apple's patch, during the referrals loop, check to see if the session key enctype of a returned credential for the final service is among the enctypes explicitly selected by the application, and retry with old_use_conf_ktypes if it is not. ticket: 4950 version_fixed: 1.6.3 git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-6@19751 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb5/krb/gc_frm_kdc.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index 5b9d3917a..987f2eb83 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -906,7 +906,6 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, /* Whether or not that succeeded, we're done. */ goto cleanup; } - else { /* Referral request succeeded; let's see what it is. */ if (krb5_principal_compare(context, in_cred->server, (*out_cred)->server)) { @@ -914,6 +913,38 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, "for requested server principal\n")); DUMP_PRINC("gc_from_kdc final referred reply", in_cred->server); + + /* + * Check if the return enctype is one that we requested if + * needed. + */ + if (old_use_conf_ktypes || context->tgs_ktype_count == 0) + goto cleanup; + for (i = 0; i < context->tgs_ktype_count; i++) { + if ((*out_cred)->keyblock.enctype == context->tgs_ktypes[i]) { + /* Found an allowable etype, so we're done */ + goto cleanup; + } + } + /* + * We need to try again, but this time use the + * tgs_ktypes in the context. At this point we should + * have all the tgts to succeed. + */ + + /* Free "wrong" credential */ + krb5_free_creds(context, *out_cred); + *out_cred = NULL; + /* Re-establish tgs etypes */ + context->use_conf_ktypes = old_use_conf_ktypes; + retval = krb5_get_cred_via_tkt(context, tgtptr, + KDC_OPT_CANONICALIZE | + FLAGS2OPTS(tgtptr->ticket_flags) | + kdcopt | + (in_cred->second_ticket.length ? + KDC_OPT_ENC_TKT_IN_SKEY : 0), + tgtptr->addresses, + in_cred, out_cred); goto cleanup; } else if (IS_TGS_PRINC(context, (*out_cred)->server)) { @@ -978,7 +1009,6 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, krb5_free_creds(context, *out_cred); *out_cred = NULL; break; - } } } -- 2.26.2