|
|
d738b9 |
From e443dfe315a38607e7c9dcba219f73253d17032b Mon Sep 17 00:00:00 2001
|
|
|
d738b9 |
From: Greg Hudson <ghudson@mit.edu>
|
|
|
d738b9 |
Date: Fri, 13 Jan 2017 20:45:48 -0500
|
|
|
d738b9 |
Subject: [PATCH] Simplify k5_preauth_tryagain()
|
|
|
d738b9 |
|
|
|
d738b9 |
When retrying pre-authentication for an error, try only the module for
|
|
|
d738b9 |
the selected preauth type, not all preauth types in the original
|
|
|
d738b9 |
method data. Pass the error and its padata to k5_preauth_tryagain()
|
|
|
d738b9 |
explicitly, so that those fields of krb5_init_creds_context are only
|
|
|
d738b9 |
referenced in get_in_tkt.c. Handle a degenerate case in
|
|
|
d738b9 |
init_creds_step_reply() to simplify the code in
|
|
|
d738b9 |
init_creds_step_request().
|
|
|
d738b9 |
|
|
|
d738b9 |
ticket: 8537
|
|
|
d738b9 |
(cherry picked from commit 27628e5d9d5e6fcfa73276106edbd8149d134dc0)
|
|
|
d738b9 |
---
|
|
|
d738b9 |
src/include/k5-trace.h | 7 ++--
|
|
|
d738b9 |
src/lib/krb5/krb/get_in_tkt.c | 20 ++++-------
|
|
|
d738b9 |
src/lib/krb5/krb/int-proto.h | 3 +-
|
|
|
d738b9 |
src/lib/krb5/krb/preauth2.c | 64 +++++++++++++++++++----------------
|
|
|
d738b9 |
4 files changed, 48 insertions(+), 46 deletions(-)
|
|
|
d738b9 |
|
|
|
d738b9 |
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
|
|
|
d738b9 |
index f44f162d3..814da3195 100644
|
|
|
d738b9 |
--- a/src/include/k5-trace.h
|
|
|
d738b9 |
+++ b/src/include/k5-trace.h
|
|
|
d738b9 |
@@ -287,8 +287,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
|
|
|
d738b9 |
#define TRACE_PREAUTH_SKIP(c, name, patype) \
|
|
|
d738b9 |
TRACE(c, "Skipping previously used preauth module {str} ({int})", \
|
|
|
d738b9 |
name, (int) patype)
|
|
|
d738b9 |
-#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, padata) \
|
|
|
d738b9 |
- TRACE(c, "Preauth tryagain input types: {patypes}", padata)
|
|
|
d738b9 |
+#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, patype, padata) \
|
|
|
d738b9 |
+ TRACE(c, "Preauth tryagain input types ({int}): {patypes}", patype, padata)
|
|
|
d738b9 |
+#define TRACE_PREAUTH_TRYAGAIN(c, name, patype, code) \
|
|
|
d738b9 |
+ TRACE(c, "Preauth module {str} ({int}) tryagain returned: {kerr}", \
|
|
|
d738b9 |
+ name, (int)patype, code)
|
|
|
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 |
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
index da12204ac..988fca233 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
|
|
d738b9 |
@@ -1340,17 +1340,11 @@ init_creds_step_request(krb5_context context,
|
|
|
d738b9 |
if (code != 0)
|
|
|
d738b9 |
goto cleanup;
|
|
|
d738b9 |
} else {
|
|
|
d738b9 |
- if (ctx->preauth_to_use != NULL) {
|
|
|
d738b9 |
- /*
|
|
|
d738b9 |
- * Retry after an error other than PREAUTH_NEEDED,
|
|
|
d738b9 |
- * using ctx->err_padata to figure out what to change.
|
|
|
d738b9 |
- */
|
|
|
d738b9 |
- code = k5_preauth_tryagain(context, ctx, ctx->preauth_to_use,
|
|
|
d738b9 |
- &ctx->request->padata);
|
|
|
d738b9 |
- } else {
|
|
|
d738b9 |
- /* No preauth supplied, so can't query the plugins. */
|
|
|
d738b9 |
- code = KRB5KRB_ERR_GENERIC;
|
|
|
d738b9 |
- }
|
|
|
d738b9 |
+ /* Retry after an error other than PREAUTH_NEEDED, using error padata
|
|
|
d738b9 |
+ * to figure out what to change. */
|
|
|
d738b9 |
+ code = k5_preauth_tryagain(context, ctx, ctx->selected_preauth_type,
|
|
|
d738b9 |
+ ctx->err_reply, ctx->err_padata,
|
|
|
d738b9 |
+ &ctx->request->padata);
|
|
|
d738b9 |
if (code != 0) {
|
|
|
d738b9 |
/* couldn't come up with anything better */
|
|
|
d738b9 |
code = ctx->err_reply->error + ERROR_TABLE_BASE_krb5;
|
|
|
d738b9 |
@@ -1535,10 +1529,10 @@ init_creds_step_reply(krb5_context context,
|
|
|
d738b9 |
ctx->enc_pa_rep_permitted = TRUE;
|
|
|
d738b9 |
code = restart_init_creds_loop(context, ctx, FALSE);
|
|
|
d738b9 |
} else {
|
|
|
d738b9 |
- if (retry) {
|
|
|
d738b9 |
+ if (retry && ctx->selected_preauth_type != KRB5_PADATA_NONE) {
|
|
|
d738b9 |
code = 0;
|
|
|
d738b9 |
} else {
|
|
|
d738b9 |
- /* error + no hints = give up */
|
|
|
d738b9 |
+ /* error + no hints (or no preauth mech) = give up */
|
|
|
d738b9 |
code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
}
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
index 628f0baa8..8903df232 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/int-proto.h
|
|
|
d738b9 |
@@ -185,7 +185,8 @@ k5_preauth(krb5_context context, krb5_init_creds_context ctx,
|
|
|
d738b9 |
|
|
|
d738b9 |
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 |
+ krb5_preauthtype pa_type, krb5_error *err,
|
|
|
d738b9 |
+ krb5_pa_data **err_padata, krb5_pa_data ***padata_out);
|
|
|
d738b9 |
|
|
|
d738b9 |
void
|
|
|
d738b9 |
k5_init_preauth_context(krb5_context context);
|
|
|
d738b9 |
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
index cfe3dd5b0..354234a93 100644
|
|
|
d738b9 |
--- a/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
+++ b/src/lib/krb5/krb/preauth2.c
|
|
|
d738b9 |
@@ -911,49 +911,53 @@ add_s4u_x509_user_padata(krb5_context context, krb5_s4u_userid *userid,
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
/*
|
|
|
d738b9 |
- * If one of the modules can adjust its AS_REQ data using the contents of the
|
|
|
d738b9 |
- * err_reply, return 0. If it's the sort of correction which requires that we
|
|
|
d738b9 |
- * ask the user another question, we let the calling application deal with it.
|
|
|
d738b9 |
+ * If the module for pa_type can adjust its AS_REQ data using the contents of
|
|
|
d738b9 |
+ * err and err_padata, return 0 with *padata_out set to a padata list for the
|
|
|
d738b9 |
+ * next request. If it's the sort of correction which requires that we ask the
|
|
|
d738b9 |
+ * user another question, we let the calling application deal with it.
|
|
|
d738b9 |
*/
|
|
|
d738b9 |
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 |
+ krb5_preauthtype pa_type, krb5_error *err,
|
|
|
d738b9 |
+ krb5_pa_data **err_padata, krb5_pa_data ***padata_out)
|
|
|
d738b9 |
{
|
|
|
d738b9 |
krb5_error_code ret;
|
|
|
d738b9 |
krb5_pa_data **mod_pa;
|
|
|
d738b9 |
krb5_clpreauth_modreq modreq;
|
|
|
d738b9 |
clpreauth_handle h;
|
|
|
d738b9 |
- int i, count;
|
|
|
d738b9 |
+ int count;
|
|
|
d738b9 |
|
|
|
d738b9 |
*padata_out = NULL;
|
|
|
d738b9 |
|
|
|
d738b9 |
- TRACE_PREAUTH_TRYAGAIN_INPUT(context, in_padata);
|
|
|
d738b9 |
+ TRACE_PREAUTH_TRYAGAIN_INPUT(context, pa_type, err_padata);
|
|
|
d738b9 |
|
|
|
d738b9 |
- for (i = 0; in_padata[i] != NULL; i++) {
|
|
|
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, modreq, ctx->opt, &callbacks,
|
|
|
d738b9 |
- (krb5_clpreauth_rock)ctx, ctx->request,
|
|
|
d738b9 |
- ctx->inner_request_body,
|
|
|
d738b9 |
- ctx->encoded_previous_request,
|
|
|
d738b9 |
- in_padata[i]->pa_type,
|
|
|
d738b9 |
- ctx->err_reply, ctx->err_padata,
|
|
|
d738b9 |
- ctx->prompter, ctx->prompter_data, &mod_pa);
|
|
|
d738b9 |
- if (ret == 0 && mod_pa != NULL) {
|
|
|
d738b9 |
- for (count = 0; mod_pa[count] != NULL; count++);
|
|
|
d738b9 |
- ret = copy_cookie(context, ctx->err_padata, &mod_pa, &count);
|
|
|
d738b9 |
- if (ret) {
|
|
|
d738b9 |
- krb5_free_pa_data(context, mod_pa);
|
|
|
d738b9 |
- return ret;
|
|
|
d738b9 |
- }
|
|
|
d738b9 |
- TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa);
|
|
|
d738b9 |
- *padata_out = mod_pa;
|
|
|
d738b9 |
- return 0;
|
|
|
d738b9 |
- }
|
|
|
d738b9 |
+ h = find_module(context, ctx, pa_type, &modreq);
|
|
|
d738b9 |
+ if (h == NULL)
|
|
|
d738b9 |
+ return KRB5KRB_ERR_GENERIC;
|
|
|
d738b9 |
+ mod_pa = NULL;
|
|
|
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, pa_type, err,
|
|
|
d738b9 |
+ err_padata, ctx->prompter, ctx->prompter_data,
|
|
|
d738b9 |
+ &mod_pa);
|
|
|
d738b9 |
+ TRACE_PREAUTH_TRYAGAIN(context, h->vt.name, pa_type, ret);
|
|
|
d738b9 |
+ if (!ret && mod_pa == NULL)
|
|
|
d738b9 |
+ ret = KRB5KRB_ERR_GENERIC;
|
|
|
d738b9 |
+ if (ret)
|
|
|
d738b9 |
+ return ret;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ for (count = 0; mod_pa[count] != NULL; count++);
|
|
|
d738b9 |
+ ret = copy_cookie(context, err_padata, &mod_pa, &count);
|
|
|
d738b9 |
+ if (ret) {
|
|
|
d738b9 |
+ krb5_free_pa_data(context, mod_pa);
|
|
|
d738b9 |
+ return ret;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
- return KRB5KRB_ERR_GENERIC;
|
|
|
d738b9 |
+
|
|
|
d738b9 |
+ TRACE_PREAUTH_TRYAGAIN_OUTPUT(context, mod_pa);
|
|
|
d738b9 |
+ *padata_out = mod_pa;
|
|
|
d738b9 |
+ return 0;
|
|
|
d738b9 |
}
|
|
|
d738b9 |
|
|
|
d738b9 |
/* Compile the set of response items for in_padata by invoke each module's
|