Skip Menu |

Subject: Multiple GSSAPI krb5 mechanism variants cause repeated operations
Download (untitled) / with headers
text/plain 2.4KiB
This may be a problem without a solution, or with several solutions
which ought to be tracked separately. But I want to have an issue
describing the problem.

At this time our mechglue supports five built-in mechanisms: SPNEGO and
four variants of krb5 (the real OID, the old OID, the wrong OID used by
some versions of Windows, and IAKERB). Having four variants of krb5 has
some unfortunate consequences:

* ssh uses gss_indicate_mechs and constructs four different mechanisms
to try. The client will try all of these mechanisms when authenticating
to a server, when it's really only necessary to try one or perhaps two.

* If you call gss_acquire_cred with no desired_mechs, you wind up
invoking krb5's acquire_cred eight times (four times directly from the
mechglue, and then four times again underneath SPNEGO). If there's a
desired_name which is host-based, this means eight calls to
krb5_sname_to_principal, which means up to 24 DNS requests. For
initiator creds, the caller is probably (but not necessarily) going to
call gss_init_sec_context with no desired_mech, which means only one of
the eight krb5 creds will actually be used. For acceptor creds, the
client token will determine which of the eight krb5 creds is used.

Some ways we could consider attacking this problem:

* We could determine that one or both of {gss_mech_krb5_old,
gss_mech_krb5_wrong} are no longer needed for interoperability in
practice. This requires research.

* We could special-case the wrong/old krb5 OIDs in the mechglue and
SPNEGO without making them full-fledged mechs. This would be
architecturally unclean, although it could perhaps be abstracted into
the concept of a "mech alias". It could also perhaps cause
interoperability issues if gss_indicate_mechs no longer returned those
OIDs; for instance, ssh would no longer use those OIDs in its version of
mechanism negotiation. (ssh probably doesn't need those variants for
interoperability in practice, but other protocols might.)

* We could defer mech credential acquisition when gss_acquire_creds is
called with no desired_mechs, if actual_mechs and time_rec are not
requested. This is probably a bad idea; we ought to be able to return
an error immediately if no mech can acquire creds (e.g. you asked for
acceptor creds, you have no keytab, and there are no non-krb5 mechs).
It would also complicate the mechglue--functions like gss_inquire_cred
and gss_set_cred_option would need to instantiate mech creds within the
union cred.
For reference:

* Heimdal appears to match our new behavior for gss_acquire_cred with no
specified mechs (that is, it gets creds for all mechanisms).

* Heimdal supports the "wrong" krb5 mech OID (the one used by Microsoft)
inside its SPNEGO implementation. It doesn't return that OID in
gss_indicate_mechs and it doesn't let applications use that OID.

* Heimdal doesn't appear to have any support for the "old" krb5 mech OID.

Adopting the above behavior would reduce the number of krb5 cred
acquisition operations for a default gss_acquire_cred from 8 to 4, and
the number of ssh userauth negotiation attempts from 4 to 2.