Subject: Re: [kitten] Checking the transited list of a kerberos ticket in a transitive cross-realm trust situation...

From: Stefan Metzmacher <[email-masked]>
Date: Thu, 21 Nov 2019 15:26:10 +0100

Hi Greg,

> On 9/25/19 4:09 AM, Stefan Metzmacher wrote:
>> I just realized that verifying the PAC gains no additional protection.
>> As the client realm, client principal and transited fields is
>> in the encrypted part of the ticket, which is encrypted with the machine
>> trust password.
> 
> I don't think this follows.  It's true that the PAC, client principal,
> and transited list are all coming from the service's KDC with integrity
> protection, but the question is to what degree the KDC is vouching for
> that information.
> 
> If the TRANSITED-POLICY-CHECKED flag is not set in the ticket, the
> service should assume that the KDC applied no policy to the transit
> path.  In practice, the DISABLE-TRANSITED-CHECK request flag, together
> with MS-KILE 3.1.5.4, means that it is easy to get most KDCs not to
> apply policy.  Without policy controls, any realm in the transitive
> closure of cross-realm keys can issue tickets for clients in any other
> realm (except perhaps the service realm itself).
> 
> The PAC contents, on the other hand, may be subject to policy controls.

Yes, the PAC contents, but also the realm of the principal names are
subject to policy controls (the SID-Filtering).

I've used a modified Samba KDC (realm W4EDOM-L4.BASE) to generate
tickets with invalid names (crealm: FAKEPRINC.PUBLIC)
and tested the reaction of Windows KDC (realm: W2012R2-L4.BASE) when
they received such a Ticket over a forest trust, where realm
FAKRPRINC.PUBLIC is not configure as valid realm (upn-suffix) the for
the trust boundary.

krb5-without-pac-fake-realm-03.pcap.gz has no PAC in the ticket for
TGS-REQ in frame 9. The crealm: FAKEPRINC.PUBLIC is rejected with
ERR_POLICY in frame 10.

krb5-with-pac-fake-realm-03.pcap.gz has a valid PAC (with the correct
names and signatures) but an altered crealm. This is also rejected with
ERR_POLICY.

So the policy check are not bound to the PAC, which means we can always
use GSS_KRB5_CRED_NO_TRANSIT_CHECK_X if we're member of an active
directory domain.

>> I implemented GSS_KRB5_CRED_NO_TRANSIT_CHECK_X for
>> MIT, Heimdal (both upstream and Samba) and make use of
>> it in Samba.
> [...]
>> So we need to push it Heimdal first in order to avoid
>> conflicts later.
> 
>>From past discussions I would not expect the Heimdal project to take
> action on a patch in an email attachment sent to the discussion list.  I
> would suggest making a pull request at
> https://github.com/heimdal/heimdal .

I was able to finish all the tests and have a branch here:
https://github.com/metze-samba/heimdal/tree/heimdal-no-transit-check

I'll add a reference to this discussion into some commit messages
and create a pull request shortly.

Are there any remaining problems, which would prevent
GSS_KRB5_CRED_NO_TRANSIT_CHECK_X from being excepted in MIT?
(Other than waiting for the Heimdal commit in order to get the OID value
fixed)

Thanks!
metze

---

From: Stefan Metzmacher <[email-masked]>
Date: Thu, 21 Nov 2019 16:57:21 +0100

Hi,

> and create a pull request shortly.

Here's the pull request.
https://github.com/heimdal/heimdal/pull/656

Issac can you please have a look at let me know if the modifications
to your changes are fine with you?

Thanks!
metze

---

From: Nico Williams <[email-masked]>
Date: Thu, 21 Nov 2019 16:39:09 -0600

On Tue, Sep 24, 2019 at 02:05:05AM +0200, Stefan Metzmacher wrote:
> resuming this old thread...
> https://lists.samba.org/archive/samba-technical/2017-August/122422.html
> 
> >> Does the Kerberos library know whether whether the application is going
> >> to look at PACs and SIDs or just use the client principal name?  I am
> >> guessing it does not.  Thus in Samba, one might need a dedicated
> >> krb5.conf configuration file that disables the transit check.  Other
> >> applications should still apply transit check even if a PAC happens
> >> to be present, as AFAIK it may well remain unused.
> > 
> > My idea was that Samba would use
> > gss_set_cred_option(GSS_KRB5_CRED_NO_TRANSIT_CHECK_X) to indicate
> > the the transited list should not be checked.
> 

Hi,

The right design for this is to use name attributes, not credential
options.  Credential options should be banished altogether.

To see why consider an acceptor application that wishes to examine the
transit path (or whatever other attribute) an authenticated initiator
principal took to reach the acceptor.  What credential should the
acceptor inspect?  There is none to inspect, not for the initiator (not
even if they delegated a credential, since that one might not have
transited any realms).  The only way to inspect the transit path taken
by the initiator is to inspect its name, as that's all we have for it.
This is one reason we added name attributes.

Correspondingly and symmetrically, the right way to request some
behavior on the side where the credential is available, is to associate
that request with the desired_name for which the credential is acquired.

Credential options are not standardized, but name attributes are.
Please use those.

Consider this my code review for the Heimdal PR.

I understand that this is probably a big change, and that this request
may seem hostile (email being such a dry medium).  I'm willing to help
you make this change, both for Heimdal and MIT -- I'll help with the
code, and I'd be happy to have a conference call or exchange further
emails.

Nico
--

---

From: Stefan Metzmacher <[email-masked]>
Date: Fri, 22 Nov 2019 11:24:44 +0100

Hi Nico,

> that request with the desired_name for which the credential is acquired.

So you mean we need to pass an explicit desired_name to
gss_acquire_cred_from() and use gss_set_name_attribute() calls
(for no_transit_check and iterate_acceptor_keytab) on that desired_name
before?

Then I think we need iterate_acceptor_keytab also for MIT.
As far as I can see GSS_C_NO_NAME is the current trigger for
iterating the keytab. The functionality we need is, try every key
with a matching keytype, but ignore name and kvno.

> code,

Thanks! I'm a bit lost on how to actually implement this, as
Heimdal doesn't seem to have a gsskrb5_gss_set_name_attribute() function
and krb5_gss_set_name_attribute() in MIT uses
krb5_authdata_set_attribute(), which just calls
krb5_authdata_context_module plugins. I'm not sure if authdata is what
we need here.

Are my changes to the lib/krb5 layer ok and we just need to change the
way the gsskrb5 layer triggers them? Or do we also need modifications there?

If you can tell me what attribute names we should use and how
the full call to gss_set_name_attribute() should look like,
I can start to change all the tests. But I need help to
implement the glue between gss_set_name_attribute() and
gsskrb5_acceptor_start() and kg_accept_krb5() respectively.

> and I'd be happy to have a conference call or exchange further
> emails.

I guess email is better for now, as we have everything archived.

Greg, do you agree, with changing to gss_set_name_attribute() instead of
gss_set_cred_option().

Thanks!
metze

---

From: Nico Williams <[email-masked]>
Date: Fri, 22 Nov 2019 16:45:28 -0600

> (for no_transit_check and iterate_acceptor_keytab) on that desired_name

Oh, wait, right.  That's not going to work when you want a default
credential.

Alright.  I've got a nasty cold and can't think straight, and deadlines
to meet to boot too.  I'll respond more thoughtfully some time next
week.

Nico
--