From 4df1b1047b8099a070cda91797af58eafb01f024 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 27 Jul 2009 17:41:19 +0000 Subject: [PATCH] Use zero-terminated enctype lists in the context structure instead of counted lists, to reduce impedance mismatches. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@22456 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/k5-int.h | 6 +- src/lib/krb5/krb/gc_frm_kdc.c | 6 +- src/lib/krb5/krb/init_ctx.c | 196 ++++++++++++++-------------------- src/lib/krb5/krb/ser_ctx.c | 115 +++++++++++--------- 4 files changed, 150 insertions(+), 173 deletions(-) diff --git a/src/include/k5-int.h b/src/include/k5-int.h index be3d1a9bf..d4407b99d 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -1322,10 +1322,8 @@ typedef struct _kdb5_dal_handle kdb5_dal_handle; struct _kdb_log_context; struct _krb5_context { krb5_magic magic; - krb5_enctype *in_tkt_ktypes; - unsigned int in_tkt_ktype_count; - krb5_enctype *tgs_ktypes; - unsigned int tgs_ktype_count; + krb5_enctype *in_tkt_etypes; + krb5_enctype *tgs_etypes; struct _krb5_os_context os_context; char *default_realm; profile_t profile; diff --git a/src/lib/krb5/krb/gc_frm_kdc.c b/src/lib/krb5/krb/gc_frm_kdc.c index 0cec57aec..3098e8e13 100644 --- a/src/lib/krb5/krb/gc_frm_kdc.c +++ b/src/lib/krb5/krb/gc_frm_kdc.c @@ -1068,10 +1068,10 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, * Check if the return enctype is one that we requested if * needed. */ - if (old_use_conf_ktypes || context->tgs_ktype_count == 0) + if (old_use_conf_ktypes || !context->tgs_etypes) goto cleanup; - for (i = 0; i < context->tgs_ktype_count; i++) { - if ((*out_cred)->keyblock.enctype == context->tgs_ktypes[i]) { + for (i = 0; context->tgs_etypes[i]; i++) { + if ((*out_cred)->keyblock.enctype == context->tgs_etypes[i]) { /* Found an allowable etype, so we're done */ goto cleanup; } diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index 67dad8cb2..e6ae2a712 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -258,10 +258,10 @@ krb5_free_context(krb5_context ctx) return; krb5_os_free_context(ctx); - free(ctx->in_tkt_ktypes); - ctx->in_tkt_ktypes = 0; - free(ctx->tgs_ktypes); - ctx->tgs_ktypes = 0; + free(ctx->in_tkt_etypes); + ctx->in_tkt_etypes = NULL; + free(ctx->tgs_etypes); + ctx->tgs_etypes = NULL; free(ctx->default_realm); ctx->default_realm = 0; if (ctx->ser_ctx_count && ctx->ser_ctx) { @@ -275,58 +275,87 @@ krb5_free_context(krb5_context ctx) free(ctx); } +/* Copy the zero-terminated enctype list old_list into *new_list. */ +static krb5_error_code +copy_enctypes(krb5_context context, const krb5_enctype *old_list, + krb5_enctype **new_list) +{ + unsigned int count; + krb5_enctype *list; + + *new_list = NULL; + for (count = 0; old_list[count]; count++); + list = malloc(sizeof(krb5_enctype) * (count + 1)); + if (list == NULL) + return ENOMEM; + memcpy(list, old_list, sizeof(krb5_enctype) * (count + 1)); + *new_list = list; + return 0; +} + /* * Set the desired default ktypes, making sure they are valid. */ -krb5_error_code -krb5_set_default_in_tkt_ktypes(krb5_context context, const krb5_enctype *ktypes) +static krb5_error_code +set_default_etype_var(krb5_context context, const krb5_enctype *etypes, + krb5_enctype **var) { - krb5_enctype * new_ktypes; + krb5_error_code code; + krb5_enctype *list; int i; - if (ktypes) { - for (i = 0; ktypes[i]; i++) { - if (!krb5_c_valid_enctype(ktypes[i])) + if (etypes) { + for (i = 0; etypes[i]; i++) { + if (!krb5_c_valid_enctype(etypes[i])) return KRB5_PROG_ETYPE_NOSUPP; - if (!context->allow_weak_crypto && krb5_c_weak_enctype(ktypes[i])) + if (!context->allow_weak_crypto && krb5_c_weak_enctype(etypes[i])) return KRB5_PROG_ETYPE_NOSUPP; } - /* Now copy the default ktypes into the context pointer */ - if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i))) - memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); - else - return ENOMEM; - + code = copy_enctypes(context, etypes, &list); + if (code) + return code; } else { - i = 0; - new_ktypes = 0; + list = NULL; } - if (context->in_tkt_ktypes) - free(context->in_tkt_ktypes); - context->in_tkt_ktypes = new_ktypes; - context->in_tkt_ktype_count = i; + free(*var); + *var = list; return 0; } +krb5_error_code +krb5_set_default_in_tkt_ktypes(krb5_context context, + const krb5_enctype *etypes) +{ + return set_default_etype_var(context, etypes, &context->in_tkt_etypes); +} + +krb5_error_code KRB5_CALLCONV +krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype *etypes) +{ + return set_default_etype_var(context, etypes, &context->tgs_etypes); +} + +/* Old name for above function. */ +krb5_error_code +krb5_set_default_tgs_ktypes(krb5_context context, const krb5_enctype *etypes) +{ + return set_default_etype_var(context, etypes, &context->tgs_etypes); +} + static krb5_error_code -get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr, - unsigned int ctx_count, krb5_enctype *ctx_list) +get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, + char *profstr, krb5_enctype *ctx_list) { krb5_enctype *old_ktypes; krb5_enctype ktype; + krb5_error_code code; - if (ctx_count) { - /* application-set defaults */ - if ((old_ktypes = - (krb5_enctype *)malloc(sizeof(krb5_enctype) * - (ctx_count + 1)))) { - memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count); - old_ktypes[ctx_count] = 0; - } else { - return ENOMEM; - } + if (ctx_list) { + code = copy_enctypes(context, ctx_list, &old_ktypes); + if (code) + return code; } else { /* XXX - For now, we only support libdefaults @@ -337,7 +366,6 @@ get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profst char *retval = NULL; char *sp = NULL, *ep = NULL; int i, j, count; - krb5_error_code code; code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, profstr, NULL, DEFAULT_ETYPE_LIST, &retval); @@ -399,50 +427,11 @@ get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profst krb5_error_code krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes) { - return(get_profile_etype_list(context, ktypes, KRB5_CONF_DEFAULT_TKT_ENCTYPES, - context->in_tkt_ktype_count, - context->in_tkt_ktypes)); + return(get_profile_etype_list(context, ktypes, + KRB5_CONF_DEFAULT_TKT_ENCTYPES, + context->in_tkt_etypes)); } -krb5_error_code KRB5_CALLCONV -krb5_set_default_tgs_enctypes (krb5_context context, const krb5_enctype *ktypes) -{ - krb5_enctype * new_ktypes; - int i; - - if (ktypes) { - for (i = 0; ktypes[i]; i++) { - if (!krb5_c_valid_enctype(ktypes[i])) - return KRB5_PROG_ETYPE_NOSUPP; - if (!context->allow_weak_crypto && krb5_c_weak_enctype(ktypes[i])) - return KRB5_PROG_ETYPE_NOSUPP; - } - - /* Now copy the default ktypes into the context pointer */ - if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i))) - memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); - else - return ENOMEM; - - } else { - i = 0; - new_ktypes = (krb5_enctype *)NULL; - } - - if (context->tgs_ktypes) - krb5_free_ktypes(context, context->tgs_ktypes); - context->tgs_ktypes = new_ktypes; - context->tgs_ktype_count = i; - return 0; -} - -krb5_error_code krb5_set_default_tgs_ktypes -(krb5_context context, const krb5_enctype *etypes) -{ - return (krb5_set_default_tgs_enctypes (context, etypes)); -} - - void KRB5_CALLCONV krb5_free_ktypes (krb5_context context, krb5_enctype *val) @@ -457,20 +446,20 @@ krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_encty if (context->use_conf_ktypes) /* This one is set *only* by reading the config file; it's not set by the application. */ - return(get_profile_etype_list(context, ktypes, KRB5_CONF_DEFAULT_TKT_ENCTYPES, - 0, NULL)); + return get_profile_etype_list(context, ktypes, + KRB5_CONF_DEFAULT_TKT_ENCTYPES, NULL); else - return(get_profile_etype_list(context, ktypes, KRB5_CONF_DEFAULT_TGS_ENCTYPES, - context->tgs_ktype_count, - context->tgs_ktypes)); + return get_profile_etype_list(context, ktypes, + KRB5_CONF_DEFAULT_TGS_ENCTYPES, + context->tgs_etypes); } krb5_error_code KRB5_CALLCONV krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes) { - return(get_profile_etype_list(context, ktypes, KRB5_CONF_PERMITTED_ENCTYPES, - context->tgs_ktype_count, - context->tgs_ktypes)); + return get_profile_etype_list(context, ktypes, + KRB5_CONF_PERMITTED_ENCTYPES, + context->tgs_etypes); } krb5_boolean @@ -526,26 +515,6 @@ krb5_is_permitted_enctype_ext ( krb5_context context, return(ret); } -static krb5_error_code -copy_ktypes(krb5_context ctx, - unsigned int nktypes, - krb5_enctype *oldktypes, - krb5_enctype **newktypes) -{ - unsigned int i; - - *newktypes = NULL; - if (!nktypes) - return 0; - - *newktypes = malloc(nktypes * sizeof(krb5_enctype)); - if (*newktypes == NULL) - return ENOMEM; - for (i = 0; i < nktypes; i++) - (*newktypes)[i] = oldktypes[i]; - return 0; -} - krb5_error_code KRB5_CALLCONV krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) { @@ -562,10 +531,8 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) *nctx = *ctx; - nctx->in_tkt_ktypes = NULL; - nctx->in_tkt_ktype_count = 0; - nctx->tgs_ktypes = NULL; - nctx->tgs_ktype_count = 0; + nctx->in_tkt_etypes = NULL; + nctx->tgs_etypes = NULL; nctx->default_realm = NULL; nctx->profile = NULL; nctx->dal_handle = NULL; @@ -583,17 +550,12 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) memset(&nctx->err, 0, sizeof(nctx->err)); - ret = copy_ktypes(nctx, ctx->in_tkt_ktype_count, - ctx->in_tkt_ktypes, &nctx->in_tkt_ktypes); + ret = copy_enctypes(nctx, ctx->in_tkt_etypes, &nctx->in_tkt_etypes); if (ret) goto errout; - nctx->in_tkt_ktype_count = ctx->in_tkt_ktype_count; - - ret = copy_ktypes(nctx, ctx->tgs_ktype_count, - ctx->tgs_ktypes, &nctx->in_tkt_ktypes); + ret = copy_enctypes(nctx, ctx->tgs_etypes, &nctx->tgs_etypes); if (ret) goto errout; - nctx->tgs_ktype_count = ctx->tgs_ktype_count; if (ctx->os_context.default_ccname != NULL) { nctx->os_context.default_ccname = diff --git a/src/lib/krb5/krb/ser_ctx.c b/src/lib/krb5/krb/ser_ctx.c index 12051d7c4..c8f673b77 100644 --- a/src/lib/krb5/krb/ser_ctx.c +++ b/src/lib/krb5/krb/ser_ctx.c @@ -92,6 +92,18 @@ static const krb5_ser_entry krb5_profile_ser_entry = { profile_ser_internalize /* Internalize routine */ }; #endif /* LEAN_CLIENT */ + +static unsigned int +etypes_len(krb5_enctype *list) +{ + unsigned int i; + + if (list == NULL) + return 0; + for (i = 0; list[i]; i++); + return i; +} + /* * krb5_context_size() - Determine the size required to externalize the * krb5_context. @@ -108,10 +120,10 @@ krb5_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) * krb5_int32 for KV5M_CONTEXT * krb5_int32 for sizeof(default_realm) * strlen(default_realm) for default_realm. - * krb5_int32 for n_in_tkt_ktypes*sizeof(krb5_int32) - * nktypes*sizeof(krb5_int32) for in_tkt_ktypes. - * krb5_int32 for n_tgs_ktypes*sizeof(krb5_int32) - * nktypes*sizeof(krb5_int32) for tgs_ktypes. + * krb5_int32 for n_in_tkt_etypes*sizeof(krb5_int32) + * nktypes*sizeof(krb5_int32) for in_tkt_etypes. + * krb5_int32 for n_tgs_etypes*sizeof(krb5_int32) + * nktypes*sizeof(krb5_int32) for tgs_etypes. * krb5_int32 for clockskew * krb5_int32 for kdc_req_sumtype * krb5_int32 for ap_req_sumtype @@ -129,8 +141,8 @@ krb5_context_size(krb5_context kcontext, krb5_pointer arg, size_t *sizep) if ((context = (krb5_context) arg)) { /* Calculate base length */ required = (14 * sizeof(krb5_int32) + - (context->in_tkt_ktype_count * sizeof(krb5_int32)) + - (context->tgs_ktype_count * sizeof(krb5_int32))); + (etypes_len(context->in_tkt_etypes) * sizeof(krb5_int32)) + + (etypes_len(context->tgs_etypes) * sizeof(krb5_int32))); if (context->default_realm) required += strlen(context->default_realm); @@ -208,31 +220,33 @@ krb5_context_externalize(krb5_context kcontext, krb5_pointer arg, krb5_octet **b } /* Now number of initial ticket ktypes */ - kret = krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktype_count, + kret = krb5_ser_pack_int32(etypes_len(context->in_tkt_etypes), &bp, &remain); if (kret) return (kret); - + /* Now serialize ktypes */ - for (i=0; iin_tkt_ktype_count; i++) { - kret = krb5_ser_pack_int32((krb5_int32) context->in_tkt_ktypes[i], - &bp, &remain); - if (kret) - return (kret); + if (context->in_tkt_etypes) { + for (i = 0; context->in_tkt_etypes[i]; i++) { + kret = krb5_ser_pack_int32(context->in_tkt_etypes[i], + &bp, &remain); + if (kret) + return (kret); + } } - + /* Now number of default ktypes */ - kret = krb5_ser_pack_int32((krb5_int32) context->tgs_ktype_count, - &bp, &remain); + kret = krb5_ser_pack_int32(etypes_len(context->tgs_etypes), &bp, &remain); if (kret) return (kret); /* Now serialize ktypes */ - for (i=0; itgs_ktype_count; i++) { - kret = krb5_ser_pack_int32((krb5_int32) context->tgs_ktypes[i], - &bp, &remain); - if (kret) - return (kret); + if (context->tgs_etypes) { + for (i = 0; context->tgs_etypes[i]; i++) { + kret = krb5_ser_pack_int32(context->tgs_etypes[i], &bp, &remain); + if (kret) + return (kret); + } } /* Now allowable clockskew */ @@ -333,7 +347,7 @@ krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet * krb5_int32 ibuf; krb5_octet *bp; size_t remain; - unsigned int i; + unsigned int i, count; bp = *buffer; remain = *lenremain; @@ -369,40 +383,43 @@ krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet * context->default_realm[ibuf] = '\0'; } - /* Get the number of in_tkt_ktypes */ + /* Get the in_tkt_etypes */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; - - context->in_tkt_ktype_count = (int) ibuf; - context->in_tkt_ktypes = (krb5_enctype *) calloc(context->in_tkt_ktype_count+1, - sizeof(krb5_enctype)); - if (!context->in_tkt_ktypes) { - kret = ENOMEM; - goto cleanup; - } - - for (i=0; iin_tkt_ktype_count; i++) { - if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + count = ibuf; + if (count > 0) { + context->in_tkt_etypes = calloc(count + 1, sizeof(krb5_enctype)); + if (!context->in_tkt_etypes) { + kret = ENOMEM; goto cleanup; - context->in_tkt_ktypes[i] = (krb5_enctype) ibuf; - } + } + for (i = 0; i < count; i++) { + if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + goto cleanup; + context->in_tkt_etypes[i] = ibuf; + } + context->in_tkt_etypes[count] = 0; + } else + context->in_tkt_etypes = NULL; - /* Get the number of tgs_ktypes */ + /* Get the tgs_etypes */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) goto cleanup; - - context->tgs_ktype_count = (int) ibuf; - context->tgs_ktypes = (krb5_enctype *) calloc(context->tgs_ktype_count+1, - sizeof(krb5_enctype)); - if (!context->tgs_ktypes) { - kret = ENOMEM; - goto cleanup; - } - for (i=0; itgs_ktype_count; i++) { - if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + count = ibuf; + if (count > 0) { + context->tgs_etypes = calloc(count + 1, sizeof(krb5_enctype)); + if (!context->tgs_etypes) { + kret = ENOMEM; goto cleanup; - context->tgs_ktypes[i] = (krb5_enctype) ibuf; - } + } + for (i = 0; i < count; i++) { + if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) + goto cleanup; + context->tgs_etypes[i] = ibuf; + } + context->tgs_etypes[count] = 0; + } else + context->tgs_etypes = NULL; /* Allowable checksum */ if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) -- 2.26.2