This PR addresses 3 issues in GSSAPI error handling:
* Fixes an uninitialized variable when calling gss_display_status().
This was causing the major statuscode error message to always return
'An invalid status code was supplied'.
* If the minor statuscode is 0 (GSS_S_COMPLETE), we shouldn't be calling
for the minor statuscode error message text. That is why we were always getting
'Unknown error' for that text.
* Added more text (help text) to certain errors returned from GSSAPI
such as when the NTLM plugin is not installed.
No new tests were added to this PR since it requires machine changes
to test. However, I manually tested various combinations of errors
including when 'gss-ntlmssp' is installed or not.
In terms of dotnet/corefx#34877, the exception message goes from:
>GSSAPI operation failed with error - An invalid status code was supplied (Unknown error).
to
>GSSAPI operation failed with error - An unsupported mechanism was requested. NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.
Fixes dotnet/corefx#34877
Commit migrated from https://github.com/dotnet/corefx/commit/
eec001d96a68376c0e504eb7635c8edec196f90f
}
public GssApiException(Status majorStatus, Status minorStatus)
- : base(GetGssApiDisplayStatus(majorStatus, minorStatus))
+ : base(GetGssApiDisplayStatus(majorStatus, minorStatus, null))
{
HResult = (int)majorStatus;
_minorStatus = minorStatus;
}
- private static string GetGssApiDisplayStatus(Status majorStatus, Status minorStatus)
+ public GssApiException(Status majorStatus, Status minorStatus, string helpText)
+ : base(GetGssApiDisplayStatus(majorStatus, minorStatus, helpText))
+ {
+ HResult = (int)majorStatus;
+ _minorStatus = minorStatus;
+ }
+
+ private static string GetGssApiDisplayStatus(Status majorStatus, Status minorStatus, string helpText)
{
string majorError = GetGssApiDisplayStatus(majorStatus, isMinor: false);
- string minorError = GetGssApiDisplayStatus(minorStatus, isMinor: true);
+ string errorMessage;
+
+ if (minorStatus != Status.GSS_S_COMPLETE)
+ {
+ string minorError = GetGssApiDisplayStatus(minorStatus, isMinor: true);
+ errorMessage = (majorError != null && minorError != null) ?
+ SR.Format(SR.net_gssapi_operation_failed_detailed, majorError, minorError) :
+ SR.Format(SR.net_gssapi_operation_failed, majorStatus.ToString("x"), minorStatus.ToString("x"));
+ }
+ else
+ {
+ errorMessage = (majorError != null) ?
+ SR.Format(SR.net_gssapi_operation_failed_detailed_majoronly, majorError) :
+ SR.Format(SR.net_gssapi_operation_failed_majoronly, majorStatus.ToString("x"));
+ }
+
+ if (!string.IsNullOrEmpty(helpText))
+ {
+ return errorMessage + " " + helpText;
+ }
- return (majorError != null && minorError != null) ?
- SR.Format(SR.net_gssapi_operation_failed_detailed, majorError, minorError) :
- SR.Format(SR.net_gssapi_operation_failed, majorStatus.ToString("x"), minorStatus.ToString("x"));
+ return errorMessage;
}
private static string GetGssApiDisplayStatus(Status status, bool isMinor)
internal enum Status : uint
{
GSS_S_COMPLETE = 0,
- GSS_S_CONTINUE_NEEDED = 1
+ GSS_S_CONTINUE_NEEDED = 1,
+ GSS_S_BAD_MECH = 65536
}
[Flags]
if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
{
retHandle.Dispose();
- throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
+ throw new Interop.NetSecurityNative.GssApiException(
+ status,
+ minorStatus,
+ (status == Interop.NetSecurityNative.Status.GSS_S_BAD_MECH && isNtlmOnly) ?
+ SR.net_gssapi_ntlm_missing_plugin :
+ null);
}
}
assert(minorStatus != NULL);
assert(outBuffer != NULL);
- uint32_t messageContext;
+ uint32_t messageContext = 0; // Must initialize to 0 before calling gss_display_status.
GssBuffer gssBuffer = {.length = 0, .value = NULL};
uint32_t majorStatus =
gss_display_status(minorStatus, statusValue, statusType, GSS_C_NO_OID, &messageContext, &gssBuffer);
<data name="net_gssapi_operation_failed" xml:space="preserve">
<value>GSSAPI operation failed with status: {0} (Minor status: {1}).</value>
</data>
+ <data name="net_gssapi_operation_failed_detailed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with error - {0}.</value>
+ </data>
+ <data name="net_gssapi_operation_failed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with status: {0}.</value>
+ </data>
+ <data name="net_gssapi_ntlm_missing_plugin" xml:space="preserve">
+ <value>NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.</value>
+ </data>
<data name="net_ntlm_not_possible_default_cred" xml:space="preserve">
<value>NTLM authentication is not possible with default credentials on this platform.</value>
</data>
<data name="net_gssapi_operation_failed" xml:space="preserve">
<value>GSSAPI operation failed with status: {0} (Minor status: {1}).</value>
</data>
+ <data name="net_gssapi_operation_failed_detailed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with error - {0}.</value>
+ </data>
+ <data name="net_gssapi_operation_failed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with status: {0}.</value>
+ </data>
+ <data name="net_gssapi_ntlm_missing_plugin" xml:space="preserve">
+ <value>NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.</value>
+ </data>
<data name="net_nego_channel_binding_not_supported" xml:space="preserve">
<value>No support for channel binding on operating systems other than Windows.</value>
</data>
<data name="net_gssapi_operation_failed" xml:space="preserve">
<value>GSSAPI operation failed with status: {0} (Minor status: {1}).</value>
</data>
+ <data name="net_gssapi_operation_failed_detailed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with error - {0}.</value>
+ </data>
+ <data name="net_gssapi_operation_failed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with status: {0}.</value>
+ </data>
+ <data name="net_gssapi_ntlm_missing_plugin" xml:space="preserve">
+ <value>NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.</value>
+ </data>
<data name="net_nego_channel_binding_not_supported" xml:space="preserve">
<value>No support for channel binding on operating systems other than Windows.</value>
</data>
<data name="net_gssapi_operation_failed" xml:space="preserve">
<value>GSSAPI operation failed with status: {0} (Minor status: {1}).</value>
</data>
+ <data name="net_gssapi_operation_failed_detailed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with error - {0}.</value>
+ </data>
+ <data name="net_gssapi_operation_failed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with status: {0}.</value>
+ </data>
+ <data name="net_gssapi_ntlm_missing_plugin" xml:space="preserve">
+ <value>NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.</value>
+ </data>
<data name="net_context_buffer_too_small" xml:space="preserve">
<value>Insufficient buffer space. Required: {0} Actual: {1}.</value>
</data>
<data name="net_gssapi_operation_failed" xml:space="preserve">
<value>GSSAPI operation failed with status: {0} (Minor status: {1})</value>
</data>
+ <data name="net_gssapi_operation_failed_detailed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with error - {0}.</value>
+ </data>
+ <data name="net_gssapi_operation_failed_majoronly" xml:space="preserve">
+ <value>GSSAPI operation failed with status: {0}.</value>
+ </data>
+ <data name="net_gssapi_ntlm_missing_plugin" xml:space="preserve">
+ <value>NTLM authentication requires the GSSAPI plugin 'gss-ntlmssp'.</value>
+ </data>
<data name="net_context_establishment_failed" xml:space="preserve">
<value>GSSAPI security context establishment failed with status: {0} (Minor status: {1})</value>
</data>