Chapter 38 - The gsasl authenticator
The gsasl authenticator provides integration for the GNU SASL library and the mechanisms it provides. This is new as of the 4.80 release and there are a few areas where the library does not let Exim smoothly scale to handle future authentication mechanisms, so no guarantee can be made that any particular new authentication mechanism will be supported without code changes in Exim.
The library is expected to add support in an upcoming realease for the SCRAM-SHA-256 method. The macro _HAVE_AUTH_GSASL_SCRAM_SHA_256 will be defined when this happens.
To see the list of mechanisms supported by the library run Exim with "auth" debug enabled and look for a line containing "GNU SASL supports". Note however that some may not have been tested from Exim.
client_authz | Use: gsasl | Type: string† | Default: unset |
This option can be used to supply an authorization id which is different to the authentication_id provided by client_username option. If unset or (after expansion) empty it is not used, which is the common case.
client_channelbinding | Use: gsasl | Type: boolean | Default: false |
See server_channelbinding below.
client_password | Use: gsasl | Type: string† | Default: unset |
This option is exapanded before use, and should result in the password to be used, in clear.
client_username | Use: gsasl | Type: string† | Default: unset |
This option is exapanded before use, and should result in the account name to be used.
client_spassword | Use: gsasl | Type: string† | Default: unset |
This option is only supported for library versions 1.9.1 and greater. The macro _HAVE_AUTH_GSASL_SCRAM_S_KEY will be defined when this is so.
If a SCRAM mechanism is being used and this option is set and correctly sized it is used in preference to client_password. The value after expansion should be a 40 (for SHA-1) or 64 (for SHA-256) character string with the PBKDF2-prepared password, hex-encoded.
Note that this value will depend on the salt and iteration-count supplied by the server. The option is expanded before use. During the expansion $auth1 is set with the client username, $auth2 with the iteration count, and $auth3 with the salt.
The intent of this option is to support clients that can cache thes salted password to save on recalculation costs. The cache lookup should return an unusable value (eg. an empty string) if the salt or iteration count has changed
If the authentication succeeds then the above variables are set, plus the calculated salted password value value in $auth4, during the expansion of the client_set_id option. A side-effect of this expansion can be used to prime the cache.
server_channelbinding | Use: gsasl | Type: boolean | Default: false |
Some authentication mechanisms are able to use external context at both ends of the session to bind the authentication to that context, and fail the authentication process if that context differs. Specifically, some TLS ciphersuites can provide identifying information about the cryptographic context.
This should have meant that certificate identity and verification becomes a non-issue, as a man-in-the-middle attack will cause the correct client and server to see different identifiers and authentication will fail.
This is only usable by mechanisms which support "channel binding"; at time of writing, that’s the SCRAM family. When using this feature the "-PLUS" variants of the method names need to be used.
This defaults off to ensure smooth upgrade across Exim releases, in case this option causes some clients to start failing. Some future release of Exim might have switched the default to be true.
This option was deprecated in previous releases due to doubts over the "Triple Handshake" vulnerability. Exim takes suitable precausions (requiring Extended Master Secret if TLS Session Resumption was used) for safety.
server_hostname | Use: gsasl | Type: string† | Default: see below |
This option selects the hostname that is used when communicating with the
library. The default value is $primary_hostname
.
Some mechanisms will use this data.
server_mech | Use: gsasl | Type: string | Default: see below |
This option selects the authentication mechanism this driver should use. The default is the value of the generic public_name option. This option allows you to use a different underlying mechanism from the advertised name. For example:
sasl: driver = gsasl public_name = X-ANYTHING server_mech = CRAM-MD5 server_set_id = $auth1
server_password | Use: gsasl | Type: string† | Default: unset |
Various mechanisms need access to the cleartext password on the server, so that proof-of-possession can be demonstrated on the wire, without sending the password itself.
The data available for lookup varies per mechanism. In all cases, $auth1 is set to the authentication id. The $auth2 variable will always be the authorization id (authz) if available, else the empty string. The $auth3 variable will always be the realm if available, else the empty string.
A forced failure will cause authentication to defer.
If using this option, it may make sense to set the server_condition option to be simply "true".
server_realm | Use: gsasl | Type: string† | Default: unset |
This specifies the SASL realm that the server claims to be in. Some mechanisms will use this data.
server_scram_iter | Use: gsasl | Type: string† | Default: 4096 |
This option provides data for the SCRAM family of mechanisms. The $auth1, $auth2 and $auth3 variables are available when this option is expanded.
The result of expansion should be a decimal number, and represents both a lower-bound on the security, and a compute cost factor imposed on the client (if it does not cache results, or the server changes either the iteration count or the salt). A minimum value of 4096 is required by the standards for all current SCRAM mechanism variants.
server_scram_salt | Use: gsasl | Type: string† | Default: unset |
This option provides data for the SCRAM family of mechanisms. The $auth1, $auth2 and $auth3 variables are available when this option is expanded. The value should be a base64-encoded string, of random data typically 4-to-16 bytes long. If unset or empty after expansion the library will provides a value for the protocol conversation.
server_key | Use: gsasl | Type: string† | Default: unset |
server_skey | Use: gsasl | Type: string† | Default: unset |
These options can be used for the SCRAM family of mechanisms to provide stored information related to a password, the storage of which is preferable to plaintext.
server_key is the value defined in the SCRAM standards as ServerKey; server_skey is StoredKey.
They are only available for version 1.9.0 (or later) of the gsasl library. When this is so, the macros _OPT_AUTHENTICATOR_GSASL_SERVER_KEY and _HAVE_AUTH_GSASL_SCRAM_S_KEY will be defined.
The $authN variables are available when these options are expanded.
If set, the results of expansion should for each should be a 28 (for SHA-1) or 44 (for SHA-256) character string of base64-coded data, and will be used in preference to the server_password option. If unset or not of the right length, server_password will be used.
The libgsasl library release includes a utility gsasl which can be used to generate these values.
server_service | Use: gsasl | Type: string | Default: smtp
|
This is the SASL service that the server claims to implement. Some mechanisms will use this data.
1. gsasl auth variables
These may be set when evaluating specific options, as detailed above. They will also be set when evaluating server_condition.
Unless otherwise stated below, the gsasl integration will use the following meanings for these variables:
-
$auth1: the authentication id
-
$auth2: the authorization id
-
$auth3: the realm
On a per-mechanism basis:
-
EXTERNAL: only $auth1 is set, to the possibly empty authorization id; the server_condition option must be present.
-
ANONYMOUS: only $auth1 is set, to the possibly empty anonymous token; the server_condition option must be present.
-
GSSAPI: $auth1 will be set to the GSSAPI Display Name; $auth2 will be set to the authorization id, the server_condition option must be present.
An anonymous token is something passed along as an unauthenticated identifier; this is analogous to FTP anonymous authentication passing an email address, or software-identifier@, as the "password".
An example showing the password having the realm specified in the callback and demonstrating a Cyrus SASL to GSASL migration approach is:
gsasl_cyrusless_crammd5: driver = gsasl public_name = CRAM-MD5 server_realm = imap.example.org server_password = ${lookup{$auth1:$auth3:userPassword}\ dbmjz{/etc/sasldb2}{$value}fail} server_set_id = ${quote:$auth1} server_condition = yes