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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user