summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/gssapi/spnego/spnego_mech.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 7529c7426..7be8d71be 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -474,6 +474,41 @@ create_spnego_ctx(void)
return (spnego_ctx);
}
+
+static const gss_OID_desc spnego_req_mic_oid =
+ { 11, "\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x02" };
+/*
+ * Helper function to check with mechanism on whether we need to force
+ * emission of a mechlistMIC. This is normally used by an NTLMSSP
+ * mechanism that wants to MIC protect an Authenticate message due to
+ * a bug i Windows servers that seem to require a mechlistMIC in violation
+ * of RFC 4178 c which says it should be optional.
+ */
+static void
+check_mic_required(spnego_gss_ctx_id_t sc)
+{
+ OM_uint32 tmpret, tmpmin;
+ gss_buffer_set_t data_set;
+ uint8_t mic_set = 0;
+
+ tmpret = gss_inquire_sec_context_by_oid(&tmpmin, sc->ctx_handle,
+ &spnego_req_mic_oid,
+ &data_set);
+ if (tmpret) return;
+
+ if (data_set &&
+ data_set->count == 1 &&
+ data_set->elements[0].length == sizeof(uint8_t)) {
+ memcpy(&mic_set, data_set->elements[0].value, sizeof(uint8_t));
+ }
+
+ if (mic_set == 1) {
+ sc->mic_reqd = 1;
+ }
+
+ gss_release_buffer_set(&tmpmin, &data_set);
+}
+
/*
* 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 +1049,9 @@ spnego_gss_init_sec_context(
actual_mech, &mechtok_out,
ret_flags, time_rec,
&negState, &send_token);
+
+ if (!HARD_ERROR(ret))
+ check_mic_required(spnego_ctx);
}
/* Step 3: process or generate the MIC, if the negotiated mech is