Check at runtime whether to use enctypes instead of keytypes. If so
use the same value to encrypt ticket, and kdc-rep as well as `keytype' for session key. Fix some obvious bugs with the handling of additional tickets. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4373 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
159
kdc/kerberos5.c
159
kdc/kerberos5.c
@@ -90,15 +90,42 @@ find_etype(hdb_entry *princ, unsigned *etypes, unsigned len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
find_keys(hdb_entry *client, hdb_entry *server,
|
find_keys1(hdb_entry *client, hdb_entry *server,
|
||||||
Key **ckey, krb5_enctype *cetype,
|
Key **ckey, krb5_enctype *cetype,
|
||||||
Key **skey, krb5_enctype *setype,
|
Key **skey, krb5_enctype *setype,
|
||||||
#ifndef KTYPE_IS_ETYPE
|
krb5_enctype *sess_ktype,
|
||||||
krb5_keytype *sess_ktype,
|
unsigned *etypes, unsigned num_etypes)
|
||||||
#else
|
{
|
||||||
krb5_enctype *sess_ktype,
|
int i;
|
||||||
#endif
|
krb5_error_code ret;
|
||||||
unsigned *etypes, unsigned num_etypes)
|
for(i = 0; i < num_etypes; i++) {
|
||||||
|
if(client){
|
||||||
|
ret = hdb_etype2key(context, client, etypes[i], ckey);
|
||||||
|
if(ret)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(server){
|
||||||
|
ret = hdb_etype2key(context, server, etypes[i], skey);
|
||||||
|
if(ret)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(cetype)
|
||||||
|
*cetype = etypes[i];
|
||||||
|
if(setype)
|
||||||
|
*setype = etypes[i];
|
||||||
|
if(sess_ktype)
|
||||||
|
*sess_ktype = etypes[i];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return KRB5KDC_ERR_ETYPE_NOSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
find_keys2(hdb_entry *client, hdb_entry *server,
|
||||||
|
Key **ckey, krb5_enctype *cetype,
|
||||||
|
Key **skey, krb5_enctype *setype,
|
||||||
|
krb5_keytype *sess_ktype,
|
||||||
|
unsigned *etypes, unsigned num_etypes)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -119,11 +146,7 @@ find_keys(hdb_entry *client, hdb_entry *server,
|
|||||||
kdc_log(0, "Server has no support for etypes");
|
kdc_log(0, "Server has no support for etypes");
|
||||||
return KRB5KDC_ERR_ETYPE_NOSUPP;
|
return KRB5KDC_ERR_ETYPE_NOSUPP;
|
||||||
}
|
}
|
||||||
#ifndef KTYPE_IS_ETYPE
|
|
||||||
*sess_ktype = (*skey)->key.keytype;
|
*sess_ktype = (*skey)->key.keytype;
|
||||||
#else
|
|
||||||
*sess_ktype = etypes[i];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if(server){
|
if(server){
|
||||||
/* find server key */
|
/* find server key */
|
||||||
@@ -227,24 +250,22 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
|
|||||||
pa.val = NULL;
|
pa.val = NULL;
|
||||||
pa.len = 0;
|
pa.len = 0;
|
||||||
for(i = 0; i < client->keys.len; i++){
|
for(i = 0; i < client->keys.len; i++){
|
||||||
#ifdef KTYPE_IS_ETYPE
|
|
||||||
krb5_enctype *etypes, *e;
|
krb5_enctype *etypes, *e;
|
||||||
ret = krb5_keytype_to_etypes(context,
|
krb5_enctype ex[2] = { client->keys.val[i].key.keytype, 0 };
|
||||||
client->keys.val[i].key.keytype,
|
if(context->ktype_is_etype)
|
||||||
&etypes);
|
ret = krb5_keytype_to_etypes(context,
|
||||||
|
client->keys.val[i].key.keytype,
|
||||||
|
&etypes);
|
||||||
|
else
|
||||||
|
etypes = ex;
|
||||||
for(e = etypes; *e; e++){
|
for(e = etypes; *e; e++){
|
||||||
#endif
|
|
||||||
tmp = realloc(pa.val, (pa.len + 1) * sizeof(*pa.val));
|
tmp = realloc(pa.val, (pa.len + 1) * sizeof(*pa.val));
|
||||||
if(tmp == NULL) {
|
if(tmp == NULL) {
|
||||||
free_PA_KEY_INFO(&pa);
|
free_PA_KEY_INFO(&pa);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pa.val = tmp;
|
pa.val = tmp;
|
||||||
#ifndef KTYPE_IS_ETYPE
|
|
||||||
pa.val[pa.len].keytype = client->keys.val[i].key.keytype;
|
|
||||||
#else
|
|
||||||
pa.val[pa.len].keytype = *e;
|
pa.val[pa.len].keytype = *e;
|
||||||
#endif
|
|
||||||
if(client->keys.val[i].salt){
|
if(client->keys.val[i].salt){
|
||||||
pa.val[pa.len].salttype = client->keys.val[i].salt->type;
|
pa.val[pa.len].salttype = client->keys.val[i].salt->type;
|
||||||
ALLOC(pa.val[pa.len].salt);
|
ALLOC(pa.val[pa.len].salt);
|
||||||
@@ -260,9 +281,9 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client)
|
|||||||
pa.val[pa.len].salt = NULL;
|
pa.val[pa.len].salt = NULL;
|
||||||
}
|
}
|
||||||
pa.len++;
|
pa.len++;
|
||||||
#ifdef KTYPE_IS_ETYPE
|
|
||||||
}
|
}
|
||||||
#endif
|
if(context->ktype_is_etype)
|
||||||
|
free(etypes);
|
||||||
}
|
}
|
||||||
len = length_PA_KEY_INFO(&pa);
|
len = length_PA_KEY_INFO(&pa);
|
||||||
buf = malloc(len);
|
buf = malloc(len);
|
||||||
@@ -536,38 +557,29 @@ as_rep(KDC_REQ *req,
|
|||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(context->ktype_is_etype)
|
||||||
|
ret = find_keys1(client, server, &ckey, &cetype, &skey, &setype,
|
||||||
ret = find_keys(client, server, &ckey, &cetype, &skey, &setype,
|
&sess_ktype, b->etype.val, b->etype.len);
|
||||||
&sess_ktype, b->etype.val, b->etype.len);
|
else
|
||||||
|
ret = find_keys2(client, server, &ckey, &cetype, &skey, &setype,
|
||||||
|
&sess_ktype, b->etype.val, b->etype.len);
|
||||||
if(ret)
|
if(ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
{
|
{
|
||||||
char *cet, *set = NULL, *skt = NULL;
|
char *cet, *set = NULL, *skt = NULL;
|
||||||
krb5_etype_to_string(context, cetype, &cet);
|
krb5_etype_to_string(context, cetype, &cet);
|
||||||
if(cetype != setype)
|
if(context->ktype_is_etype){
|
||||||
krb5_etype_to_string(context, setype, &set);
|
kdc_log(5, "Using %s", cet);
|
||||||
#ifndef KTYPE_IS_ETYPE
|
}else{
|
||||||
krb5_keytype_to_string(context, sess_ktype, &skt);
|
if(cetype != setype)
|
||||||
#else
|
krb5_etype_to_string(context, setype, &set);
|
||||||
if(cetype != sess_ktype)
|
krb5_keytype_to_string(context, sess_ktype, &skt);
|
||||||
krb5_etype_to_string(context, sess_ktype, &skt);
|
if(set)
|
||||||
#endif
|
|
||||||
if(set)
|
|
||||||
if(skt)
|
|
||||||
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
|
kdc_log(5, "Using %s/%s/%s", cet, set, skt);
|
||||||
else
|
else
|
||||||
kdc_log(5, "Using %s/%s", cet, set);
|
|
||||||
else
|
|
||||||
if(skt){
|
|
||||||
#ifndef KTYPE_IS_ETYPE
|
|
||||||
kdc_log(5, "Using %s/%s", cet, skt);
|
kdc_log(5, "Using %s/%s", cet, skt);
|
||||||
#else
|
}
|
||||||
kdc_log(5, "Using %s/%s/%s", cet, cet, skt);
|
|
||||||
#endif
|
|
||||||
}else
|
|
||||||
kdc_log(5, "Using %s", cet);
|
|
||||||
free(skt);
|
free(skt);
|
||||||
free(set);
|
free(set);
|
||||||
free(cet);
|
free(cet);
|
||||||
@@ -620,15 +632,13 @@ as_rep(KDC_REQ *req,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef KTYPE_IS_ETYPE
|
if(context->ktype_is_etype) {
|
||||||
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
krb5_keytype kt;
|
krb5_keytype kt;
|
||||||
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
|
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
|
||||||
krb5_generate_random_keyblock(context, kt, &et.key);
|
krb5_generate_random_keyblock(context, kt, &et.key);
|
||||||
}
|
et.key.keytype = sess_ktype;
|
||||||
#endif
|
}else
|
||||||
|
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
|
||||||
copy_PrincipalName(b->cname, &et.cname);
|
copy_PrincipalName(b->cname, &et.cname);
|
||||||
copy_Realm(&b->realm, &et.crealm);
|
copy_Realm(&b->realm, &et.crealm);
|
||||||
|
|
||||||
@@ -970,15 +980,35 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
|||||||
krb5_enctype sess_ktype;
|
krb5_enctype sess_ktype;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = find_keys(NULL, server, NULL, NULL, &skey, &setype,
|
if(adtkt) {
|
||||||
&sess_ktype, b->etype.val, b->etype.len);
|
int i;
|
||||||
if(ret)
|
krb5_keytype kt;
|
||||||
return ret;
|
|
||||||
if(adtkt)
|
|
||||||
ekey = &adtkt->key;
|
ekey = &adtkt->key;
|
||||||
else
|
for(i = 0; i < b->etype.len; i++){
|
||||||
|
ret = krb5_etype_to_keytype(context, b->etype.val[i], &kt);
|
||||||
|
if(ret)
|
||||||
|
continue;
|
||||||
|
if(adtkt->key.keytype == kt)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(i == b->etype.len)
|
||||||
|
return KRB5KDC_ERR_ETYPE_NOSUPP;
|
||||||
|
setype = b->etype.val[i];
|
||||||
|
if(context->ktype_is_etype)
|
||||||
|
sess_ktype = b->etype.val[i];
|
||||||
|
else
|
||||||
|
sess_ktype = kt;
|
||||||
|
}else{
|
||||||
|
if(context->ktype_is_etype)
|
||||||
|
ret = find_keys1(NULL, server, NULL, NULL, &skey, &setype,
|
||||||
|
&sess_ktype, b->etype.val, b->etype.len);
|
||||||
|
else
|
||||||
|
ret = find_keys2(NULL, server, NULL, NULL, &skey, &setype,
|
||||||
|
&sess_ktype, b->etype.val, b->etype.len);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
ekey = &skey->key;
|
ekey = &skey->key;
|
||||||
ret = krb5_keytype_to_etype(context, ekey->keytype, &setype);
|
}
|
||||||
|
|
||||||
memset(&rep, 0, sizeof(rep));
|
memset(&rep, 0, sizeof(rep));
|
||||||
memset(&et, 0, sizeof(et));
|
memset(&et, 0, sizeof(et));
|
||||||
@@ -1068,15 +1098,12 @@ tgs_make_reply(KDC_REQ_BODY *b,
|
|||||||
/* XXX Check enc-authorization-data */
|
/* XXX Check enc-authorization-data */
|
||||||
et.authorization_data = auth_data;
|
et.authorization_data = auth_data;
|
||||||
|
|
||||||
#ifndef KTYPE_IS_ETYPE
|
if(context->ktype_is_etype) {
|
||||||
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
krb5_keytype kt;
|
krb5_keytype kt;
|
||||||
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
|
ret = krb5_etype_to_keytype(context, sess_ktype, &kt);
|
||||||
krb5_generate_random_keyblock(context, kt, &et.key);
|
krb5_generate_random_keyblock(context, kt, &et.key);
|
||||||
}
|
}else
|
||||||
#endif
|
krb5_generate_random_keyblock(context, sess_ktype, &et.key);
|
||||||
et.crealm = tgt->crealm;
|
et.crealm = tgt->crealm;
|
||||||
et.cname = tgt->cname;
|
et.cname = tgt->cname;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user