
Heimdal implements draft-perez-krb-wg-gss-preauth-03 without protocol changes (the draft was updated to match the implementation)
111 lines
5.0 KiB
Markdown
111 lines
5.0 KiB
Markdown
# GSS-API Pre-authentication in Heimdal
|
|
|
|
GSS-API pre-authentication in Heimdal is based on
|
|
[draft-perez-krb-wg-gss-preauth](https://datatracker.ietf.org/doc/html/draft-perez-krb-wg-gss-preauth)
|
|
but with some simplifications to the protocol.
|
|
|
|
The following text assumes the reader is familiar with the draft.
|
|
|
|
## Client side
|
|
|
|
Because libkrb5 cannot have a recursive dependency on libgssapi, it instead
|
|
exports the function `_krb5_init_creds_init_gss()` which allows libgssapi to
|
|
register a set of function pointers for:
|
|
|
|
- Generating context tokens
|
|
- Finalizing a context (inquiring the initiator name and reply key)
|
|
- Releasing context and credential handles
|
|
|
|
This is a private API.
|
|
|
|
This architecture also means that the libkrb5 implementation could be used with
|
|
an alternative GSS-API implementation such as SSPI, without too much work. The
|
|
bulk of the pre-authentication logic remains in libkrb5, however, in
|
|
[`init_creds_pw.c`](../../krb5/init_creds_pw.c).
|
|
|
|
libgssapi itself exports `krb5_gss_set_init_creds()`, which is the public
|
|
interface for GSS-API pre-authentication.
|
|
|
|
`krb5_gss_set_init_creds()` enables GSS-API pre-authentication on an initial
|
|
credentials context, taking a GSS-API credential handle and mechanism. Both are
|
|
optional; defaults will be used if absent. These two parameters are exposed as
|
|
the `--gss-name` and `--gss-mech` options to `kinit` (see
|
|
[kinit(1)](../../../kuser/kinit.1) for further details). `kinit` supports
|
|
acquiring anonymous, keytab- and password-based GSS-API credentials using the
|
|
same arguments as regular Kerberos.
|
|
|
|
The selected GSS-API mechanism must support mutual authentication (ie.
|
|
authenticating the KDC) as it replaces the AS-REP reply key, However, if FAST
|
|
was used, and we know that the KDC was verified, then this requirement is
|
|
removed.
|
|
|
|
If the client does not know its initiator name, it can specify the last
|
|
arugment to `kinit` as `@REALM`, and the initiator name will be filled in when
|
|
the authentication is complete. (The realm is required to select a KDC.)
|
|
|
|
## KDC side
|
|
|
|
The KDC implements the acceptor side of the GSS-API authentication exchange.
|
|
The selected GSS-API mechanism must allow `gss_export_sec_context()` to be
|
|
called by the acceptor before the context is established, if it needs more than
|
|
a single round trip of token exchanges.
|
|
|
|
### Configuration
|
|
|
|
Configuration directives live in the [kdc] section of
|
|
[krb5.conf(5)](../../krb5/krb5.conf.5).
|
|
|
|
The `enable_gss_preauth` krb5.conf option must be set in order to enable
|
|
GSS-API pre-authentication in the KDC. When authenticating federated principals
|
|
which may not exist in the KDC, the `synthetic_clients` option should also be
|
|
set.
|
|
|
|
The `gss_mechanisms_allowed` option can be used to limit the set of GSS-API
|
|
mechanisms which are allowed to perform pre-authentication. Mechanisms are
|
|
specified as dot-separated OIDs or by a short name, such as `sanon-x25519`.
|
|
|
|
The `enable_gss_auth_data` option will include a composite GSS name in the
|
|
authorization data of returned tickets.
|
|
|
|
### Authorization
|
|
|
|
The default is that the initiator is permitted to authenticate to the Kerberos
|
|
principal that directly corresponds to it. The correspondence is governed as
|
|
follows: if the authenticating mechanism is in the list of mechanisms in the
|
|
`gss_cross_realm_mechanisms_allowed` configuration option, then the principal
|
|
is mapped identically: an initiator named `lukeh@AAA.PADL.COM` will be mapped
|
|
to the Kerberos principal `lukeh@AAA.PADL.COM`.
|
|
|
|
If the authenticating mechanism is not in this list, then the initiator will be
|
|
mapped to an enterprise principal in the service realm. For example,
|
|
`lukeh@AAA.PADL.COM` might be mapped to `lukeh\@AAA.PADL.COM@PADL.COM`
|
|
(enterprise principal name type);
|
|
|
|
This mapping has no effect for principals that exist in the HDB, because
|
|
enterprise principal names are always looked up by their first component (as if
|
|
they were an ordinary principal name). This logic is instead useful when
|
|
synthetic principals are enabled as we wish to avoid issuing tickets with a
|
|
client name in a foreign Kerberos realm, as that would conflate GSS-API
|
|
"realms" with Kerberos realms.
|
|
|
|
A custom authorization plugin installed in `$prefix/lib/plugin/kdc` will
|
|
replace this mapping and authorization logic. The plugin interface is defined in
|
|
[`gss_preauth_authorizer_plugin.h`](../../../kdc/gss_preauth_authorizer_plugin.h)).
|
|
|
|
### Anonymous authentication
|
|
|
|
A further note on the interaction of anonymous GSS-API authentication and
|
|
pre-authentication. Initiator contexts that set `GSS_C_ANON_FLAG` and a
|
|
`GSS_C_NT_ANONYMOUS` name are mapped to the unauthenticated anonymous Kerberos
|
|
principal, `WELLKNOWN/ANONYMOUS@WELLKNOWN:ANONYMOUS`. However, the local
|
|
`WELLKNOWN/ANONYMOUS` HDB entry is used to perform any authorization decisions
|
|
(as it would be for anonymous PKINIT). The AP-REP will contain the well-known
|
|
anonymous realm.
|
|
|
|
If `GSS_C_NT_ANONYMOUS` was set but a different name type was returned, then
|
|
the initiator is treated as authenticated anonymous, and the client realm will
|
|
be present in the AP-REP.
|
|
|
|
The `request-anonymous` AP-REQ flag must also be set for GSS-API anonymous
|
|
authentication to succeed.
|