## 13 Pmilter multiplexer program. ¶

`Pmult` is a Pmilter–Milter multiplexer, i.e. a program that acts as a mediator between the Pmilter server and one or several Milter clients. Usually, the former is an instance of `smtps` from MeTA1, and the latter are running `mailfromd` instances. `Pmult` receives Pmilter commands from the server, translates them into equivalent Milter commands and passes the translated requests to a preconfigured set of Milter filters. When the filters reply, the reverse operation is performed: Milter responses are translated into their Pmilter equivalents and are sent back to the server.

                                                +-----------------+
                                         +----->| Milter Client 1 |
                                         |      +-----------------+
                                         |
       +-----------+       +---------+   |      +-----------------+
       |   MeTA1   |<=====>|  Pmult  |<--+----->| Milter Client 1 |
       +-----------+       +---------+   |      +-----------------+
                                         |
                                         +--------->    //
                                         |
                                         |      +-----------------+
                                         +----->| Milter Client N |
                                                +-----------------+

Due to the specifics nature of the threaded MeTA1 libraries, `pmult` does not detach from the controlling terminal (i.e. does not become a daemon). To run it as a background process, we recommend to use `pies` daemon. ‘`Pies`’ is a powerful utility that allows you to launch several foreground-designed programs in the background and control their execution. See Pies in Pies Manual, for a detailed description of the program. For a practical advice on how to use it with `pmult`, see Using Pies to Run Pmult in Pies Manual. For a description on how to start both `pmult` and MeTA1 from the same `pies` configuration file, see Using Pies to Run Pmult and MeTA1 in Pies Manual.

### 13.1 Pmult Configuration ¶

`Pmult` reads its configuration from the main configuration file `/etc/mailfromd.conf`. Unless it is the only component of the ‘`Mailfromd`’ package that is being run, its configuration should be explicitly marked as such by using either `program` or `include` statement, as described in Configuring `mailfromd`.

The following standard Mailutils statements are understood:

Statement | Reference
--- | ---
debug | See Mailutils Configuration File in GNU Mailutils Manual.
logging | See Mailutils Configuration File in GNU Mailutils Manual.
include | See Mailutils Configuration File in GNU Mailutils Manual.

#### 13.1.1 Multiplexer Configuration. ¶

`Pmult` listens for Pmilter requests on a socket, configured using `listen` statement:

Pmult Conf: listen url ¶

  Listen on the given url. Argument is a valid Mailutils URL. See milter port specification, for a description of url.

Since `pmult` runs as a foreground program, it does not write its PID number to a file by default. If this behavior is required, it can be enabled using the following statement:

Pmult Conf: pidfile file ¶

  Store PID of the `pmult` process in file.

The following three limits require MeTA1 version ‘`PreAlpha30.0`’ or later.

Pmult Conf: max-threads-soft n ¶

  “Soft” limit on the number of ‘`pmilter`’ threads. Default is 2.

Pmult Conf: max-threads-hard n ¶

  “Hard” limit on the number of ‘`pmilter`’ threads. This is roughly equivalent to the number of emails `pmult` is able to handle simultaneously. The default value is 6. Raise this limit if you experience long delays when connecting to the SMTP port.

Pmult Conf: max-pmilter-fd n ¶

  Maximum number of file descriptors ‘`pmilter`’ library is allowed to open simultaneously. Default is 10.

#### 13.1.2 Translating MeTA1 macros. ¶

MeTA1’s notion of macros differs considerably from that of Sendmail. Macros in MeTA1 are identified by integer numbers and only a limited number of macros can be provided for each Pmilter stage. Pmilter stages mostly correspond to Milter states (see handler names), except that there are no distinct header and body stages, instead these two are combined into a single ‘`data`’ stage. This comes unnoticed to mailfromd scripts, because `pmult` takes care to invoke right Milter handlers within the single ‘`data`’ Pmilter state. Therefore in the discussion that follows we will refer to Mailfromd handlers, rather than to Pmilter stages.

The most important standard Milter macros are always provided by `pmult` itself. These are:

client_addr

  The IP address of the SMTP client. As of version 9.1, only IPv4 addresses are supported. Defined in all handlers.

client_port

  The port number of the SMTP client. Defined in all handlers.

i

  MeTA1 session ID. Defined in all handlers.

f

  The envelope sender (from) address. Defined in `envfrom` and subsequent handlers.

nbadrcpts

  The number of bad recipients for a single message. Defined in `envfrom` and `envrcpt` handlers.

ntries

  The number of delivery attempts. As of version 9.1 it is always ‘`1`’. Defined in `envfrom` and subsequent handlers.

nrcpts

  The number of validated recipients for a single message. Defined in `envfrom` and `envrcpt` handlers.

r

  Protocol used to receive the message. The value of this macro is always ‘`SMTP`’. Defined in all handlers.

rcpt_host

  The host from the resolved triple of the address given for the SMTP RCPT command. Defined in `envrcpt` handler.

rcpt_addr

  The address part of the resolved triple of the address given for the SMTP RCPT command. Defined in `envrcpt` handler.

s

  Sender’s helo domain (parameter to `EHLO` or `HELO` command).

Two additional macros are provided for all handlers that allow to identify whether the message is processed via `pmult`:

multiplexer

  Canonical name of the multiplexer program, i.e. ‘`pmult`’.

mult_version

  Version of `pmult`.

These macros can be used in mailfromd filters to provide alternative processing for messages coming from a MeTA1 server.

Macros defined in MeTA1 can be made available in Mailfromd handlers using the `define-macros` statement.

Pmult Conf: define-macros handler macros ¶

  Define a set of Sendmail macros for the given Mailfromd handler. Allowed values for handler are: ‘`connect`’, ‘`helo`’, ‘`mail`’ (or ‘`envfrom`’), ‘`rcpt`’ (or ‘`envrcpt`’), ‘`data`’ (or ‘`header`’ or ‘`body`’), ‘`dot`’ (‘`eom`’). A list of these values is also accepted, in which case macros are defined for each handler from the list.

  The second argument specifies a list of names of the macros that should be defined in this handler. Allowed macro names are:

  hostname

    Hostname of SMTP server.

  client_resolve

    Result of client lookup.

  tls_version

    TLS/SSL version used.

  tls_cipher_suite

    TLS cipher suite used.

  tls_cipher_bits

    Effective key length of the symmetric encryption algorithm.

  tls_cert_subject

    The DN (distinguished name) of the presented certificate.

  tls_cert_issuer

    The DN (distinguished name) of the CA (certificate authority) that signed the presented certificate (the cert issuer).

  tls_alg_bits

    Maximum key length of the symmetric encryption algorithm. This may be less than the effective key length for export controlled algorithms.

  tls_vrfy

    The result of the verification of the presented cert.

  tls_cn_subject
  cn_subject

    The CN (common name) of the presented certificate.

  tls_cn_issuer
  cn_issuer

    The CN (common name) of the CA that signed the presented certificate.

  auth_type

    The mechanism used for SMTP authentication (only set if successful).

  auth_authen

    The client’s authentication credentials as determined by authentication (only set if successful). The actual format depends on the mechanism used, it might be just ‘`user`’, or ‘`user@realm`’, or something similar.

  auth_author

    The authorization identity, i.e. the ‘`AUTH=`’ parameter of the SMTP MAIL command if supplied.

  taid

    MeTA1 transaction id.

  msgid

    Message-Id of the message.

  c

    The hop count. Basically, this is the number of ‘`Received:`’ headers.

  Notice the following limitations:

  1. ‘`taid`’ cannot be requested before ‘`mail`’ stage.
  2. ‘`msgid`’ can be requested only in ‘`dot`’ stage.
  3. All ‘`tls_*`’ macros are valid only after a `STARTTLS` command.
  4. The number of MeTA1 macros per stage is limited by `PM_MAX_MACROS` define in `include/sm/pmfdef.h`. In MeTA1 versions up to and including 1.0.PreAlpha28.0, this number is 8. If you need more macros, increase this number and recompile MeTA1.

Pmult Conf: auth-macros bool ¶

  If bool is `true` (see boolean in GNU Mailutils Manual), pass auth macros to mailfromd ‘`mail`’ handler. It is equivalent to:

      define-macros mail (auth_type, auth_authen, auth_author);

#### 13.1.3 Pmult Client Configuration. ¶

In `pmult` terminology, remote Milters are clients. The number of clients `pmult` is able to handle is not limited. Each client is declared using `client` statement:

    client [ident] {
      # Set remote protocol type.
      type protocol-type;
      # Set remote client URL.
      url arg;
      # Set write timeout.
      write-timeout duration;
      # Set read timeout.
      read-timeout duration;
      # Set timeout for EOM.
      eom-timeout duration;
      # Set connect timeout.
      connect-timeout duration;
      # Set log verbosity level.
      log-level level;
    };

Pmult Conf: client [ident] { statements } ¶

  Declare a Milter client. Optional ident gives the identifier of this client, which will be used in diagnostics messages.

  Statements are described below.

Pmult Conf: type typestr ¶

  This statement is reserved for future use. In version 9.1 it is a no-op.

  If given, the value of typestr must be ‘`milter`’.

  In future versions this statement will declare the protocol to be used to interact with this client. The syntax for typestr is

        type [version]

  where type is either ‘`milter`’ or ‘`pmilter`’, and optional version is minimal protocol version.

Pmult Conf: url arg ¶

  Set remote client URL. See milter port specification, for a description of url.

Pmult Conf: connect-timeout interval ¶

  Configure Milter initial connection timeout. Default is 300.

  See time interval specification, for information on interval format.

Pmult Conf: write-timeout interval ¶

  Configure Milter write timeout. Default is 10.

  See time interval specification, for information on interval format.

Pmult Conf: read-timeout interval ¶

  Configure Milter read timeout. Default is 10.

  See time interval specification, for information on interval format.

Pmult Conf: eom-timeout interval ¶

  Configure Milter end of message timeout. Default is 300.

  See time interval specification, for information on interval format.

Pmult Conf: log-level arg ¶

  Set Milter log verbosity level for this client. Argument is a list of items separated by commas or whitespace. Each item is a log level optionally prefixed with ‘`!`’ to indicate “any level except this”, ‘`<`’, meaning “all levels up to and including this”, or with ‘`>`’, meaning “all levels starting from this”.

  Log levels in order of increasing priority are: ‘`proto`’, ‘`debug`’, ‘`info`’, ‘`warn`’, ‘`err`’, ‘`fatal`’. The first two levels are needed for debugging `libgacopyz` and Milter protocol. See Gacopyz, for the description of the `libgacopyz` library. See also the following subsection.

#### 13.1.4 Debugging Pmult ¶

If needed, `pmult` can be instructed to provide additional debugging information. The amount of this information is configured by three configuration statements. First of all, the standard `debug` block statement controls debugging of the underlying GNU Mailutils libraries (see Mailutils Configuration File in GNU Mailutils Manual). Secondly, the `debug` statement controls debugging output of the `pmult` utility itself. The `pmilter-debug` statement controls debugging output of the underlying MeTA1 libraries, and, finally, the `log-level` statement, described in the previous subsection, defines debugging level for the Milter library (`libgacopyz`).

Pmult Conf: debug spec ¶

  Set debugging level for the `pmult` code. See Mailutils Configuration File in GNU Mailutils Manual, for a description of spec syntax. Multiplexor-specific debugging is enabled by the ‘`pmult`’ category. The following levels are used:

  pmult.trace1

    Prints the following information:

    - opening and closing incoming connections;
    - entering particular Pmilter stage handlers;
    - received requests with unknown command code;
    - header modification requests that does not match any headers.
  pmult.trace2

    Information about milter to Pmilter request translation.

  pmult.trace7

    Detailed dump of message body chunks received during Pmilter ‘`DATA`’ stage.

  pmult.error

    Logs bad recipient addresses.

  This information is printed using the output channel defined in the `logging` statement (see Mailutils Configuration File in GNU Mailutils Manual).

Pmult Conf: pmilter-debug level ¶

  Set debug verbosity level for the Pmilter library. Argument is a positive integer between zero (no debugging, the default), and 100 (maximum debugging).

  Pmilter debugging information is printed on the standard error. Use `pies` `stderr` statement to capture this stream and redirect it to the syslog or file (see Output Redirectors in Pies Manual).

### 13.2 Pmult Example ¶

The following is an example of a working `pmult` configuration. The multiplexer listens on localhost, port ‘`3333`’. It prints its diagnostics using syslog facility `local2`. A single Mailfromd client is declared, which listens on UNIX socket `/usr/local/var/mailfromd/mailfrom`. The log verbosity level for this client is set to ‘`info`’ and higher, i.e.: ‘`info`’, ‘`warn`’, ‘`err`’ and ‘`fatal`’.

    listen inet://127.0.0.1:3333;

    logging {
       facility local2;
    };

    debug {
       level "pmult.trace7";
    }

    define-macros envmail (auth_type, auth_authen, auth_author, tls_vrfy);
    define-macros envrcpt (auth_type, auth_authen, auth_author);

    client {
       type milter;
       url /usr/local/var/mailfromd/mailfrom;
       log-level ">info";
       # Set write timeout.
       write-timeout 30 seconds;
       # Set read timeout.
       read-timeout 5 minutes;
       # Set timeout for EOM.
       eom-timeout 5 minutes;
    }

### 13.3 Pmult Invocation ¶

Normally, `pmult` is invoked without command line arguments. However, it does support several command line options. First of all, the common GNU Mailutils options are understood, which are useful for checking `pmult` configuration file for syntax errors. See Common Options in GNU Mailutils Manual, for a detailed description of these.

The rest of command line options supported by `pmult` is useful mostly for debugging. These options are summarized in the table below:

`--log-tag=string`

  Set the identifier used in syslog messages to string. This option mostly is for debugging purposes. We advise to use `logging` configuration statement for this purpose (see Logging Statement in GNU Mailutils Manual).

`--no-signal-handler`

  Disable signal handling in the main thread. This is for debugging purposes.

`--syslog`

  Log to the syslog. This is the default. See Logging Statement in GNU Mailutils Manual, for information on how to configure syslog logging.

`-s`
`--stderr`

  Log to the standard error stream.

`--url=url`

  Listen on the given url. This overrides the `url` configuration statement (see url).

`-x`
`--debug=level`

  Set debug verbosity level. This overrides the `debug` configuration statement. See Debugging Pmult, for more information.