|
Packit |
fd8b60 |
GSSAPI mechanism interface
|
|
Packit |
fd8b60 |
==========================
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
The GSSAPI library in MIT krb5 can load mechanism modules to augment
|
|
Packit |
fd8b60 |
the set of built-in mechanisms.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
.. note: The GSSAPI loadable mechanism interface does not follow the
|
|
Packit |
fd8b60 |
normal conventions for MIT krb5 pluggable interfaces.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
A mechanism module is a Unix shared object or Windows DLL, built
|
|
Packit |
fd8b60 |
separately from the krb5 tree. Modules are loaded according to the
|
|
Packit |
fd8b60 |
GSS mechanism config files described in :ref:`gssapi_plugin_config`.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
For the most part, a GSSAPI mechanism module exports the same
|
|
Packit |
fd8b60 |
functions as would a GSSAPI implementation itself, with the same
|
|
Packit |
fd8b60 |
function signatures. The mechanism selection layer within the GSSAPI
|
|
Packit |
fd8b60 |
library (called the "mechglue") will dispatch calls from the
|
|
Packit |
fd8b60 |
application to the module if the module's mechanism is requested. If
|
|
Packit |
fd8b60 |
a module does not wish to implement a GSSAPI extension, it can simply
|
|
Packit |
fd8b60 |
refrain from exporting it, and the mechglue will fail gracefully if
|
|
Packit |
fd8b60 |
the application calls that function.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
The mechglue does not invoke a module's **gss_add_cred**,
|
|
Packit |
fd8b60 |
**gss_add_cred_from**, **gss_add_cred_impersonate_name**, or
|
|
Packit |
fd8b60 |
**gss_add_cred_with_password** function. A mechanism only needs to
|
|
Packit |
fd8b60 |
implement the "acquire" variants of those functions.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
A module does not need to coordinate its minor status codes with those
|
|
Packit |
fd8b60 |
of other mechanisms. If the mechglue detects conflicts, it will map
|
|
Packit |
fd8b60 |
the mechanism's status codes onto unique values, and then map them
|
|
Packit |
fd8b60 |
back again when **gss_display_status** is called.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
NegoEx modules
|
|
Packit |
fd8b60 |
--------------
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Some Windows GSSAPI mechanisms can only be negotiated via a Microsoft
|
|
Packit |
fd8b60 |
extension to SPNEGO called NegoEx. Beginning with release 1.18,
|
|
Packit |
fd8b60 |
mechanism modules can support NegoEx as follows:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* Implement the gssspi_query_meta_data(), gssspi_exchange_meta_data(),
|
|
Packit |
fd8b60 |
and gssspi_query_mechanism_info() SPIs declared in
|
|
Packit |
fd8b60 |
``<gssapi/gssapi_ext.h>``.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* Implement gss_inquire_sec_context_by_oid() and answer the
|
|
Packit |
fd8b60 |
**GSS_C_INQ_NEGOEX_KEY** and **GSS_C_INQ_NEGOEX_VERIFY_KEY** OIDs
|
|
Packit |
fd8b60 |
to provide the checksum keys for outgoing and incoming checksums,
|
|
Packit |
fd8b60 |
respectively. The answer must be in two buffers: the first buffer
|
|
Packit |
fd8b60 |
contains the key contents, and the second buffer contains the key
|
|
Packit |
fd8b60 |
encryption type as a four-byte little-endian integer.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
By default, NegoEx mechanisms will not be directly negotiated via
|
|
Packit |
fd8b60 |
SPNEGO. If direct SPNEGO negotiation is required for
|
|
Packit |
fd8b60 |
interoperability, implement gss_inquire_attrs_for_mech() and assert
|
|
Packit |
fd8b60 |
the GSS_C_MA_NEGOEX_AND_SPNEGO attribute (along with any applicable
|
|
Packit |
fd8b60 |
RFC 5587 attributes).
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Interposer modules
|
|
Packit |
fd8b60 |
------------------
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
The mechglue also supports a kind of loadable module, called an
|
|
Packit |
fd8b60 |
interposer module, which intercepts calls to existing mechanisms
|
|
Packit |
fd8b60 |
rather than implementing a new mechanism.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
An interposer module must export the symbol **gss_mech_interposer**
|
|
Packit |
fd8b60 |
with the following signature::
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
gss_OID_set gss_mech_interposer(gss_OID mech_type);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
This function is invoked with the OID of the interposer mechanism as
|
|
Packit |
fd8b60 |
specified in the mechanism config file, and returns a set of mechanism
|
|
Packit |
fd8b60 |
OIDs to be interposed. The returned OID set must have been created
|
|
Packit |
fd8b60 |
using the mechglue's gss_create_empty_oid_set and
|
|
Packit |
fd8b60 |
gss_add_oid_set_member functions.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
An interposer module must use the prefix ``gssi_`` for the GSSAPI
|
|
Packit |
fd8b60 |
functions it exports, instead of the prefix ``gss_``.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
An interposer module can link against the GSSAPI library in order to
|
|
Packit |
fd8b60 |
make calls to the original mechanism. To do so, it must specify a
|
|
Packit |
fd8b60 |
special mechanism OID which is the concatention of the interposer's
|
|
Packit |
fd8b60 |
own OID byte string and the original mechanism's OID byte string.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Since **gss_accept_sec_context** does not accept a mechanism argument,
|
|
Packit |
fd8b60 |
an interposer mechanism must, in order to invoke the original
|
|
Packit |
fd8b60 |
mechanism's function, acquire a credential for the concatenated OID
|
|
Packit |
fd8b60 |
and pass that as the *verifier_cred_handle* parameter.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
Since **gss_import_name**, **gss_import_cred**, and
|
|
Packit |
fd8b60 |
**gss_import_sec_context** do not accept mechanism parameters, the SPI
|
|
Packit |
fd8b60 |
has been extended to include variants which do. This allows the
|
|
Packit |
fd8b60 |
interposer module to know which mechanism should be used to interpret
|
|
Packit |
fd8b60 |
the token. These functions have the following signatures::
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
OM_uint32 gssi_import_sec_context_by_mech(OM_uint32 *minor_status,
|
|
Packit |
fd8b60 |
gss_OID desired_mech, gss_buffer_t interprocess_token,
|
|
Packit |
fd8b60 |
gss_ctx_id_t *context_handle);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
OM_uint32 gssi_import_name_by_mech(OM_uint32 *minor_status,
|
|
Packit |
fd8b60 |
gss_OID mech_type, gss_buffer_t input_name_buffer,
|
|
Packit |
fd8b60 |
gss_OID input_name_type, gss_name_t output_name);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
OM_uint32 gssi_import_cred_by_mech(OM_uint32 *minor_status,
|
|
Packit |
fd8b60 |
gss_OID mech_type, gss_buffer_t token,
|
|
Packit |
fd8b60 |
gss_cred_id_t *cred_handle);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
To re-enter the original mechanism when importing tokens for the above
|
|
Packit |
fd8b60 |
functions, the interposer module must wrap the mechanism token in the
|
|
Packit |
fd8b60 |
mechglue's format, using the concatenated OID. The mechglue token
|
|
Packit |
fd8b60 |
formats are:
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* For **gss_import_sec_context**, a four-byte OID length in big-endian
|
|
Packit |
fd8b60 |
order, followed by the mechanism OID, followed by the mechanism
|
|
Packit |
fd8b60 |
token.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* For **gss_import_name**, the bytes 04 01, followed by a two-byte OID
|
|
Packit |
fd8b60 |
length in big-endian order, followed by the mechanism OID, followed
|
|
Packit |
fd8b60 |
by the bytes 06, followed by the OID length as a single byte,
|
|
Packit |
fd8b60 |
followed by the mechanism OID, followed by the mechanism token.
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
* For **gss_import_cred**, a four-byte OID length in big-endian order,
|
|
Packit |
fd8b60 |
followed by the mechanism OID, followed by a four-byte token length
|
|
Packit |
fd8b60 |
in big-endian order, followed by the mechanism token. This sequence
|
|
Packit |
fd8b60 |
may be repeated multiple times.
|