return result;
}
+/* iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) Microsoft(311)
+ * security(2) mechanisms(2) NTLM(10) */
+static const gss_OID_desc gss_mech_ntlmssp_oid =
+ { 10, "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a" };
+
+/* iso(1) org(3) dod(6) internet(1) private(4) enterprises(1) samba(7165)
+ * gssntlmssp(655) controls(1) ntlmssp_reset_crypto(3) */
+static const gss_OID_desc ntlmssp_reset_crypto_oid =
+ { 11, "\x2B\x06\x01\x04\x01\xB7\x7D\x85\x0F\x01\x03" };
+
+/*
+ * MS-SPNG section 3.3.5.1 warns that the NTLM mechanism requires special
+ * handling of the crypto state to interop with Windows. If the mechanism for
+ * sc is SPNEGO, invoke a mechanism-specific operation on the context to reset
+ * the RC4 state after producing or verifying a MIC. Ignore a result of
+ * GSS_S_UNAVAILABLE for compatibility with older versions of the mechanism
+ * that do not support this functionality.
+ */
+static OM_uint32
+ntlmssp_reset_crypto_state(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
+ OM_uint32 verify)
+{
+ OM_uint32 major, minor;
+ gss_buffer_desc value;
+
+ if (!g_OID_equal(sc->internal_mech, &gss_mech_ntlmssp_oid))
+ return GSS_S_COMPLETE;
+
+ value.length = sizeof(verify);
+ value.value = &verify;
+ major = gss_set_sec_context_option(&minor, &sc->ctx_handle,
+ (gss_OID)&ntlmssp_reset_crypto_oid,
+ &value);
+ if (major == GSS_S_UNAVAILABLE)
+ return GSS_S_COMPLETE;
+ *minor_status = minor;
+ return major;
+}
+
/*
* 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
ret = gss_verify_mic(minor_status, sc->ctx_handle,
&sc->DER_mechTypes,
mic_in, &qop_state);
+ if (ret == GSS_S_COMPLETE)
+ ret = ntlmssp_reset_crypto_state(minor_status, sc, 1);
if (ret != GSS_S_COMPLETE) {
*negState = REJECT;
*tokflag = ERROR_TOKEN_SEND;
GSS_C_QOP_DEFAULT,
&sc->DER_mechTypes,
&tmpmic);
+ if (ret == GSS_S_COMPLETE)
+ ret = ntlmssp_reset_crypto_state(minor_status, sc, 0);
if (ret != GSS_S_COMPLETE) {
gss_release_buffer(&tmpmin, &tmpmic);
*tokflag = NO_TOKEN_SEND;
return ret;
}
-/* iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) Microsoft(311)
- * security(2) mechanisms(2) NTLM(10) */
-static const gss_OID_desc gss_mech_ntlmssp_oid =
- { 10, "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a" };
-
/*
* Handle acceptor's counter-proposal of an alternative mechanism.
*/