-
Notifications
You must be signed in to change notification settings - Fork 0
[✨ Triage] dotnet/runtime#126337 by mconnew - NegotiateAuthentication failed authentication doesn't notify of Target ... #179
Description
Triage for dotnet/runtime#126337.
Repo filter: All networking issues.
MihuBot version: 246635.
Ping MihaZupan for any issues.
This is a test triage report generated by AI, aimed at helping the triage team quickly identify past issues/PRs that may be related.
Take any conclusions with a large grain of salt.
Tool logs
dotnet/runtime#126337: NegotiateAuthentication failed authentication doesn't notify of TargetUnknown by mconnew
Extracted 5 search queries: NegotiateAuthentication returns GenericFailure instead of TargetUnknown, SecurityStatusPalErrorCode.TargetUnknown mapping to NegotiateAuthenticationStatusCode on Windows, GSS_S_FAILURE KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN mapped to GenericFailure in NegotiateAuthentication on Unix, Non-existent SPN (target unknown) yields GenericFailure in System.Net.Security NegotiateAuthentication, Mapping native Kerberos/GSS errors to NegotiateAuthenticationStatusCode in System.Net.Security
Found 25 candidate issues
Issue #69920 (May 2022) - " [API Proposal]: Expose a high level authentication API"
- Proposed a public NegotiateAuthentication API and an accompanying NegotiateAuthenticationStatusCode enum that already includes TargetUnknown as a distinct status.
- Discussion covered expected API shape, error reporting, and how to map native SSPI/GSSAPI errors into the managed enum. Multiple reviewers suggested using spans, avoiding throwing for normal authentication failures, and exposing richer status info where needed.
- This issue is the origin of the higher-level API design that later became PR #70720.
PR #70720 (June 2022) - "Implement NegotiateAuthentication API" (merged)
- Implemented the NegotiateAuthentication API based on the proposal.
- The implementation maps platform-native security results (SecurityStatusPalErrorCode) to the managed NegotiateAuthenticationStatusCode. In that mapping SecurityStatusPalErrorCode.TargetUnknown was intentionally mapped to NegotiateAuthenticationStatusCode.GenericFailure (i.e. TargetUnknown on Windows became GenericFailure in the public enum).
- Several reviewers called out error mapping and exceptional cases during review; the merged code is the current behavior your issue reports as surprising.
Issue #103536 (June 16, 2024) - "NegotiateAuthentication - Provide method to get error messages"
- Reporter asked for a way to obtain the native GSSAPI/SSPI major/minor error codes and messages (clock skew example) instead of getting only GenericFailure.
- Core team members (filipnavara and others) acknowledged that some native errors could be mapped better and pointed out that tracing already contains native details. They discussed API options (out substatus parameter, overloads, returning tuples, or exposing a last-error stack) and cautioned about platform differences (SSPI GetLastError undefined).
- Triage: room for improvement; not critical for 9.0. This discussion directly recognizes the problem you’re hitting (native-specific errors becoming GenericFailure) and explores adding finer-grained native/status exposure.
Issue #69828 (May 25, 2022) - "Unhandled SECURITY_STATUS (0x80090016) ... InternalException"
- Described a missing mapping in SecurityStatusAdapterPal that caused an InternalException when an unknown SECURITY_STATUS was encountered.
- Triage recommended adding the missing mapping entry; the associated PR (#69942) added the mapping so the runtime translates the native code into a managed status instead of throwing InternalException.
- Conclusion / relevance: there is precedent for fixing missing or insufficient mappings by adding mappings in the adapter layer so callers receive a meaningful managed status/exception rather than an internal-only exception.
PR #69942 (May–Jun 2022) - "handle SECURITY_STATUS 0x80090016" (merged)
- Implemented the mapping for the specific SECURITY_STATUS that was previously unhandled.
- Reinforces that adding explicit mappings in the adapter layer is the established fix pattern.
PR #70474 (June 2022) - "Avoid throwing Win32Exception from HTTP authentication" (merged)
- Fixed cases where native/SSPI failures bubbled out as Win32Exception from higher-level HTTP APIs; instead the stack translates them into HttpRequestException or other higher-level errors.
- Shows that mapping/translation behavior of native errors is intentionally adjusted to be more appropriate for public APIs.
PR #87930 (Jun–Jul 2023) - "Restructure NegotiateAuthentication implementation" (merged)
- Reworked the internal implementation to use per-platform PALs and introduced a managed NTLM/SPNEGO fallback option (UseManagedNtlm switch) for Unix.
- Relevant because platform-specific PALs are where native results are produced/mapped; differences in mapping behavior across PALs can lead to mismatches like the one you report.
Issue #18557 (Sep 2016) - "Failed assert in NegotiateStream_StreamToStream_Authentication_TargetName_Success"
- Older example where a Windows SEC_E_* code (SEC_E_DOWNGRADE_DETECTED) was not present in the adapter table and was added after investigation.
- Historical precedent: when Windows/SSPI return codes are not in the mapping table, the codebase has accepted adding entries so callers get meaningful mapped results.
Summary of relevance to your report
- The current public NegotiateAuthentication API and its status enum do include TargetUnknown as a symbolic status, but the implementation (mapping layer) has in multiple places chosen to map some native error codes (including SecurityStatusPalErrorCode.TargetUnknown) to GenericFailure. PR #70720 explicitly shows that mapping choice.
- There is precedent and recent discussion (see #103536 and the 2022 mapping fixes) for improving the mapping surface: either by mapping more native codes to distinct managed statuses, or by exposing native major/minor/substatus details (via out parameters or richer APIs/tracing) so callers can diagnose protocol-specific failures (Kerberos minor codes, KRB5 errors, etc.).
- Practical precedent for fixes: when a native SECURITY_STATUS was unhandled, the fix was to add a mapping in the adapter (see #69828 / #69942). That suggests the simplest fix for your case is to add/adjust the mapping so SecurityStatusPalErrorCode.TargetUnknown → NegotiateAuthenticationStatusCode.TargetUnknown (and/or to surface native substatus info).
If you want, next steps you can reference or include in the issue:
- Point to the exact mapping code (the switch that maps SecurityStatusPalErrorCode to NegotiateAuthenticationStatusCode in the NegotiateAuthentication implementation / SecurityStatusAdapterPal) and propose changing the TargetUnknown entry from GenericFailure to TargetUnknown.
- If more diagnostic detail is desirable, reference Issue #103536 as the discussion around exposing native major/minor codes or an out substatus parameter (e.g. GetOutgoingBlob(..., out int substatus) or equivalent) so callers can get GSSAPI/Kerberos minor codes when available.