/* GSS_C_INQ_NEGOEX_VERIFY_KEY - 1.2.840.113554.1.2.2.5.17 */
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_negoex_verify_key_oid_desc = { 11, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x11") };
+/* GSS_C_INQ_REQUIRE_MECHLIST_MIC - 1.3.6.1.4.1.7165.655.1.2 */
+gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_inq_require_mechlist_mic_oid_desc = { 11, rk_UNCONST("\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x02") };
+
/* GSS_KRB5_MECHANISM - 1.2.840.113554.1.2.2 */
gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_mechanism_oid_desc = { 9, rk_UNCONST("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
&__gss_c_inq_sspi_session_key_oid_desc,
&__gss_c_inq_negoex_key_oid_desc,
&__gss_c_inq_negoex_verify_key_oid_desc,
+ &__gss_c_inq_require_mechlist_mic_oid_desc,
&__gss_krb5_mechanism_oid_desc,
&__gss_ntlm_mechanism_oid_desc,
&__gss_spnego_mechanism_oid_desc,
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)
+{
+ OM_uint32 major, minor;
+ gss_buffer_set_t data_set = GSS_C_NO_BUFFER_SET;
+ uint8_t mech_require_mic = 0;
+
+ major = gss_inquire_sec_context_by_oid(&minor, ctx->negotiated_ctx_id,
+ GSS_C_INQ_REQUIRE_MECHLIST_MIC, &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);
+
+ gss_release_buffer_set(&minor, &data_set);
+
+ return mech_require_mic == 1;
+}
+
/*
* Returns TRUE if it is safe to omit mechListMIC because the preferred
* mechanism was selected, and the peer did not require it.
int
_gss_spnego_safe_omit_mechlist_mic(gssspnego_ctx ctx)
{
- int safe_omit = 0;
-
- if (ctx->flags.peer_require_mic == FALSE)
- safe_omit = gss_oid_equal(ctx->selected_mech_type, ctx->preferred_mech_type);
-
- if (safe_omit)
- _gss_mg_log(10, "spnego: safe to omit mechListMIC, as preferred mechanism selected");
- else
- _gss_mg_log(10, "spnego: mechListMIC required");
+ int safe_omit = FALSE;
+
+ if (ctx->flags.peer_require_mic) {
+ _gss_mg_log(10, "spnego: mechListMIC required by peer");
+ } else if (mech_require_mechlist_mic_p(ctx)) {
+ _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");
+ } else {
+ _gss_mg_log(10, "spnego: mechListMIC required by default");
+ }
return safe_omit;
}