krb5 commit: Allow GSS mechs to force mechlistMIC in SPNEGO

Greg Hudson ghudson at MIT.EDU
Thu May 8 15:20:04 EDT 2014


https://github.com/krb5/krb5/commit/bff6bbf52401f9464df365d76f0987fbf8101c5e
commit bff6bbf52401f9464df365d76f0987fbf8101c5e
Author: Simo Sorce <simo at redhat.com>
Date:   Mon May 5 17:59:08 2014 -0400

    Allow GSS mechs to force mechlistMIC in SPNEGO
    
    During a SPNEGO negotiation, if the NTLMSSP mechanism is used and a
    MIC is produced within the final initiator mechanism token, Microsoft
    servers require a mechlistMIC even if NTLMSSP was the most preferred
    mechanism.
    
    In spnego_mech.c, add a helper function mech_requires_mechlistMIC
    which queries the mechanism to determine whether we might need to
    produce a mechlistMIC for interoperability.  Call it after each call
    to the mechanism's gss_init_sec_context and set sc->mic_reqd if it
    returns true.  Although only the second call to NTLMSSP will actually
    ever return true, the first call makes the mechanism aware that the
    SPNEGO implementation supports this feature.
    
    [ghudson at mit.edu: clarified commit message and code]
    
    ticket: 7907 (new)

 src/lib/gssapi/spnego/spnego_mech.c |   37 +++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 7529c74..c9c1b11 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -474,6 +474,39 @@ create_spnego_ctx(void)
 	return (spnego_ctx);
 }
 
+/* iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) samba(7165)
+ * gssntlmssp(655) controls(1) spnego_req_mechlistMIC(2) */
+static const gss_OID_desc spnego_req_mechlistMIC_oid =
+	{ 11, "\x2B\x06\x01\x04\x01\xB7\x7D\x85\x0F\x01\x02" };
+
+/*
+ * Return nonzero if the mechanism has reason to believe that a mechlistMIC
+ * exchange will be required.  Microsoft servers erroneously require SPNEGO
+ * mechlistMIC if they see an internal MIC within an NTLMSSP Authenticate
+ * message, even if NTLMSSP was the preferred mechanism.
+ */
+static int
+mech_requires_mechlistMIC(spnego_gss_ctx_id_t sc)
+{
+	OM_uint32 major, minor;
+	gss_ctx_id_t ctx = sc->ctx_handle;
+	gss_OID oid = (gss_OID)&spnego_req_mechlistMIC_oid;
+	gss_buffer_set_t bufs;
+	int result;
+
+	major = gss_inquire_sec_context_by_oid(&minor, ctx, oid, &bufs);
+	if (major != GSS_S_COMPLETE)
+		return 0;
+
+	/* Report true if the mech returns a single buffer containing a single
+	 * byte with value 1. */
+	result = (bufs != NULL && bufs->count == 1 &&
+		  bufs->elements[0].length == 1 &&
+		  memcmp(bufs->elements[0].value, "\1", 1) == 0);
+	(void) gss_release_buffer_set(&minor, &bufs);
+	return result;
+}
+
 /*
  * 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
@@ -1014,6 +1047,10 @@ spnego_gss_init_sec_context(
 			actual_mech, &mechtok_out,
 			ret_flags, time_rec,
 			&negState, &send_token);
+
+		/* Give the mechanism a chance to force a mechlistMIC. */
+		if (!HARD_ERROR(ret) && mech_requires_mechlistMIC(spnego_ctx))
+			spnego_ctx->mic_reqd = 1;
 	}
 
 	/* Step 3: process or generate the MIC, if the negotiated mech is


More information about the cvs-krb5 mailing list