Current semantics for channel-bindings in GSSAPI

Isaac Boukris iboukris at gmail.com
Mon Mar 2 15:14:20 EST 2020


On Mon, Mar 2, 2020 at 9:11 PM Simo Sorce <simo at redhat.com> wrote:
>
> On Mon, 2020-03-02 at 21:00 +0100, Isaac Boukris wrote:
> > 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.
>
> I do not see why you would want to weaken a client connection on the
> same server where you want to require inbound connections to use CBs by
> distinguishing the two options.
> After all the peer of the initiator can always ignore bindings, so it
> is not like there is going to be an interop issue if you force your
> client to provide the bindings.
> But it gives you better assurance that the machine, as a whole, tries
> to bound on to channels in all communications.

I really don't follow, as initiator you you talk to other servers, you
likely to need different options.


More information about the krbdev mailing list