add support for KRB5_PADATA_ETYPE_INFO2
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@12512 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
149
kdc/kerberos5.c
149
kdc/kerberos5.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997-2002 Kungliga Tekniska H<>gskolan
|
* Copyright (c) 1997-2003 Kungliga Tekniska H<>gskolan
|
||||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -329,6 +329,7 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
|
|||||||
pa.val = malloc(pa.len * sizeof(*pa.val));
|
pa.val = malloc(pa.len * sizeof(*pa.val));
|
||||||
if(pa.val == NULL)
|
if(pa.val == NULL)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
memset(pa.val, 0, pa.len * sizeof(*pa.val));
|
||||||
|
|
||||||
for(j = 0; j < etypes_len; j++) {
|
for(j = 0; j < etypes_len; j++) {
|
||||||
for(i = 0; i < client->keys.len; i++) {
|
for(i = 0; i < client->keys.len; i++) {
|
||||||
@@ -377,6 +378,142 @@ get_pa_etype_info(METHOD_DATA *md, hdb_entry *client,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ENABLE_AES
|
||||||
|
extern int _krb5_AES_string_to_default_iterator;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
|
||||||
|
{
|
||||||
|
ent->etype = key->key.keytype;
|
||||||
|
if(key->salt) {
|
||||||
|
ALLOC(ent->salt);
|
||||||
|
if (ent->salt == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
*ent->salt = strndup(key->salt->salt.data, key->salt->salt.length);
|
||||||
|
} else
|
||||||
|
ent->salt = NULL;
|
||||||
|
|
||||||
|
switch (key->key.keytype) {
|
||||||
|
#ifdef ENABLE_AES
|
||||||
|
case KEYTYPE_AES128:
|
||||||
|
case KEYTYPE_AES256:
|
||||||
|
ALLOC(ent->s2kparams);
|
||||||
|
if (ent->s2kparams == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
ent->s2kparams->length = 4;
|
||||||
|
ent->s2kparams->data = malloc(ent->s2kparams->length);
|
||||||
|
if (ent->s2kparams->data == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
_krb5_put_int(ent->s2kparams->data,
|
||||||
|
_krb5_AES_string_to_default_iterator,
|
||||||
|
ent->s2kparams->length);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ent->s2kparams = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return 1 if the client have only older enctypes, this is for
|
||||||
|
* determining if the server should send ETYPE_INFO2 or not.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
only_older_enctype_p(const hdb_entry *client)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < client->keys.len; i++) {
|
||||||
|
switch (client->keys.val[i].key.keytype) {
|
||||||
|
case KEYTYPE_DES:
|
||||||
|
case KEYTYPE_DES3:
|
||||||
|
case KEYTYPE_ARCFOUR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
get_pa_etype_info2(METHOD_DATA *md, hdb_entry *client,
|
||||||
|
ENCTYPE *etypes, unsigned int etypes_len)
|
||||||
|
{
|
||||||
|
krb5_error_code ret = 0;
|
||||||
|
int i, j;
|
||||||
|
unsigned int n = 0;
|
||||||
|
ETYPE_INFO2 pa;
|
||||||
|
unsigned char *buf;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
pa.len = client->keys.len;
|
||||||
|
if(pa.len > UINT_MAX/sizeof(*pa.val))
|
||||||
|
return ERANGE;
|
||||||
|
pa.val = malloc(pa.len * sizeof(*pa.val));
|
||||||
|
if(pa.val == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
memset(pa.val, 0, pa.len * sizeof(*pa.val));
|
||||||
|
|
||||||
|
for(j = 0; j < etypes_len; j++) {
|
||||||
|
for(i = 0; i < client->keys.len; i++) {
|
||||||
|
if(client->keys.val[i].key.keytype == etypes[j])
|
||||||
|
if((ret = make_etype_info2_entry(&pa.val[n++],
|
||||||
|
&client->keys.val[i])) != 0) {
|
||||||
|
free_ETYPE_INFO2(&pa);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i = 0; i < client->keys.len; i++) {
|
||||||
|
for(j = 0; j < etypes_len; j++) {
|
||||||
|
if(client->keys.val[i].key.keytype == etypes[j])
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
if((ret = make_etype_info2_entry(&pa.val[n++],
|
||||||
|
&client->keys.val[i])) != 0) {
|
||||||
|
free_ETYPE_INFO2(&pa);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
skip:;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n != pa.len) {
|
||||||
|
char *name;
|
||||||
|
krb5_unparse_name(context, client->principal, &name);
|
||||||
|
kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
|
||||||
|
name, n, pa.len);
|
||||||
|
free(name);
|
||||||
|
pa.len = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
|
||||||
|
free_ETYPE_INFO2(&pa);
|
||||||
|
if(ret)
|
||||||
|
return ret;
|
||||||
|
ret = realloc_method_data(md);
|
||||||
|
if(ret) {
|
||||||
|
free(buf);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
md->val[md->len - 1].padata_type = KRB5_PADATA_ETYPE_INFO2;
|
||||||
|
md->val[md->len - 1].padata_value.length = len;
|
||||||
|
md->val[md->len - 1].padata_value.data = buf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* verify the flags on `client' and `server', returning 0
|
* verify the flags on `client' and `server', returning 0
|
||||||
* if they are OK and generating an error messages and returning
|
* if they are OK and generating an error messages and returning
|
||||||
@@ -675,8 +812,14 @@ as_rep(KDC_REQ *req,
|
|||||||
pa->padata_value.length = 0;
|
pa->padata_value.length = 0;
|
||||||
pa->padata_value.data = NULL;
|
pa->padata_value.data = NULL;
|
||||||
|
|
||||||
ret = get_pa_etype_info(&method_data, client,
|
/* XXX check ret */
|
||||||
b->etype.val, b->etype.len); /* XXX check ret */
|
if (only_older_enctype_p(client))
|
||||||
|
ret = get_pa_etype_info(&method_data, client,
|
||||||
|
b->etype.val, b->etype.len);
|
||||||
|
/* XXX check ret */
|
||||||
|
ret = get_pa_etype_info2(&method_data, client,
|
||||||
|
b->etype.val, b->etype.len);
|
||||||
|
|
||||||
|
|
||||||
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
|
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
|
||||||
free_METHOD_DATA(&method_data);
|
free_METHOD_DATA(&method_data);
|
||||||
|
Reference in New Issue
Block a user