38. The gsasl authenticator
Author: The Exim Project. <https://www.exim.org/>
Description: Exim is a message transfer agent (MTA) developed at the University of Cambridge for use on Unix systems connected to the Internet.
Keywords: exim,smtp,mta,email

# Exim Internet Mailer

<-previous next->

## 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

<-previous Table of Contents next->