Use zero-terminated enctype lists in the context structure instead of
authorGreg Hudson <ghudson@mit.edu>
Mon, 27 Jul 2009 17:41:19 +0000 (17:41 +0000)
committerGreg Hudson <ghudson@mit.edu>
Mon, 27 Jul 2009 17:41:19 +0000 (17:41 +0000)
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
src/lib/krb5/krb/gc_frm_kdc.c
src/lib/krb5/krb/init_ctx.c
src/lib/krb5/krb/ser_ctx.c

index be3d1a9bf2145997488654b2c2abb13126d9551c..d4407b99d2793f093c6f22d3e7162d630f7d97af 100644 (file)
@@ -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;
index 0cec57aecaff822a8a1d3b8abeffff32d364c03f..3098e8e13cd6551753231b1cb675fbcc38fdf7f9 100644 (file)
@@ -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;
                }
index 67dad8cb21d70ae56caa921727c746e2bd35e2fd..e6ae2a7129ac8e1a0cb63fe7550ad3b526b5acd5 100644 (file)
@@ -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 =
index 12051d7c4a29ea3a1da2e3cee119fd1c6c1b8fc1..c8f673b77133c5c989f6d5b62f5ce59087b694c0 100644 (file)
@@ -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; i<context->in_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; i<context->tgs_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; i<context->in_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; i<context->tgs_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)))