From 20001366aa55e167f520798646eb97f5df248460 Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Sun, 30 Aug 2009 13:25:38 -0700 Subject: [PATCH] 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. --- lib/krb5/init_creds_pw.c | 64 +++++++++++++++++++++++++++++++++++++++- tests/kdc/check-kdc.in | 13 ++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c index ff89a90d5..0c2f5cf53 100644 --- a/lib/krb5/init_creds_pw.c +++ b/lib/krb5/init_creds_pw.c @@ -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; } diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in index 237e099f5..ead3dde66 100644 --- a/tests/kdc/check-kdc.in +++ b/tests/kdc/check-kdc.in @@ -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}"; }