svn rev #24840: trunk/src/lib/gssapi/mechglue/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Apr 4 19:06:09 EDT 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=24840
Commit By: ghudson
Log Message:
ticket: 6894
subject: More sensical mech selection for gss_acquire_cred/accept_sec_context

If a caller passes an empty mech set to gss_acquire_cred, get a cred
for all mechs instead of just the krb5 mech, as we don't know what
mechanism the cred is going to be used with (particularly in the
acceptor case).  As a related fix, if a caller passes a credential to
gss_accept_sec_context and it does not contain a mech-specific cred
for the token's mech, error out instead of using the default cred with
the token's mechanism.



Changed Files:
U   trunk/src/lib/gssapi/mechglue/g_accept_sec_context.c
U   trunk/src/lib/gssapi/mechglue/g_acquire_cred.c
Modified: trunk/src/lib/gssapi/mechglue/g_accept_sec_context.c
===================================================================
--- trunk/src/lib/gssapi/mechglue/g_accept_sec_context.c	2011-04-04 20:57:59 UTC (rev 24839)
+++ trunk/src/lib/gssapi/mechglue/g_accept_sec_context.c	2011-04-04 23:06:09 UTC (rev 24840)
@@ -115,7 +115,6 @@
     OM_uint32		status, temp_status, temp_minor_status;
     OM_uint32		temp_ret_flags = 0;
     gss_union_ctx_id_t	union_ctx_id;
-    gss_union_cred_t	union_cred;
     gss_cred_id_t	input_cred_handle = GSS_C_NO_CREDENTIAL;
     gss_cred_id_t	tmp_d_cred = GSS_C_NO_CREDENTIAL;
     gss_name_t		internal_name = GSS_C_NO_NAME;
@@ -181,11 +180,17 @@
 
     /*
      * get the appropriate cred handle from the union cred struct.
-     * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
-     * use the default credential.
      */
-    union_cred = (gss_union_cred_t) verifier_cred_handle;
-    input_cred_handle = gssint_get_mechanism_cred(union_cred, token_mech_type);
+    if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
+	input_cred_handle =
+	    gssint_get_mechanism_cred((gss_union_cred_t)verifier_cred_handle,
+				      token_mech_type);
+	if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+	    /* verifier credential specified but no acceptor credential found */
+	    status = GSS_S_NO_CRED;
+	    goto error_out;
+	}
+    }
 
     /*
      * now select the approprate underlying mechanism routine and

Modified: trunk/src/lib/gssapi/mechglue/g_acquire_cred.c
===================================================================
--- trunk/src/lib/gssapi/mechglue/g_acquire_cred.c	2011-04-04 20:57:59 UTC (rev 24839)
+++ trunk/src/lib/gssapi/mechglue/g_acquire_cred.c	2011-04-04 23:06:09 UTC (rev 24840)
@@ -103,14 +103,11 @@
 OM_uint32 *		time_rec;
 
 {
-    OM_uint32 major = GSS_S_FAILURE;
+    OM_uint32 major = GSS_S_FAILURE, tmpMinor;
     OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
-    gss_OID_set_desc default_OID_set;
-    gss_OID_set mechs;
-    gss_OID_desc default_OID;
-    gss_mechanism mech;
+    gss_OID_set mechs = GSS_C_NO_OID_SET;
     unsigned int i;
-    gss_union_cred_t creds;
+    gss_union_cred_t creds = NULL;
 
     major = val_acq_cred_args(minor_status,
 			      desired_name,
@@ -121,44 +118,37 @@
 			      actual_mechs,
 			      time_rec);
     if (major != GSS_S_COMPLETE)
-	return (major);
+	goto cleanup;
 
-    /* Initial value needed below. */
-    major = GSS_S_FAILURE;
-
     /*
-     * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an
-     * appropriate default.  We use the first mechanism in the
-     * mechansim list as the default. This set is created with
-     * statics thus needs not be freed
+     * if desired_mechs equals GSS_C_NULL_OID_SET, then try to
+     * acquire credentials for all mechanisms.
      */
-    if(desired_mechs == GSS_C_NULL_OID_SET) {
-	mech = gssint_get_mechanism(NULL);
-	if (mech == NULL)
-	    return (GSS_S_BAD_MECH);
-
-	mechs = &default_OID_set;
-	default_OID_set.count = 1;
-	default_OID_set.elements = &default_OID;
-	default_OID.length = mech->mech_type.length;
-	default_OID.elements = mech->mech_type.elements;
+    if (desired_mechs == GSS_C_NULL_OID_SET) {
+	major = gss_indicate_mechs(minor_status, &mechs);
+	if (major != GSS_S_COMPLETE)
+	    goto cleanup;
     } else
 	mechs = desired_mechs;
 
-    if (mechs->count == 0)
-	return (GSS_S_BAD_MECH);
+    if (mechs->count == 0) {
+	major = GSS_S_BAD_MECH;
+	goto cleanup;
+    }
 
     /* allocate the output credential structure */
-    creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc));
-    if (creds == NULL)
-	return (GSS_S_FAILURE);
+    creds = (gss_union_cred_t)calloc(1, sizeof (gss_union_cred_desc));
+    if (creds == NULL) {
+	major = GSS_S_FAILURE;
+	*minor_status = ENOMEM;
+	goto cleanup;
+    }
 
-    /* initialize to 0s */
-    (void) memset(creds, 0, sizeof (gss_union_cred_desc));
+    creds->count = 0;
     creds->loopback = creds;
 
     /* for each requested mech attempt to obtain a credential */
-    for (i = 0; i < mechs->count; i++) {
+    for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) {
 	major = gss_add_cred(minor_status, (gss_cred_id_t)creds,
 			     desired_name,
 			     &mechs->elements[i],
@@ -188,10 +178,8 @@
     } /* for */
 
     /* ensure that we have at least one credential element */
-    if (creds->count < 1) {
-	free(creds);
-	return (major);
-    }
+    if (creds->count < 1)
+	goto cleanup;
 
     /*
      * fill in output parameters
@@ -204,20 +192,22 @@
 	oids.elements = creds->mechs_array;
 
 	major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
-	if (GSS_ERROR(major)) {
-	    (void) gss_release_cred(minor_status,
-				    (gss_cred_id_t *)&creds);
-	    return (major);
-	}
+	if (GSS_ERROR(major))
+	    goto cleanup;
     }
 
     if (time_rec)
 	*time_rec = outTime;
 
-
-    creds->loopback = creds;
     *output_cred_handle = (gss_cred_id_t)creds;
-    return (GSS_S_COMPLETE);
+
+cleanup:
+    if (GSS_ERROR(major))
+	gss_release_cred(&tmpMinor, (gss_cred_id_t *)&creds);
+    if (desired_mechs == GSS_C_NO_OID_SET)
+        generic_gss_release_oid_set(&tmpMinor, &mechs);
+
+    return (major);
 }
 
 static OM_uint32




More information about the cvs-krb5 mailing list