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

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

krb5 commit: Continue preauth after client-side failures

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

Date: Thu, 23 Feb 2017 12:53:32 -0500
From: Greg Hudson <ghudson@mit.edu>
Message-Id: <201702231753.v1NHrWqj022338@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/644840a207917661a6ccf706e7830bec273e23b3
commit 644840a207917661a6ccf706e7830bec273e23b3
Author: Greg Hudson <ghudson@mit.edu>
Date:   Sat Jan 14 13:55:22 2017 -0500

    Continue preauth after client-side failures
    
    If the module for the selected preauth mechanism fails when processing
    a KDC_ERR_MORE_PREAUTH_DATA_REQUIRED error, or fails a tryagain
    operation, try again with a different preauth mech using the cached
    method data.
    
    If optimistic preauth fails on the client side, send an
    unauthenticated request, allowing the mechanisms we tried
    optimistically to be tried again.
    
    ticket: 8537

 src/lib/krb5/krb/get_in_tkt.c |   49 ++++++++++++++++++++++++++--------------
 1 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index dc4943b..11883e6 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1325,6 +1325,7 @@ init_creds_step_request(krb5_context context,
 {
     krb5_error_code code;
     krb5_preauthtype pa_type;
+    struct errinfo save = EMPTY_ERRINFO;
 
     if (ctx->loopcount >= MAX_IN_TKT_LOOPS) {
         code = KRB5_GET_IN_TKT_LOOP;
@@ -1359,38 +1360,51 @@ init_creds_step_request(krb5_context context,
     if (ctx->optimistic_padata != NULL) {
         /* Our first attempt, using an optimistic padata list. */
         TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(context);
-        code = k5_preauth(context, ctx, ctx->optimistic_padata, FALSE,
+        code = k5_preauth(context, ctx, ctx->optimistic_padata, TRUE,
                           &ctx->request->padata, &ctx->selected_preauth_type);
         krb5_free_pa_data(context, ctx->optimistic_padata);
         ctx->optimistic_padata = NULL;
-        if (code != 0)
-            goto cleanup;
+        if (code) {
+            /* Make an unauthenticated request, and possibly try again using
+             * the same mechanisms as we tried optimistically. */
+            k5_reset_preauth_types_tried(ctx);
+            krb5_clear_error_message(context);
+            code = 0;
+        }
     } if (ctx->more_padata != NULL) {
         /* Continuing after KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */
         TRACE_INIT_CREDS_PREAUTH_MORE(context, ctx->selected_preauth_type);
         code = k5_preauth(context, ctx, ctx->more_padata, TRUE,
                           &ctx->request->padata, &pa_type);
-        if (code != 0)
-            goto cleanup;
     } else if (ctx->err_reply != NULL &&
-               ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED) {
-        /* Continuing after KDC_ERR_PREAUTH_REQUIRED, using method data. */
-        TRACE_INIT_CREDS_PREAUTH(context);
-        code = k5_preauth(context, ctx, ctx->method_padata, TRUE,
-                          &ctx->request->padata, &ctx->selected_preauth_type);
-        if (code != 0)
-            goto cleanup;
-    } else if (ctx->err_reply != NULL) {
-        /* Retry after an error other than PREAUTH_REQUIRED, using error padata
-         * to figure out what to change. */
+               ctx->err_reply->error != 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,
                                           ctx->selected_preauth_type);
         code = k5_preauth_tryagain(context, ctx, ctx->selected_preauth_type,
                                    ctx->err_reply, ctx->err_padata,
                                    &ctx->request->padata);
-        if (code != 0) {
-            /* couldn't come up with anything better */
+        if (code) {
+            krb5_clear_error_message(context);
             code = ctx->err_reply->error + ERROR_TABLE_BASE_krb5;
+        }
+    }
+    if (code) {
+        /* See if we can try a different preauth mech before giving up. */
+        k5_save_ctx_error(context, code, &save);
+        ctx->selected_preauth_type = KRB5_PADATA_NONE;
+    }
+
+    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. */
+        TRACE_INIT_CREDS_PREAUTH(context);
+        code = k5_preauth(context, ctx, ctx->method_padata, TRUE,
+                          &ctx->request->padata, &ctx->selected_preauth_type);
+        if (code) {
+            if (save.code != 0)
+                code = k5_restore_ctx_error(context, &save);
             goto cleanup;
         }
     }
@@ -1431,6 +1445,7 @@ init_creds_step_request(krb5_context context,
 cleanup:
     krb5_free_pa_data(context, ctx->request->padata);
     ctx->request->padata = NULL;
+    k5_clear_error(&save);
     return code;
 }
 
_______________________________________________
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