|
|
d738b9 |
From b3472e687181719dec6561c96aca6036b34865a5 Mon Sep 17 00:00:00 2001
|
|
|
d738b9 |
From: Greg Hudson <ghudson@mit.edu>
|
|
|
d738b9 |
Date: Tue, 20 Dec 2016 16:06:24 -0500
|
|
|
d738b9 |
Subject: [PATCH] Properly scope per-request preauth data
|
|
|
d738b9 |
|
|
|
d738b9 |
It should be possible to successfully use multiple initial credentials
|
|
|
d738b9 |
contexts with the same library context. Create a new internal type
|
|
|
d738b9 |
krb5_preauth_req_context containing per-request preauth state,
|
|
|
d738b9 |
including the clpreauth modreq handles and the list of preauth types
|
|
|
d738b9 |
already tried. Remove this state from clpreauth_handle and
|
|
|
d738b9 |
krb5_preauth_context.
|
|
|
d738b9 |
|
|
|
d738b9 |
ticket: 7877
|
|
|
d738b9 |
(cherry picked from commit b061f419cfc9653b7549b905e54fbbd78deea49e)
|
|
|
d738b9 |
---
|
|
|
d738b9 |
src/include/k5-trace.h | 3 +
|
|
|
d738b9 |
src/lib/krb5/krb/get_in_tkt.c | 12 +-
|
|
|
d738b9 |
src/lib/krb5/krb/init_creds_ctx.h | 3 +
|
|
|
d738b9 |
src/lib/krb5/krb/int-proto.h | 8 +-
|
|
|
d738b9 |
src/lib/krb5/krb/preauth2.c | 190 +++++++++++++++++++-----------
|
|
|
d738b9 |
5 files changed, 135 insertions(+), 81 deletions(-)
|
|
|
d738b9 |
|
|
|
d738b9 |
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
|
|
|
d738b9 |
index 2885408a2..f44f162d3 100644
|
|
|
d738b9 |
--- a/src/include/k5-trace.h
|
|
|
d738b9 |
+++ b/src/include/k5-trace.h
|
|
|
d738b9 |
@@ -291,6 +291,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
|
|
|
d738b9 |
TRACE(c, "Preauth tryagain input types: {patypes}", padata)
|
|
|
d738b9 |
#define TRACE_PREAUTH_TRYAGAIN_OUTPUT(c, padata) \
|
|
|
d738b9 |
TRACE(c, "Followup preauth for next request: {patypes}", padata)
|
|
|
d738b9 |
+#define TRACE_PREAUTH_WRONG_CONTEXT(c) \
|
|
|
d738b9 |
+ TRACE(c, "Wrong context passed to krb5_init_creds_free(); leaking " \
|
|
|
d738b9 |
+ "modreq objects")
|
|
|
d738b9 |
|
|
|
d738b9 |
#define TRACE_PROFILE_ERR(c,subsection, section, retval) \
|
|
|
d738b9 |
TRACE(c, "Bad value of {str} from [{str}] in conf file: {kerr}", \
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
index ed15550f0..80f5e1870 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
@@ -565,7 +565,7 @@ krb5_init_creds_free(krb5_context context,
|
|
|
d738b9 |
k5_response_items_free(ctx->rctx.items);
|
|
|
d738b9 |
free(ctx->in_tkt_service);
|
|
|
d738b9 |
zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length);
|
|
|
d738b9 |
- k5_preauth_request_context_fini(context);
|
|
|
d738b9 |
+ k5_preauth_request_context_fini(context, ctx);
|
|
|
d738b9 |
krb5_free_error(context, ctx->err_reply);
|
|
|
d738b9 |
krb5_free_pa_data(context, ctx->err_padata);
|
|
|
d738b9 |
krb5_free_cred_contents(context, &ctx->cred);
|
|
|
d738b9 |
@@ -816,8 +816,8 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
if (fast_upgrade)
|
|
|
d738b9 |
ctx->fast_state->fast_state_flags |= KRB5INT_FAST_DO_FAST;
|
|
|
d738b9 |
|
|
|
d738b9 |
- k5_preauth_request_context_fini(context);
|
|
|
d738b9 |
- k5_preauth_request_context_init(context);
|
|
|
d738b9 |
+ k5_preauth_request_context_fini(context, ctx);
|
|
|
d738b9 |
+ k5_preauth_request_context_init(context, ctx);
|
|
|
d738b9 |
krb5_free_data(context, ctx->outer_request_body);
|
|
|
d738b9 |
ctx->outer_request_body = NULL;
|
|
|
d738b9 |
if (ctx->opt->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) {
|
|
|
d738b9 |
@@ -1504,7 +1504,7 @@ init_creds_step_reply(krb5_context context,
|
|
|
d738b9 |
} else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED ||
|
|
|
d738b9 |
reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) {
|
|
|
d738b9 |
/* reset the list of preauth types to try */
|
|
|
d738b9 |
- k5_reset_preauth_types_tried(context);
|
|
|
d738b9 |
+ k5_reset_preauth_types_tried(ctx);
|
|
|
d738b9 |
krb5_free_pa_data(context, ctx->preauth_to_use);
|
|
|
d738b9 |
ctx->preauth_to_use = ctx->err_padata;
|
|
|
d738b9 |
ctx->err_padata = NULL;
|
|
|
d738b9 |
@@ -1555,7 +1555,7 @@ init_creds_step_reply(krb5_context context,
|
|
|
d738b9 |
goto cleanup;
|
|
|
d738b9 |
|
|
|
d738b9 |
/* process any preauth data in the as_reply */
|
|
|
d738b9 |
- k5_reset_preauth_types_tried(context);
|
|
|
d738b9 |
+ k5_reset_preauth_types_tried(ctx);
|
|
|
d738b9 |
code = krb5int_fast_process_response(context, ctx->fast_state,
|
|
|
d738b9 |
ctx->reply, &strengthen_key);
|
|
|
d738b9 |
if (code != 0)
|
|
|
d738b9 |
@@ -1640,7 +1640,7 @@ init_creds_step_reply(krb5_context context,
|
|
|
d738b9 |
k5_prependmsg(context, code, _("Failed to store credentials"));
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
- k5_preauth_request_context_fini(context);
|
|
|
d738b9 |
+ k5_preauth_request_context_fini(context, ctx);
|
|
|
d738b9 |
|
|
|
d738b9 |
/* success */
|
|
|
d738b9 |
ctx->complete = TRUE;
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
|
|
|
d738b9 |
index 38c01c775..a7cded942 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/init_creds_ctx.h
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/init_creds_ctx.h
|
|
|
d738b9 |
@@ -6,6 +6,8 @@
|
|
|
d738b9 |
#include "k5-json.h"
|
|
|
d738b9 |
#include "int-proto.h"
|
|
|
d738b9 |
|
|
|
d738b9 |
+typedef struct krb5_preauth_req_context_st *krb5_preauth_req_context;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
struct krb5_responder_context_st {
|
|
|
d738b9 |
k5_response_items *items;
|
|
|
d738b9 |
};
|
|
|
d738b9 |
@@ -67,6 +69,7 @@ struct _krb5_init_creds_context {
|
|
|
d738b9 |
krb5_timestamp pa_offset;
|
|
|
d738b9 |
krb5_int32 pa_offset_usec;
|
|
|
d738b9 |
enum { NO_OFFSET = 0, UNAUTH_OFFSET, AUTH_OFFSET } pa_offset_state;
|
|
|
d738b9 |
+ krb5_preauth_req_context preauth_reqctx;
|
|
|
d738b9 |
};
|
|
|
d738b9 |
|
|
|
d738b9 |
krb5_error_code
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
index 9c746d05b..f1667c238 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
@@ -194,17 +194,19 @@ void
|
|
|
d738b9 |
k5_free_preauth_context(krb5_context context);
|
|
|
d738b9 |
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_reset_preauth_types_tried(krb5_context context);
|
|
|
d738b9 |
+k5_reset_preauth_types_tried(krb5_init_creds_context ctx);
|
|
|
d738b9 |
|
|
|
d738b9 |
void
|
|
|
d738b9 |
k5_preauth_prepare_request(krb5_context context, krb5_get_init_creds_opt *opt,
|
|
|
d738b9 |
krb5_kdc_req *request);
|
|
|
d738b9 |
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_preauth_request_context_init(krb5_context context);
|
|
|
d738b9 |
+k5_preauth_request_context_init(krb5_context context,
|
|
|
d738b9 |
+ krb5_init_creds_context ctx);
|
|
|
d738b9 |
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_preauth_request_context_fini(krb5_context context);
|
|
|
d738b9 |
+k5_preauth_request_context_fini(krb5_context context,
|
|
|
d738b9 |
+ krb5_init_creds_context ctx);
|
|
|
d738b9 |
|
|
|
d738b9 |
krb5_error_code
|
|
|
d738b9 |
k5_response_items_new(k5_response_items **ri_out);
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
index b04d14829..9a178f4e3 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
@@ -46,14 +46,18 @@
|
|
|
d738b9 |
typedef struct {
|
|
|
d738b9 |
struct krb5_clpreauth_vtable_st vt;
|
|
|
d738b9 |
krb5_clpreauth_moddata data;
|
|
|
d738b9 |
- krb5_clpreauth_modreq req;
|
|
|
d738b9 |
} *clpreauth_handle;
|
|
|
d738b9 |
|
|
|
d738b9 |
struct krb5_preauth_context_st {
|
|
|
d738b9 |
- krb5_preauthtype *tried;
|
|
|
d738b9 |
clpreauth_handle *handles;
|
|
|
d738b9 |
};
|
|
|
d738b9 |
|
|
|
d738b9 |
+struct krb5_preauth_req_context_st {
|
|
|
d738b9 |
+ krb5_context orig_context;
|
|
|
d738b9 |
+ krb5_preauthtype *tried;
|
|
|
d738b9 |
+ krb5_clpreauth_modreq *modreqs;
|
|
|
d738b9 |
+};
|
|
|
d738b9 |
+
|
|
|
d738b9 |
/* Release the memory used by a list of handles. */
|
|
|
d738b9 |
static void
|
|
|
d738b9 |
free_handles(krb5_context context, clpreauth_handle *handles)
|
|
|
d738b9 |
@@ -71,21 +75,44 @@ free_handles(krb5_context context, clpreauth_handle *handles)
|
|
|
d738b9 |
free(handles);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
-/* Find the handle in handles which can process pa_type. */
|
|
|
d738b9 |
-static clpreauth_handle
|
|
|
d738b9 |
-find_module(clpreauth_handle *handles, krb5_preauthtype pa_type)
|
|
|
d738b9 |
+/* Return an index into handles which can process pa_type, or -1 if none is
|
|
|
d738b9 |
+ * found found. */
|
|
|
d738b9 |
+static int
|
|
|
d738b9 |
+search_module_list(clpreauth_handle *handles, krb5_preauthtype pa_type)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- clpreauth_handle *hp, h;
|
|
|
d738b9 |
- krb5_preauthtype *tp;
|
|
|
d738b9 |
+ clpreauth_handle h;
|
|
|
d738b9 |
+ int i, j;
|
|
|
d738b9 |
|
|
|
d738b9 |
- for (hp = handles; *hp != NULL; hp++) {
|
|
|
d738b9 |
- h = *hp;
|
|
|
d738b9 |
- for (tp = h->vt.pa_type_list; *tp != 0; tp++) {
|
|
|
d738b9 |
- if (*tp == pa_type)
|
|
|
d738b9 |
- return h;
|
|
|
d738b9 |
+ for (i = 0; handles[i] != NULL; i++) {
|
|
|
d738b9 |
+ h = handles[i];
|
|
|
d738b9 |
+ for (j = 0; h->vt.pa_type_list[j] != 0; j++) {
|
|
|
d738b9 |
+ if (h->vt.pa_type_list[j] == pa_type)
|
|
|
d738b9 |
+ return i;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
}
|
|
|
d738b9 |
- return FALSE;
|
|
|
d738b9 |
+ return -1;
|
|
|
d738b9 |
+}
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+/* Find the handle which can process pa_type, or NULL if none is found. On
|
|
|
d738b9 |
+ * success, set *modreq_out to the corresponding per-request module data. */
|
|
|
d738b9 |
+static clpreauth_handle
|
|
|
d738b9 |
+find_module(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
+ krb5_preauthtype pa_type, krb5_clpreauth_modreq *modreq_out)
|
|
|
d738b9 |
+{
|
|
|
d738b9 |
+ krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
+ krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
|
|
|
d738b9 |
+ int i;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ *modreq_out = NULL;
|
|
|
d738b9 |
+ if (pctx == NULL || reqctx == NULL)
|
|
|
d738b9 |
+ return NULL;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ i = search_module_list(pctx->handles, pa_type);
|
|
|
d738b9 |
+ if (i == -1)
|
|
|
d738b9 |
+ return NULL;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ *modreq_out = reqctx->modreqs[i];
|
|
|
d738b9 |
+ return pctx->handles[i];
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
/* Initialize the preauth state for a krb5 context. */
|
|
|
d738b9 |
@@ -93,7 +120,8 @@ void
|
|
|
d738b9 |
k5_init_preauth_context(krb5_context context)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
krb5_plugin_initvt_fn *modules = NULL, *mod;
|
|
|
d738b9 |
- clpreauth_handle *list = NULL, h, h2;
|
|
|
d738b9 |
+ clpreauth_handle *list = NULL, h;
|
|
|
d738b9 |
+ int i;
|
|
|
d738b9 |
size_t count;
|
|
|
d738b9 |
krb5_preauthtype *tp;
|
|
|
d738b9 |
|
|
|
d738b9 |
@@ -140,9 +168,10 @@ k5_init_preauth_context(krb5_context context)
|
|
|
d738b9 |
|
|
|
d738b9 |
/* Check for a preauth type conflict with an existing module. */
|
|
|
d738b9 |
for (tp = h->vt.pa_type_list; *tp != 0; tp++) {
|
|
|
d738b9 |
- h2 = find_module(list, *tp);
|
|
|
d738b9 |
- if (h2 != NULL) {
|
|
|
d738b9 |
- TRACE_PREAUTH_CONFLICT(context, h->vt.name, h2->vt.name, *tp);
|
|
|
d738b9 |
+ i = search_module_list(list, *tp);
|
|
|
d738b9 |
+ if (i != -1) {
|
|
|
d738b9 |
+ TRACE_PREAUTH_CONFLICT(context, h->vt.name, list[i]->vt.name,
|
|
|
d738b9 |
+ *tp);
|
|
|
d738b9 |
break;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
}
|
|
|
d738b9 |
@@ -164,7 +193,6 @@ k5_init_preauth_context(krb5_context context)
|
|
|
d738b9 |
context->preauth_context = malloc(sizeof(*context->preauth_context));
|
|
|
d738b9 |
if (context->preauth_context == NULL)
|
|
|
d738b9 |
goto cleanup;
|
|
|
d738b9 |
- context->preauth_context->tried = NULL;
|
|
|
d738b9 |
context->preauth_context->handles = list;
|
|
|
d738b9 |
list = NULL;
|
|
|
d738b9 |
|
|
|
d738b9 |
@@ -179,14 +207,14 @@ cleanup:
|
|
|
d738b9 |
* AS-REP).
|
|
|
d738b9 |
*/
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_reset_preauth_types_tried(krb5_context context)
|
|
|
d738b9 |
+k5_reset_preauth_types_tried(krb5_init_creds_context ctx)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
+ krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
|
|
|
d738b9 |
|
|
|
d738b9 |
- if (pctx == NULL)
|
|
|
d738b9 |
+ if (reqctx == NULL)
|
|
|
d738b9 |
return;
|
|
|
d738b9 |
- free(pctx->tried);
|
|
|
d738b9 |
- pctx->tried = NULL;
|
|
|
d738b9 |
+ free(reqctx->tried);
|
|
|
d738b9 |
+ reqctx->tried = NULL;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
|
|
|
d738b9 |
@@ -200,7 +228,6 @@ k5_free_preauth_context(krb5_context context)
|
|
|
d738b9 |
|
|
|
d738b9 |
if (pctx == NULL)
|
|
|
d738b9 |
return;
|
|
|
d738b9 |
- free(pctx->tried);
|
|
|
d738b9 |
free_handles(context, pctx->handles);
|
|
|
d738b9 |
free(pctx);
|
|
|
d738b9 |
context->preauth_context = NULL;
|
|
|
d738b9 |
@@ -209,10 +236,13 @@ k5_free_preauth_context(krb5_context context)
|
|
|
d738b9 |
/* Initialize the per-AS-REQ context. This means calling the client_req_init
|
|
|
d738b9 |
* function to give the plugin a chance to allocate a per-request context. */
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_preauth_request_context_init(krb5_context context)
|
|
|
d738b9 |
+k5_preauth_request_context_init(krb5_context context,
|
|
|
d738b9 |
+ krb5_init_creds_context ctx)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
- clpreauth_handle *hp, h;
|
|
|
d738b9 |
+ clpreauth_handle h;
|
|
|
d738b9 |
+ krb5_preauth_req_context reqctx;
|
|
|
d738b9 |
+ size_t count, i;
|
|
|
d738b9 |
|
|
|
d738b9 |
if (pctx == NULL) {
|
|
|
d738b9 |
k5_init_preauth_context(context);
|
|
|
d738b9 |
@@ -220,30 +250,50 @@ k5_preauth_request_context_init(krb5_context context)
|
|
|
d738b9 |
if (pctx == NULL)
|
|
|
d738b9 |
return;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
- k5_reset_preauth_types_tried(context);
|
|
|
d738b9 |
- for (hp = pctx->handles; *hp != NULL; hp++) {
|
|
|
d738b9 |
- h = *hp;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ reqctx = calloc(1, sizeof(*reqctx));
|
|
|
d738b9 |
+ if (reqctx == NULL)
|
|
|
d738b9 |
+ return;
|
|
|
d738b9 |
+ reqctx->orig_context = context;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ /* Create an array of per-request module data objects corresponding to the
|
|
|
d738b9 |
+ * preauth context's array of handles. */
|
|
|
d738b9 |
+ for (count = 0; pctx->handles[count] != NULL; count++);
|
|
|
d738b9 |
+ reqctx->modreqs = calloc(count, sizeof(*reqctx->modreqs));
|
|
|
d738b9 |
+ for (i = 0; i < count; i++) {
|
|
|
d738b9 |
+ h = pctx->handles[i];
|
|
|
d738b9 |
if (h->vt.request_init != NULL)
|
|
|
d738b9 |
- h->vt.request_init(context, h->data, &h->req);
|
|
|
d738b9 |
+ h->vt.request_init(context, h->data, &reqctx->modreqs[i]);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
+ ctx->preauth_reqctx = reqctx;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
/* Free the per-AS-REQ context. This means clearing any request-specific
|
|
|
d738b9 |
* context which the plugin may have created. */
|
|
|
d738b9 |
void
|
|
|
d738b9 |
-k5_preauth_request_context_fini(krb5_context context)
|
|
|
d738b9 |
+k5_preauth_request_context_fini(krb5_context context,
|
|
|
d738b9 |
+ krb5_init_creds_context ctx)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
- clpreauth_handle *hp, h;
|
|
|
d738b9 |
+ krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
|
|
|
d738b9 |
+ size_t i;
|
|
|
d738b9 |
+ clpreauth_handle h;
|
|
|
d738b9 |
|
|
|
d738b9 |
- if (pctx == NULL)
|
|
|
d738b9 |
+ if (reqctx == NULL)
|
|
|
d738b9 |
return;
|
|
|
d738b9 |
- for (hp = pctx->handles; *hp != NULL; hp++) {
|
|
|
d738b9 |
- h = *hp;
|
|
|
d738b9 |
- if (h->req != NULL && h->vt.request_fini != NULL)
|
|
|
d738b9 |
- h->vt.request_fini(context, h->data, h->req);
|
|
|
d738b9 |
- h->req = NULL;
|
|
|
d738b9 |
+ if (reqctx->orig_context == context && pctx != NULL) {
|
|
|
d738b9 |
+ for (i = 0; pctx->handles[i] != NULL; i++) {
|
|
|
d738b9 |
+ h = pctx->handles[i];
|
|
|
d738b9 |
+ if (reqctx->modreqs[i] != NULL && h->vt.request_fini != NULL)
|
|
|
d738b9 |
+ h->vt.request_fini(context, h->data, reqctx->modreqs[i]);
|
|
|
d738b9 |
+ }
|
|
|
d738b9 |
+ } else {
|
|
|
d738b9 |
+ TRACE_PREAUTH_WRONG_CONTEXT(context);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
+ free(reqctx->modreqs);
|
|
|
d738b9 |
+ free(reqctx->tried);
|
|
|
d738b9 |
+ free(reqctx);
|
|
|
d738b9 |
+ ctx->preauth_reqctx = NULL;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
/* Return 1 if pa_type is a real preauthentication mechanism according to the
|
|
|
d738b9 |
@@ -259,6 +309,7 @@ clpreauth_is_real(krb5_context context, clpreauth_handle h,
|
|
|
d738b9 |
|
|
|
d738b9 |
static krb5_error_code
|
|
|
d738b9 |
clpreauth_prep_questions(krb5_context context, clpreauth_handle h,
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq,
|
|
|
d738b9 |
krb5_get_init_creds_opt *opt,
|
|
|
d738b9 |
krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
|
|
|
d738b9 |
krb5_kdc_req *req, krb5_data *req_body,
|
|
|
d738b9 |
@@ -266,35 +317,35 @@ clpreauth_prep_questions(krb5_context context, clpreauth_handle h,
|
|
|
d738b9 |
{
|
|
|
d738b9 |
if (h->vt.prep_questions == NULL)
|
|
|
d738b9 |
return 0;
|
|
|
d738b9 |
- return h->vt.prep_questions(context, h->data, h->req, opt, cb, rock, req,
|
|
|
d738b9 |
+ return h->vt.prep_questions(context, h->data, modreq, opt, cb, rock, req,
|
|
|
d738b9 |
req_body, prev_req, pa_data);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
static krb5_error_code
|
|
|
d738b9 |
clpreauth_process(krb5_context context, clpreauth_handle h,
|
|
|
d738b9 |
- krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb,
|
|
|
d738b9 |
- krb5_clpreauth_rock rock, krb5_kdc_req *req,
|
|
|
d738b9 |
- krb5_data *req_body, krb5_data *prev_req,
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt,
|
|
|
d738b9 |
+ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
|
|
|
d738b9 |
+ krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req,
|
|
|
d738b9 |
krb5_pa_data *pa_data, krb5_prompter_fct prompter,
|
|
|
d738b9 |
void *prompter_data, krb5_pa_data ***pa_data_out)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- return h->vt.process(context, h->data, h->req, opt, cb, rock, req,
|
|
|
d738b9 |
+ return h->vt.process(context, h->data, modreq, opt, cb, rock, req,
|
|
|
d738b9 |
req_body, prev_req, pa_data, prompter, prompter_data,
|
|
|
d738b9 |
pa_data_out);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
static krb5_error_code
|
|
|
d738b9 |
clpreauth_tryagain(krb5_context context, clpreauth_handle h,
|
|
|
d738b9 |
- krb5_get_init_creds_opt *opt, krb5_clpreauth_callbacks cb,
|
|
|
d738b9 |
- krb5_clpreauth_rock rock, krb5_kdc_req *req,
|
|
|
d738b9 |
- krb5_data *req_body, krb5_data *prev_req,
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt,
|
|
|
d738b9 |
+ krb5_clpreauth_callbacks cb, krb5_clpreauth_rock rock,
|
|
|
d738b9 |
+ krb5_kdc_req *req, krb5_data *req_body, krb5_data *prev_req,
|
|
|
d738b9 |
krb5_preauthtype pa_type, krb5_error *error,
|
|
|
d738b9 |
krb5_pa_data **error_padata, krb5_prompter_fct prompter,
|
|
|
d738b9 |
void *prompter_data, krb5_pa_data ***pa_data_out)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
if (h->vt.tryagain == NULL)
|
|
|
d738b9 |
return 0;
|
|
|
d738b9 |
- return h->vt.tryagain(context, h->data, h->req, opt, cb, rock, req,
|
|
|
d738b9 |
+ return h->vt.tryagain(context, h->data, modreq, opt, cb, rock, req,
|
|
|
d738b9 |
req_body, prev_req, pa_type, error, error_padata,
|
|
|
d738b9 |
prompter, prompter_data, pa_data_out);
|
|
|
d738b9 |
}
|
|
|
d738b9 |
@@ -554,22 +605,22 @@ pa_type_allowed(krb5_init_creds_context ctx, krb5_preauthtype pa_type)
|
|
|
d738b9 |
* types and return false.
|
|
|
d738b9 |
*/
|
|
|
d738b9 |
static krb5_boolean
|
|
|
d738b9 |
-already_tried(krb5_context context, krb5_preauthtype pa_type)
|
|
|
d738b9 |
+already_tried(krb5_init_creds_context ctx, krb5_preauthtype pa_type)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
- size_t count;
|
|
|
d738b9 |
+ krb5_preauth_req_context reqctx = ctx->preauth_reqctx;
|
|
|
d738b9 |
+ size_t i;
|
|
|
d738b9 |
krb5_preauthtype *newptr;
|
|
|
d738b9 |
|
|
|
d738b9 |
- for (count = 0; pctx->tried != NULL && pctx->tried[count] != 0; count++) {
|
|
|
d738b9 |
- if (pctx->tried[count] == pa_type)
|
|
|
d738b9 |
+ for (i = 0; reqctx->tried != NULL && reqctx->tried[i] != 0; i++) {
|
|
|
d738b9 |
+ if (reqctx->tried[i] == pa_type)
|
|
|
d738b9 |
return TRUE;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
- newptr = realloc(pctx->tried, (count + 2) * sizeof(*newptr));
|
|
|
d738b9 |
+ newptr = realloc(reqctx->tried, (i + 2) * sizeof(*newptr));
|
|
|
d738b9 |
if (newptr == NULL)
|
|
|
d738b9 |
return FALSE;
|
|
|
d738b9 |
- pctx->tried = newptr;
|
|
|
d738b9 |
- pctx->tried[count] = pa_type;
|
|
|
d738b9 |
- pctx->tried[count + 1] = ENCTYPE_NULL;
|
|
|
d738b9 |
+ reqctx->tried = newptr;
|
|
|
d738b9 |
+ reqctx->tried[i] = pa_type;
|
|
|
d738b9 |
+ reqctx->tried[i + 1] = ENCTYPE_NULL;
|
|
|
d738b9 |
return FALSE;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
@@ -580,16 +631,13 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
krb5_pa_data ***out_pa_list, int *out_pa_list_size,
|
|
|
d738b9 |
krb5_preauthtype *out_type)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
struct errinfo save = EMPTY_ERRINFO;
|
|
|
d738b9 |
krb5_pa_data *pa, **pa_ptr, **mod_pa;
|
|
|
d738b9 |
krb5_error_code ret = 0;
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq;
|
|
|
d738b9 |
clpreauth_handle h;
|
|
|
d738b9 |
int real, i;
|
|
|
d738b9 |
|
|
|
d738b9 |
- if (pctx == NULL)
|
|
|
d738b9 |
- return ENOENT;
|
|
|
d738b9 |
-
|
|
|
d738b9 |
/* Process all informational padata types, then the first real preauth type
|
|
|
d738b9 |
* we succeed on. */
|
|
|
d738b9 |
for (real = 0; real <= 1; real++) {
|
|
|
d738b9 |
@@ -598,17 +646,17 @@ process_pa_data(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
/* Restrict real mechanisms to the chosen one if we have one. */
|
|
|
d738b9 |
if (real && !pa_type_allowed(ctx, pa->pa_type))
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
- h = find_module(pctx->handles, pa->pa_type);
|
|
|
d738b9 |
+ h = find_module(context, ctx, pa->pa_type, &modreq);
|
|
|
d738b9 |
if (h == NULL)
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
/* Make sure this type is for the current pass. */
|
|
|
d738b9 |
if (clpreauth_is_real(context, h, pa->pa_type) != real)
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
/* Only try a real mechanism once per authentication. */
|
|
|
d738b9 |
- if (real && already_tried(context, pa->pa_type))
|
|
|
d738b9 |
+ if (real && already_tried(ctx, pa->pa_type))
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
mod_pa = NULL;
|
|
|
d738b9 |
- ret = clpreauth_process(context, h, ctx->opt, &callbacks,
|
|
|
d738b9 |
+ ret = clpreauth_process(context, h, modreq, ctx->opt, &callbacks,
|
|
|
d738b9 |
(krb5_clpreauth_rock)ctx, ctx->request,
|
|
|
d738b9 |
ctx->inner_request_body,
|
|
|
d738b9 |
ctx->encoded_previous_request, pa,
|
|
|
d738b9 |
@@ -858,24 +906,22 @@ krb5_error_code
|
|
|
d738b9 |
k5_preauth_tryagain(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
krb5_pa_data **in_padata, krb5_pa_data ***padata_out)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
krb5_error_code ret;
|
|
|
d738b9 |
krb5_pa_data **mod_pa;
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq;
|
|
|
d738b9 |
clpreauth_handle h;
|
|
|
d738b9 |
int i;
|
|
|
d738b9 |
|
|
|
d738b9 |
*padata_out = NULL;
|
|
|
d738b9 |
- if (pctx == NULL)
|
|
|
d738b9 |
- return KRB5KRB_ERR_GENERIC;
|
|
|
d738b9 |
|
|
|
d738b9 |
TRACE_PREAUTH_TRYAGAIN_INPUT(context, in_padata);
|
|
|
d738b9 |
|
|
|
d738b9 |
for (i = 0; in_padata[i] != NULL; i++) {
|
|
|
d738b9 |
- h = find_module(pctx->handles, in_padata[i]->pa_type);
|
|
|
d738b9 |
+ h = find_module(context, ctx, in_padata[i]->pa_type, &modreq);
|
|
|
d738b9 |
if (h == NULL)
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
mod_pa = NULL;
|
|
|
d738b9 |
- ret = clpreauth_tryagain(context, h, ctx->opt, &callbacks,
|
|
|
d738b9 |
+ ret = clpreauth_tryagain(context, h, modreq, ctx->opt, &callbacks,
|
|
|
d738b9 |
(krb5_clpreauth_rock)ctx, ctx->request,
|
|
|
d738b9 |
ctx->inner_request_body,
|
|
|
d738b9 |
ctx->encoded_previous_request,
|
|
|
d738b9 |
@@ -897,9 +943,9 @@ static krb5_error_code
|
|
|
d738b9 |
fill_response_items(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
krb5_pa_data **in_padata)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
- krb5_preauth_context pctx = context->preauth_context;
|
|
|
d738b9 |
krb5_error_code ret;
|
|
|
d738b9 |
krb5_pa_data *pa;
|
|
|
d738b9 |
+ krb5_clpreauth_modreq modreq;
|
|
|
d738b9 |
clpreauth_handle h;
|
|
|
d738b9 |
int i;
|
|
|
d738b9 |
|
|
|
d738b9 |
@@ -908,11 +954,11 @@ fill_response_items(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
pa = in_padata[i];
|
|
|
d738b9 |
if (!pa_type_allowed(ctx, pa->pa_type))
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
- h = find_module(pctx->handles, pa->pa_type);
|
|
|
d738b9 |
+ h = find_module(context, ctx, pa->pa_type, &modreq);
|
|
|
d738b9 |
if (h == NULL)
|
|
|
d738b9 |
continue;
|
|
|
d738b9 |
- ret = clpreauth_prep_questions(context, h, ctx->opt, &callbacks,
|
|
|
d738b9 |
- (krb5_clpreauth_rock)ctx,
|
|
|
d738b9 |
+ ret = clpreauth_prep_questions(context, h, modreq, ctx->opt,
|
|
|
d738b9 |
+ &callbacks, (krb5_clpreauth_rock)ctx,
|
|
|
d738b9 |
ctx->request, ctx->inner_request_body,
|
|
|
d738b9 |
ctx->encoded_previous_request, pa);
|
|
|
d738b9 |
if (ret)
|