@c This file is part of the Mailfromd manual. @c Copyright (C) 2008-2011 Sergey Poznyakoff @c See file mailfromd.texi for copying conditions. @c ******************************************************************* @cindex @command{pmult}, described @pindex pmult @command{Pmult} is a @dfn{Pmilter--Milter multiplexer}, i.e. a program that acts as a mediator between the @i{Pmilter} server and one or several @i{Milter} clients. Usually, the former is an instance of @command{smtps} from MeTA1, and the latter are running @command{mailfromd} instances. @command{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. @smallexample @group +-----------------+ +----->| Milter Client 1 | | +-----------------+ | +-----------+ +---------+ | +-----------------+ | MeTA1 |<=====>| Pmult |<--+----->| Milter Client 1 | +-----------+ +---------+ | +-----------------+ | +---------> // | | +-----------------+ +----->| Milter Client N | +-----------------+ @end group @end smallexample @cindex @command{pies} Due to the specifics nature of the threaded MeTA1 libraries, @command{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 @command{pies} daemon. @samp{Pies} is a powerful utility that allows you to launch several foreground-designed programs in the background and control their execution. @xref{Top, Pies Manual, Pies, pies, Pies Manual}, for a detailed description of the program. For a practical advice on how to use it with @command{pmult}, see @ref{Simple Pies, Using Pies to Run Pmult,, pies, Pies Manual}. For a description on how to start both @command{pmult} and MeTA1 from the same @command{pies} configuration file, see @ref{Hairy Pies, Using Pies to Run Pmult and MeTA1 ,, pies, Pies Manual}. @menu * pmult configuration:: * pmult example:: * pmult invocation:: @end menu @node pmult configuration @section Pmult Configuration @command{Pmult} reads its configuration from the main Mailutils configuration file. @xref{configuration, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}, for a description of GNU Mailutils configuration system. The following standard Mailutils statements are understood: @multitable @columnfractions 0.3 0.6 @headitem Statement @tab Reference @item debug @tab @xref{Debug Statement, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}. @item logging @tab @xref{Logging Statement, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}. @item include @tab @xref{Include, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}. @end multitable @menu * pmult-conf:: Multiplexer Configuration. * pmult-macros:: Translating MeTA1 macros. * pmult-client:: Pmult Client Configuration. * pmult-debug:: Debugging Pmult. @end menu @node pmult-conf @subsection Multiplexer Configuration. @cindex debugging, pmult @cindex pmult debugging @command{Pmult} listens for Pmilter requests on a socket, configured using @code{listen} statement: @deffn {Pmult Conf} listen @var{url} Listen on the given @var{url}. Argument is a valid Mailutils @acronym{URL}. @xref{milter port specification}, for a description of @var{url}. @end deffn Since @command{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: @deffn {Pmult Conf} pidfile @var{file} Store PID of the @command{pmult} process in @var{file}. @end deffn The following three limits require MeTA1 version @samp{PreAlpha30.0} or later. @deffn {Pmult Conf} max-threads-soft @var{n} ``Soft'' limit on the number of @samp{pmilter} threads. Default is 2. @end deffn @deffn {Pmult Conf} max-threads-hard @var{n} ``Hard'' limit on the number of @samp{pmilter} threads. This is roughly equivalent to the number of emails @command{pmult} is able to handle simultaneously. The default value is 6. Raise this limit if you experience long delays when connecting to the @acronym{SMTP} port. @end deffn @deffn {Pmult Conf} max-pmilter-fd @var{n} Maximum number of file descriptors @samp{pmilter} library is allowed to open simultaneously. Default is 10. @end deffn @node pmult-macros @subsection Translating MeTA1 macros. @cindex macros, MeTA1 @cindex 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 @dfn{Pmilter stage}. Pmilter stages mostly correspond to Milter states (@pxref{handler names}), except that there are no distinct header and body stages, instead these two are combined into a single @samp{data} stage. This comes unnoticed to mailfromd scripts, because @command{pmult} takes care to invoke right Milter handlers within the single @samp{data} Pmilter state. Therefore in the discussion that follows we will refer to Mailfromd handlers, rather than to Pmilter stages. @cindex i, @command{Sendmail} macro in @command{MeTA1} The most important standard Milter macros are always provided by @command{pmult} itself. These are: @table @asis @item client_addr The IP address of the SMTP client. As of version @value{VERSION}, only IPv4 addresses are supported. Defined in all handlers. @item client_port The port number of the SMTP client. Defined in all handlers. @item i MeTA1 session ID. Defined in all handlers. @item f The envelope sender (from) address. Defined in @code{envfrom} and subsequent handlers. @item nbadrcpts The number of bad recipients for a single message. Defined in @code{envfrom} and @code{envrcpt} handlers. @item ntries The number of delivery attempts. As of version @value{VERSION} it is always @samp{1}. Defined in @code{envfrom} and subsequent handlers. @item nrcpts The number of validated recipients for a single message. Defined in @code{envfrom} and @code{envrcpt} handlers. @item r Protocol used to receive the message. The value of this macro is always @samp{SMTP}. Defined in all handlers. @item rcpt_host The host from the resolved triple of the address given for the SMTP RCPT command. Defined in @code{envrcpt} handler. @item rcpt_addr The address part of the resolved triple of the address given for the SMTP RCPT command. Defined in @code{envrcpt} handler. @item s Sender's helo domain (parameter to @code{EHLO} or @code{HELO} command). @end table Two additional macros are provided for all handlers that allow to identify whether the message is processed via @command{pmult}: @table @asis @item multiplexer Canonical name of the multiplexer program, i.e. @samp{pmult}. @item mult_version Version of @command{pmult}. @end table 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 @code{define-macros} statement. @deffn {Pmult Conf} define-macros @var{handler} @var{macros} Define a set of Sendmail macros for the given Mailfromd handler. Allowed values for @var{handler} are: @samp{connect}, @samp{helo}, @samp{mail} (or @samp{envfrom}), @samp{rcpt} (or @samp{envrcpt}), @samp{data} (or @samp{header} or @samp{body}), @samp{dot} (@samp{eom}). A list of these values is also accepted, in which case @var{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: @table @asis @item hostname Hostname of SMTP server. @item client_resolve Result of client lookup. @item tls_version TLS/SSL version used. @item tls_cipher_suite TLS cipher suite used. @item tls_cipher_bits Effective key length of the symmetric encryption algorithm. @item tls_cert_subject The DN (distinguished name) of the presented certificate. @item tls_cert_issuer The DN (distinguished name) of the CA (certificate authority) that signed the presented certificate (the cert issuer). @item tls_alg_bits Maximum key length of the symmetric encryption algorithm. This may be less than the effective key length for export controlled algorithms. @item tls_vrfy The result of the verification of the presented cert. @item tls_cn_subject @itemx cn_subject The CN (common name) of the presented certificate. @item tls_cn_issuer @itemx cn_issuer The CN (common name) of the CA that signed the presented certificate. @item auth_type The mechanism used for SMTP authentication (only set if successful). @item 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 @samp{user}, or @samp{user@@realm}, or something similar. @item auth_author The authorization identity, i.e. the @samp{AUTH=} parameter of the SMTP MAIL command if supplied. @item taid MeTA1 transaction id. @item msgid Message-Id of the message. @item c The hop count. Basically, this is the number of @samp{Received:} headers. @end table Notice the following limitations: @enumerate 1 @item @samp{taid} cannot be requested before @samp{mail} stage. @item @samp{msgid} can be requested only in @samp{dot} stage. @item All @samp{tls_*} macros are valid only after a @code{STARTTLS} command. @item The number of MeTA1 macros per stage is limited by @code{PM_MAX_MACROS} define in @file{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. @end enumerate @end deffn @deffn {Pmult Conf} auth-macros @var{bool} If @var{bool} is @code{true} (@pxref{Statements,boolean,,mailutils, GNU Mailutils Manual}), pass auth macros to mailfromd @samp{mail} handler. It is equivalent to: @smallexample define-macros mail (auth_type, auth_authen, auth_author); @end smallexample @end deffn @node pmult-client @subsection Pmult Client Configuration. In @command{pmult} terminology, remote Milters are @dfn{clients}. The number of clients @command{pmult} is able to handle is not limited. Each client is declared using @code{client} statement: @smallexample client [@var{ident}] @{ # @r{Set remote protocol type.} type @var{protocol-type}; # @r{Set remote client URL.} url @var{arg}; # @r{Set write timeout.} write-timeout @var{duration}; # @r{Set read timeout.} read-timeout @var{duration}; # @r{Set timeout for EOM.} eom-timeout @var{duration}; # @r{Set connect timeout.} connect-timeout @var{duration}; # @r{Set log verbosity level.} log-level @var{level}; @}; @end smallexample @deffn {Pmult Conf} client [@var{ident}] @{ @var{statements} @} Declare a Milter client. Optional @var{ident} gives the identifier of this client, which will be used in diagnostics messages. @var{Statements} are described below. @end deffn @deffn {Pmult Conf} type @var{typestr} This statement is reserved for future use. In version @value{VERSION} it is a no-op. If given, the value of @var{typestr} must be @samp{milter}. In future versions this statement will declare the protocol to be used to interact with this client. The syntax for @var{typestr} is @smallexample @var{type} [@var{version}] @end smallexample @noindent where @var{type} is either @samp{milter} or @samp{pmilter}, and optional @var{version} is minimal protocol version. @end deffn @deffn {Pmult Conf} url @var{arg} Set remote client @acronym{URL}. @xref{milter port specification}, for a description of @var{url}. @end deffn @deffn {Pmult Conf} connect-timeout @var{interval} Configure Milter initial connection timeout. Default is @value{GACOPYZ_CONNECT_TIMEOUT}. @xref{time interval specification}, for information on @var{interval} format. @end deffn @deffn {Pmult Conf} write-timeout @var{interval} Configure Milter write timeout. Default is @value{GACOPYZ_WRITE_TIMEOUT}. @xref{time interval specification}, for information on @var{interval} format. @end deffn @deffn {Pmult Conf} read-timeout @var{interval} Configure Milter read timeout. Default is @value{GACOPYZ_READ_TIMEOUT}. @xref{time interval specification}, for information on @var{interval} format. @end deffn @deffn {Pmult Conf} eom-timeout @var{interval} Configure Milter end of message timeout. Default is @value{GACOPYZ_EOM_TIMEOUT}. @xref{time interval specification}, for information on @var{interval} format. @end deffn @deffn {Pmult Conf} log-level @var{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 @samp{!} to indicate ``any level except this'', @samp{<}, meaning ``all levels up to and including this'', or with @samp{>}, meaning ``all levels starting from this''. Log levels in order of increasing priority are: @samp{proto}, @samp{debug}, @samp{info}, @samp{warn}, @samp{err}, @samp{fatal}. The first two levels are needed for debugging @code{libgacopyz} and Milter protocol. @xref{Gacopyz}, for the description of the @code{libgacopyz} library. See also the following subsection. @end deffn @node pmult-debug @subsection Debugging Pmult If needed, @command{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 @code{debug} block statement controls debugging of the underlying GNU Mailutils libraries (@pxref{Debug Statement, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}). Secondly, the @code{debug} statement controls debugging output of the @command{pmult} utility itself. The @code{pmilter-debug} statement controls debugging output of the underlying MeTA1 libraries, and, finally, the @code{log-level} statement, described in the previous subsection, defines debugging level for the Milter library (@code{libgacopyz}). @deffn {Pmult Conf} debug @var{spec} Set debugging level for the @command{pmult} code. @xref{Debug Statement, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}, for a description of @var{spec} syntax. The following debugging levels are used: @table @asis @item trace1 Prints the following information: @itemize @bullet @item opening and closing incoming connections; @item entering particular Pmilter stage handlers; @item received requests with unknown command code; @item header modification requests that does not match any headers. @end itemize @item trace2 Information about milter to Pmilter request translation. @item trace7 Detailed dump of message body chunks received during Pmilter @samp{DATA} stage. @item error Bad recipient addresses. @end table This information is printed using the output channel defined in the @command{logging} statement (@pxref{Logging Statement, Mailutils Configuration File,, mailutils, GNU Mailutils Manual}). @end deffn @deffn {Pmult Conf} pmilter-debug @var{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 @command{pies} @code{stderr} statement to capture this stream and redirect it to the syslog or file (@pxref{Output Redirectors,,,pies, Pies Manual}). @end deffn @node pmult example @section Pmult Example The following is an example of a working @command{pmult} configuration. The multiplexer listens on localhost, port @samp{3333}. It prints its diagnostics using syslog facility @code{local2}. A single Mailfromd client is declared, which listens on @acronym{UNIX} socket @file{/usr/local/var/mailfromd/mailfrom}. The log verbosity level for this client is set to @samp{info} and higher, i.e.: @samp{info}, @samp{warn}, @samp{err} and @samp{fatal}. @smallexample listen inet://127.0.0.1:3333; logging @{ facility local2; @}; debug "info"; # Set write timeout. write-timeout 30 seconds; # Set read timeout. read-timeout 5 minutes; # Set timeout for EOM. eom-timeout 5 minutes; @} @end smallexample @node pmult invocation @section Pmult Invocation Normally, @command{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 @command{pmult} configuration file for syntax errors. @xref{Common Options, Common Options, , mailutils, GNU Mailutils Manual}, for a detailed description of these. The rest of command line options supported by @command{pmult} is useful mostly for debugging. These options are summarized in the table below: @table @option @item --log-tag=@var{string} Set the identifier used in syslog messages to @var{string}. This option mostly is for debugging purposes. We advise to use @code{logging} configuration statement for this purpose (@pxref{Logging Statement, Logging Statement, , mailutils, GNU Mailutils Manual}). @item --no-signal-handler Disable signal handling in the main thread. This is for debugging purposes. @item --syslog Log to the syslog. This is the default. @xref{Logging Statement, Logging Statement, , mailutils, GNU Mailutils Manual}, for information on how to configure syslog logging. @item -s @itemx --stderr Log to the standard error stream. @item --url=@var{url} Listen on the given @var{url}. This overrides the @code{url} configuration statement (@pxref{pmult-client,url}). @item -x @itemx --debug=@var{level} Set debug verbosity level. This overrides the @code{debug} configuration statement. @xref{pmult-debug}, for more information. @end table