krb5 commit: Get default cred only once in gss-krb5 initiator

Greg Hudson ghudson at MIT.EDU
Mon Jul 2 00:57:41 EDT 2012


https://github.com/krb5/krb5/commit/49ba7c90fce86581ff6faaa9ee48c80b0be9491e
commit 49ba7c90fce86581ff6faaa9ee48c80b0be9491e
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Jul 2 00:57:34 2012 -0400

    Get default cred only once in gss-krb5 initiator
    
    In the regular krb5 code path, only get a default krb5 cred for the
    initial token, since we don't need the cred for mutual_auth anyway.
    
    In the IAKERB mechanism, cache the default cred in iakerb_ctx_id_rec
    so we don't have to construct it again for each token.  Also, get an
    IAKERB default cred, not a regular krb5 cred (a bug which is harmless
    now, but becomes more of a problem with keytab initiation changes).

 src/lib/gssapi/krb5/iakerb.c           |   32 ++++++++++---------
 src/lib/gssapi/krb5/init_sec_context.c |   51 +++++++++++++++-----------------
 2 files changed, 41 insertions(+), 42 deletions(-)

diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index 31fd190..1b3236e 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -40,6 +40,7 @@ enum iakerb_state {
 struct _iakerb_ctx_id_rec {
     krb5_magic magic;                   /* KG_IAKERB_CONTEXT */
     krb5_context k5c;
+    gss_cred_id_t defcred;              /* Initiator only */
     enum iakerb_state state;            /* Initiator only */
     krb5_init_creds_context icc;        /* Initiator only */
     krb5_tkt_creds_context tcc;         /* Initiator only */
@@ -65,6 +66,7 @@ iakerb_release_context(iakerb_ctx_id_t ctx)
     if (ctx == NULL)
         return;
 
+    krb5_gss_release_cred(&tmp, &ctx->defcred);
     krb5_init_creds_free(ctx->k5c, ctx->icc);
     krb5_tkt_creds_free(ctx->k5c, ctx->tcc);
     krb5_gss_delete_sec_context(&tmp, &ctx->gssc, NULL);
@@ -710,6 +712,7 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx)
     ctx = k5alloc(sizeof(*ctx), &code);
     if (ctx == NULL)
         goto cleanup;
+    ctx->defcred = GSS_C_NO_CREDENTIAL;
     ctx->magic = KG_IAKERB_CONTEXT;
     ctx->state = IAKERB_AS_REQ;
     ctx->count = 0;
@@ -893,10 +896,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
                             OM_uint32 *time_rec)
 {
     OM_uint32 major_status = GSS_S_FAILURE;
-    OM_uint32 tmpmin;
     krb5_error_code code;
     iakerb_ctx_id_t ctx;
-    gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
     krb5_gss_cred_id_t kcred;
     krb5_gss_name_t kname;
     krb5_boolean cred_locked = FALSE;
@@ -908,22 +909,24 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
             *minor_status = code;
             goto cleanup;
         }
-    } else
+        if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+            major_status = iakerb_gss_acquire_cred(minor_status, NULL,
+                                                   GSS_C_INDEFINITE,
+                                                   GSS_C_NULL_OID_SET,
+                                                   GSS_C_INITIATE,
+                                                   &ctx->defcred, NULL, NULL);
+            if (GSS_ERROR(major_status))
+                goto cleanup;
+            claimant_cred_handle = ctx->defcred;
+        }
+    } else {
         ctx = (iakerb_ctx_id_t)*context_handle;
+        if (claimant_cred_handle == GSS_C_NO_CREDENTIAL)
+            claimant_cred_handle = ctx->defcred;
+    }
 
     kname = (krb5_gss_name_t)target_name;
 
-    if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
-        major_status = krb5_gss_acquire_cred(minor_status, NULL,
-                                             GSS_C_INDEFINITE,
-                                             GSS_C_NULL_OID_SET,
-                                             GSS_C_INITIATE,
-                                             &defcred, NULL, NULL);
-        if (GSS_ERROR(major_status))
-            goto cleanup;
-        claimant_cred_handle = defcred;
-    }
-
     major_status = kg_cred_resolve(minor_status, ctx->k5c,
                                    claimant_cred_handle, target_name);
     if (GSS_ERROR(major_status))
@@ -1011,7 +1014,6 @@ cleanup:
         iakerb_release_context(ctx);
         *context_handle = GSS_C_NO_CONTEXT;
     }
-    krb5_gss_release_cred(&tmpmin, &defcred);
 
     return major_status;
 }
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
index 6451a6d..d0eda5f 100644
--- a/src/lib/gssapi/krb5/init_sec_context.c
+++ b/src/lib/gssapi/krb5/init_sec_context.c
@@ -948,29 +948,6 @@ krb5_gss_init_sec_context_ext(
     if (actual_mech_type)
         *actual_mech_type = NULL;
 
-    /* verify the credential, or use the default */
-    /*SUPPRESS 29*/
-    if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
-        major_status = kg_get_defcred(minor_status, &defcred);
-        if (major_status && GSS_ERROR(major_status)) {
-            if (*context_handle == GSS_C_NO_CONTEXT)
-                krb5_free_context(context);
-            return(major_status);
-        }
-        claimant_cred_handle = defcred;
-    }
-
-    major_status = kg_cred_resolve(minor_status, context, claimant_cred_handle,
-                                   target_name);
-    if (GSS_ERROR(major_status)) {
-        save_error_info(*minor_status, context);
-        krb5_gss_release_cred(&tmp_min_stat, &defcred);
-        if (*context_handle == GSS_C_NO_CONTEXT)
-            krb5_free_context(context);
-        return(major_status);
-    }
-    cred = (krb5_gss_cred_id_t)claimant_cred_handle;
-
     /* verify the mech_type */
 
     if (mech_type == GSS_C_NULL_OID || g_OID_equal(mech_type, gss_mech_krb5)) {
@@ -982,8 +959,6 @@ krb5_gss_init_sec_context_ext(
     } else if (g_OID_equal(mech_type, gss_mech_iakerb)) {
         mech_type = (gss_OID) gss_mech_iakerb;
     } else {
-        k5_mutex_unlock(&cred->lock);
-        krb5_gss_release_cred(minor_status, &defcred);
         *minor_status = 0;
         if (*context_handle == GSS_C_NO_CONTEXT)
             krb5_free_context(context);
@@ -994,6 +969,29 @@ krb5_gss_init_sec_context_ext(
 
     /*SUPPRESS 29*/
     if (*context_handle == GSS_C_NO_CONTEXT) {
+        /* verify the credential, or use the default */
+        /*SUPPRESS 29*/
+        if (claimant_cred_handle == GSS_C_NO_CREDENTIAL) {
+            major_status = kg_get_defcred(minor_status, &defcred);
+            if (major_status && GSS_ERROR(major_status)) {
+                if (*context_handle == GSS_C_NO_CONTEXT)
+                    krb5_free_context(context);
+                return(major_status);
+            }
+            claimant_cred_handle = defcred;
+        }
+
+        major_status = kg_cred_resolve(minor_status, context,
+                                       claimant_cred_handle, target_name);
+        if (GSS_ERROR(major_status)) {
+            save_error_info(*minor_status, context);
+            krb5_gss_release_cred(&tmp_min_stat, &defcred);
+            if (*context_handle == GSS_C_NO_CONTEXT)
+                krb5_free_context(context);
+            return(major_status);
+        }
+        cred = (krb5_gss_cred_id_t)claimant_cred_handle;
+
         major_status = kg_new_connection(minor_status, cred, context_handle,
                                          target_name, mech_type, req_flags,
                                          time_req, input_chan_bindings,
@@ -1001,6 +999,7 @@ krb5_gss_init_sec_context_ext(
                                          output_token, ret_flags, time_rec,
                                          context, exts);
         k5_mutex_unlock(&cred->lock);
+        krb5_gss_release_cred(&tmp_min_stat, &defcred);
         if (*context_handle == GSS_C_NO_CONTEXT) {
             save_error_info (*minor_status, context);
             krb5_free_context(context);
@@ -1008,7 +1007,6 @@ krb5_gss_init_sec_context_ext(
             ((krb5_gss_ctx_id_rec *) *context_handle)->k5_context = context;
     } else {
         /* mutual_auth doesn't care about the credentials */
-        k5_mutex_unlock(&cred->lock);
         major_status = mutual_auth(minor_status, context_handle,
                                    target_name, mech_type, req_flags,
                                    time_req, input_chan_bindings,
@@ -1020,7 +1018,6 @@ krb5_gss_init_sec_context_ext(
            too.  */
     }
 
-    krb5_gss_release_cred(&tmp_min_stat, &defcred);
     return(major_status);
 }
 


More information about the cvs-krb5 mailing list