Better support for kinit -k when client have subset of enctypes compared to KDC

Get the list of enctypes and use that to calculate the list of client supported
enctypes when talking to the KDC, this to make sure that KDC doesn't send
pw-challanges to the client for enctypes that the client software support
but there is no entry in the keytab.
This commit is contained in:
Love Hornquist Astrand
2009-08-30 13:25:38 -07:00
parent 54e10a2a13
commit 20001366aa
2 changed files with 76 additions and 1 deletions

View File

@@ -398,6 +398,9 @@ get_init_creds_common(krb5_context context,
}
}
if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) {
if (ctx->etypes)
free(ctx->etypes);
etypes = malloc((options->etype_list_length + 1)
* sizeof(krb5_enctype));
if (etypes == NULL) {
@@ -1417,10 +1420,17 @@ krb5_init_creds_set_keytab(krb5_context context,
krb5_keytab keytab)
{
krb5_keytab_key_proc_args *a;
krb5_keytab_entry entry;
krb5_kt_cursor cursor;
krb5_enctype *etypes = NULL;
krb5_error_code ret;
size_t netypes = 0;
int kvno = 0;
a = malloc(sizeof(*a));
if (a == NULL) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
krb5_set_error_message(context, ENOMEM,
N_("malloc: out of memory", ""));
return ENOMEM;
}
@@ -1431,6 +1441,58 @@ krb5_init_creds_set_keytab(krb5_context context,
ctx->keyseed = (void *)a;
ctx->keyproc = keytab_key_proc;
/*
* We need to the KDC what enctypes we support for this keytab,
* esp if the keytab is really a password based entry, then the
* KDC might have more enctypes in the database then what we have
* in the keytab.
*/
ret = krb5_kt_start_seq_get(context, keytab, &cursor);
if(ret)
goto out;
while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0){
void *ptr;
if (!krb5_principal_compare(context, entry.principal, ctx->cred.client))
goto next;
/* check if we ahve this kvno already */
if (entry.vno > kvno) {
/* remove old list of etype */
if (etypes)
free(etypes);
netypes = 0;
kvno = entry.vno;
} else if (entry.vno != kvno)
goto next;
/* check if enctype is supported */
if (krb5_enctype_valid(context, entry.keyblock.keytype) != 0)
goto next;
/* add enctype to supported list */
ptr = realloc(etypes, sizeof(etypes[0]) * (netypes + 1));
if (ptr == NULL)
goto next;
etypes = ptr;
etypes[netypes] = entry.keyblock.keytype;
etypes[netypes + 1] = 0;
netypes++;
next:
krb5_kt_free_entry(context, &entry);
}
krb5_kt_end_seq_get(context, keytab, &cursor);
if (etypes) {
if (ctx->etypes)
free(ctx->etypes);
ctx->etypes = etypes;
}
out:
return 0;
}

View File

@@ -113,6 +113,7 @@ ${kadmin} add -p bar --use-defaults bar@${R} || exit 1
${kadmin} add -p foo --use-defaults remove@${R} || exit 1
${kadmin} add -p kaka --use-defaults ${server}@${R} || exit 1
${kadmin} add -p kaka --use-defaults ${server}-des3@${R} || exit 1
${kadmin} add -p kaka --use-defaults kt-des3@${R} || exit 1
${kadmin} add -p foo --use-defaults ${ps} || exit 1
${kadmin} modify --attributes=+trusted-for-delegation ${ps} || exit 1
${kadmin} modify --constrained-delegation=${server} ${ps} || exit 1
@@ -157,6 +158,12 @@ enctypes=`grep Keytypes: tempfile | sed 's/(pw-salt)//g' | sed 's/,//g' | sed 's
enctype_sans_aes=`echo $enctypes | sed 's/aes[^ ]*//g'`
enctype_sans_des3=`echo $enctypes | sed 's/des3-cbc-sha1//g'`
echo "deleting all but des enctypes on kt-des3 in keytab"
${kadmin} ext -k ${keytab} kt-des3@${R} || exit 1
for a in ${enctype_sans_des3} ; do
${ktutil} -k ${keytab} remove -p kt-des3@${R} -e $a
done
echo foo > ${objdir}/foopassword
echo Starting kdc
@@ -274,6 +281,12 @@ ${klist} | grep "Principal: ${server}" > /dev/null || \
{ ec=1 ; eval "${testfailed}"; }
${kdestroy}
echo "Getting key for key that are a subset in keytab compared to kdb"
${kinit} --keytab=${keytab} kt-des3@${R}
${klist} | grep "Principal: kt-des3" > /dev/null || \
{ ec=1 ; eval "${testfailed}"; }
${kdestroy}
echo "initial tickets for deleted user test case"; > messages.log
${kinit} --password-file=${objdir}/foopassword remove@$R || \
{ ec=1 ; eval "${testfailed}"; }