 774f50b28b
			
		
	
	774f50b28b
	
	
	
		
			
			GSS pre-auth helpers do not belong in libgssapi, so move them to a separate convenience library.
		
			
				
	
	
		
			120 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			5.4 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.
 | |
| 
 | |
| ## Protocol changes
 | |
| 
 | |
|   - The pre-authentication type KRB5-PADATA-GSS is 655
 | |
|   - Pre-authentication data is the raw context token rather than being
 | |
|     wrapped in another ASN.1 type
 | |
|   - Acceptor GSS state is stored in FX-COOKIE rather than alongside the
 | |
|     context token
 | |
|   - Key derivation salt is the string "KRB-GSS\0" || nonce
 | |
| 
 | |
| ## 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.
 |