]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED
authorNathaniel McCallum <npmccallum@redhat.com>
Sun, 25 Jan 2015 21:53:49 +0000 (16:53 -0500)
committerGreg Hudson <ghudson@mit.edu>
Wed, 28 Jan 2015 22:35:30 +0000 (17:35 -0500)
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
src/include/k5-int.h
src/kdc/kdc_preauth.c
src/lib/krb5/error_tables/krb5_err.et
src/lib/krb5/krb/get_in_tkt.c

index c3e729813d6b74538b9cf41971198f3bfc6b3966..38aa52e8bfa4a6314612fab9850d8cf5a41c7929 100644 (file)
@@ -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
index a1ea25aac08270eaddd57fe26006bf6d0eecbca7..4868e7df02a2de9245257e0dee3fed7ce8fc62ac 100644 (file)
@@ -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 */
 
 /*
index 50cc2520de837221924f3e37a07c371fd3ea7785..dd83844591c6eee3cebc731d4b70c3a358421c05 100644 (file)
@@ -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:
index 5c6f10b23eaeedbfb87204ba7e0d1778729833c8..7ba7c1e0a84b9de4788895340f2397a4d80be401 100644 (file)
@@ -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"
index f9bc027aaa78cbb57aaf86a3fb776b5e2a069a08..fa8afcc38db26ce7eb8e0337f80ab3beaed69719 100644 (file)
@@ -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;
             }
         }