svn rev #23742: trunk/src/lib/gssapi/spnego/

ghudson@MIT.EDU ghudson at MIT.EDU
Sun Feb 21 23:52:30 EST 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=23742
Commit By: ghudson
Log Message:
ticket: 6603
target_version: 1.8
tags: pullup

Fix two unrelated problems in SPNEGO which don't crop up with the krb5
mechanism.

1. The third call to spnego_init_accept_context uses faulty logic to
determine if the exchange is complete, preventing a third mech token
from being sent to the acceptor if no MIC exchange is required.
Follow the logic used in the second call (in init_ctx_nego), which is
correct.

2. If the acceptor selects a mech other than the optimistic mech, it
sets sc->mic_reqd to 1 whether or not the selected mech supports MICs
(which isn't known until the mech completes).  Most code outside of
handle_mic checks sc->mic_reqd along with (sc->ctx_flags &
GSS_C_INTEG_FLAG), but the code in acc_ctx_call_acc neglected to do
so, so it could improperly delegate responsibility for deciding when
the negotiation was finished to handle_mic--which never gets called if
(sc->ctx_flags & GSS_C_INTEG_FLAG) is false.  Fix acc_ctx_call_acc to
check sc->ctx_flags so that mechs which don't support integrity
protection can complete if they are selected non-optimistically.



Changed Files:
U   trunk/src/lib/gssapi/spnego/spnego_mech.c
Modified: trunk/src/lib/gssapi/spnego/spnego_mech.c
===================================================================
--- trunk/src/lib/gssapi/spnego/spnego_mech.c	2010-02-20 07:37:13 UTC (rev 23741)
+++ trunk/src/lib/gssapi/spnego/spnego_mech.c	2010-02-22 04:52:30 UTC (rev 23742)
@@ -448,8 +448,9 @@
 }
 
 /*
- * Both initiator and acceptor call here to verify and/or create
- * mechListMIC, and to consistency-check the MIC state.
+ * Both initiator and acceptor call here to verify and/or create mechListMIC,
+ * and to consistency-check the MIC state.  handle_mic is invoked only if the
+ * negotiated mech has completed and supports MICs.
  */
 static OM_uint32
 handle_mic(OM_uint32 *minor_status, gss_buffer_t mic_in,
@@ -658,18 +659,20 @@
 				    supportedMech, responseToken,
 				    mechListMIC,
 				    negState, tokflag);
-	} else if (!sc->mech_complete &&
-		   *responseToken == GSS_C_NO_BUFFER) {
-		/*
-		 * mech not finished and mech token missing
-		 */
+	} else if ((!sc->mech_complete && *responseToken == GSS_C_NO_BUFFER) ||
+		   (sc->mech_complete && *responseToken != GSS_C_NO_BUFFER)) {
+		/* Missing or spurious token from acceptor. */
 		ret = GSS_S_DEFECTIVE_TOKEN;
-	} else if (sc->mic_reqd &&
-		   (sc->ctx_flags & GSS_C_INTEG_FLAG)) {
+	} else if (!sc->mech_complete ||
+		   (sc->mic_reqd &&
+		    (sc->ctx_flags & GSS_C_INTEG_FLAG))) {
+		/* Not obviously done; we may decide we're done later in
+		 * init_ctx_call_init or handle_mic. */
 		*negState = ACCEPT_INCOMPLETE;
 		*tokflag = CONT_TOKEN_SEND;
 		ret = GSS_S_CONTINUE_NEEDED;
 	} else {
+		/* mech finished on last pass and no MIC required, so done. */
 		*negState = ACCEPT_COMPLETE;
 		*tokflag = NO_TOKEN_SEND;
 		ret = GSS_S_COMPLETE;
@@ -1529,10 +1532,13 @@
 		if (ret_flags != NULL)
 			*ret_flags = sc->ctx_flags;
 
-		if (!sc->mic_reqd) {
+		if (!sc->mic_reqd ||
+		    !(sc->ctx_flags & GSS_C_INTEG_FLAG)) {
+			/* No MIC exchange required, so we're done. */
 			*negState = ACCEPT_COMPLETE;
 			ret = GSS_S_COMPLETE;
 		} else {
+			/* handle_mic will decide if we're done. */
 			ret = GSS_S_CONTINUE_NEEDED;
 		}
 	} else if (ret != GSS_S_CONTINUE_NEEDED) {




More information about the cvs-krb5 mailing list