Skip to content
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