svn rev #25628: branches/krb5-1-10/src/lib/gssapi/spnego/

tlyu@MIT.EDU tlyu at MIT.EDU
Mon Jan 9 16:23:43 EST 2012


http://src.mit.edu/fisheye/changelog/krb5/?cs=25628
Commit By: tlyu
Log Message:
ticket: 6936
version_fixed: 1.10
status: resolved

Pull up r25591, r25604 from trunk

 ------------------------------------------------------------------------
 r25604 | ghudson | 2011-12-27 01:39:07 -0500 (Tue, 27 Dec 2011) | 4 lines

 ticket: 6936

 Fix an unlikely memory leak in r25591
 ------------------------------------------------------------------------
 r25591 | ghudson | 2011-12-16 18:19:01 -0500 (Fri, 16 Dec 2011) | 14 lines

 ticket: 6936
 target_version: 1.10
 tags: pullup

 Do mech fallback for first SPNEGO context token

 When producing the first SPNEGO security context token, if the first
 mechanism's init_sec_context fails, fall back to a later mechanism.

 This fixes a regression in 1.10 for SPNEGO initiators using non-krb5
 credentials.  The identity selection work causes errors to be deferred
 from krb5's acquire_cred in some cases, which means SPNEGO doesn't see
 an error until it tries the krb5 init_sec_context.


Changed Files:
U   branches/krb5-1-10/src/lib/gssapi/spnego/spnego_mech.c
Modified: branches/krb5-1-10/src/lib/gssapi/spnego/spnego_mech.c
===================================================================
--- branches/krb5-1-10/src/lib/gssapi/spnego/spnego_mech.c	2012-01-09 21:23:40 UTC (rev 25627)
+++ branches/krb5-1-10/src/lib/gssapi/spnego/spnego_mech.c	2012-01-09 21:23:43 UTC (rev 25628)
@@ -589,7 +589,7 @@
 	ret = get_negotiable_mechs(minor_status, spcred, GSS_C_INITIATE,
 				   &sc->mech_set);
 	if (ret != GSS_S_COMPLETE)
-		return ret;
+		goto cleanup;
 
 	/* Set an initial internal mech to make the first context token. */
 	sc->internal_mech = &sc->mech_set->elements[0];
@@ -821,7 +821,7 @@
 		   OM_uint32 *negState,
 		   send_token_flag *send_token)
 {
-	OM_uint32 ret;
+	OM_uint32 ret, tmpret, tmpmin;
 	gss_cred_id_t mcred;
 
 	mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred;
@@ -862,15 +862,44 @@
 			*negState = ACCEPT_INCOMPLETE;
 			ret = GSS_S_CONTINUE_NEEDED;
 		}
-	} else if (ret != GSS_S_CONTINUE_NEEDED) {
-		if (*send_token == INIT_TOKEN_SEND) {
-			/* Don't output token on error if first call. */
-			*send_token = NO_TOKEN_SEND;
-		} else {
-			*send_token = ERROR_TOKEN_SEND;
-		}
+		return ret;
+	}
+
+	if (ret == GSS_S_CONTINUE_NEEDED)
+		return ret;
+
+	if (*send_token != INIT_TOKEN_SEND) {
+		*send_token = ERROR_TOKEN_SEND;
 		*negState = REJECT;
+		return ret;
 	}
+
+	/*
+	 * Since this is the first token, we can fall back to later mechanisms
+	 * in the list.  Since the mechanism list is expected to be short, we
+	 * can do this with recursion.  If all mechanisms produce errors, the
+	 * caller should get the error from the first mech in the list.
+	 */
+	memmove(sc->mech_set->elements, sc->mech_set->elements + 1,
+		--sc->mech_set->count * sizeof(*sc->mech_set->elements));
+	if (sc->mech_set->count == 0)
+		goto fail;
+	gss_release_buffer(&tmpmin, &sc->DER_mechTypes);
+	if (put_mech_set(sc->mech_set, &sc->DER_mechTypes) < 0)
+		goto fail;
+	tmpret = init_ctx_call_init(&tmpmin, sc, spcred, target_name,
+				    req_flags, time_req, mechtok_in,
+				    actual_mech, mechtok_out, ret_flags,
+				    time_rec, negState, send_token);
+	if (HARD_ERROR(tmpret))
+		goto fail;
+	*minor_status = tmpmin;
+	return tmpret;
+
+fail:
+	/* Don't output token on error from first call. */
+	*send_token = NO_TOKEN_SEND;
+	*negState = REJECT;
 	return ret;
 }
 



More information about the cvs-krb5 mailing list