diff --git a/lib/gssapi/gssapi/gssapi_oid.h b/lib/gssapi/gssapi/gssapi_oid.h index 6081c6989..751fa491a 100644 --- a/lib/gssapi/gssapi/gssapi_oid.h +++ b/lib/gssapi/gssapi/gssapi_oid.h @@ -154,8 +154,8 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_spnego_mechanism_oid_desc; #define GSS_SPNEGO_MECHANISM (&__gss_spnego_mechanism_oid_desc) /* From Luke Howard */ -extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_peer_has_updated_spnego_oid_desc; -#define GSS_C_PEER_HAS_UPDATED_SPNEGO (&__gss_c_peer_has_updated_spnego_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_inq_peer_has_buggy_spnego_oid_desc; +#define GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO (&__gss_c_inq_peer_has_buggy_spnego_oid_desc) extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_reset_crypto_oid_desc; #define GSS_C_NTLM_RESET_CRYPTO (&__gss_c_ntlm_reset_crypto_oid_desc) diff --git a/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/lib/gssapi/krb5/inquire_sec_context_by_oid.c index f1ed99320..f57277422 100644 --- a/lib/gssapi/krb5/inquire_sec_context_by_oid.c +++ b/lib/gssapi/krb5/inquire_sec_context_by_oid.c @@ -263,39 +263,31 @@ static OM_uint32 inquire_sec_context_authz_data return ret; } -static OM_uint32 inquire_sec_context_has_updated_spnego +static OM_uint32 inquire_sec_context_has_buggy_spnego (OM_uint32 *minor_status, const gsskrb5_ctx context_handle, gss_buffer_set_t *data_set) { - int is_updated = 0; + uint8_t old_enctype; + gss_buffer_desc buffer; *minor_status = 0; *data_set = GSS_C_NO_BUFFER_SET; /* - * For Windows SPNEGO implementations, both the initiator and the - * acceptor are assumed to have been updated if a "newer" [CLAR] or - * different enctype is negotiated for use by the Kerberos GSS-API - * mechanism. + * For Windows SPNEGO implementations, the initiator or acceptor + * are presumed to be "buggy" (Windows 2003 or earlier) if an + * "older" (i.e. pre-AES per RFC 4121) encryption type was used. */ + HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex); - is_updated = (context_handle->more_flags & IS_CFX); - if (is_updated == 0) { - krb5_keyblock *acceptor_subkey; - - if (context_handle->more_flags & LOCAL) - acceptor_subkey = context_handle->auth_context->remote_subkey; - else - acceptor_subkey = context_handle->auth_context->local_subkey; - - if (acceptor_subkey != NULL) - is_updated = (acceptor_subkey->keytype != - context_handle->auth_context->keyblock->keytype); - } + old_enctype = ((context_handle->more_flags & IS_CFX) == 0); HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex); - return is_updated ? GSS_S_COMPLETE : GSS_S_FAILURE; + buffer.value = &old_enctype; + buffer.length = sizeof(old_enctype); + + return gss_add_buffer_set_member(minor_status, &buffer, data_set); } /* @@ -549,10 +541,10 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_sec_context_by_oid return inquire_sec_context_tkt_flags(minor_status, ctx, data_set); - } else if (gss_oid_equal(desired_object, GSS_C_PEER_HAS_UPDATED_SPNEGO)) { - return inquire_sec_context_has_updated_spnego(minor_status, - ctx, - data_set); + } else if (gss_oid_equal(desired_object, GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO)) { + return inquire_sec_context_has_buggy_spnego(minor_status, + ctx, + data_set); } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_SUBKEY_X)) { return inquire_sec_context_get_subkey(minor_status, ctx, diff --git a/lib/gssapi/libgssapi-exports.def b/lib/gssapi/libgssapi-exports.def index c699cad43..f54471cd4 100644 --- a/lib/gssapi/libgssapi-exports.def +++ b/lib/gssapi/libgssapi-exports.def @@ -168,7 +168,6 @@ EXPORTS __gss_krb5_mechanism_oid_desc DATA __gss_ntlm_mechanism_oid_desc DATA __gss_spnego_mechanism_oid_desc DATA - __gss_c_peer_has_updated_spnego_oid_desc DATA __gss_c_ma_mech_concrete_oid_desc DATA __gss_c_ma_mech_pseudo_oid_desc DATA __gss_c_ma_mech_composite_oid_desc DATA diff --git a/lib/gssapi/mech/gss_oid.c b/lib/gssapi/mech/gss_oid.c index 20d216069..99eacf4ef 100644 --- a/lib/gssapi/mech/gss_oid.c +++ b/lib/gssapi/mech/gss_oid.c @@ -142,8 +142,8 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_ntlm_mechanism_oid_desc = { 10, rk_UNCONS /* GSS_SPNEGO_MECHANISM - 1.3.6.1.5.5.2 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_spnego_mechanism_oid_desc = { 6, rk_UNCONST("\x2b\x06\x01\x05\x05\x02") }; -/* GSS_C_PEER_HAS_UPDATED_SPNEGO - 1.3.6.1.4.1.5322.19.5 */ -gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_peer_has_updated_spnego_oid_desc = { 9, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x13\x05") }; +/* GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO - 1.3.6.1.4.1.5322.19.6 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_peer_has_buggy_spnego_oid_desc = { 9, rk_UNCONST("\x2b\x06\x01\x04\x01\xa9\x4a\x13\x06") }; /* GSS_C_NTLM_RESET_CRYPTO - 1.3.6.1.4.1.7165.655.1.3 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ntlm_reset_crypto_oid_desc = { 11, rk_UNCONST("\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x03") }; @@ -325,7 +325,7 @@ gss_OID _gss_ot_internal[] = { &__gss_krb5_mechanism_oid_desc, &__gss_ntlm_mechanism_oid_desc, &__gss_spnego_mechanism_oid_desc, - &__gss_c_peer_has_updated_spnego_oid_desc, + &__gss_c_inq_peer_has_buggy_spnego_oid_desc, &__gss_c_ntlm_reset_crypto_oid_desc, &__gss_negoex_mechanism_oid_desc, &__gss_c_ma_mech_concrete_oid_desc, diff --git a/lib/gssapi/oid.txt b/lib/gssapi/oid.txt index 2bf101ea6..7d56b639a 100644 --- a/lib/gssapi/oid.txt +++ b/lib/gssapi/oid.txt @@ -66,7 +66,7 @@ oid base GSS_SPNEGO_MECHANISM 1.3.6.1.5.5.2 # /* From Luke Howard */ -oid base GSS_C_PEER_HAS_UPDATED_SPNEGO 1.3.6.1.4.1.5322.19.5 +oid base GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO 1.3.6.1.4.1.5322.19.6 oid base GSS_C_NTLM_RESET_CRYPTO 1.3.6.1.4.1.7165.655.1.3 oid base GSS_NEGOEX_MECHANISM 1.3.6.1.4.1.311.2.2.30 diff --git a/lib/gssapi/spnego/compat.c b/lib/gssapi/spnego/compat.c index d24a2f848..1e09addac 100644 --- a/lib/gssapi/spnego/compat.c +++ b/lib/gssapi/spnego/compat.c @@ -152,38 +152,30 @@ OM_uint32 GSSAPI_CALLCONV _gss_spnego_internal_delete_sec_context return ret; } -/* - * Returns TRUE if the mechanism believes that a mechListMIC is required. - * This is an internal interface for NTLM which requires a mechListMIC if - * an internal MIC in the NTLM protocol was used. Note that only the Samba - * NTLM mechanism supports this, it is not yet implemented in Heimdal's. - */ - static int -mech_require_mechlist_mic_p(gssspnego_ctx ctx) +inq_context_by_oid_bool(gssspnego_ctx ctx, gss_OID oid) { OM_uint32 major, minor; gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET; - uint8_t mech_require_mic = 0; + uint8_t ret = 0; major = gss_inquire_sec_context_by_oid(&minor, ctx->negotiated_ctx_id, - GSS_C_INQ_REQUIRE_MECHLIST_MIC, &data_set); + oid, &data_set); if (major != GSS_S_COMPLETE) return FALSE; if (data_set != GSS_C_NO_BUFFER_SET && data_set->count == 1 && data_set->elements[0].length == 1) - mech_require_mic = *((uint8_t *)data_set->elements[0].value); + ret = *((uint8_t *)data_set->elements[0].value); gss_release_buffer_set(&minor, &data_set); - return mech_require_mic == 1; + return ret != 0; } /* - * Returns TRUE if it is safe to omit mechListMIC because the preferred - * mechanism was selected, and the peer did not require it. + * Returns TRUE if it is safe to omit mechListMIC. */ int @@ -193,11 +185,16 @@ _gss_spnego_safe_omit_mechlist_mic(gssspnego_ctx ctx) if (ctx->flags.peer_require_mic) { _gss_mg_log(10, "spnego: mechListMIC required by peer"); - } else if (mech_require_mechlist_mic_p(ctx)) { + } else if (inq_context_by_oid_bool(ctx, GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO)) { + /* [MS-SPNG] Appendix A <7> Section 3.1.5.1: may be old peer with buggy SPNEGO */ + safe_omit = TRUE; + _gss_mg_log(10, "spnego: mechListMIC omitted for legacy interoperability"); + } else if (inq_context_by_oid_bool(ctx, GSS_C_INQ_REQUIRE_MECHLIST_MIC)) { + /* [MS-SPNG] Appendix A <7> Section 3.1.5.1: allow NTLM to force MIC */ _gss_mg_log(10, "spnego: mechListMIC required by mechanism"); } else if (gss_oid_equal(ctx->selected_mech_type, ctx->preferred_mech_type)) { safe_omit = TRUE; - _gss_mg_log(10, "spnego: mechListMIC may be omitted as preferred mechanism selected"); + _gss_mg_log(10, "spnego: mechListMIC omitted as preferred mechanism selected"); } else { _gss_mg_log(10, "spnego: mechListMIC required by default"); } diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 03ef28e4a..59c76a3d1 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -171,7 +171,6 @@ HEIMDAL_GSS_2.0 { __gss_krb5_mechanism_oid_desc; __gss_ntlm_mechanism_oid_desc; __gss_spnego_mechanism_oid_desc; - __gss_c_peer_has_updated_spnego_oid_desc; __gss_c_ma_mech_concrete_oid_desc; __gss_c_ma_mech_pseudo_oid_desc; __gss_c_ma_mech_composite_oid_desc;