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

kdc: Reduce max UDP reply size default to 500 bytes and document better (fix #1216) #1218

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

nicowilliams
Copy link
Contributor

@nicowilliams nicowilliams commented Jan 10, 2024

See #1216. This change will drop the max UDP reply size to 500 bytes, causing the KDC to reply to all requests sent via UDP with a KRB5_ERR_RESPONSE_TOO_BIG error that causes clients to switch to using TCP.

@nicowilliams nicowilliams changed the title kdc: Reduce max UDP reply size default to 1200 bytes and document better (fix #1216) kdc: Reduce max UDP reply size default to 0 bytes and document better (fix #1216) Jan 10, 2024
@nicowilliams
Copy link
Contributor Author

Well, all these test failures...

@nicowilliams
Copy link
Contributor Author

The KRB5_ERR_RESPONSE_TOO_BIG handling in the FAST case is busted, and that's what's causing at least some of the test failures.

@nicowilliams
Copy link
Contributor Author

The send_to_kdc logic for handling KRB5_ERR_RESPONSE_TOO_BIG can only do that for the outer KRB-ERROR, but in the FAST case the KRB5_ERR_RESPONSE_TOO_BIG will be in the inner KRB-ERROR, so we fail in the TGS case, though somehow not in the AS case. I believe it's secure to return KRB5_ERR_RESPONSE_TOO_BIG in the outer error and dispense with FAST in that case, but I'm not sure whether that will interoperate with MIT, Windows, etc. I don't believe the RFC (6113) discusses this case.

Of course we could and should fix the Heimdal client to handle KRB5_ERR_RESPONSE_TOO_BIG in the inner KRB-ERROR, but that's not a KDC-side-only fix, and rolling out the client-side fix first would be painful. Still, any site that finds its on-the-Internet KDCs being used in an amplification attack can just stop advertising UDP support in DNS and then stop allowing UDP access to its KDCs via IP filtering.

@nicowilliams
Copy link
Contributor Author

The MIT Kerberos KDC sends always KRB5KRB_ERR_RESPONSE_TOO_BIG as a naked, non-FAST error. Heimdal should do the same then!

@nicowilliams
Copy link
Contributor Author

The place where we handle the too-big error in kdc/kerberos5.c and kdc/krb5tgs.c may not be quite right in that I think it causes other errors to be sent as usual.

@jsutton24
Copy link
Contributor

I believe it's secure to return KRB5_ERR_RESPONSE_TOO_BIG in the outer error and dispense with FAST in that case, but I'm not sure whether that will interoperate with MIT, Windows, etc. I don't believe the RFC (6113) discusses this case.

I think the third paragraph of section 5.4.4 mentions it:

“If the Kerberos FAST padata is included in the request but not included in the error reply, it is a matter of the local policy on the client to accept the information in the error message without integrity protection. However, the client SHOULD process the KDC errors as the result of the KDC's inability to accept the AP_REQ armor and potentially retry another request with a different armor when applicable. […]”

@riastradh
Copy link

I haven't looked closely at any of this but the prospect of a server returning any kind of fine-grained error information to an unauthenticated client, and of a client acting meaningfully on any unauthenticated error reports, is making my skin crawl.

@nicowilliams
Copy link
Contributor Author

I haven't looked closely at any of this but the prospect of a server returning any kind of fine-grained error information to an unauthenticated client, and of a client acting meaningfully on any unauthenticated error reports, is making my skin crawl.

It's not ready for review. Kerberos relies on some "fine-grained error information" (e.g., what enctypes are supported, salts, etc.) to be provided to unauthenticated clients in order for them to authenticate. Anyways, when I'm done, if you set max-kdc-datagram-reply-length to 0 then all UDP requests will elicit a minimal KRB5_ERR_RESPONSE_TOO_BIG error.

@nicowilliams nicowilliams force-pushed the reduce-max-kdc-udp-reply-def branch 2 times, most recently from ba739f6 to a0b37aa Compare January 16, 2024 16:31
@nicowilliams
Copy link
Contributor Author

I think this is almost ready for code review. The code is getting excercised, but now we're now not testing [kdc] max-kdc-datagram-reply-length values larger than zero, so I should update one of the krb5.conf.in files in the tests to set it to something else. Also, we should check the logs to make sure that it's actually being used....

@nicowilliams
Copy link
Contributor Author

And now with testing.

@nicowilliams
Copy link
Contributor Author

@riastradh would you like to do a code review?

@nicowilliams
Copy link
Contributor Author

I've also added two somewhat unrelated commits, one to speed up tests/kdc/check-kdc, and one to fix the OS X build which was failing tests/kdc/check-hdb-mitdb.

@nicowilliams
Copy link
Contributor Author

I might as well do the here-document thing for most uses of kadmin in the tests as it may significantly speed up all the tests.

@nicowilliams nicowilliams force-pushed the reduce-max-kdc-udp-reply-def branch 2 times, most recently from f0c1008 to 93bcc1d Compare January 16, 2024 22:29
@nicowilliams
Copy link
Contributor Author

I've pushed the extraneous commits separately to master. This branch is ready now.

kdc/kerberos5.c Outdated Show resolved Hide resolved
kdc/kerberos5.c Outdated Show resolved Hide resolved
kdc/fast.c Outdated Show resolved Hide resolved
kdc/fast.c Outdated Show resolved Hide resolved
@nicowilliams nicowilliams force-pushed the reduce-max-kdc-udp-reply-def branch 3 times, most recently from 9d1a9cf to a2e0258 Compare January 20, 2024 02:36
@nicowilliams
Copy link
Contributor Author

Also minimizing the sname in the KRB-ERROR causes Java interop issues, specifically causing the tests/java/check-kinit to fail with:

image

Authentication failed:java.lang.IllegalArgumentException: Empty nameStrings not allowed
	at java.security.jgss/sun.security.krb5.PrincipalName.validateNameStrings(PrincipalName.java:172)
	at java.security.jgss/sun.security.krb5.PrincipalName.<init>(PrincipalName.java:282)
	at java.security.jgss/sun.security.krb5.PrincipalName.parse(PrincipalName.java:320)
	at java.security.jgss/sun.security.krb5.internal.KRBError.init(KRBError.java:362)
	at java.security.jgss/sun.security.krb5.internal.KRBError.<init>(KRBError.java:189)
	at java.security.jgss/sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:63)
	at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:345)
	at java.security.jgss/sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:498)
	at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:746)
	at jdk.security.auth/com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:592)
	at java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:747)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:672)
	at java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:670)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:670)
	at java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:581)
	at KerberosInit.main(KerberosInit.java:84)

This is due to a) the sname field of KRB-ERROR not being OPTIONAL and b) krb5_mk_error_ext() with NULL server causing the sname field of the KRB-ERROR to have zero components (and the srealm gets set to a bogus realm).

We can further minimize the KRB-ERROR by using a smaller bogus srealm and making the sname a 1-component name with a small bogus component value.

krb5_mk_error_ext() with a NULL server name would generate a KRB-ERROR
with its sname field set to a zero-component principal name.  This
causes Java's Krb5 client to throw an IllegalArgumentException with
`Empty nameStrings not allowed` as its message.

Now krb5_mk_error_ext() with a NULL server name will set the sname field
to a one-component name with the one component being "<>".  We also
minimize the srealm, setting it to "<>" as well.
@nicowilliams nicowilliams changed the title kdc: Reduce max UDP reply size default to 0 bytes and document better (fix #1216) kdc: Reduce max UDP reply size default to 500 bytes and document better (fix #1216) Jan 21, 2024
@nicowilliams
Copy link
Contributor Author

After some discussion we think that defaulting this to zero is asking for trouble, so we'll go with 500.

(Also, I think I found a referrals bug. @lhoward @josephsutton1 @jaltman ? Let's see if fixing it breaks tests.)

@abartlet
Copy link
Member

Thanks @nicowilliams for putting the explanation about Samba's strange NOT_FOUND_HERE handling into the code, that will help others understand our strange RODC hook.

The code looks pretty good to me at an initial glance.

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

Successfully merging this pull request may close these issues.

None yet

4 participants