dotnet / dotnet/wcf

UnixDomainSocketBinding default security on Windows doesn't work

Open
#5,621 3 comments 2 reactions 0 assignees View on GitHub
triaged
Dominant language
C#
Stars
1.8k
Forks
576
Avg merge
6d 9h
Merged PRs (30d)
2

Description

On Windows, it uses NegotiateStream to establish the connection. As part of that, we pass a target name to NegotiateStream.AuthenticateAsClientAsync which is used to get a Kerberos ticket or decide to use NTLM. There's shared code which implicitly uses the hostname from the endpoint address Uri, but with UDS there is no hostname. This results in a bad target name being used (it ends up using `host/`) and authentication failing.

Workaround:
Construct you EndpointAddress like this:
```c#
var endpointAddress = new EndpointAddress(new Uri("net.uds://" + servicePath), new SpnEndpointIdentity("host/localhost"));
```

This will override the implicit target name to be `host/localhost` and the NegotiateStream authentication will succeed.

A few options to fix this.
1. On the CreateChannel code path, we could create a new Uri from the passed in Uri which has the hostname portion populated with localhost if it's currently empty.
2. On the CreateChannel code path, we could add an SpnEndpointIdentity("host/localhost") to the EndpointAddress if there isn't currently an identity.
3. In the code which calculates the target name, treat an empty hostname as the empty string target name. So if the hostname is non-empty, generate the target name `host/localhost`, but if the hostname is empty, generate the target name String.Empty. I have verified String.Empty successfully authenticates.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.