-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add Kerberos loopback test #71824
Add Kerberos loopback test #71824
Conversation
Tagging subscribers to this area: @dotnet/ncl, @vcsjones Issue DetailsTODO:
Contributes to #71453
|
cc: @SteveSyfuhs in case we publish to some internal feds as well beyond NuGet |
contributes to #68067. If we can run Kerberos tests during normal run, we don't need special reporting (and possibly separate pipeline) |
I've played with this a bit and some of the enterprise tests can be converted to use this approach. I'm still planning to see if I can get the same thing done for NTLM. |
65edc0a
to
f95e6e2
Compare
Have at it. Let me know if there's anything you need. |
…on to NTLM and Negotiate)
… test for invalid credentials
Not sure what are the guidelines for code style in tests. In particular, I used Coding style guidelines don't seem to mention the file-scoped namespaces (cc @stephentoub). |
I can also split off c6619e1 into separate PR to make it easier to review. Thoughts? |
I'm not sure if we should change the production code at this point. I would be happy with getting some coverage with Kerberos.Net. e.g. splitting/postponing c6619e1. I'm on the road once again, I should be able to take closer look by and of the week. |
Alright, I will split it (#72024). The reasoning behind c6619e1 is that it's a behavior difference between Unix-based OSes and Windows. Fixing it allows to test incorrect credentials which is test coverage for #71484. Without the change it's only possible to specify Negotiate authentication package which will fallback to NTLM instead of reporting the error from invalid credentials. |
…n addition to NTLM and Negotiate)" This reverts commit c6619e1.
8d14128
to
952dad5
Compare
952dad5
to
b2e8daf
Compare
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.
generally looks good to me.
sorry for the long delay @filipnavara.
public FakeKdcServer(KdcServerOptions serverOptions) | ||
{ | ||
_kdcServer = new KdcServer(serverOptions); | ||
_tcpListener = new TcpListener(System.Net.IPAddress.Loopback, 0); |
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.
nit: IPAddress.Loopback? We may eventually figure out how to do dual mode but this is ok for now IMHO
{ | ||
_kdcServer = new KdcServer(serverOptions); | ||
_tcpListener = new TcpListener(System.Net.IPAddress.Loopback, 0); | ||
_runningLock = new object(); |
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 new object?
object _runningLock => TcpListener
?
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 we don't. It's a habit not to reuse other objects for locks because it's prone to misuse but I can change it.
|
||
class FakeKerberosPrincipal : IKerberosPrincipal | ||
{ | ||
private readonly byte[] _password; |
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.
nit: I would change the name to decrease chance we get flagged by security scans.
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.
RFC-wise it's called "long term secret"
|
||
var krbName = KrbPrincipalName.FromString($"krbtgt/{predictedRealm}"); | ||
|
||
return new FakeKerberosPrincipal(PrincipalType.Service, krbName.FullyQualifiedName, predictedRealm, new byte[16]); |
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.
should we initialize the password to something? (may not matter but looks odd to me)
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.
It's fine as long as it's consistently x00 everywhere and is never used for anything in production.
_principalService = new FakePrincipalService(realm); | ||
|
||
byte[] krbtgtPassword = new byte[16]; | ||
//RandomNumberGenerator.Fill(krbtgtPassword); |
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.
remove? Or set to some string if we need decrypt for debugging.
_krb5Path = Path.GetTempFileName(); | ||
File.WriteAllText(_krb5Path, | ||
OperatingSystem.IsLinux() ? | ||
$"[realms]\n{_options.DefaultRealm} = {{\n master_kdc = {endpoint}\n kdc = {endpoint}\n}}\n" : |
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.
Why this depends on OS?
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.
Different notation to force TCP over UDP and to specify the KDC as master.
} | ||
|
||
// Set environment variables for GSSAPI | ||
Environment.SetEnvironmentVariable("KRB5_CONFIG", _krb5Path); |
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.
does this actually work? Last time (long time ago) I check this did not change the actual ENV e.g. was invisible to native bits.
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.
Yes. That's why the test run inside RemoteExecutor
. Environment.SetEnvironmentVariable
doesn't call setenv
but for newly launched processes it is used and that's what remote executor does.
Introduces an infrastructure to run Kerberos.NET powered KDC inside a unit test and to redirect the system GSSAPI libraries to connect to it. This enables testing Kerberos scenarios without special Docker containers and also allows testing on macOS which had no coverage.
TODO:
Contributes to #71453