Skip to content
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

NegotiateStream question #2057

Closed
xqrzd opened this issue Jan 23, 2020 · 10 comments
Closed

NegotiateStream question #2057

xqrzd opened this issue Jan 23, 2020 · 10 comments
Labels
area-System.Net.Security question Answer questions and provide assistance, not an issue with source code or documentation.
Milestone

Comments

@xqrzd
Copy link

xqrzd commented Jan 23, 2020

I'm writing a C# client for Apache Kudu, and using NegotiateStream for kerberos authentication. I have it working, but there's an odd difference between running the client on Windows vs Linux. After AuthenticateAsClient succeeds, I need to exchange some kerberos protected messages.

On Linux, only ProtectionOptions.EncryptAndSign works, and on Windows only ProtectionOptions.Sign works.

On Windows, specifying ProtectionOptions.EncryptAndSign gives this error:
Protocol error: A received message contains a valid signature but it was not encrypted as required by the effective Protection Level

On Linux, specifying ProtectionOptions.Sign gives this error:
System.PlatformNotSupportedException: Requested protection level is not supported with the GSSAPI implementation currently installed

Is this expected, and I should just do a runtime check to select the one that works, or is something misconfigured somewhere?

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Net.Security untriaged New issue has not been triaged by the area owner labels Jan 23, 2020
@scalablecory scalablecory added question Answer questions and provide assistance, not an issue with source code or documentation. and removed untriaged New issue has not been triaged by the area owner labels Jan 23, 2020
@karelz
Copy link
Member

karelz commented Jan 24, 2020

@xqrzd this is area where we have been investing for a while. It is tricky and we do not have everything automated and documented yet.
@davidsh is our expert and will be interested in details. He should be back at work in 1-2 weeks. Is that ok to wait?

@karelz karelz added this to the 5.0 milestone Jan 24, 2020
@xqrzd
Copy link
Author

xqrzd commented Jan 24, 2020

Yeah I'm in no rush for an answer, I have a solution that seems to work across many machines (OS platform check). I just wasn't sure if the platform check is the correct answer here.

@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2020

I'm writing a C# client for Apache Kudu, and using NegotiateStream for kerberos authentication.

Does that mean that your server is always on Linux? Is the server using .NET Core on Linux?

On Linux, only ProtectionOptions.EncryptAndSign works, and on Windows only ProtectionOptions.Sign works.

On Windows (both server and client on Windows) NegotiateStream works for all values of ProtectionOptions. However, we have seen issues with using Linux for NegotiateStream server-side. In fact, server-side for NegotiateStream on Linux is something that only recently became supported (.NET Core 3.1).

On Linux, specifying ProtectionOptions.Sign gives this error:
System.PlatformNotSupportedException: Requested protection level is not supported with the GSSAPI implementation currently installed

On Linux, client-side NegotiateStream only supports ProtectionOptions.EncryptAndSign currently due to limitations with GSS-API.

@xqrzd
Copy link
Author

xqrzd commented Feb 10, 2020

Thanks for replying.

Does that mean that your server is always on Linux? Is the server using .NET Core on Linux?

Yes the server is always Linux. There aren't any .NET components on the server, Apache Kudu is written in C++, using Cyrus SASL for GSSAPI/Kerberos. I'm just writing a client for it, which may run on Windows or Linux.

The strangeness I think is the error from Windows, when EncryptAndSign fails with Protocol error: A received message contains a valid signature but it was not encrypted as required by the effective Protection Level. The error message makes it seem like the problem is on Kudu's end (it didn't encrypt the message), but EncryptAndSign does work on Linux.

@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2020

Yes the server is always Linux. There aren't any .NET components on the server, Apache Kudu is written in C++, using Cyrus SASL for GSSAPI/Kerberos. I'm just writing a client for it, which may run on Windows or Linux.

The NegotiateStream API is meant to handle communications between instances of the NegotiateStream class (a .NET class). So, you need to have a NegotiateStream client talking with a NegotiateStream server.

Does your "server" implement an equivalent NegotiateStream server? That would require that it implements the protocol as per MS-NNS: .NET NegotiateStream Protocol.

@xqrzd
Copy link
Author

xqrzd commented Feb 10, 2020

Kudu does SASL GSSAPI (not sure on the details there). It definitely doesn't implement a .NET equivalent NegotiateStream though. I did have to work around some things to get it to work (removing / adding FrameHeader). When exchanging protected messages I also had to add/remove some length prefixes, and adjust their endianness).

It's a tad hacky, but afaik there wasn't another way to do Kerberos authentication from .NET. It sounds like though what I'm doing is not really supported, so I may be stuck with hack-fixes to get it to work?

@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2020

but afaik there wasn't another way to do Kerberos authentication from .NET.

We have a few open issues (#29270, #27395) around exposing Kerberos related APIs.

It sounds like though what I'm doing is not really supported, so I may be stuck with hack-fixes to get it to work?

Yes. Unfortunately, using the NegotiateStream API on the client against something that doesn't fully implement NegotiateStream on the server side is not supported.

@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2020

Closing this issue since your scenario is not supported.

@davidsh davidsh closed this as completed Feb 10, 2020
@davidsh
Copy link
Contributor

davidsh commented Feb 10, 2020

but afaik there wasn't another way to do Kerberos authentication from .NET.

You can also consider using Kerberos .NET. It was written by a Microsoft engineer and might meet your requirements.
https://github.com/SteveSyfuhs/Kerberos.NET

@xqrzd
Copy link
Author

xqrzd commented Feb 10, 2020

Thanks for the info. I did take a look at Kerberos.NET, but unfortunately it doesn't support client authentication yet, dotnet/Kerberos.NET#9

For now since I have it working (albeit rather poorly) I'll probably stick with that, but keep an eye on the issues for providing Kerberos related APIs.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Security question Answer questions and provide assistance, not an issue with source code or documentation.
Projects
None yet
Development

No branches or pull requests

5 participants