Go to the first, previous, next, last section, table of contents.


The plaintext authenticator

The `plaintext' authenticator can be configured to support the PLAIN and LOGIN authentication mechanisms, both of which transfer authentication data as plain (unencrypted) text, though encoded in base 64.

Using plaintext in a server

When running as a server, `plaintext' performs the authentication test by expanding a string. It has the following options:

server_prompts (plaintext) option

Option: server_prompts
Type: string
Default: unset

This option contains a colon-separated list of prompt strings.

server_condition (plaintext) option

Option: server_condition
Type: string
Default: unset

This option must be set in order to configure the driver as a server. Its use is described below.

The data sent with the AUTH command or in response to subsequent prompts is encoded in base 64, and so may contain any byte values when decoded. If any data was supplied with the command, it is treated as a list of NUL-separated strings which are placed in the expansion variables `$1', `$2', etc. If there are more strings in `server_prompts' than the number of strings supplied with the AUTH command, the remaining prompts are used to obtain more data. Each response from the client may be a list of NUL-separated strings.

Once a sufficient number of data strings has been received, `server_condition' is expanded. Failure of the expansion (forced or otherwise) causes a temporary error code to be returned. If the result of a successful expansion is an empty string, `0', `no', or `false', authentication fails. If the result of the expansion is `1', `yes', or `true', authentication succeeds and the generic `server_set_id' option is expanded and saved in `$authenticated_id'. For any other result, a temporary error code is returned, with the expanded string as the error text.

The PLAIN authentication mechanism (RFC 2595) specifies that three strings be sent with the AUTH command. The second and third of them are treated as a user/password pair. Using a single fixed user and password as an example, this could be configured as follows:

fixed_plain:
  driver = plaintext
  public_name = PLAIN
  server_condition = "\
    ${if and {{eq{$2}{ph10}}{eq{$3}{secret}}}{yes}{no}}"
  server_set_id = $2

This would be advertised in the response to EHLO as

250-AUTH PLAIN

and a client host could authenticate itself by sending the command

AUTH PLAIN AHBoMTAAc2VjcmV0

The argument string is encoded in base 64, as required by the RFC. This example, when decoded, is `<NUL>ph10<NUL>secret', where <NUL> represents a zero byte. This is split up into three strings, the first of which is empty. The condition checks that the second two are `ph10' and `secret' respectively. Because no prompt strings are set, if no data is given with the AUTH command, authentication fails.

A more sophisticated instance of this authenticator could make use of the user name in `$2' to look up a password in a file or database, and maybe do an encrypted comparison (see `crypteq' in chapter "String expansions"). Note, however, that the authentication data has traversed the network in clear, albeit encoded as a base 64 string.

The LOGIN authentication mechanism is not documented in any RFC, but is in use in a number of programs. No data is sent with the AUTH command. Instead, a user name and password are supplied separately, in response to prompts. The plaintext authenticator can be configured to support this as in this example:

fixed_login:
  driver = plaintext
  public_name = LOGIN
  server_prompts = "User Name : Password"
  server_condition = "\
    ${if and {{eq{$1}{ph10}}{eq{$2}{secret}}}{yes}{no}}"
  server_set_id = $1

This authenticator would accept data with the AUTH command, but if the client does not supply it (as is the case for LOGIN clients), the prompt strings are used to obtain two data items.

Using plaintext in a client

The `plaintext' authenticator has just one client option:

client_send (plaintext) option

Option: client_send
Type: string
Default: unset

The string is a colon-separated list of authentication data strings. Each string is independently expanded before being sent to the server. The first string is sent with the AUTH command; any more strings are sent in response to prompts from the server.

Because the PLAIN authentication mechanism requires NUL (zero) bytes in the data sent with the AUTH command, further processing is applied to each string before it is sent. If there are any single circumflex characters in the string, they are converted to NULs. Should an actual circumflex be required as data, it must be doubled in the string.

This is an example of a client configuration that implements PLAIN authentication mechanism with a fixed name and password:

fixed_plain:
  driver = plaintext
  public_name = PLAIN
  client_send = "^ph10^secret"

The lack of colons means that the entire text is sent with the AUTH comand, with the circumflex characters converted to zero bytes. A similar example that uses the LOGIN mechanism is:

fixed_login:
  driver = plaintext
  public_name = LOGIN
  client_send = ": ph10 : secret"

The initial colon ensures that no data is sent with the AUTH command itself. The remaining strings are sent in response to prompts.


Go to the first, previous, next, last section, table of contents.