krb5 commit: Use krb5_init_creds_context as clpreauth rock

Greg Hudson ghudson at MIT.EDU
Sat Dec 22 02:05:06 EST 2012


https://github.com/krb5/krb5/commit/af26a3e882372b6617a62cad01966ab90b045114
commit af26a3e882372b6617a62cad01966ab90b045114
Author: Greg Hudson <ghudson at mit.edu>
Date:   Fri Dec 21 12:20:43 2012 -0500

    Use krb5_init_creds_context as clpreauth rock
    
    The clpreauth rock had become a collection of alias pointers into the
    init_creds context structure.  Get rid of it and just pass the context
    (suitably casted) to clpreauth modules.  Simplify the signatures of
    k5_preauth(), k5_preauth_tryagain(), process_pa_data(), and
    fill_response_items() by referencing fields from the init_creds
    context.
    
    Since we can't use the non-nullity of rock->selected_preauth_type to
    determine whether to record the selected preauth type, k5_preauth now
    reports it in an output parameter, and get_in_tkt.c decides whether or
    not to record it.

 src/lib/krb5/krb/get_in_tkt.c     |   62 +++--------
 src/lib/krb5/krb/init_creds_ctx.h |   54 +---------
 src/lib/krb5/krb/int-proto.h      |   20 +--
 src/lib/krb5/krb/preauth2.c       |  219 +++++++++++++++++++------------------
 src/lib/krb5/krb/preauth_sam2.c   |   43 ++++----
 5 files changed, 162 insertions(+), 236 deletions(-)

diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 3bf1b3a..462ec22 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -684,7 +684,6 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
     code = krb5int_fast_make_state(context, &ctx->fast_state);
     if (code != 0)
         goto cleanup;
-    ctx->preauth_rock.fast_state = ctx->fast_state;
     k5_preauth_request_context_init(context);
     if (ctx->outer_request_body) {
         krb5_free_data(context, ctx->outer_request_body);
@@ -820,23 +819,6 @@ krb5_init_creds_init(krb5_context context,
 
     opte = ctx->opte;
 
-    ctx->preauth_rock.magic = CLIENT_ROCK_MAGIC;
-    ctx->preauth_rock.etype = &ctx->etype;
-    ctx->preauth_rock.as_key = &ctx->as_key;
-    ctx->preauth_rock.gak_fct = &ctx->gak_fct;
-    ctx->preauth_rock.gak_data = &ctx->gak_data;
-    ctx->preauth_rock.default_salt = &ctx->default_salt;
-    ctx->preauth_rock.salt = &ctx->salt;
-    ctx->preauth_rock.s2kparams = &ctx->s2kparams;
-    ctx->preauth_rock.rctx = ctx->rctx;
-    ctx->preauth_rock.client = client;
-    ctx->preauth_rock.prompter = prompter;
-    ctx->preauth_rock.prompter_data = data;
-    ctx->preauth_rock.allowed_preauth_type = &ctx->allowed_preauth_type;
-    ctx->preauth_rock.selected_preauth_type = &ctx->selected_preauth_type;
-    ctx->preauth_rock.cc_config_in = &ctx->cc_config_in;
-    ctx->preauth_rock.cc_config_out = &ctx->cc_config_out;
-
     /* Initialise request parameters as per krb5_get_init_creds() */
     ctx->request->kdc_options = context->kdc_default_options;
 
@@ -1262,11 +1244,9 @@ init_creds_step_request(krb5_context context,
 
     if (ctx->err_reply == NULL) {
         /* either our first attempt, or retrying after PREAUTH_NEEDED */
-        code = k5_preauth(context, ctx->opte, &ctx->preauth_rock, ctx->request,
-                          ctx->inner_request_body,
-                          ctx->encoded_previous_request, ctx->preauth_to_use,
-                          ctx->prompter, ctx->prompter_data,
-                          ctx->preauth_required, &ctx->request->padata);
+        code = k5_preauth(context, ctx, ctx->preauth_to_use,
+                          ctx->preauth_required, &ctx->request->padata,
+                          &ctx->selected_preauth_type);
         if (code != 0)
             goto cleanup;
     } else {
@@ -1275,12 +1255,7 @@ init_creds_step_request(krb5_context context,
              * Retry after an error other than PREAUTH_NEEDED,
              * using ctx->err_padata to figure out what to change.
              */
-            code = k5_preauth_tryagain(context, ctx->opte, &ctx->preauth_rock,
-                                       ctx->request, ctx->inner_request_body,
-                                       ctx->encoded_previous_request,
-                                       ctx->preauth_to_use, ctx->err_reply,
-                                       ctx->err_padata, ctx->prompter,
-                                       ctx->prompter_data,
+            code = k5_preauth_tryagain(context, ctx, ctx->preauth_to_use,
                                        &ctx->request->padata);
         } else {
             /* No preauth supplied, so can't query the plugins. */
@@ -1391,7 +1366,7 @@ check_reply_enctype(krb5_init_creds_context ctx)
 /* Note the difference between the KDC's time, as reported to us in a
  * preauth-required error, and the current time. */
 static void
-note_req_timestamp(krb5_context kcontext, krb5_clpreauth_rock rock,
+note_req_timestamp(krb5_context context, krb5_init_creds_context ctx,
                    krb5_timestamp kdc_time, krb5_int32 kdc_usec)
 {
     krb5_timestamp now;
@@ -1399,9 +1374,9 @@ note_req_timestamp(krb5_context kcontext, krb5_clpreauth_rock rock,
 
     if (k5_time_with_offset(0, 0, &now, &usec) != 0)
         return;
-    rock->pa_offset = kdc_time - now;
-    rock->pa_offset_usec = kdc_usec - usec;
-    rock->pa_offset_state = (rock->fast_state->armor_key != NULL) ?
+    ctx->pa_offset = kdc_time - now;
+    ctx->pa_offset_usec = kdc_usec - usec;
+    ctx->pa_offset_state = (ctx->fast_state->armor_key != NULL) ?
         AUTH_OFFSET : UNAUTH_OFFSET;
 }
 
@@ -1412,6 +1387,7 @@ init_creds_step_reply(krb5_context context,
 {
     krb5_error_code code;
     krb5_pa_data **kdc_padata = NULL;
+    krb5_preauthtype kdc_pa_type;
     krb5_boolean retry = FALSE;
     int canon_flag = 0;
     krb5_keyblock *strengthen_key = NULL;
@@ -1452,8 +1428,8 @@ init_creds_step_reply(krb5_context context,
             krb5_free_pa_data(context, ctx->preauth_to_use);
             ctx->preauth_to_use = ctx->err_padata;
             ctx->err_padata = NULL;
-            note_req_timestamp(context, &ctx->preauth_rock,
-                               ctx->err_reply->stime, ctx->err_reply->susec);
+            note_req_timestamp(context, ctx, ctx->err_reply->stime,
+                               ctx->err_reply->susec);
             /* This will trigger a new call to k5_preauth(). */
             krb5_free_error(context, ctx->err_reply);
             ctx->err_reply = NULL;
@@ -1520,19 +1496,11 @@ init_creds_step_reply(krb5_context context,
 
     ctx->etype = ctx->reply->enc_part.enctype;
 
-    /*
-     * At this point, allow whichever preauth plugin that can handle the KDC's
-     * reply padata to do so, regardless of that data's padata type.  We don't
-     * want to record the type of padata in the reply, so set the pointer for
-     * that data to NULL.
-     */
+    /* Process the final reply padata.  Don't restrict the preauth types or
+     * record a selected preauth type. */
     ctx->allowed_preauth_type = KRB5_PADATA_NONE;
-    ctx->preauth_rock.selected_preauth_type = NULL;
-
-    code = k5_preauth(context, ctx->opte, &ctx->preauth_rock, ctx->request,
-                      ctx->inner_request_body, ctx->encoded_previous_request,
-                      ctx->reply->padata, ctx->prompter, ctx->prompter_data,
-                      FALSE, &kdc_padata);
+    code = k5_preauth(context, ctx, ctx->reply->padata, FALSE, &kdc_padata,
+                      &kdc_pa_type);
     if (code != 0)
         goto cleanup;
 
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index e893113..5d81391 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -5,55 +5,6 @@
 
 #include "k5-json.h"
 
-#define CLIENT_ROCK_MAGIC 0x4352434b
-/*
- * This structure is passed into the clpreauth methods and passed back to
- * clpreauth callbacks so that they can locate the requested information.  It
- * is opaque to the plugin code and can be expanded in the future as new types
- * of requests are defined which may require other things to be passed through.
- * All pointer fields are aliases and should not be freed.
- */
-struct krb5_clpreauth_rock_st {
-    krb5_magic magic;
-    krb5_enctype *etype;
-    struct krb5int_fast_request_state *fast_state;
-
-    /*
-     * These fields allow gak_fct to be called via the rock.  The
-     * gak_fct and gak_data fields have an extra level of indirection
-     * since they can change in the init_creds context.
-     */
-    krb5_keyblock *as_key;
-    krb5_gic_get_as_key_fct *gak_fct;
-    void **gak_data;
-    krb5_boolean *default_salt;
-    krb5_data *salt;
-    krb5_data *s2kparams;
-    krb5_principal client;
-    krb5_prompter_fct prompter;
-    void *prompter_data;
-
-    /* Discovered offset of server time during preauth */
-    krb5_timestamp pa_offset;
-    krb5_int32 pa_offset_usec;
-    enum { NO_OFFSET = 0, UNAUTH_OFFSET, AUTH_OFFSET } pa_offset_state;
-    struct krb5_responder_context_st rctx;
-
-    /*
-     * Configuration information read from an in_ccache, actually stored in the
-     * containing context structure, but needed by callbacks which currently
-     * only get a pointer to the rock.
-     */
-
-    /* The allowed preauth type (number) that we might use, equal to
-     * KRB5_PADATA_NONE if none was set. */
-    krb5_preauthtype *allowed_preauth_type;
-    krb5_preauthtype *selected_preauth_type;
-    /* Preauth configuration data which can help us make some decisions. */
-    k5_json_value *cc_config_in;
-    k5_json_value *cc_config_out;
-};
-
 struct _krb5_init_creds_context {
     krb5_gic_opt_ext *opte;
     char *in_tkt_service;
@@ -92,7 +43,6 @@ struct _krb5_init_creds_context {
     krb5_data s2kparams;
     krb5_keyblock as_key;
     krb5_enctype etype;
-    struct krb5_clpreauth_rock_st preauth_rock;
     krb5_boolean enc_pa_rep_permitted;
     krb5_boolean have_restarted;
     krb5_boolean sent_nontrivial_preauth;
@@ -102,6 +52,10 @@ struct _krb5_init_creds_context {
     krb5_preauthtype allowed_preauth_type;
     void *cc_config_in;
     void *cc_config_out;
+    /* Discovered offset of server time during preauth */
+    krb5_timestamp pa_offset;
+    krb5_int32 pa_offset_usec;
+    enum { NO_OFFSET = 0, UNAUTH_OFFSET, AUTH_OFFSET } pa_offset_state;
 };
 
 krb5_error_code
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
index ca534cd..4ebae56 100644
--- a/src/lib/krb5/krb/int-proto.h
+++ b/src/lib/krb5/krb/int-proto.h
@@ -204,19 +204,13 @@ k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
                   int *use_master);
 
 krb5_error_code
-k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
-           krb5_clpreauth_rock rock, krb5_kdc_req *req,
-           krb5_data *req_body, krb5_data *prev_req, krb5_pa_data **in_padata,
-           krb5_prompter_fct prompter, void *prompter_data,
-           krb5_boolean must_preauth, krb5_pa_data ***padata_out);
+k5_preauth(krb5_context context, krb5_init_creds_context ctx,
+           krb5_pa_data **in_padata, krb5_boolean must_preauth,
+           krb5_pa_data ***padata_out, krb5_preauthtype *pa_type_out);
 
 krb5_error_code
-k5_preauth_tryagain(krb5_context context, krb5_gic_opt_ext *opte,
-                    krb5_clpreauth_rock rock, krb5_kdc_req *req,
-                    krb5_data *req_body, krb5_data *prev_req,
-                    krb5_pa_data **in_padata, krb5_error *err_reply,
-                    krb5_pa_data **err_padata, krb5_prompter_fct prompter,
-                    void *prompter_data, krb5_pa_data ***padata_out);
+k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx,
+                    krb5_pa_data **in_padata, krb5_pa_data ***padata_out);
 
 void
 k5_init_preauth_context(krb5_context context);
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index 8d5439c..ad1618a 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -350,32 +350,33 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size,
 static krb5_enctype
 get_etype(krb5_context context, krb5_clpreauth_rock rock)
 {
-    return *rock->etype;
+    return ((krb5_init_creds_context)rock)->etype;
 }
 
 static krb5_keyblock *
 fast_armor(krb5_context context, krb5_clpreauth_rock rock)
 {
-    return rock->fast_state->armor_key;
+    return ((krb5_init_creds_context)rock)->fast_state->armor_key;
 }
 
 static krb5_error_code
 get_as_key(krb5_context context, krb5_clpreauth_rock rock,
            krb5_keyblock **keyblock)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
     krb5_error_code ret;
     krb5_data *salt;
 
-    if (rock->as_key->length == 0) {
-        salt = (*rock->default_salt) ? NULL : rock->salt;
-        ret = (*rock->gak_fct)(context, rock->client, *rock->etype,
-                               rock->prompter, rock->prompter_data, salt,
-                               rock->s2kparams, rock->as_key, *rock->gak_data,
-                               rock->rctx.items);
+    if (ctx->as_key.length == 0) {
+        salt = ctx->default_salt ? NULL : &ctx->salt;
+        ret = ctx->gak_fct(context, ctx->request->client, ctx->etype,
+                           ctx->prompter, ctx->prompter_data, salt,
+                           &ctx->s2kparams, &ctx->as_key, ctx->gak_data,
+                           ctx->rctx.items);
         if (ret)
             return ret;
     }
-    *keyblock = rock->as_key;
+    *keyblock = &ctx->as_key;
     return 0;
 }
 
@@ -383,8 +384,10 @@ static krb5_error_code
 set_as_key(krb5_context context, krb5_clpreauth_rock rock,
            const krb5_keyblock *keyblock)
 {
-    krb5_free_keyblock_contents(context, rock->as_key);
-    return krb5_copy_keyblock_contents(context, keyblock, rock->as_key);
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
+    krb5_free_keyblock_contents(context, &ctx->as_key);
+    return krb5_copy_keyblock_contents(context, keyblock, &ctx->as_key);
 }
 
 static krb5_error_code
@@ -392,11 +395,13 @@ get_preauth_time(krb5_context context, krb5_clpreauth_rock rock,
                  krb5_boolean allow_unauth_time, krb5_timestamp *time_out,
                  krb5_int32 *usec_out)
 {
-    if (rock->pa_offset_state != NO_OFFSET &&
-        (allow_unauth_time || rock->pa_offset_state == AUTH_OFFSET) &&
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
+    if (ctx->pa_offset_state != NO_OFFSET &&
+        (allow_unauth_time || ctx->pa_offset_state == AUTH_OFFSET) &&
         (context->library_options & KRB5_LIBOPT_SYNC_KDCTIME)) {
         /* Use the offset we got from the preauth-required error. */
-        return k5_time_with_offset(rock->pa_offset, rock->pa_offset_usec,
+        return k5_time_with_offset(ctx->pa_offset, ctx->pa_offset_usec,
                                    time_out, usec_out);
 
     } else {
@@ -409,10 +414,12 @@ static krb5_error_code
 responder_ask_question(krb5_context context, krb5_clpreauth_rock rock,
                        const char *question, const char *challenge)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
     /* Force plugins to use need_as_key(). */
     if (strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0)
         return EINVAL;
-    return k5_response_items_ask_question(rock->rctx.items, question,
+    return k5_response_items_ask_question(ctx->rctx.items, question,
                                           challenge);
 }
 
@@ -420,29 +427,34 @@ static const char *
 responder_get_answer(krb5_context context, krb5_clpreauth_rock rock,
                      const char *question)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
     /* Don't let plugins get the raw password. */
     if (question && strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0)
         return NULL;
-    return k5_response_items_get_answer(rock->rctx.items, question);
+    return k5_response_items_get_answer(ctx->rctx.items, question);
 }
 
 static void
 need_as_key(krb5_context context, krb5_clpreauth_rock rock)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
+
     /* Calling gac_fct() with NULL as_key indicates desire for the AS key. */
-    (*rock->gak_fct)(context, rock->client, *rock->etype, NULL, NULL, NULL,
-                     NULL, NULL, *rock->gak_data, rock->rctx.items);
+    ctx->gak_fct(context, ctx->request->client, ctx->etype, NULL, NULL, NULL,
+                 NULL, NULL, ctx->gak_data, ctx->rctx.items);
 }
 
 static const char *
 get_cc_config(krb5_context context, krb5_clpreauth_rock rock, const char *key)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
     k5_json_value value;
 
-    if (rock->cc_config_in == NULL || *rock->cc_config_in == NULL)
+    if (ctx->cc_config_in == NULL)
         return NULL;
 
-    value = k5_json_object_get(*rock->cc_config_in, key);
+    value = k5_json_object_get(ctx->cc_config_in, key);
     if (value == NULL)
         return NULL;
 
@@ -456,17 +468,18 @@ static krb5_error_code
 set_cc_config(krb5_context context, krb5_clpreauth_rock rock,
               const char *key, const char *data)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
     k5_json_value value;
     int i;
 
-    if (rock->cc_config_out == NULL || *rock->cc_config_out == NULL)
+    if (ctx->cc_config_out == NULL)
         return ENOENT;
 
     value = k5_json_string_create(data);
     if (value == NULL)
         return ENOMEM;
 
-    i = k5_json_object_set(*rock->cc_config_out, key, value);
+    i = k5_json_object_set(ctx->cc_config_out, key, value);
     k5_json_release(value);
     if (i < 0)
         return ENOMEM;
@@ -542,10 +555,10 @@ krb5_responder_set_answer(krb5_context ctx, krb5_responder_context rctx,
 /* Return true if pa_type matches the specific preauth type allowed for this
  * authentication, or if there is no specific allowed type. */
 static inline krb5_boolean
-pa_type_allowed(krb5_clpreauth_rock rock, krb5_preauthtype pa_type)
+pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type)
 {
-    return *rock->allowed_preauth_type == KRB5_PADATA_NONE ||
-        pa_type == *rock->allowed_preauth_type;
+    return ctx->allowed_preauth_type == KRB5_PADATA_NONE ||
+        pa_type == ctx->allowed_preauth_type;
 }
 
 /*
@@ -573,17 +586,15 @@ already_tried(krb5_context context, krb5_preauthtype pa_type)
     return FALSE;
 }
 
-/* Allow clpreauth modules to process in_pa_list and produce output padata.
- * Set *preauthed to true if we succeeded on a real preauth type. */
+/* Allow clpreauth modules to process in_pa_list and produce output padata. */
 static krb5_error_code
-process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
-                krb5_clpreauth_rock rock, krb5_kdc_req *req,
-                krb5_data *req_body, krb5_data *prev_req,
-                krb5_pa_data **in_pa_list, krb5_prompter_fct prompter,
-                void *prompter_data, krb5_boolean must_preauth,
-                krb5_pa_data ***out_pa_list, int *out_pa_list_size)
+process_pa_data(krb5_context context, krb5_init_creds_context ctx,
+                krb5_pa_data **in_pa_list, krb5_boolean must_preauth,
+                krb5_pa_data ***out_pa_list, int *out_pa_list_size,
+                krb5_preauthtype *out_type)
 {
     struct krb5_preauth_context_st *pctx = context->preauth_context;
+    krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte;
     struct errinfo save = EMPTY_ERRINFO;
     krb5_pa_data *pa, **pa_ptr, **mod_pa;
     krb5_error_code ret = 0;
@@ -599,7 +610,7 @@ process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
         for (pa_ptr = in_pa_list; *pa_ptr != NULL; pa_ptr++) {
             pa = *pa_ptr;
             /* Restrict real mechanisms to the chosen one if we have one. */
-            if (real && !pa_type_allowed(rock, pa->pa_type))
+            if (real && !pa_type_allowed(ctx, pa->pa_type))
                 continue;
             h = find_module(pctx->handles, pa->pa_type);
             if (h == NULL)
@@ -611,9 +622,12 @@ process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
             if (real && already_tried(context, pa->pa_type))
                 continue;
             mod_pa = NULL;
-            ret = clpreauth_process(context, h, opt, &callbacks, rock, req,
-                                    req_body, prev_req, pa, prompter,
-                                    prompter_data, &mod_pa);
+            ret = clpreauth_process(context, h, opt, &callbacks,
+                                    (krb5_clpreauth_rock)ctx, ctx->request,
+                                    ctx->inner_request_body,
+                                    ctx->encoded_previous_request, pa,
+                                    ctx->prompter, ctx->prompter_data,
+                                    &mod_pa);
             TRACE_PREAUTH_PROCESS(context, h->vt.name, pa->pa_type, real,
                                   ret);
             if (mod_pa != NULL) {
@@ -627,8 +641,7 @@ process_pa_data(krb5_context context, krb5_get_init_creds_opt *opt,
             }
             if (ret == 0 && real) {
                 /* Stop now and record which real padata type we answered. */
-                if (rock->selected_preauth_type != NULL)
-                    *rock->selected_preauth_type = pa->pa_type;
+                *out_type = pa->pa_type;
                 goto cleanup;
             } else if (real && save.code == 0) {
                 /* Save the first error we get from a real preauth type. */
@@ -660,8 +673,8 @@ padata2data(krb5_pa_data p)
 
 /* Set salt in rock based on pw-salt or afs3-salt elements in padata. */
 static krb5_error_code
-get_salt(krb5_context context, krb5_pa_data **padata,
-         krb5_kdc_req *request, krb5_clpreauth_rock rock)
+get_salt(krb5_context context, krb5_init_creds_context ctx,
+         krb5_pa_data **padata)
 {
     krb5_error_code ret;
     krb5_pa_data *pa;
@@ -675,40 +688,40 @@ get_salt(krb5_context context, krb5_pa_data **padata,
     if (pa == NULL)
         return 0;
 
-    /* Set rock->salt based on the element we found. */
-    krb5_free_data_contents(context, rock->salt);
+    /* Set ctx->salt based on the element we found. */
+    krb5_free_data_contents(context, &ctx->salt);
     d = padata2data(*pa);
-    ret = krb5int_copy_data_contents(context, &d, rock->salt);
+    ret = krb5int_copy_data_contents(context, &d, &ctx->salt);
     if (ret)
         return ret;
 
     /* Adjust the salt if we got it from an afs3-salt element. */
     if (pa->pa_type == KRB5_PADATA_AFS3_SALT) {
         /* Work around a (possible) old Heimdal KDC foible. */
-        p = memchr(rock->salt->data, '@', rock->salt->length);
+        p = memchr(ctx->salt.data, '@', ctx->salt.length);
         if (p != NULL)
-            rock->salt->length = p - rock->salt->data;
+            ctx->salt.length = p - ctx->salt.data;
         /* Tolerate extra null in MIT KDC afs3-salt value. */
-        if (rock->salt->length > 0 &&
-            rock->salt->data[rock->salt->length - 1] == '\0')
-            rock->salt->length--;
+        if (ctx->salt.length > 0 &&
+            ctx->salt.data[ctx->salt.length - 1] == '\0')
+            ctx->salt.length--;
         /* Set an s2kparams value to indicate AFS string-to-key. */
-        krb5_free_data_contents(context, rock->s2kparams);
-        ret = alloc_data(rock->s2kparams, 1);
+        krb5_free_data_contents(context, &ctx->s2kparams);
+        ret = alloc_data(&ctx->s2kparams, 1);
         if (ret)
             return ret;
-        rock->s2kparams->data[0] = '\1';
+        ctx->s2kparams.data[0] = '\1';
     }
 
-    *rock->default_salt = FALSE;
-    TRACE_PREAUTH_SALT(context, rock->salt, pa->pa_type);
+    ctx->default_salt = FALSE;
+    TRACE_PREAUTH_SALT(context, &ctx->salt, pa->pa_type);
     return 0;
 }
 
 /* Set etype info parameters in rock based on padata. */
 static krb5_error_code
-get_etype_info(krb5_context context, krb5_pa_data **padata,
-               krb5_kdc_req *request, krb5_clpreauth_rock rock)
+get_etype_info(krb5_context context, krb5_init_creds_context ctx,
+               krb5_pa_data **padata)
 {
     krb5_error_code ret = 0;
     krb5_pa_data *pa;
@@ -733,14 +746,14 @@ get_etype_info(krb5_context context, krb5_pa_data **padata,
 
     /* Fall back to pw-salt/afs3-salt if no etype-info element is present. */
     if (etype_info == NULL)
-        return get_salt(context, padata, request, rock);
+        return get_salt(context, ctx, padata);
 
     /* Search entries in order of the request's enctype preference. */
     entry = NULL;
     valid_found = FALSE;
-    for (i = 0; i < request->nktypes && entry == NULL; i++) {
+    for (i = 0; i < ctx->request->nktypes && entry == NULL; i++) {
         for (e = etype_info; *e != NULL && entry == NULL; e++) {
-            if ((*e)->etype == request->ktype[i])
+            if ((*e)->etype == ctx->request->ktype[i])
                 entry = *e;
             if (krb5_c_valid_enctype((*e)->etype))
                 valid_found = TRUE;
@@ -752,22 +765,21 @@ get_etype_info(krb5_context context, krb5_pa_data **padata,
         goto cleanup;
     }
 
-    /* Set rock fields based on the entry we selected. */
-    *rock->etype = entry->etype;
-    krb5_free_data_contents(context, rock->salt);
+    /* Set etype/salt/s2kparams fields based on the entry we selected. */
+    ctx->etype = entry->etype;
+    krb5_free_data_contents(context, &ctx->salt);
     if (entry->length != KRB5_ETYPE_NO_SALT) {
-        *rock->salt = make_data(entry->salt, entry->length);
+        ctx->salt = make_data(entry->salt, entry->length);
         entry->salt = NULL;
-        *rock->default_salt = FALSE;
+        ctx->default_salt = FALSE;
     } else {
-        *rock->salt = empty_data();
-        *rock->default_salt = TRUE;
+        ctx->salt = empty_data();
+        ctx->default_salt = TRUE;
     }
-    krb5_free_data_contents(context, rock->s2kparams);
-    *rock->s2kparams = entry->s2kparams;
+    krb5_free_data_contents(context, &ctx->s2kparams);
+    ctx->s2kparams = entry->s2kparams;
     entry->s2kparams = empty_data();
-    TRACE_PREAUTH_ETYPE_INFO(context, *rock->etype, rock->salt,
-                             rock->s2kparams);
+    TRACE_PREAUTH_ETYPE_INFO(context, ctx->etype, &ctx->salt, &ctx->s2kparams);
 
 cleanup:
     krb5_free_etype_info(context, etype_info);
@@ -854,17 +866,13 @@ add_s4u_x509_user_padata(krb5_context context, krb5_s4u_userid *userid,
  * ask the user another question, we let the calling application deal with it.
  */
 krb5_error_code
-k5_preauth_tryagain(krb5_context context, krb5_gic_opt_ext *opte,
-                    krb5_clpreauth_rock rock, krb5_kdc_req *req,
-                    krb5_data *req_body, krb5_data *prev_req,
-                    krb5_pa_data **in_padata, krb5_error *err_reply,
-                    krb5_pa_data **err_padata, krb5_prompter_fct prompter,
-                    void *prompter_data, krb5_pa_data ***padata_out)
+k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx,
+                    krb5_pa_data **in_padata, krb5_pa_data ***padata_out)
 {
     struct krb5_preauth_context_st *pctx = context->preauth_context;
     krb5_error_code ret;
     krb5_pa_data **mod_pa;
-    krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)opte;
+    krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte;
     clpreauth_handle h;
     int i;
 
@@ -879,10 +887,13 @@ k5_preauth_tryagain(krb5_context context, krb5_gic_opt_ext *opte,
         if (h == NULL)
             continue;
         mod_pa = NULL;
-        ret = clpreauth_tryagain(context, h, opt, &callbacks, rock, req,
-                                 req_body, prev_req, in_padata[i]->pa_type,
-                                 err_reply, err_padata, prompter,
-                                 prompter_data, &mod_pa);
+        ret = clpreauth_tryagain(context, h, opt, &callbacks,
+                                 (krb5_clpreauth_rock)ctx, ctx->request,
+                                 ctx->inner_request_body,
+                                 ctx->encoded_previous_request,
+                                 in_padata[i]->pa_type,
+                                 ctx->err_reply, ctx->err_padata,
+                                 ctx->prompter, ctx->prompter_data, &mod_pa);
         if (ret == 0 && mod_pa != NULL) {
             TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa);
             *padata_out = mod_pa;
@@ -895,27 +906,28 @@ k5_preauth_tryagain(krb5_context context, krb5_gic_opt_ext *opte,
 /* Compile the set of response items for in_padata by invoke each module's
  * prep_questions method. */
 static krb5_error_code
-fill_response_items(krb5_context context, krb5_get_init_creds_opt *opt,
-                    krb5_clpreauth_rock rock, krb5_kdc_req *req,
-                    krb5_data *req_body, krb5_data *prev_req,
+fill_response_items(krb5_context context, krb5_init_creds_context ctx,
                     krb5_pa_data **in_padata)
 {
     struct krb5_preauth_context_st *pctx = context->preauth_context;
+    krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)ctx->opte;
     krb5_error_code ret;
     krb5_pa_data *pa;
     clpreauth_handle h;
     int i;
 
-    k5_response_items_reset(rock->rctx.items);
+    k5_response_items_reset(ctx->rctx.items);
     for (i = 0; in_padata[i] != NULL; i++) {
         pa = in_padata[i];
-        if (!pa_type_allowed(rock, pa->pa_type))
+        if (!pa_type_allowed(ctx, pa->pa_type))
             continue;
         h = find_module(pctx->handles, pa->pa_type);
         if (h == NULL)
             continue;
-        ret = clpreauth_prep_questions(context, h, opt, &callbacks, rock, req,
-                                       req_body, prev_req, pa);
+        ret = clpreauth_prep_questions(context, h, opt, &callbacks,
+                                       (krb5_clpreauth_rock)ctx,
+                                       ctx->request, ctx->inner_request_body,
+                                       ctx->encoded_previous_request, pa);
         if (ret)
             return ret;
     }
@@ -923,19 +935,18 @@ fill_response_items(krb5_context context, krb5_get_init_creds_opt *opt,
 }
 
 krb5_error_code
-k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
-           krb5_clpreauth_rock rock, krb5_kdc_req *req,
-           krb5_data *req_body, krb5_data *prev_req, krb5_pa_data **in_padata,
-           krb5_prompter_fct prompter, void *prompter_data,
-           krb5_boolean must_preauth, krb5_pa_data ***padata_out)
+k5_preauth(krb5_context context, krb5_init_creds_context ctx,
+           krb5_pa_data **in_padata, krb5_boolean must_preauth,
+           krb5_pa_data ***padata_out, krb5_preauthtype *pa_type_out)
 {
     int out_pa_list_size = 0;
     krb5_pa_data **out_pa_list = NULL;
     krb5_error_code ret;
-    krb5_responder_fn responder = opte->opt_private->responder;
-    krb5_get_init_creds_opt *opt = (krb5_get_init_creds_opt *)opte;
+    krb5_responder_fn responder = ctx->opte->opt_private->responder;
+    void *responder_data = ctx->opte->opt_private->responder_data;
 
     *padata_out = NULL;
+    *pa_type_out = KRB5_PADATA_NONE;
 
     if (in_padata == NULL)
         return 0;
@@ -943,7 +954,7 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
     TRACE_PREAUTH_INPUT(context, in_padata);
 
     /* Scan the padata list and process etype-info or salt elements. */
-    ret = get_etype_info(context, in_padata, req, rock);
+    ret = get_etype_info(context, ctx, in_padata);
     if (ret)
         return ret;
 
@@ -955,7 +966,8 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
     if (krb5int_find_pa_data(context, in_padata,
                              KRB5_PADATA_S4U_X509_USER) != NULL) {
         /* Fulfill a private contract with krb5_get_credentials_for_user. */
-        ret = add_s4u_x509_user_padata(context, *rock->gak_data, req->client,
+        ret = add_s4u_x509_user_padata(context, ctx->gak_data,
+                                       ctx->request->client,
                                        &out_pa_list, &out_pa_list_size);
         if (ret)
             goto error;
@@ -970,22 +982,19 @@ k5_preauth(krb5_context context, krb5_gic_opt_ext *opte,
     }
 
     /* Get a list of response items for in_padata from the preauth modules. */
-    ret = fill_response_items(context, opt, rock, req, req_body, prev_req,
-                              in_padata);
+    ret = fill_response_items(context, ctx, in_padata);
     if (ret)
         goto error;
 
     /* Call the responder to answer response items. */
-    if (responder != NULL && !k5_response_items_empty(rock->rctx.items)) {
-        ret = (*responder)(context, opte->opt_private->responder_data,
-                           &rock->rctx);
+    if (responder != NULL && !k5_response_items_empty(ctx->rctx.items)) {
+        ret = (*responder)(context, responder_data, &ctx->rctx);
         if (ret)
             goto error;
     }
 
-    ret = process_pa_data(context, opt, rock, req, req_body, prev_req,
-                          in_padata, prompter, prompter_data, must_preauth,
-                          &out_pa_list, &out_pa_list_size);
+    ret = process_pa_data(context, ctx, in_padata, must_preauth,
+                          &out_pa_list, &out_pa_list_size, pa_type_out);
     if (ret)
         goto error;
 
diff --git a/src/lib/krb5/krb/preauth_sam2.c b/src/lib/krb5/krb/preauth_sam2.c
index c52564e..e6e2c68 100644
--- a/src/lib/krb5/krb/preauth_sam2.c
+++ b/src/lib/krb5/krb/preauth_sam2.c
@@ -84,6 +84,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
              krb5_prompter_fct prompter, void *prompter_data,
              krb5_pa_data ***out_padata)
 {
+    krb5_init_creds_context ctx = (krb5_init_creds_context)rock;
     krb5_error_code retval;
     krb5_sam_challenge_2 *sc2 = NULL;
     krb5_sam_challenge_2_body *sc2b = NULL;
@@ -147,11 +148,11 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
         /* Go ahead and get it now, preserving the ordering of  */
         /* prompts for the user.                                */
 
-        salt = (*rock->default_salt) ? NULL : rock->salt;
-        retval = (*rock->gak_fct)(context, request->client, sc2b->sam_etype,
-                                  prompter, prompter_data, rock->salt,
-                                  rock->s2kparams, rock->as_key,
-                                  *rock->gak_data, rock->rctx.items);
+        salt = ctx->default_salt ? NULL : &ctx->salt;
+        retval = ctx->gak_fct(context, request->client, sc2b->sam_etype,
+                              prompter, prompter_data, &ctx->salt,
+                              &ctx->s2kparams, &ctx->as_key,
+                              ctx->gak_data, ctx->rctx.items);
         if (retval) {
             krb5_free_sam_challenge_2(context, sc2);
             krb5_free_sam_challenge_2_body(context, sc2b);
@@ -194,7 +195,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
     krb5int_set_prompt_types(context, (krb5_prompt_type *)NULL);
 
     /* Generate salt used by string_to_key() */
-    if (*rock->default_salt) {
+    if (ctx->default_salt) {
         if ((retval =
              krb5_principal2salt(context, request->client, &defsalt))) {
             krb5_free_sam_challenge_2(context, sc2);
@@ -203,7 +204,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
         }
         salt = &defsalt;
     } else {
-        salt = rock->salt;
+        salt = &ctx->salt;
         defsalt.length = 0;
     }
 
@@ -211,15 +212,15 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
     if (!(sc2b->sam_flags & KRB5_SAM_USE_SAD_AS_KEY)) {
         /* as_key = string_to_key(password) */
 
-        if (rock->as_key->length) {
-            krb5_free_keyblock_contents(context, rock->as_key);
-            rock->as_key->length = 0;
+        if (ctx->as_key.length) {
+            krb5_free_keyblock_contents(context, &ctx->as_key);
+            ctx->as_key.length = 0;
         }
 
         /* generate a key using the supplied password */
         retval = krb5_c_string_to_key(context, sc2b->sam_etype,
-                                      (krb5_data *)*rock->gak_data, salt,
-                                      rock->as_key);
+                                      (krb5_data *)ctx->gak_data, salt,
+                                      &ctx->as_key);
 
         if (retval) {
             krb5_free_sam_challenge_2(context, sc2);
@@ -244,8 +245,8 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
 
             /* This should be a call to the crypto library some day */
             /* key types should already match the sam_etype */
-            retval = krb5int_c_combine_keys(context, rock->as_key, &tmp_kb,
-                                            rock->as_key);
+            retval = krb5int_c_combine_keys(context, &ctx->as_key, &tmp_kb,
+                                            &ctx->as_key);
 
             if (retval) {
                 krb5_free_sam_challenge_2(context, sc2);
@@ -262,14 +263,14 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
     } else {
         /* as_key = string_to_key(SAD) */
 
-        if (rock->as_key->length) {
-            krb5_free_keyblock_contents(context, rock->as_key);
-            rock->as_key->length = 0;
+        if (ctx->as_key.length) {
+            krb5_free_keyblock_contents(context, &ctx->as_key);
+            ctx->as_key.length = 0;
         }
 
         /* generate a key using the supplied password */
         retval = krb5_c_string_to_key(context, sc2b->sam_etype,
-                                      &response_data, salt, rock->as_key);
+                                      &response_data, salt, &ctx->as_key);
 
         if (defsalt.length)
             free(defsalt.data);
@@ -289,7 +290,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
         if (!krb5_c_is_keyed_cksum((*cksum)->checksum_type))
             continue;
         /* Check this cksum */
-        retval = krb5_c_verify_checksum(context, rock->as_key,
+        retval = krb5_c_verify_checksum(context, &ctx->as_key,
                                         KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
                                         &sc2->sam_challenge_2_body,
                                         *cksum, &valid_cksum);
@@ -343,7 +344,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
     /* Now take care of sr2.sam_enc_nonce_or_sad by encrypting encoded   */
     /* enc_sam_response_enc_2 from above */
 
-    retval = krb5_c_encrypt_length(context, rock->as_key->enctype,
+    retval = krb5_c_encrypt_length(context, ctx->as_key.enctype,
                                    scratch->length, &ciph_len);
     if (retval) {
         krb5_free_sam_challenge_2(context, sc2);
@@ -363,7 +364,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
         return(ENOMEM);
     }
 
-    retval = krb5_c_encrypt(context, rock->as_key,
+    retval = krb5_c_encrypt(context, &ctx->as_key,
                             KRB5_KEYUSAGE_PA_SAM_RESPONSE, NULL, scratch,
                             &sr2.sam_enc_nonce_or_sad);
     if (retval) {


More information about the cvs-krb5 mailing list