143 lines
6.4 KiB
Diff
143 lines
6.4 KiB
Diff
|
From 95c3cab051aa1b8b4f7eb309bf135e8f51665baa Mon Sep 17 00:00:00 2001
|
||
|
From: Nathaniel McCallum <npmccallum@redhat.com>
|
||
|
Date: Sun, 25 Jan 2015 16:53:49 -0500
|
||
|
Subject: [PATCH] Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
|
||
|
|
||
|
Add support for multi-hop preauth mechs.
|
||
|
|
||
|
In the KDC, allow kdcpreauth modules to return
|
||
|
KDC_ERR_MORE_PREAUTH_DATA_REQUIRED as defined in RFC 6113.
|
||
|
|
||
|
In libkrb5, treat this code like KDC_ERR_PREAUTH_REQUIRED. clpreauth
|
||
|
modules can use the modreq parameter to distinguish between the first
|
||
|
and subsequent KDC messages. We assume that the error padata will
|
||
|
include an element of the preauth mech's type, or at least of a type
|
||
|
recognized by the clpreauth module.
|
||
|
|
||
|
Also reset the list of previously attempted preauth types for both
|
||
|
kinds of errors. That list is really only appropriate for retrying
|
||
|
after a failed preauth attempt, which we don't currently do. Add an
|
||
|
intermediate variable for the reply code to avoid a long conditional
|
||
|
expression.
|
||
|
|
||
|
[ghudson@mit.edu: adjust get_in_tkt.c logic to avoid needing a helper
|
||
|
function; clarify commit message]
|
||
|
|
||
|
ticket: 8063 (new)
|
||
|
---
|
||
|
doc/plugindev/clpreauth.rst | 6 +++---
|
||
|
src/include/k5-int.h | 1 +
|
||
|
src/kdc/kdc_preauth.c | 2 ++
|
||
|
src/lib/krb5/error_tables/krb5_err.et | 2 +-
|
||
|
src/lib/krb5/krb/get_in_tkt.c | 13 ++++++++-----
|
||
|
5 files changed, 15 insertions(+), 9 deletions(-)
|
||
|
|
||
|
diff --git a/doc/plugindev/clpreauth.rst b/doc/plugindev/clpreauth.rst
|
||
|
index c3e7298..38aa52e 100644
|
||
|
--- a/doc/plugindev/clpreauth.rst
|
||
|
+++ b/doc/plugindev/clpreauth.rst
|
||
|
@@ -21,9 +21,9 @@ A clpreauth module is generally responsible for:
|
||
|
just returns ``PA_REAL``, indicating that it implements a normal
|
||
|
preauthentication type.
|
||
|
|
||
|
-* Examining the padata information included in the preauth_required
|
||
|
- error and producing padata values for the next AS request. This is
|
||
|
- done with the **process** method.
|
||
|
+* Examining the padata information included in a PREAUTH_REQUIRED or
|
||
|
+ MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the
|
||
|
+ next AS request. This is done with the **process** method.
|
||
|
|
||
|
* Examining the padata information included in a successful ticket
|
||
|
reply, possibly verifying the KDC identity and computing a reply
|
||
|
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||
|
index a1ea25a..4868e7d 100644
|
||
|
--- a/src/include/k5-int.h
|
||
|
+++ b/src/include/k5-int.h
|
||
|
@@ -391,6 +391,7 @@ typedef unsigned char u_char;
|
||
|
not find a KDC */
|
||
|
#define KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE 86 /* The KDC did not respond
|
||
|
to the IAKERB proxy */
|
||
|
+#define KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91 /* RFC 6113 */
|
||
|
#define KRB_ERR_MAX 127 /* err table base max offset for protocol err codes */
|
||
|
|
||
|
/*
|
||
|
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
|
||
|
index 50cc252..dd83844 100644
|
||
|
--- a/src/kdc/kdc_preauth.c
|
||
|
+++ b/src/kdc/kdc_preauth.c
|
||
|
@@ -1000,6 +1000,8 @@ finish_check_padata(struct padata_state *state, krb5_error_code code)
|
||
|
case KRB5KDC_ERR_DISCARD:
|
||
|
/* pkinit alg-agility */
|
||
|
case KRB5KDC_ERR_NO_ACCEPTABLE_KDF:
|
||
|
+ /* rfc 6113 */
|
||
|
+ case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED:
|
||
|
(*oldrespond)(oldarg, code);
|
||
|
return;
|
||
|
default:
|
||
|
diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et
|
||
|
index 5c6f10b..7ba7c1e 100644
|
||
|
--- a/src/lib/krb5/error_tables/krb5_err.et
|
||
|
+++ b/src/lib/krb5/error_tables/krb5_err.et
|
||
|
@@ -132,7 +132,7 @@ error_code KRB5PLACEHOLD_87, "KRB5 error code 87"
|
||
|
error_code KRB5PLACEHOLD_88, "KRB5 error code 88"
|
||
|
error_code KRB5PLACEHOLD_89, "KRB5 error code 89"
|
||
|
error_code KRB5PLACEHOLD_90, "KRB5 error code 90"
|
||
|
-error_code KRB5PLACEHOLD_91, "KRB5 error code 91"
|
||
|
+error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "More preauthentication data is required"
|
||
|
error_code KRB5PLACEHOLD_92, "KRB5 error code 92"
|
||
|
error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested"
|
||
|
error_code KRB5PLACEHOLD_94, "KRB5 error code 94"
|
||
|
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||
|
index f9bc027..fa8afcc 100644
|
||
|
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||
|
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||
|
@@ -1239,7 +1239,8 @@ init_creds_step_request(krb5_context context,
|
||
|
clear_cc_config_out_data(context, ctx);
|
||
|
|
||
|
if (ctx->err_reply == NULL) {
|
||
|
- /* either our first attempt, or retrying after PREAUTH_NEEDED */
|
||
|
+ /* Either our first attempt, or retrying after KDC_ERR_PREAUTH_REQUIRED
|
||
|
+ * or KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */
|
||
|
code = k5_preauth(context, ctx, ctx->preauth_to_use,
|
||
|
ctx->preauth_required, &ctx->request->padata,
|
||
|
&ctx->selected_preauth_type);
|
||
|
@@ -1408,6 +1409,7 @@ init_creds_step_reply(krb5_context context,
|
||
|
krb5_preauthtype kdc_pa_type;
|
||
|
krb5_boolean retry = FALSE;
|
||
|
int canon_flag = 0;
|
||
|
+ uint32_t reply_code;
|
||
|
krb5_keyblock *strengthen_key = NULL;
|
||
|
krb5_keyblock encrypting_key;
|
||
|
krb5_boolean fast_avail;
|
||
|
@@ -1431,6 +1433,7 @@ init_creds_step_reply(krb5_context context,
|
||
|
&retry);
|
||
|
if (code != 0)
|
||
|
goto cleanup;
|
||
|
+ reply_code = ctx->err_reply->error;
|
||
|
if (negotiation_requests_restart(context, ctx, ctx->err_padata)) {
|
||
|
ctx->have_restarted = 1;
|
||
|
k5_preauth_request_context_fini(context);
|
||
|
@@ -1441,9 +1444,10 @@ init_creds_step_reply(krb5_context context,
|
||
|
ctx->err_reply = NULL;
|
||
|
krb5_free_pa_data(context, ctx->err_padata);
|
||
|
ctx->err_padata = NULL;
|
||
|
- } else if (ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED &&
|
||
|
- retry) {
|
||
|
+ } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED ||
|
||
|
+ reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) {
|
||
|
/* reset the list of preauth types to try */
|
||
|
+ k5_reset_preauth_types_tried(context);
|
||
|
krb5_free_pa_data(context, ctx->preauth_to_use);
|
||
|
ctx->preauth_to_use = ctx->err_padata;
|
||
|
ctx->err_padata = NULL;
|
||
|
@@ -1480,8 +1484,7 @@ init_creds_step_reply(krb5_context context,
|
||
|
code = 0;
|
||
|
} else {
|
||
|
/* error + no hints = give up */
|
||
|
- code = (krb5_error_code)ctx->err_reply->error +
|
||
|
- ERROR_TABLE_BASE_krb5;
|
||
|
+ code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5;
|
||
|
}
|
||
|
}
|
||
|
|