Current semantics for channel-bindings in GSSAPI

Isaac Boukris iboukris at gmail.com
Mon Mar 2 15:00:39 EST 2020


On Mon, Mar 2, 2020 at 8:44 PM Simo Sorce <simo at redhat.com> wrote:
>
> On Mon, 2020-03-02 at 19:00 +0100, Isaac Boukris wrote:
> > On Mon, Mar 2, 2020 at 6:30 PM Simo Sorce <simo at redhat.com> wrote:
> > > On Mon, 2020-03-02 at 15:12 +0100, Isaac Boukris wrote:
> > > > On Fri, Feb 28, 2020 at 6:00 PM Greg Hudson <ghudson at mit.edu> wrote:
> > > > > On 2/27/20 8:27 PM, Isaac Boukris wrote:
> > > > > > Following the discussion on  IRC, there is currently a difference in
> > > > > > between Heimdal and MIT, when the client does not send bindings, and
> > > > > > the server does pass bindings to accept(), in MIT it fails, in Heimdal
> > > > > > it succeeds.
> > > > >
> > > > > There are a few reasons why I think Heimdal's behavior is better:
> > > >
> > > > Taking a closer look at MIT accept() code, it looks like there is a
> > > > case where no checksum is provided at all, where MIT would skip
> > > > channel-bindings even if the server provided ones. It sounds like
> > > > Windows also supports this.
> > > >
> > > > https://github.com/krb5/krb5/blob/2b1acc07a267782a7f4c9644da78587cc29b6f56/src/lib/gssapi/krb5/accept_sec_context.c#L659
> > >
> > > Given this case it sounds like relaxing MITs code to accept when
> > > clients do not send Channel Bindings to allow the context to be
> > > established brings consistency not only across implementations but also
> > > within the MIT code by simplifying away that condition.
> > >
> > >
> > > Here I am going to try to summarize how I and Isaac think we should
> > > change the semantics so that we can interoperate better.
> > >
> > > Premise: Isaac was investigating on how to handle connecting to Windows
> > > servers that implement a configuration flag called
> > > LdapEnforceChannelBinding
> > >
> > > This flag can be configured with 3 levels:
> > >
> > > Level 0: CBs are completely disabled
> > > Level 1: CBs are optional. Specifically clients that do not send
> > > KERB_AP_OPTIONS_CBT can still connect with or withouth CBs, while
> > > clients that send KERB_AP_OPTIONS_CBT are required to send matching
> > > Channel Bindings.
> > > Level 2: All clients must send Channel Bindings, without exceptions.
> > >
> > > This applies only to the LDAP service as far as we know, but requires
> > > us to try to allow these configurations in servers that are used to
> > > emulate Windows AD (eg Samba).
> > >
> > > With current MIT code we can only really implement
> > > LdapEnforceChannelBinding levels 0 and 2. Level 0 when setting no CBs
> > > in the acceptor, and level 2 when passing CBs, however as stated
> > > multiple times over the years in previous conversations, this MIT krb5
> > > behavior makes it hard to perform gradual conversions of the clients.
> > >
> > > With current Heimdal, in contrast, it looks like we can only implement
> > > LdapEnforceChannelBinding levels 0 and 1. Level 0 when setting no CBs
> > > in the acceptor, and level 1 when passing CBs, this means we do not
> > > have a way to enforce CBs at all.
> > >
> > > We'd like to propose that both MIT and Heimdal code converge in
> > > behavior and agree in implementing the following behavior:
> > >
> > > [ACCEPTOR SIDE]
> > >
> > > 1) When passing GSS_C_NO_CHANNEL_BINDINGS to gss_accept_sec_context()
> > > then Channel Bindings are ignored (equivalent to level = 0)
> > > 2) When passing actual Channel Bindings to gss_accept_sec_context()
> > > then Channel Bindings are checked only if the client sends non zero
> > > CBs. (allows us to implement level = 1)
> > > 3) If the client sent CBs and we verified them set a new flag in
> > > ret_flags that signify CBs were received and checked (this will allow
> > > us to implement level = 2 behavior by failing the connection if the
> > > flag is missing).
> > >
> > > Optionally[A] support the presence of the KERB_AP_OPTIONS_CBT. If we do
> > > this then the above point (2) above is split in two sub options:
> > >
> > > 2) When passing actual Channel Bindings to gss_accept_sec_context()
> > > then:
> > > 2.1) Channel Bindings are checked only if the client sends non zero CBs
> > > and KERB_AP_OPTIONS_CBT is not present.
> > > 2.2) Channel Bindings are enforced if the client provides the
> > > KERB_AP_OPTIONS_CBT.
> > >
> > > NOTE in 2.2 we propose that context establishment fails if CBs are not
> > > provided, we do not rely on the application to check ret_flags in this
> > > case.
> > >
> > > Optionally[B] we add a krb5.conf flag like "require channel bindings"
> > > that causes the gss_accept_sec_context() function to fail if CBs are
> > > passed into it and the client does not send CBs (ie we do not rely on
> > > the applications to check ret_flags, the context establishment fails
> > > just like MIT code currently does).
> >
> > Hmm, if we provide a krb5.conf for this, then I think it might make
> > more sense to use set_cred/context_option over ret flag. So the logic
> > would be lib-defaults is false (not fail), can be overridden by
> > krb5.conf, and again by application code.
>
> set_context_option would require a new API to create a context before
> calling gss_accept_sec_context()
> set_cred_option would force to acquire crede before accepting which
> means you cannot accept and let the system chose the best key in a
> keytab.
> Either of these means bigger changes to existing code as well.
>
> So they both have drawbacks that I rather not have to rely on,
> ret_flags still is the simplest way to provide a signal back when
> needed, even though in some cases it won't be used.
> however if ret_flags is undesireable to touch a
> gss_inquire_sec_context_by_oid() could be used, it still has a greater
> impact on existing code than may be desirable, but at least it won't
> require new APIs or forcing creds.

I see.

> > > Option B allows operators relying on current MIT behavior to retain it
> > > by simply adding this option in krb5.conf and not having to worry to
> > > change pre-existing applications in order to enforce CBs.
> > >
> > >
> > > [INITIATOR SIDE]
> > >
> > > Optionally [C] we add a krb5.conf flag like "require channel bindings"
> > > that causes gss_init_sec_context() to emit the KERB_AP_OPTIONS_CBT.
> > > The flag should always be emitted and will cause clients that have not
> > > been updated to send CBs to fail against servers that have support for
> > > interpreting KERB_AP_OPTIONS_CBT. This is useful for deployers to check
> > > that all their client software has been properly updated before
> > > switching the same flag on on the servers.
> > >
> > >
> > > In closing,
> > >
> > > Although Options B and C could use different config options we suggest
> > > the exact same option to be used for both initiator and acceptor for
> > > consistency of behavior and to reduce the number of knobs to dial for
> > > admins. Applications that need special exceptions can always be
> > > configured to point to a different custom krb5.conf file.
> >
> > Not sure about making it the same option, it has side impacts.
>
> I feel like distinguishing is excessive, it is unlikely you are ok to
> force one and not another, in practice, on the same system. And should

Initiator is for talking with other servers, I don't see why that
would be unlikely.


More information about the krbdev mailing list