kdc: omit default salt from PA-ETYPE-INFO[2]

If the salt for the AS-REP client key matches the default password salt for the
client principal in the AS-REQ, then it can be omitted from the PA-ETYPE-INFO,
PA-ETYPE-INFO2 (RFC4120) as the client will assume the default salt in its
absence.
This commit is contained in:
Luke Howard
2019-01-07 15:45:36 +11:00
parent a3fd75f368
commit de1f37a6aa
2 changed files with 41 additions and 22 deletions

View File

@@ -125,8 +125,9 @@ is_default_salt_p(const krb5_salt *default_salt, const Key *key)
krb5_error_code krb5_error_code
_kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key, _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
krb5_boolean is_preauth, hdb_entry_ex *princ, krb5_boolean is_preauth, hdb_entry_ex *princ,
krb5_enctype *etypes, unsigned len, krb5_principal request_princ, krb5_enctype *etypes, unsigned len,
krb5_enctype *ret_enctype, Key **ret_key) krb5_enctype *ret_enctype, Key **ret_key,
krb5_boolean *ret_default_salt)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_salt def_salt; krb5_salt def_salt;
@@ -136,7 +137,7 @@ _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
int i, k; int i, k;
/* We'll want to avoid keys with v4 salted keys in the pre-auth case... */ /* 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); ret = krb5_get_pw_salt(context, request_princ, &def_salt);
if (ret) if (ret)
return ret; return ret;
@@ -239,6 +240,8 @@ _kdc_find_etype(krb5_context context, krb5_boolean use_strongest_session_key,
*ret_enctype = enctype; *ret_enctype = enctype;
if (ret_key != NULL) if (ret_key != NULL)
*ret_key = key; *ret_key = key;
if (ret_default_salt != NULL)
*ret_default_salt = is_default_salt_p(&def_salt, key);
} }
krb5_free_salt (context, def_salt); krb5_free_salt (context, def_salt);
@@ -1019,10 +1022,13 @@ older_enctype(krb5_enctype enctype)
*/ */
static krb5_error_code static krb5_error_code
make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key) make_etype_info_entry(krb5_context context,
ETYPE_INFO_ENTRY *ent,
Key *key,
krb5_boolean include_salt)
{ {
ent->etype = key->key.keytype; ent->etype = key->key.keytype;
if(key->salt){ if (key->salt && include_salt){
#if 0 #if 0
ALLOC(ent->salttype); ALLOC(ent->salttype);
@@ -1069,7 +1075,8 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
static krb5_error_code static krb5_error_code
get_pa_etype_info(krb5_context context, get_pa_etype_info(krb5_context context,
krb5_kdc_configuration *config, krb5_kdc_configuration *config,
METHOD_DATA *md, Key *ckey) METHOD_DATA *md, Key *ckey,
krb5_boolean include_salt)
{ {
krb5_error_code ret = 0; krb5_error_code ret = 0;
ETYPE_INFO pa; ETYPE_INFO pa;
@@ -1082,7 +1089,7 @@ get_pa_etype_info(krb5_context context,
if(pa.val == NULL) if(pa.val == NULL)
return ENOMEM; return ENOMEM;
ret = make_etype_info_entry(context, &pa.val[0], ckey); ret = make_etype_info_entry(context, &pa.val[0], ckey, include_salt);
if (ret) { if (ret) {
free_ETYPE_INFO(&pa); free_ETYPE_INFO(&pa);
return ret; return ret;
@@ -1130,12 +1137,14 @@ make_s2kparams(int value, size_t len, krb5_data **ps2kparams)
} }
static krb5_error_code static krb5_error_code
make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key) make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent,
Key *key,
krb5_boolean include_salt)
{ {
krb5_error_code ret; krb5_error_code ret;
ent->etype = key->key.keytype; ent->etype = key->key.keytype;
if(key->salt) { if (key->salt && include_salt) {
ALLOC(ent->salt); ALLOC(ent->salt);
if (ent->salt == NULL) if (ent->salt == NULL)
return ENOMEM; return ENOMEM;
@@ -1188,7 +1197,8 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
static krb5_error_code static krb5_error_code
get_pa_etype_info2(krb5_context context, get_pa_etype_info2(krb5_context context,
krb5_kdc_configuration *config, krb5_kdc_configuration *config,
METHOD_DATA *md, Key *ckey) METHOD_DATA *md, Key *ckey,
krb5_boolean include_salt)
{ {
krb5_error_code ret = 0; krb5_error_code ret = 0;
ETYPE_INFO2 pa; ETYPE_INFO2 pa;
@@ -1200,7 +1210,7 @@ get_pa_etype_info2(krb5_context context,
if(pa.val == NULL) if(pa.val == NULL)
return ENOMEM; return ENOMEM;
ret = make_etype_info2_entry(&pa.val[0], ckey); ret = make_etype_info2_entry(&pa.val[0], ckey, include_salt);
if (ret) { if (ret) {
free_ETYPE_INFO2(&pa); free_ETYPE_INFO2(&pa);
return ret; return ret;
@@ -1237,7 +1247,8 @@ static krb5_error_code
get_pa_etype_info_both(krb5_context context, get_pa_etype_info_both(krb5_context context,
krb5_kdc_configuration *config, krb5_kdc_configuration *config,
struct KDC_REQ_BODY_etype *etype_list, struct KDC_REQ_BODY_etype *etype_list,
METHOD_DATA *md, Key *ckey) METHOD_DATA *md, Key *ckey,
krb5_boolean include_salt)
{ {
krb5_error_code ret; krb5_error_code ret;
@@ -1262,12 +1273,12 @@ get_pa_etype_info_both(krb5_context context,
* "newer" etype. * "newer" etype.
*/ */
ret = get_pa_etype_info2(context, config, md, ckey); ret = get_pa_etype_info2(context, config, md, ckey, include_salt);
if (ret) if (ret)
return ret; return ret;
if (!newer_enctype_present(etype_list)) if (!newer_enctype_present(etype_list))
ret = get_pa_etype_info(context, config, md, ckey); ret = get_pa_etype_info(context, config, md, ckey, include_salt);
return ret; return ret;
} }
@@ -1835,8 +1846,9 @@ _kdc_as_rep(kdc_request_t r,
ret = _kdc_find_etype(context, ret = _kdc_find_etype(context,
is_tgs ? config->tgt_use_strongest_session_key is_tgs ? config->tgt_use_strongest_session_key
: config->svc_use_strongest_session_key, : config->svc_use_strongest_session_key,
FALSE, r->client, b->etype.val, b->etype.len, FALSE, r->client, r->client_princ,
&r->sessionetype, NULL); b->etype.val, b->etype.len,
&r->sessionetype, NULL, NULL);
if (ret) { if (ret) {
kdc_log(context, config, 0, kdc_log(context, config, 0,
"Client (%s) from %s has no common enctypes with KDC " "Client (%s) from %s has no common enctypes with KDC "
@@ -1871,16 +1883,18 @@ _kdc_as_rep(kdc_request_t r,
if (ret != 0) { if (ret != 0) {
krb5_error_code ret2; krb5_error_code ret2;
Key *ckey = NULL; Key *ckey = NULL;
krb5_boolean default_salt;
/* /*
* If there is a client key, send ETYPE_INFO{,2} * If there is a client key, send ETYPE_INFO{,2}
*/ */
ret2 = _kdc_find_etype(context, ret2 = _kdc_find_etype(context,
config->preauth_use_strongest_session_key, config->preauth_use_strongest_session_key,
TRUE, r->client, b->etype.val, TRUE, r->client, r->client_princ, b->etype.val,
b->etype.len, NULL, &ckey); b->etype.len, NULL, &ckey, &default_salt);
if (ret2 == 0) { if (ret2 == 0) {
ret2 = get_pa_etype_info_both(context, config, &b->etype, ret2 = get_pa_etype_info_both(context, config, &b->etype,
&error_method, ckey); &error_method, ckey, !default_salt);
if (ret2 != 0) if (ret2 != 0)
ret = ret2; ret = ret2;
} }
@@ -1898,6 +1912,7 @@ _kdc_as_rep(kdc_request_t r,
if (found_pa == 0) { if (found_pa == 0) {
Key *ckey = NULL; Key *ckey = NULL;
size_t n; size_t n;
krb5_boolean default_salt;
for (n = 0; n < sizeof(pat) / sizeof(pat[0]); n++) { for (n = 0; n < sizeof(pat) / sizeof(pat[0]); n++) {
if ((pat[n].flags & PA_ANNOUNCE) == 0) if ((pat[n].flags & PA_ANNOUNCE) == 0)
@@ -1913,10 +1928,12 @@ _kdc_as_rep(kdc_request_t r,
*/ */
ret = _kdc_find_etype(context, ret = _kdc_find_etype(context,
config->preauth_use_strongest_session_key, TRUE, config->preauth_use_strongest_session_key, TRUE,
r->client, b->etype.val, b->etype.len, NULL, &ckey); r->client, r->client_princ,
b->etype.val, b->etype.len, NULL,
&ckey, &default_salt);
if (ret == 0) { if (ret == 0) {
ret = get_pa_etype_info_both(context, config, &b->etype, ret = get_pa_etype_info_both(context, config, &b->etype,
&error_method, ckey); &error_method, ckey, !default_salt);
if (ret) if (ret)
goto out; goto out;
} }

View File

@@ -1794,7 +1794,9 @@ server_lookup:
krb5_principal_is_krbtgt(context, sp) ? krb5_principal_is_krbtgt(context, sp) ?
config->tgt_use_strongest_session_key : config->tgt_use_strongest_session_key :
config->svc_use_strongest_session_key, FALSE, config->svc_use_strongest_session_key, FALSE,
server, b->etype.val, b->etype.len, &etype, server, server->entry.principal,
b->etype.val, b->etype.len, &etype,
NULL,
NULL); NULL);
if(ret) { if(ret) {
kdc_log(context, config, 0, kdc_log(context, config, 0,