From 71fb56309c63f51ce9a4e0b6d454b60ff3ea786b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 27 Jul 2013 20:02:16 -0400 Subject: [PATCH] _kdc_find_etype consolidation The 'use_strongest_session_key' block and its alternate should have similar behavior except for the order in which the enctype lists are processed. This patchset attempts to consolidate the exit processing and ensure that the inner loop enctype and key validation is the same. Bugs fixed: 1. In the 'use_strongest_session_key' case, the _kdc_is_weak_exception() test was applied during the client enctype loop which is only processed for acceptable enctypes. This test is moved to the local supported enctypes loop so as not to filter out weak keys when the service principal has an explicit exception. 2. In the 'use_strongest_session_key' case, the possibility of an enctype having keys with more than one salt was excluded. 3. In the 'use_strongest_session_key' case, the 'key' variable was not reset to NULL within each loop of the client enctype list. 4. In the '!use_strongest_session_key' case, the default salt test and is_preauth was inconsistent with the 'use_strongest_session_key' block. With this consolidation, if no enctype is selected and the service principal is permitted to use 1DES, then 1DES is selected. It doesn't matter whether 'use_strongest_session_key' is in use or not. Change-Id: Ib57264fc8bc23df64c70d39b4f6de48beeb54739 --- kdc/kerberos5.c | 92 ++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/kdc/kerberos5.c b/kdc/kerberos5.c index dddcd3bb6..bf091f560 100644 --- a/kdc/kerberos5.c +++ b/kdc/kerberos5.c @@ -130,12 +130,11 @@ _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key, { krb5_error_code ret; krb5_salt def_salt; - krb5_enctype enctype = ETYPE_NULL; + krb5_enctype enctype = (krb5_enctype)ETYPE_NULL; krb5_enctype clientbest = (krb5_enctype)ETYPE_NULL; const krb5_enctype *p; Key *key = NULL; int i, k; - int client_offered_1des = 0; /* We'll want to avoid keys with v4 salted keys in the pre-auth case... */ ret = krb5_get_pw_salt(context, princ->entry.principal, &def_salt); @@ -162,50 +161,32 @@ _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key, for (i = 0; p[i] != (krb5_enctype)ETYPE_NULL && enctype == (krb5_enctype)ETYPE_NULL; i++) { - if (krb5_enctype_valid(context, p[i]) != 0) + if (krb5_enctype_valid(context, p[i]) != 0 && + !_kdc_is_weak_exception(princ->entry.principal, p[i])) continue; /* check that the client supports it too */ - for (k = 0; k < len && enctype == (krb5_enctype)ETYPE_NULL; k++) { - if (krb5_enctype_valid(context, etypes[k]) != 0 && - !_kdc_is_weak_exception(princ->entry.principal, etypes[k])) - continue; - if (etypes[k] == (krb5_enctype)ETYPE_DES_CBC_CRC || - etypes[k] == (krb5_enctype)ETYPE_DES_CBC_MD4 || - etypes[k] == (krb5_enctype)ETYPE_DES_CBC_MD5) - client_offered_1des = 1; + for (k = 0; k < len && enctype == (krb5_enctype)ETYPE_NULL; k++, key = NULL) { if (p[i] != etypes[k]) continue; if (clientbest == (krb5_enctype)ETYPE_NULL) clientbest = p[i]; - if (key) - continue; /* already picked a key below */ - /* check target princ support */ - ret = hdb_enctype2key(context, &princ->entry, NULL, p[i], &key); - if (ret) - continue; - if (is_preauth && !is_default_salt_p(&def_salt, key)) - continue; - enctype = p[i]; - } - } - if (clientbest != (krb5_enctype)ETYPE_NULL && - enctype == (krb5_enctype)ETYPE_NULL) { - ret = 0; - enctype = clientbest; - } else if (enctype == (krb5_enctype)ETYPE_NULL) { - if (client_offered_1des && - _kdc_is_weak_exception(princ->entry.principal, ETYPE_DES_CBC_CRC)) { - ret = 0; - enctype = ETYPE_DES_CBC_CRC; - } else { - ret = KRB5KDC_ERR_ETYPE_NOSUPP; + + /* check target princ support */ + while (ret != 0 && + hdb_next_enctype2key(context, &princ->entry, NULL, + p[i], &key) == 0) { + if (key->key.keyvalue.length == 0) { + ret = KRB5KDC_ERR_NULL_KEY; + continue; + } + if (is_preauth && !is_default_salt_p(&def_salt, key)) + continue; + enctype = p[i]; + ret = 0; + } } - } - if (ret == 0 && ret_enctype != NULL) - *ret_enctype = enctype; - if (ret == 0 && ret_key != NULL) - *ret_key = key; + } } else { /* * Pick the first key from the client's enctype list that is @@ -222,24 +203,43 @@ _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key, !_kdc_is_weak_exception(princ->entry.principal, etypes[i])) continue; - while (hdb_next_enctype2key(context, &princ->entry, NULL, + while (ret != 0 && + hdb_next_enctype2key(context, &princ->entry, NULL, etypes[i], &key) == 0) { if (key->key.keyvalue.length == 0) { ret = KRB5KDC_ERR_NULL_KEY; continue; } - if (ret_key != NULL) - *ret_key = key; - if (ret_enctype != NULL) - *ret_enctype = etypes[i]; + if (is_preauth && !is_default_salt_p(&def_salt, key)) + continue; + enctype = etypes[i]; ret = 0; - if (is_preauth && is_default_salt_p(&def_salt, key)) - goto out; } } } -out: + if (enctype == (krb5_enctype)ETYPE_NULL && + clientbest ! = (krb5_enctype)ETYPE_NULL) { + ret = 0; + enctype = clientbest; + } else if (enctype == (krb5_enctype)ETYPE_NULL) { + /* + * if the service principal is one for which there is a known 1DES + * exception and no other enctype matches both the client request and + * the service key list, provide a DES-CBC-CRC key. + */ + if (_kdc_is_weak_exception(princ->entry.principal, ETYPE_DES_CBC_CRC)) { + ret = 0; + enctype = ETYPE_DES_CBC_CRC; + } else { + ret = KRB5KDC_ERR_ETYPE_NOSUPP; + } + } + if (ret == 0 && ret_enctype != NULL) + *ret_enctype = enctype; + if (ret == 0 && ret_key != NULL) + *ret_key = key; + krb5_free_salt (context, def_salt); return ret; }