SPNEGO was already using union creds. Now make the mechglue know about
it, delete all of the cred-related SPNEGO stubs that are now not called
(lib/gssapi/spnego/cred_stubs.c), and implement gss_get/set_neg_mechs()
by storing the OID set in the union cred.
This commit was essentially authored as much if not more by Luke Howard
<lukeh at padl.com> as much as by the listed author.
If an initial security context token doesn't have a standard header per
RFC2743 then try all mechanisms until one succeeds or all fail.
We still try to guess NTLMSSP, raw Kerberos, and SPNEGO, from tasting
the initial security context token.
Add a new private interface (accessed through _gss_mg_import_rfc4121_context())
through which a skeletal krb5 mechanism context can be created, suitable for
RFC4121 message protection and PRF services.
Allow the source and target names to be NULL when exporting or importing a
security context for the krb5 mechanism. This will be used in the future to
support skeletal contexts that only provide RFC4121 message protection
services.
The recent changes to SPNEGO removed support for GSS_C_PEER_HAS_UPDATED_SPNEGO,
through which the Kerberos mechanism could indicate to SPNEGO that the peer did
not suffer from SPNEGO conformance bugs present in some versions of Windows.*
This patch restores this workaround, documented in [MS-SPNG] Appendix A <7>
Section 3.1.5.1. Whilst improving interoperability with these admittedly now
unsupported versions of Windows, it does introduce a risk that Kerberos with
pre-AES ciphers could be negotiated in lieu of a stronger and more preferred
mechanism.
Note: this patch inverts the mechanism interface from
GSS_C_PEER_HAS_UPDATED_SPNEGO to GSS_C_INQ_PEER_HAS_BUGGY_SPNEGO, so that new
mechanisms (which did not ship with these older versions of Windows) are not
required to implement it.
* Windows 2000, Windows 2003, and Windows XP
Pending integration of #551, the krb5 mechanism does not support
GSS_C_ANON_FLAG. Remove the GSS_C_MA_AUTH_INIT_ANON mechanism attribute until
such time it does.
This is needed so that sshd and such can get make practical use of the
"ccache" key in GSS cred stores.
This commit only changes the store path, not the acquisition path.
gss_store_cred_into*() will now switch the new cred cache to be the
primary/default cred cache when
- the caller requested it and,
- if the caller passed in a user name, the creds' principal is the best
principal for the named user.
A principal is the best principal for a user when the principal has just
one component, the component is the user's username, and the realm is
the configured user_realm.
- Formalize the TYPE:collection_name:subsidiary_name naming scheme for
ccaches in ccache collections
- KEYRING: ccaches are weird because they have one more optional field: the
"anchor", so rather than just assume a naming convention everywhere, we
add new functions as well
- Add krb5_cc_{resolve,default}_sub() that allows one to specify a
"subsidiary" ccache name in a collection separately from the
collection name
- Add krb5_cc_{resolve,default}_for() which take a principal name,
unparse it, and use it as the subsidiary ccache name (with colons
replaced)
- Make kinit use the new interfaces
- Add missing DIR ccache iteration functionality
- Revamps test_cc
- Add krb5_cc_get_collection() and krb5_cc_get_subsidiary()
- Bump the ccops SPI version number
- Add gss_store_cred_into2()
- Make MEMORY:anonymous not linked into the global MEMORY ccache
collection, and uses this for delegated cred handles
TBD:
- Split this up into a krb5 change and gss mech_krb5 change?
- Add krb5_cc_init_and_store() utility, per Greg's suggestion?
An implementation of draft-zhu-negoex-04 for MIT Kerberos was developed in
2011. This has been recently integrated, with many fixes from Greg Hudson. This
commit ports it to Heimdal. The implementation has been interoperability tested
with MIT Kerberos and Windows, using the GSS EAP mechanism developed as part of
the Moonshot project.
The SPNEGO code was also updated to import the state machine from Apple which
improves mechListMIC processing and avoids discarding initial context tokens
generated during mechanism probing, that can be used for optimistic tokens.
Finally, to aid in testing, the GSS-API mechanism glue configuration file can
be changed using the environment variable GSS_MECH_CONFIG. This environment
variable name, along with the format of the configuration file, is compatible
with MIT (although it would be difficult for a single mechanism binary to
support both implementations).
The Kerberos GSS mechanism specific error table in gkrb5_err.et was never
registered with libkrb5, so the messages corresponding to those errors would
never be available. Register them with the thread local context used by the
krb5 mechanism.
Refactor and enhance TGT forwarding to allow forwarding of leaf
(destination) TGTs for selected destination realms.
Enhance kinit(1) to renew non-origin realm tickets
Document delegate-destination-tgt
Use the newly implemented _krb5_mk_1cred().
krb5_cc_cache_match() searches all ccache collections for a ccache that
has credentials for a given principal name. This includes MEMORY
ccaches, which means it can find the same ccache as is referenced by a
GSS cred handle given to gss_store_cred(), which means that
gss_store_cred() can fail.
For now we work around this by including a private variant of
krb5_cc_cache_match() that only searches the default ccache, not all
collections. Eventually we should ensure that krb5_cc_default() also
searches all collection-type (other than MEMORY) ccaches for a default
credential, then we can go back to using krb5_cc_cache_match() (though
we'll need to make sure that MEMORY is searched last or not at all).
Implementation of gss_set_neg_mechs() and gss_get_neg_mechs() as defined in RFC
4178. New gss_release_cred_by_mech() API for dropping a credential from a
mechanism glue credential.
Implement the GSS-API credential store API extensions defined by MIT here:
https://k5wiki.kerberos.org/wiki/Projects/Credential_Store_extensions
Note: we kill off gss_acquire_cred_ext() here. This was never a public API,
although mechanisms could have implemented it and I briefly used it in my
BrowserID prototype mechanism. gss_acquire_cred_ext_from() occupies the place
in the dispatch table where gss_acquire_cred_ext() used to, but this structure
was never visible outside Heimdal (i.e. it is only used by internal
mechanisms);
(Mechanisms that need to accept arbitrary key/value dictionaries from
applications should now implement gss_acquire_cred_from().)
gss_krb5_set_allowable_enctypes() was declared with an array of int32_t types
representing the enctype list, but the definition had an array of krb5_enctype.
Whilst these are likely the same size, they may not be. On the receiving end,
allocate an array of krb5_enctype.
For compatibility with MIT Kerberos, support automatic acquisition of initiator
credentials if a client keytab is available. The default path on non-Windows is
/var/heimdal/user/%{euid}/client.keytab, but can be overriden with the
KRB5_CLIENT_KTNAME environment variable or the default_client_keytab_name
configuration option. If a client keytab does not exist, or exists but does not
contain the principal for which initiator credentials are being acquired, the
system keytab is tried.
It turns out gss_add_cred() really needed a complete rewrite. It's much
better to first have a gss_duplicate_cred() (which has been needed for
other reasons anyways), and use that when the input_cred_handle is not
GSS_C_NO_CREDENTIAL and output_cred_handle is not NULL, then mutate that
duplicate credential handle (or the input_cred_handle if
output_cred_handle is NULL).
Zero out the DES_cblock structure instead of the (not yet used at this point
in the function) key schedule. The contents could potentially be left
on the stack in the case of an error return from _gssapi_verify_pad().
We generally clear out the cryptographic key and key schedule from
local variables before relinquishing control flow, but this case was
missed. Reported by jhb@FreeBSD.org.
Treat principals of type NT-UNKNOWN as NT-SRV-HST if the first component
of the principal name is "host".
Change-Id: I28fb619379daac827436040e701d4ab7b279852b
gsskrb5_acceptor_start() was making a copy of the global pointer
_gsskrb5_keytab to use later. This invites a race condition where
another thread could call gsskrb5_register_acceptor_identity()
(thus invalidating the target of the copied pointer) before it is
used by gsskrb5_acceptor_start().
So instead, clone the keytab to a new one while protected by the
mutex lock (similar to get_keytab() in acquire_cred.c).
Signed-off-by: Nicolas Williams <nico@twosigma.com>