-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Restructure NegotiateAuthentication implementation #87930
Conversation
…ugh NegotiateAuthenticationPal to the actual implementation. The PAL implementation are merged from different sources to follow the same structure: - NTAuthentication.Managed.cs -> NegotiateAuthenticationPal.Managed.cs - NTAuthentication.Common.cs + NegotiateStreamPal.Windows.cs -> NegotiateAuthenticationPal.Windows.cs - NTAuthentication.Common.cs + NegotiateStreamPal.Unix.cs -> NegotiateAuthenticationPal.Unix.cs This split allows to delete ContextFlagsPal, SafeDeleteNegoContext, and SafeFreeNegoCredentials abstractions that were used in NegotiateStreamPal.
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones Issue Details[NOT FOR REVIEW YET, JUST WANT TO RUN THROUGH CI] Change The PAL implementation are merged from different sources to follow the same structure:
This split allows to delete
|
…Ntlm switch on Unix platforms
@wfurt While not quite polished and ready for review yet, this implements the changes for Please let me know if the general direction makes sense to you. I'm still undecided whether it would make sense to have two switches ( |
3851657
to
f082fcd
Compare
{ | ||
try | ||
{ | ||
if (!Interop.NetSecurityNative.IsNtlmInstalled()) | ||
{ | ||
_useManagedNtlm = !AppContext.TryGetSwitch("System.Net.Security.UseManagedNtlm", out bool useManagedNtlm) || useManagedNtlm; | ||
} | ||
else | ||
{ | ||
_useManagedNtlm = AppContext.TryGetSwitch("System.Net.Security.UseManagedNtlm", out bool useManagedNtlm) && useManagedNtlm; | ||
} | ||
_isGssApiAvailable = true; | ||
} | ||
catch (EntryPointNotFoundException) | ||
{ | ||
// GSSAPI shim may not be available on some platforms (Linux Bionic) | ||
_isGssApiAvailable = false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I am not entirely keen on shipping the fallbacks this way.
I propose to change it to the following:
- Add the optional
System.Net.Security.UseManagedNtlm
switch and default tofalse
. - Do not fallback to managed NTLM/SPNEGO if the native GSSAPI is missing NTLM-SSP (ie. align behavior with .NET 7 and older).
- Add ILLink script that links away
ManagedNtlm
andManagedSpnego
unlessSystem.Net.Security.UseManagedNtlm
is set. - Update NativeAOT linux-bionic builds to set
System.Net.Security.UseManagedNtlm=true
unconditionally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to fallback to managed only for NTLM and not Negotiate if NTLM-SSP is missing? We would not interfere with negotiation in any way but it would provide some legacy capability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For reference, this is implementation of the proposal above: aa22b0a
It mostly reverts all the fallback paths to .NET 7 behavior and only enables them with the AppContext switch.
Doing only managed NTLM without managed SPNEGO is feasible but not very practical. HTTP servers almost universally send either Negotiate only, or both Negotiate+NTLM. In both cases this would still fail the authentication because Negotiate gets the preference. There may be some SMTP server that supports only NTLM but that's really niche use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, if you feel like we should do ManagedNtlm
-only and not ManagedSpNego
for !Interop.NetSecurityNative.IsNtlmInstalled()
I can do it. It will just need a re-run of the whole test matrix to figure out what breaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about #87568 and perhaps Azure functions were there is no control over installed packages. But I guess the AppContext should be good enough for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed the one extra commit mentioned above. It passed CI in #89051 test PR except for few legs that failed due to infra failures. They are now re-running 🤞
…enticationPal.Unix.cs
I assume at this point we are pretty much out of luck for .NET 8, right @wfurt? I would like to wrap this up soon anyway... |
sorry for the delay, I will look today. can you please resolve the conflict. I saw bunch of test failures but I did not go through them. |
// GSS on Linux does not work with OpenSSL 3.0. Fix was submitted to gss-ntlm but it will take a while to make to | ||
// all supported distributions. The second part of the check should be removed when it does. | ||
return Interop.NetSecurityNative.IsNtlmInstalled() && (!PlatformDetection.IsOpenSslSupported || PlatformDetection.OpenSslVersion.Major < 3); | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need the property at all? Or keep it for future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that depends on the answer in #87930 (comment). In any case I would not remove it as part of this PR, it would be separate change. Mainly there's a concern about Windows with NTLM disabled, so there would still be use for it.
…m has to be enabled explicitly; NativeAOT on Linux Bionic does that by default because it doesn't have GSSAPI and native shim
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. thanks @filipnavara
test failures seems unrelated. |
seems like another merge conflict from #88810 @filipnavara. I can merge in the morning. |
Fixed. |
thanks @filipnavara |
Thanks for review! |
@filipnavara @wfurt I just moved from .NET 7 to .NET 8 and my IWA tests on Android are now broken hitting this bit of code this PR added: runtime/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.ManagedNtlm.cs Line 229 in f9b07d4
|
@dotMorten Can you file issue with some small repro? That use case was definitely not supported in .NET 7 either. |
Yup working on it. Definitely a regression/change in behavior over 7 |
I'm wondering if it just failed to authenticate in the past and now it throws...? As @filipnavara said, there is no default identity on Android we can use for NTLM. |
Change
NegotiateAuthentication
implementation to use indirection throughNegotiateAuthenticationPal
to the actual implementation.The PAL implementations are merged from different sources to follow the same structure:
This split allows to delete
ContextFlagsPal
,SafeDeleteNegoContext
, andSafeFreeNegoCredentials
abstractions that were used inNegotiateStreamPal
.Additionally, a new app context option is added (
System.Net.Security.UseManagedNtlm
) to unconditionally turn on managed implementation of NTLM and SPNEGO on Unix-like platforms. On Linux systems without NTLM GSSAPI provider the managed NTLM and SPNEGO implementations are turned on by default, they can be turned off by setting theSystem.Net.Security.UseManagedNtlm
option tofalse
.Contributes to #87665, #80846