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.
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 |
If a SCRAM mechanism is being used and this option is set 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.
server_channelbinding | Use: gsasl | Type: boolean | Default: false |
Do not set this true and rely on the properties without consulting a cryptographic engineer.
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.
However, Channel Binding in TLS has proven to be vulnerable in current versions. Do not plan to rely upon this feature for security, ever, without consulting with a subject matter expert (a cryptographic engineer).
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