[29854] in CVS-changelog-for-Kerberos-V5

home help back first fref pref prev next nref lref last post

krb5 commit: Continue after KDC_ERR_PREAUTH_FAILED

daemon@ATHENA.MIT.EDU (Greg Hudson)
Thu Feb 23 12:53:37 2017

Date: Thu, 23 Feb 2017 12:53:32 -0500
From: Greg Hudson <ghudson@mit.edu>
Message-Id: <201702231753.v1NHrWGw022360@drugstore.mit.edu>
To: cvs-krb5@mit.edu
Reply-To: krbdev@mit.edu
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: cvs-krb5-bounces@mit.edu

https://github.com/krb5/krb5/commit/52d2de31bc4728dbc2f59c6033dcdab86da919e9
commit 52d2de31bc4728dbc2f59c6033dcdab86da919e9
Author: Greg Hudson <ghudson@mit.edu>
Date:   Mon Jan 16 15:09:32 2017 -0500

    Continue after KDC_ERR_PREAUTH_FAILED
    
    If the KDC sends KDC_ERR_PREAUTH_FAILED, try another mechanism, or
    send an unauthenticated request if optimistic preauth failed.
    
    ticket: 8537

 src/lib/krb5/krb/get_in_tkt.c |   45 ++++++++++++++++++++++++++++++++--------
 1 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 11883e6..dfc7fa8 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1326,6 +1326,7 @@ init_creds_step_request(krb5_context context,
     krb5_error_code code;
     krb5_preauthtype pa_type;
     struct errinfo save = EMPTY_ERRINFO;
+    uint32_t rcode = (ctx->err_reply == NULL) ? 0 : ctx->err_reply->error;
 
     if (ctx->loopcount >= MAX_IN_TKT_LOOPS) {
         code = KRB5_GET_IN_TKT_LOOP;
@@ -1376,8 +1377,10 @@ init_creds_step_request(krb5_context context,
         TRACE_INIT_CREDS_PREAUTH_MORE(context, ctx->selected_preauth_type);
         code = k5_preauth(context, ctx, ctx->more_padata, TRUE,
                           &ctx->request->padata, &pa_type);
-    } else if (ctx->err_reply != NULL &&
-               ctx->err_reply->error != KDC_ERR_PREAUTH_REQUIRED) {
+    } else if (rcode == KDC_ERR_PREAUTH_FAILED) {
+        /* Report the KDC-side failure code if we can't try another mech. */
+        code = KRB5KDC_ERR_PREAUTH_FAILED;
+    } else if (rcode && rcode != KDC_ERR_PREAUTH_REQUIRED) {
         /* Retrying after an error (possibly mechanism-specific), using error
          * padata to figure out what to change. */
         TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(context, ctx->err_reply->error,
@@ -1398,7 +1401,7 @@ init_creds_step_request(krb5_context context,
 
     if (ctx->request->padata == NULL && ctx->method_padata != NULL) {
         /* Retrying after KDC_ERR_PREAUTH_REQUIRED, or trying again with a
-         * different mechanism after a client-side failure. */
+         * different mechanism after a failure. */
         TRACE_INIT_CREDS_PREAUTH(context);
         code = k5_preauth(context, ctx, ctx->method_padata, TRUE,
                           &ctx->request->padata, &ctx->selected_preauth_type);
@@ -1498,6 +1501,18 @@ is_referral(krb5_context context, krb5_error *err, krb5_principal client)
     return !krb5_realm_compare(context, err->client, client);
 }
 
+/* Transfer error padata to method data in ctx and sort it according to
+ * configuration. */
+static krb5_error_code
+accept_method_data(krb5_context context, krb5_init_creds_context ctx)
+{
+    krb5_free_pa_data(context, ctx->method_padata);
+    ctx->method_padata = ctx->err_padata;
+    ctx->err_padata = NULL;
+    return sort_krb5_padata_sequence(context, &ctx->request->client->realm,
+                                     ctx->method_padata);
+}
+
 static krb5_error_code
 init_creds_step_reply(krb5_context context,
                       krb5_init_creds_context ctx,
@@ -1556,14 +1571,26 @@ init_creds_step_reply(krb5_context context,
             ctx->restarted = FALSE;
             code = restart_init_creds_loop(context, ctx, FALSE);
         } else if (reply_code == KDC_ERR_PREAUTH_REQUIRED && retry) {
-            krb5_free_pa_data(context, ctx->method_padata);
-            ctx->method_padata = ctx->err_padata;
-            ctx->err_padata = NULL;
             note_req_timestamp(context, ctx, ctx->err_reply->stime,
                                ctx->err_reply->susec);
-            code = sort_krb5_padata_sequence(context,
-                                             &ctx->request->client->realm,
-                                             ctx->method_padata);
+            code = accept_method_data(context, ctx);
+        } else if (reply_code == KDC_ERR_PREAUTH_FAILED && retry) {
+            note_req_timestamp(context, ctx, ctx->err_reply->stime,
+                               ctx->err_reply->susec);
+            if (ctx->method_padata == NULL) {
+                /* Optimistic preauth failed on the KDC.  Allow all mechanisms
+                 * to be tried again using method data. */
+                k5_reset_preauth_types_tried(ctx);
+            } else {
+                /* Don't try again with the mechanism that failed. */
+                code = k5_preauth_note_failed(ctx, ctx->selected_preauth_type);
+                if (code)
+                    goto cleanup;
+            }
+            ctx->selected_preauth_type = KRB5_PADATA_NONE;
+            /* Accept or update method data if the KDC sent it. */
+            if (ctx->err_padata != NULL)
+                code = accept_method_data(context, ctx);
         } else if (reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED && retry) {
             ctx->more_padata = ctx->err_padata;
             ctx->err_padata = NULL;
_______________________________________________
cvs-krb5 mailing list
cvs-krb5@mit.edu
https://mailman.mit.edu/mailman/listinfo/cvs-krb5

home help back first fref pref prev next nref lref last post