From a7e899281f24aadec536f3cb0adf7340683c27cb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 30 Mar 2016 13:00:19 -0400 Subject: [PATCH] Add SPNEGO special case for NTLMSSP+MechListMIC MS-SPNG section 3.3.5.1 documents an odd behavior the SPNEGO layer needs to implement specifically for the NTLMSSP mechanism. This is required for compatibility with Windows services. ticket: 8423 (new) --- src/lib/gssapi/spnego/spnego_mech.c | 48 +++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index bb754d9..b76f7d6 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -520,6 +520,45 @@ mech_requires_mechlistMIC(spnego_gss_ctx_id_t sc) 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 @@ -601,6 +640,8 @@ process_mic(OM_uint32 *minor_status, gss_buffer_t mic_in, 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; @@ -615,6 +656,8 @@ process_mic(OM_uint32 *minor_status, gss_buffer_t mic_in, 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; @@ -820,11 +863,6 @@ init_ctx_nego(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc, 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. */ -- 2.8.1