Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NTLM: Enable MIC generation with the gss-ntlmssp provider #65627

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/native/libs/System.Net.Security.Native/pal_gssapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o
.elements = gss_ntlm_oid_value};
#endif

static char gss_ntlmssp_require_mic_oid_value[] =
"\x2b\x06\x01\x04\x01\xb7\x7d\x85\x0f\x01\x02"; // Binary representation of SPNEGO Require MIC OID of gss-ntlmssp
static gss_OID_desc gss_ntlmssp_require_mic_OID_desc = {.length = STRING_LENGTH(gss_ntlmssp_require_mic_oid_value),
.elements = gss_ntlmssp_require_mic_oid_value};

#if defined(GSS_SHIM)

#define FOR_ALL_GSS_FUNCTIONS \
Expand All @@ -69,9 +74,11 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o
PER_FUNCTION_BLOCK(gss_indicate_mechs) \
PER_FUNCTION_BLOCK(gss_init_sec_context) \
PER_FUNCTION_BLOCK(gss_inquire_context) \
PER_FUNCTION_BLOCK(gss_inquire_sec_context_by_oid) \
PER_FUNCTION_BLOCK(gss_mech_krb5) \
PER_FUNCTION_BLOCK(gss_oid_equal) \
PER_FUNCTION_BLOCK(gss_release_buffer) \
PER_FUNCTION_BLOCK(gss_release_buffer_set) \
PER_FUNCTION_BLOCK(gss_release_cred) \
PER_FUNCTION_BLOCK(gss_release_name) \
PER_FUNCTION_BLOCK(gss_release_oid_set) \
Expand Down Expand Up @@ -108,8 +115,10 @@ static void* volatile s_gssLib = NULL;
#define gss_indicate_mechs(...) gss_indicate_mechs_ptr(__VA_ARGS__)
#define gss_init_sec_context(...) gss_init_sec_context_ptr(__VA_ARGS__)
#define gss_inquire_context(...) gss_inquire_context_ptr(__VA_ARGS__)
#define gss_inquire_sec_context_by_oid(...) gss_inquire_sec_context_by_oid_ptr(__VA_ARGS__)
#define gss_oid_equal(...) gss_oid_equal_ptr(__VA_ARGS__)
#define gss_release_buffer(...) gss_release_buffer_ptr(__VA_ARGS__)
#define gss_release_buffer_set(...) gss_release_buffer_set_ptr(__VA_ARGS__)
#define gss_release_cred(...) gss_release_cred_ptr(__VA_ARGS__)
#define gss_release_name(...) gss_release_name_ptr(__VA_ARGS__)
#define gss_release_oid_set(...) gss_release_oid_set_ptr(__VA_ARGS__)
Expand Down Expand Up @@ -373,6 +382,7 @@ uint32_t NetSecurityNative_InitSecContextEx(uint32_t* minorStatus,
GssBuffer inputToken = {.length = inputLength, .value = inputBytes};
GssBuffer gssBuffer = {.length = 0, .value = NULL};
gss_OID_desc* outmech;
int contextHandleWasNull = *contextHandle == NULL;

struct gss_channel_bindings_struct gssCbt;
if (cbt != NULL)
Expand All @@ -398,6 +408,26 @@ uint32_t NetSecurityNative_InitSecContextEx(uint32_t* minorStatus,

*isNtlmUsed = (isNtlm || majorStatus != GSS_S_COMPLETE || gss_oid_equal(outmech, krbMech) == 0) ? 1 : 0;

if (*isNtlmUsed && majorStatus == GSS_S_CONTINUE_NEEDED && contextHandleWasNull)
{
// Opportunistically try to enable the MIC for the gss-ntlmssp provider
// through a private option. Ignore errors since NTLM can be implemented
// by a different provider.
uint32_t tempMajorStatus;
uint32_t tempMinorStatus;
gss_buffer_set_t tempSet = GSS_C_NO_BUFFER_SET;

tempMajorStatus = gss_inquire_sec_context_by_oid(&tempMinorStatus,
*contextHandle,
&gss_ntlmssp_require_mic_OID_desc,
&tempSet);

if (tempSet != GSS_C_NO_BUFFER_SET)
{
tempMajorStatus = gss_release_buffer_set(&tempMinorStatus, &tempSet);
}
}

NetSecurityNative_MoveBuffer(&gssBuffer, outBuffer);
return majorStatus;
}
Expand Down