Uh oh!
There was an error while loading. Please reload this page.
Fix NegotiateStream connections between Linux clients and Windows servers - #99909
Conversation
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones |
| if (message.Length > 0) | ||
| { | ||
| Debug.Assert(_context != null); | ||
| _context.GetOutgoingBlob(message, out NegotiateAuthenticationStatusCode statusCode); | ||
| _remoteOk = statusCode is NegotiateAuthenticationStatusCode.Completed; | ||
| } |
There was a problem hiding this comment.
Review note:
This was likely broken for quite a long time and went unnoticed. Windows clients send raw NTLM instead of SPNEGO if NTLM is the only protocol available. Linux/macOS GSSAPI libraries are aware of this quirk and handle it too. In that case the last handshake message will be empty.
Skipping the processing of the last handshake message is mostly harmless. In SPNEGO it would contain the final message integrity check. Skipping this check could enable some man-in-the-middle attacks, at least in theory. In case of managed NTLM/SPNEGO, however, we reset the NTLM keys only after this very last message is processed. If this is skipped the client and server will have mismatched encryption keys. This is how the bug was discovered.
In theory we can align with GSSAPI by calling (_mechanism as ManagedNtlmNegotiateAuthenticationPal)?.ResetKeys(); here:
We would reset the key both after
GetMIC and VerifyMIC instead of doing it only after VerifyMIC. It may not be desirable to do so though; when the API is used correctly and securely this is not an issue.
wfurt
left a comment
There was a problem hiding this comment.
LGTM. Seems like test is failing on some platforms.
filipnavara
commented
Mar 19, 2024
I will have a look. Helix was rather unhealthy today so I forgot to check the test results. |
ProtectionLevel.EncryptAndSign. Process the last handshake done message in NegotiateStream. In case of SPNEGO protocol it may contain message integrity check. Additionally, if the negotiated protocol is NTLM then we need to reset the encryption key after the message integrity check is verified.
filipnavara
commented
Mar 19, 2024
Turns out that I had one check order bug and one incorrect assumption in the test. The incorrect assumption was that I tried to check the scenario where the server doesn't support the
Linux and the managed implementation handle it by returning error. Windows implementation silently assumes that the specification is followed and ignores that the server stripped |
filipnavara
commented
Mar 19, 2024
Just when I thought the CI cannot be any more borken... it fails to start any pipelines at all. |
wfurt
commented
Mar 19, 2024
thanks @filipnavara for digging deep into this. while your chance did not touched |
filipnavara
commented
Mar 20, 2024
These correlate with a Also, the osx-x64 tests should be using Managed NTLM and should not fail like that. |
…shakeComplete. If HandshakeComplete is not true, then the authentication blob will get processed with the normal flow.
filipnavara
commented
Mar 20, 2024
Helix is in quite a disrepair for the past few days (auto-scaler fails to scale several queues; already reported). The relevant pipelines succeeded though (win-x86, osx-x64). |
rzikm
commented
May 14, 2024
/backport to release/8.0-staging |
Started backporting to release/8.0-staging: https://github.com/dotnet/runtime/actions/runs/9084265804 |
@rzikm backporting to release/8.0-staging failed, the patch most likely resulted in conflicts: $ git am --3way --ignore-whitespace --keep-non-patch changes.patch
Applying: Send the NegotiateSeal NTLM flag when client asked for ProtectionLevel.EncryptAndSign.
Applying: Add testfor the NegotiateSeal flag
Using index info to reconstruct a base tree...
M src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs
Falling back to patching base and 3-way merge...
Auto-merging src/libraries/System.Net.Security/tests/UnitTests/NegotiateAuthenticationTests.cs
Applying: Fix the test
Patch is empty.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To record the empty patch as an empty commit, run "git am --allow-empty".
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128Please backport manually! |
@rzikm an error occurred while backporting to release/8.0-staging, please check the run log for details! Error: git am failed, most likely due to a merge conflict. |
karelz
commented
May 30, 2024
Backport to 8.0 in PR #102216 |
Fixes#99227
Managed NTLM: Send the NegotiateSeal NTLM flag when client asks for ProtectionLevel.EncryptAndSign.
NegotiateStream: Process the last handshake done message. In case of SPNEGO protocol it may contain message integrity check. Additionally, if the negotiated protocol is NTLM then we need to reset the encryption keys after the message integrity check is verified.