Add support for SAnon, a simple key agreement protocol that provides no
authentication of initiator or acceptor using x25519 ECDH key exchange.
See doc/standardization/draft-howard-gss-sanon-xx.txt for a protocol
description.
gss_release_cred_by_mech() was previously used by SPNEGO's implementation of
gss_set_neg_mechs(). This is now implemented in the mechanism glue. As we never
shipped gss_release_cred_by_mech(), it is safe to remove it and its exported
symbol.
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.
gss_add_oid_set_member() should according to RFC2744 add a copy of the OID to
the set; the current implementation just stored a pointer (which may not be
stable). As we have _gss_intern_oid(), call that before adding.
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.
gss_decapsulate_token() should return GSS_S_BAD_MECH if the mechanism did not
match the expected one, and GSS_S_DEFECTIVE_TOKEN if the token could not be
parsed for some other reason, rather than GSS_S_FAILURE in both cases
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.
The NegoEx gss_{exchange,query}_meta_data functions set allocated_ctx but never
did anything with it. Use it to determine whether we should free the context
handle on error.
_gss_secure_release_buffer_set() patch changed minor_status to 0, not
*minor_status as correct. No behavioural change as
_gss_secure_release_buffer_set() would have set it anyway, but obviously this
was unintentional.
Anonymous names should always compare FALSE in GSS_Compare_name(). If the names
are being compared at the mechglue layer then we should check for
GSS_C_NT_ANONYMOUS.
The prototype for gss_set_sec_context_option() allows it to return a new
context, however this was not implemented. This functionality is required by
GSS_KRB5_IMPORT_RFC4121_CONTEXT_X.
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
__gss_c_attr_stream_sizes_oid_desc was tagged with GSSAPI_LIB_FUNCTION instead
of GSSAPI_LIB_VARIABLE; whilst the macro expansion is identical, fix for
cleanliness
- 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?
This is the second of two commits in a series that must be picked together.
This series of two commits moves parts of lib/krb5/ infrastructure
functionality to lib/base/, leaving behind wrappers.
Some parts of libkrb5 are entirely generic or easily made so, and could
be useful in various parts of Heimdal that are not specific to the krb5
API, such as:
- lib/gssapi/ (especially since the integration of NegoEx)
- lib/hx509/
- bx509d (which should really move out of kdc/)
For the above we need to move these bits of lib/krb5/:
- lib/krb5/config_file.c (all of it, leaving forwardings behind)
- lib/krb5/config_reg.c (all of it)
- lib/krb5/plugin.c (all of it, leaving forwardings behind)
- lib/krb5/log.c (all of it, ditto)
- lib/krb5/heim_err.et (all of it)
And because of those two, these too must also move:
- lib/krb5/expand_path.c (all of it, leaving forwardings behind)
- lib/krb5/warn.c (just the warning functions, ditto)
The changes to the moved files are mostly quite straightforward and are
best reviewed with --word-diff=color.
We're also creating a heim_context and a heim API to go with it. But
it's as thin as possible, with as little state as necessary to enable
this move. Functions for dealing with error messages use callbacks.
Moving plugin.c does have one knock-on effect on all users of the old
krb5 plugin API (which remains), which is that a global search and
replace of struct krb5_plugin_data to struct heim_plugin_data was
needed, though the layout and size of that structure doesn't change, so
the ABI doesn't either.
As well, we now build lib/vers/ and lib/com_err/ before lib/base/ so as
to be able to move lib/krb5/heim_err.et to lib/base/ so that we can make
use of HEIM_ERR_* in lib/base/, specifically in the files that moved.
Once this is all done we'll be able to use config files and plugins in
lib/hx509/, we'll be able to move bx509d out of kdc/, and so on.
Most if not all of the new functions in lib/base/ are Heimdal-private,
thus calling conventions for them are not declared.
Status:
- builds and passes CIs (Travis, Appveyor)
- ran make check-valgrind and no new leaks or other memory errors
- ready for review
HOW TO REVIEW:
$ # Review file moves:
$ git log --stat -n1 HEAD^
$
$ # Review changes to moved files using --word-diff=color
$ git log -p -b -w --word-diff=color HEAD^..HEAD \
lib/base/config_file.c \
lib/base/config_reg.c \
lib/base/expand_path.c \
lib/base/warn.c \
lib/krb5/config_file.c \
lib/krb5/config_reg.c \
lib/krb5/expand_path.c \
lib/krb5/warn.c
$
$ # Review the whole thing, possibly adding -b and/or -w, and
$ # maybe --word-diff=color:
$ git log -p origin/master..HEAD
$ git log -p -b -w origin/master..HEAD
$ git log -p -b -w --word-diff=color origin/master..HEAD
TBD (future commits):
- make lib/gssapi use the new heimbase functions
- move kx509/bx509d common code to lib/hx509/ or other approp. location
- move bx509d out of kdc/
Initialize mechanism output parameters before calling mechanism
GSS_Accept_sec_context(), to behave robustly with poorly implemented mechanisms
that may return before initializing them.
NTLM erroneously requires a mechListMIC at the SPNEGO layer if an internal MIC
in the NTLM protocol was used. Add a private interface between SPNEGO and the
Samba NTLM mechanism to allow the mechanism to signal that a mechListMIC is
required even if it otherwise would not be.
This interface is the same as that supported by MIT.
Note that only the Samba NTLM mechanism currently implements this feature, it
is not implemented by the Heimdal NTLM mechanism (which does not support NTLM
authenticate message MICs).
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).
GM_USE_MG_CRED allows a mechanism glue credential to be used by a mechanism
without additional wrapping. Although no extant mechanisms use this flag, the
flag had sporadic support in the mechanism glue already. In the interest of
consistency, add missing GM_USE_MG_CRED checks. If this functionality is not
desired, then all checks should be removed.
Add helper APIs to the mechanism glue from the Apple implementation.
gss_mg_export_name() can be used by a mechanism to create an exported name
(this is used by the future SAnon implementation). _gss_mech_import_name()
allows the mechanism to pass in a list of parsing functions for specific name
tiypes. This commit only adds support to the mechanism glue itself.
The GSS mechglue uses singly linked lists for mechanisms and mechanism objects,
to which new entries are inserted at the head. This breaks ordering of
mechanisms specified in OID sets and in /etc/gss/mech, as they will be back to
front. Use a tail queue instead so that new entries are inserted at the end.
Make mechanism interfaces that are optional in usage, optional in
implementation, i.e. do not require them to be present when dynamically loading
a mechanism. In order to aid minimal mechanism implementation, more of these
should likely be made optional (this will require an additional check in the
mechglue to return GSS_S_UNAVAILABLE if the function pointer is NULL). This is
left as a future exercise.
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).
gss_acquire_cred_from() is an exported function and therefore
must be tagged with GSSAPI_LIB_FUNCTION and GSSAPI_LIB_CALL.
Change-Id: I80918cb8083eaeac2d0eba5347f7b428e997cfaa
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.
Apple's Heimdal impelmentation uses a number of utility functions for
allocating names and credentials, to avoid calling malloc or calloc directly.
Import them.
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.