Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Fix NegotitateStream (server) on Linux for NTLM #42522

Merged
merged 2 commits into from
Nov 11, 2019

Conversation

davidsh
Copy link
Contributor

@davidsh davidsh commented Nov 10, 2019

This PR is a follow up to PR #36827 which added support for Linux server-side
GSS-API (AcceptSecContext). This enabled NegotitateStream AuthenticateAsServer*
support. It also provided support for ASP.NET Core to allow Kestrel server to have
Negotiate authentication on Linux.

This PR fixes some problems with Negotiate (SPNEGO) fallback from Kerberos to NTLM.
Notably it passes in a correct GSS Acceptor credential so that fallback will work
correctly. As part of fixing that, I noticed some other problems with returning the
user-identity when NTLM is used.

This was tested in a separate enterprise testing environment that I have created.
It builds on technologies that we have started using like docker containers and Azure
pipelines (e.g. HttpStress). The environment is currently here. The extra Kerberos tests
and container support is here.

When the repo merge is completed, I will work with the infra team to see what things
can be merged back into the main repo/CI pipeline and migrate the test sources to an
appropriate place in the new repo.

Contributes to #10041
Contributes to #24707
Contributes to #30150

@davidsh davidsh added this to the 5.0 milestone Nov 10, 2019
@davidsh davidsh self-assigned this Nov 10, 2019
This PR is a follow up to PR dotnet#36827 which added support for Linux server-side
GSS-API (AcceptSecContext). This enabled NegotitateStream AuthenticateAsServer*
support. It also provided support for ASP.NET Core to allow Kestrel server to have
Negotiate authentication on Linux.

This PR fixes some problems with Negotiate (SPNEGO) fallback from Kerberos to NTLM.
Notably it passes in a correct GSS Acceptor credential so that fallback will work
correctly. As part of fixing that, I noticed some other problems with returning the
user-identity when NTLM is used.

This was tested in a separate enterprise testing environment that I have created.
It builds on technologies that we have started using like docker containers and Azure
pipelines (e.g. HttpStress). The environment is currently here:
https://dev.azure.com/systemnetncl/Enterprise%20Testing. The extra Kerberos tests
and container support is here: https://github.com/davidsh/networkingtests

When the repo merge is completed, I will work with the infra team to see what things
can be merged back into the main repo/CI pipeline and migrate the test sources to an
appropriate place in the new repo.

Contributes to #10041
Contributes to #24707
Contributes to #30150
@davidsh
Copy link
Contributor Author

davidsh commented Nov 10, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@davidsh
Copy link
Contributor Author

davidsh commented Nov 10, 2019

@mconnew @Tratcher

@davidsh davidsh requested review from stephentoub and a team November 10, 2019 20:43
@eiriktsarpalis
Copy link
Member

Have you been able to verify that the changes fix the failures in the new tests? It seems that the docker infrastructure you linked to is pinned to the 3.0.100 sdk.

@davidsh
Copy link
Contributor Author

davidsh commented Nov 11, 2019

Have you been able to verify that the changes fix the failures in the new tests? It seems that the docker infrastructure you linked to is pinned to the 3.0.100 sdk.

Yes. The docker infrastructure is pinned to 3.0 SDK. But that was just a template as I was working out the mechanics of getting it set up. You might notice that the scripts can copy any files from the /patch directory into the container's shared framework.

https://github.com/davidsh/NetworkingTests/blob/1e0098067670f56279ea6580b1f3691cca8fceaf/Containers/SingleContainer/run.sh#L16-L19

# Copy and patch files if present
echo "Patching Microsoft.NETCore.App/3.0.0 files"
ls -l /patch
cp -r /patch/. /usr/share/dotnet/shared/Microsoft.NETCore.App/3.0.0

I built the 'master' branch on my machine and copied that output into a volume mount for the container. So, when the container runs on my machine, it uses the latest 'master' from my PR.

Once the new repo is set up and the pipeline is modified for new repo, it will be more automated.

Copy link

@scalablecory scalablecory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only a few things, otherwise lgtm.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@davidsh
Copy link
Contributor Author

davidsh commented Nov 11, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 4 pipeline(s).

@davidsh davidsh merged commit 1054f1f into dotnet:master Nov 11, 2019
@davidsh davidsh deleted the ntlm_server branch November 11, 2019 23:49
@safern
Copy link
Member

safern commented Nov 12, 2019

This was merged with a compile error in the all configurations leg:

src\Common\src\System\Net\Security\NegotiateStreamPal.Unix.cs(266,48): error CS1503: (NETCORE_ENGINEERING_TELEMETRY=Build) Argument 1: cannot convert from 'System.ReadOnlySpan' to 'byte[]'

It seems like the implicit cast from ROS to [] is not there for one of the SqlClient configurations. I would thing it is netstandard2.0

New pull requests/builds are failing with that error:
https://dev.azure.com/dnceng/public/_build/results?buildId=423433&view=logs

@@ -78,6 +88,12 @@ protected override void Dispose(bool disposing)
_targetName.Dispose();
_targetName = null;
}

if (_acceptorCredential != null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you've already merged this and there's existing code with this pattern, but this isn't thread safe. If Dispose is called on two threads at the same time, you can get a null reference exception. You could simply replace this with:

_acceptorCredential?.Dispose();
_acceptorCredential = null;

The generated IL is thread safe when using the ?. operator.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants