<?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<article>
 <articleinfo>
  <title>E-MailRelay</title>
 </articleinfo>
  <section><title>E-MailRelay User Guide</title>
   <section><title>What is it?</title>
    <para>
     E-MailRelay is a simple store-and-forward message transfer agent and proxy
     server. It runs on Unix-like operating systems (including Linux and Mac OS X),
     and on Windows.
    </para>

    <para>
     When used as proxy server the E-MailRelay program (<emphasis>emailrelay</emphasis>) runs in the
     background and accepts e-mail from local e-mail client programs (Thunderbird,
     Outlook etc.) or from the outside world, using the SMTP protocol. As soon as an
     e-mail message is received it is forwarded on to the next SMTP server for onward
     delivery. This becomes more useful when you add in your own message processing:
     as each message is received it can be passed one of your programs for editing,
     filtering, encrypting etc.
    </para>

    <para>
     When used as a store-and-forward transfer agent E-MailRelay runs in two modes:
     the storage daemon part, and the forwarding agent. The storage daemon
     waits for incoming mail and stores anything it receives in a spool directory.
     As a forwarding agent E-MailRelay pulls messages out of the spool directory
     and passes them on to a remote server -- perhaps your ISP mail server.
    </para>

    <para>
     E-MailRelay can also run as a POP3 server so that e-mail client programs can
     read the spooled messages.
    </para>
   </section>
   <section><title>What it's not</title>
    <para>
     E-MailRelay does not do routing of individual messages; it is not a routing MTA.
     It forwards all e-mail messages to a pre-configured SMTP server, regardless of
     any message addressing or DNS redirects.
    </para>

    <para>
     E-MailRelay is not a delivery agent. Some programs like <emphasis>fetchmail</emphasis> send
     locally-addressed e-mail to the local SMTP server in order to deliver them to
     local system mailboxes. E-MailRelay will not normally do this.
    </para>
   </section>
   <section><title>Why use it?</title>
    <para>
     E-MailRelay is a simple tool that does SMTP. For simple tasks it is likely
     to be easier to understand and configure than a more general purpose MTA.
    </para>

    <para>
     The code has few dependencies on third-party libraries or run-time environments
     so it is easy to build and install especially when targeting embedded systems.
    </para>

    <para>
     The single-threaded, event-driven design with non-blocking i/o may provide
     better performance and resource usage than some of the alternatives.
    </para>

    <para>
     E-MailRelay is designed to be policy-free, so that you can implement your own
     policies for message retries, bounces, local mailbox delivery, spam filtering
     etc. through external scripts.
    </para>

    <para>
     Typical applications of E-MailRelay include:
    </para>
    <itemizedlist>
     <listitem><para>spam filtering and virus checking incoming mail</para></listitem>
     <listitem><para>adding digital signatures or legal disclaimers to outgoing mail</para></listitem>
     <listitem><para>store-and-forward for outgoing mail across an intermittent Internet connection</para></listitem>
     <listitem><para>adding authentication and encryption where the existing infrastructure does not support it</para></listitem>
     <listitem><para>taking messages in with SMTP and serving them to local POP clients</para></listitem>
     <listitem><para>giving multiple POP clients independent copies of incoming e-mail</para></listitem>
     <listitem><para>SMTP proxying by running the proxy server on the firewall host</para></listitem>
    </itemizedlist>
   </section>
   <section><title>Running E-MailRelay</title>
    <para>
     To use E-MailRelay in store-and-forward mode use the <emphasis>--as-server</emphasis> option to
     start the storage daemon in the background, and then trigger delivery of spooled
     messages by running with the <emphasis>--as-client</emphasis> option and the address of the target
     host.
    </para>

    <para>
     For example, to start a storage daemon listening on port 10025 use a command
     like this:
    </para>

      <programlisting>emailrelay --as-server --port 10025 --spool-dir /tmp
</programlisting>
    <para>
     And then to forward the spooled mail to <emphasis>smarthost</emphasis> run something like this:
    </para>

      <programlisting>emailrelay --as-client smarthost:25 --spool-dir /tmp
</programlisting>
    <para>
     To get behaviour more like a proxy you can add the <emphasis>--poll</emphasis> option so that
     messages are forwarded continuously rather than on-demand. This example starts a
     store-and-forward server that forwards spooled-up e-mail every hour:
    </para>

      <programlisting>emailrelay --as-server --poll 3600 --forward-to smarthost:25
</programlisting>
    <para>
     For a proxy server that forwards each message as it is being received, without
     any delay, you can use the <emphasis>--as-proxy</emphasis> mode:
    </para>

      <programlisting>emailrelay --as-proxy smarthost:25
</programlisting>
    <para>
     If you want to edit or filter e-mail as it passes through the proxy then specify
     your pre-processor program with the <emphasis>--filter</emphasis> option, something like this:
    </para>

      <programlisting>emailrelay --as-proxy smarthost:25 --filter /usr/local/bin/addsig
</programlisting>
    <para>
     To run E-MailRelay as a POP server without SMTP use <emphasis>--pop</emphasis> and <emphasis>--no-smtp</emphasis>:
    </para>

      <programlisting>emailrelay --pop --no-smtp --log --close-stderr
</programlisting>
    <para>
     The <emphasis>emailrelay-submit</emphasis> utility can be used to put messages straight into the
     spool directory so that the POP clients can fetch them.
    </para>

    <para>
     By default E-MailRelay will always reject connections from remote machines. To
     allow connections from anywhere use the <emphasis>--remote-clients</emphasis> option, but please
     check your firewall settings to make sure this cannot be exploited by spammers.
    </para>

    <para>
     On Windows add <emphasis>--hidden</emphasis> to suppress message boxes and also add <emphasis>--no-daemon</emphasis>
     if running as a service.
    </para>

    <para>
     For more information on the command-line options refer to the reference guide
     or run:
    </para>

      <programlisting>emailrelay --help --verbose</programlisting>
   </section>
   <section><title>Configuration</title>
    <para>
     The <emphasis>emailrelay</emphasis> program itself is mostly configured through command-line
     options (such as <emphasis>--port</emphasis> and <emphasis>--forward-to</emphasis>), so there is no single
     definitive configuration file.
    </para>

    <para>
     However, in most installations on Unix-like system the E-MailRelay server will
     be started up by the boot-time script called <emphasis>emailrelay</emphasis> in the <emphasis>/etc/init.d</emphasis>
     directory, and this script uses the configuration file <emphasis>/etc/emailrelay.conf</emphasis> to
     define the server command-line. Each entry in the configuration file corresponds
     to an E-MailRelay command-line option, so you can edit this file to add and
     remove server options. Refer to the reference guide for a complete list of
     configuration options.
    </para>

    <para>
     On Windows the installation program creates a startup batch file called
     <emphasis>emailrelay-start.bat</emphasis> that contains all the server command-line options and
     you can edit this file to tailor the server configuration. You can also set up
     your own shortcuts to the E-MailRelay executable and add and remove command-line
     options using the shortcut properties tab.
    </para>

    <para>
     If you are using authentication then you will have to create the text files
     containing your authentication secrets (account names, passwords and password
     hashes). The <emphasis>--server-auth</emphasis>, <emphasis>--client-auth</emphasis> and <emphasis>--pop-auth</emphasis> command-line
     options are used to point to these files.
    </para>

    <para>
     There is also a graphical configuration program called <emphasis>emailrelay-gui</emphasis> that
     may be available to help with configuring the system. This is intended to be
     used once at installation time (and it is the basis of the self-extracting
     installer on Windows) but it may also be used to do some simple reconfiguration
     of an alreay-installed system. It takes you through a sequence of configuration
     pages and then on the last page creates or updates the configuration files, ie.
     the authentication secrets file and the configuration file <emphasis>emailrelay.conf</emphasis>
     or <emphasis>emailrelay-start.bat</emphasis>.
    </para>
   </section>
   <section><title>Logging</title>
    <para>
     If the <emphasis>--log</emphasis> option is used then E-MailRelay program issues warnings and error
     messages to the <emphasis>syslog</emphasis> system on Unix or to the Event Viewer's Application log
     on Windows.
    </para>

    <para>
     On Unix systems you can also redirect the standard error stream to a file,
     although you should note that the <emphasis>--as-server</emphasis> and <emphasis>--as-proxy</emphasis> options
     implicitly close the standard error stream soon after startup, so you should
     replace them with their equivalent options without the <emphasis>--close-stderr</emphasis> part.
    </para>

    <para>
     On Windows you can log to a file by adding the <emphasis>--log-file</emphasis> option to the
     command-line in the startup batch file. The installation process creates a
     second startup batch file that contains this option, so check for that first.
    </para>

    <para>
     For more verbose logging add the <emphasis>--verbose</emphasis> option to the command-line.
    </para>
   </section>
   <section><title>Preventing open mail relay</title>
    <para>
     If you are running E-MailRelay as a server with a permanent connection to the
     Internet it is important to prevent open mail relay because this can be
     exploited by spammers and get you into trouble with your ISP. By default open
     mail relaying is not possible because E-MailRelay does not accept IP connections
     from remote clients. However, if you use the <emphasis>--remote-clients</emphasis> option then you
     need to be more careful.
    </para>

    <para>
     If the only required access to the E-MailRelay server is from a local network
     and not from the Internet then just set up your firewall to block incoming
     connections on ports 25 (SMTP) and 110 (POP) and also use the <emphasis>--interface</emphasis>
     option on the E-MailRelay command-line so that it only listens for incoming
     connections on the local network.
    </para>

    <para>
     If you do need to accept connections from the Internet then you should require
     all clients to authenticate themselves by using the <emphasis>--server-auth</emphasis> option on
     the E-MailRelay command-line. If you also want local clients running on your
     internal network to be able to bypass this authentication then you can put those
     trusted IP addresses in the E-MailRelay secrets file with an authentication
     mechanism of <emphasis>NONE</emphasis>. Refer to the reference guide for more information.
    </para>
   </section>
   <section><title>Running as a POP server</title>
    <para>
     E-MailRelay can run as a POP server so that e-mail client programs can retrieve
     messages from the E-MailRelay spool directory directly.
    </para>

    <para>
     To allow POP access to spooled messages use a command-line something like this:
    </para>

      <programlisting>emailrelay --as-server --pop --pop-auth=/etc/emailrelay.auth
</programlisting>
    <para>
     You will need to create the authentication secrets file (<emphasis>emailrelay.auth</emphasis> in
     this example) containing usernames and passwords. A simple example would look
     like this:
    </para>

      <programlisting>server APOP user1 password1
server APOP user2 password2
</programlisting>
    <para>
     It can sometimes be useful to serve up the same e-mail messages to multiple POP
     clients. For example, you might use several e-mail clients on your local network
     and you would like to see your mail on all of them equally. The <emphasis>--pop-by-name</emphasis>
     option is intended to be used in this scenario; each e-mail client sees its own
     copy of the e-mail messages, stored in its own sub-directory of the main spool
     directory. The name of the sub-directory is simply the name that the client uses
     to authenticate with the E-MailRelay server. You just need to create the
     sub-directory for each client and then specify <emphasis>emailrelay-filter-copy</emphasis>
     as the <emphasis>--filter</emphasis> program.
    </para>

    <para>
     Refer to the reference guide for more information.
    </para>
   </section>
   <section><title>Triggering delivery over dial-up</title>
    <para>
     If you are using E-MailRelay on Unix to store and forward e-mail over an
     intermittent link to Internet such as dial-up or wireless networking, then you
     might need to set things up so that the network tells E-MailRelay when to start
     forwarding e-mail.
    </para>

    <para>
     On Linux systems you should find that there are special directories where you
     can install your own hook scripts that are called whenever a dial-up or wireless
     network connection is established. For dial-up this might be <emphasis>/etc/ppp/ip-up.d</emphasis>,
     and for wireless <emphasis>/etc/network/if-up.d</emphasis>.
    </para>

    <para>
     Just create a two-line script like this in the relevant directory:
    </para>

      <programlisting>#!/bin/sh
exec /usr/local/sbin/emailrelay --as-client=myisp.net:smtp
</programlisting>
    <para>
     and make it executable using <emphasis>chmod +x</emphasis>.
    </para>
   </section>
   <section><title>Notification of failed e-mails</title>
    <para>
     If e-mail messages cannot be forwarded by the E-MailRelay system then the
     envelope files in the spool directory are given a <emphasis>.bad</emphasis> suffix. The reason for
     the failure will be recorded in the envelope file itself.
    </para>

    <para>
     You should check for <emphasis>.bad</emphasis> envelope files in the E-MailRelay spool directory
     from time to time.
    </para>

    <para>
     If you want failed e-mails to be retried a few times you can run the
     <emphasis>emailrelay-resubmit</emphasis> script periodically. This script simply removes the <emphasis>.bad</emphasis>
     suffix from files in the spool directory, as long as they have not been retried
     too many times already.
    </para>
   </section>
   <section><title>Usage patterns</title>
    <para>
     The simplest ways of using E-MailRelay for SMTP are as a proxy or for
     store-and-forward, but many other configurations are possible. For example,
     multiple E-MailRelay servers can run in parallel sharing the same spool
     directory, or they can be chained in series to that e-mail messages get
     transferred from one to the next.
    </para>

    <para>
     Remember that messages can be introduced directly into the E-MailRelay spool
     directory using the <emphasis>emailrelay-submit</emphasis> utility, and they can be moved out again
     at any time, as long as the envelope file is not locked (ie. with a special
     filename extension). Your <emphasis>--filter</emphasis> program can edit messages in any way you
     want, and it can even remove the current message from the spool directory.
    </para>

    <para>
     When using E-MailRelay as a POP server the <emphasis>--pop-by-name</emphasis> feature can be used
     to serve up different spooled messages according to the username that the client
     authenticated with: each user's messages are taken from their own sub-directory
     of the main spool directory. If messages are coming in over SMTP then you could
     install an SMTP <emphasis>--filter</emphasis> script to move each new message into the relevant
     sub-directory based on the message addressing.
    </para>

    <para>
     For more ideas check out the <emphasis>--client-filter</emphasis> and <emphasis>--poll</emphasis> options, and don't
     overlook the administration and control interface (<emphasis>--admin</emphasis>) which you can use
     to receive notification of message arrival or force message forwarding at any
     time.
    </para>
   </section>
   <section><title>SpamAssassin</title>
    <para>
     The E-MailRelay server can use <ulink url="http://spamassassin.apache.org">SpamAssassin</ulink>
     to mark or reject potential spam.
    </para>

    <para>
     To get E-MailRelay to reject spam outright you can just use <emphasis>spamassassin -e</emphasis> as
     your E-MailRelay <emphasis>--filter</emphasis> program:
    </para>

      <programlisting>emailrelay --as-server --filter="/usr/bin/spamassassin --exit-code"
</programlisting>
    <para>
     Or on Windows:
    </para>

      <programlisting>emailrelay --as-server --filter="c:/Program\ Files/perl/site/bin/spamassassin.bat --exit-code"
</programlisting>
    <para>
     To get spam messages identified by SpamAssassin but still pass through the
     E-MailRelay system you will have to have a small <emphasis>--filter</emphasis> script to collect
     the output from the <emphasis>spamassassin</emphasis> program and write it back into the
     E-MailRelay content file.
    </para>

    <para>
     On Unix your <emphasis>--filter</emphasis> shell script could look something like this:
    </para>

      <programlisting>#!/bin/sh
spamassassin "$1" &gt; "$1.tmp"
mv "$1.tmp" "$1"
exit 0
</programlisting>
    <para>
     On Windows an equivalent batch script would be:
    </para>

      <programlisting>c:\Program Files\perl\site\bin\spamassassin.bat %1 &gt; %1.tmp
ren %1.tmp %1
exit 0
</programlisting>
    <para>
     Or you could adapt the <emphasis>emailrelay-runperl.js</emphasis> example script.
    </para>
   </section>
   <section><title>Google mail</title>
    <para>
     To send mail via Google mail's SMTP gateway you will need to create a client
     secrets file containing your account details and also enable TLS/SSL support in
     E-MailRelay by using the <emphasis>--client-tls</emphasis> option.
    </para>

    <para>
     The secrets file should contain one line of text something like this:
    </para>

      <programlisting>login client myname@gmail.com mypassword
</programlisting>
    <para>
     Reference this file using <emphasis>--client-auth</emphasis> on the E-MailRelay command-line and
     also add in the <emphasis>--client-tls</emphasis> option:
    </para>

      <programlisting>emailrelay --as-proxy=smtp.gmail.com:587 --client-tls --client-auth=/etc/emailrelay.auth ...</programlisting>
   </section>
   <section><title>Connection tunnelling</title>
    <para>
     E-MailRelay can send mail out via a SOCKS v4 proxy, which makes it easy to route
     your mail through an encrypted tunnel using <emphasis>ssh -N -D</emphasis> or via the Tor
     anonymising network.
    </para>

    <para>
     For example, this will run an E-MailRelay proxy on port 1025 that routes via a
     local tor server on port 9050 to the mail server at example.com:
    </para>

      <programlisting>emailrelay --port 1025 --as-proxy=example.com:25@localhost:9050 --domain=anonymous.org --connection-timeout=300



</programlisting>
    <para>
     Copyright (C) 2001-2013 Graeme Walker &lt;graeme_walker@users.sourceforge.net&gt;. All rights reserved.
    </para>
   </section>
  </section>
  <section><title>E-MailRelay Reference</title>
   <section><title>Command line usage</title>
    <para>
     The <emphasis>emailrelay</emphasis> program supports the following command-line usage:
    </para>

      <programlisting>emailrelay [&lt;option&gt; [&lt;option&gt; ...]]
</programlisting>
    <para>
     where &lt;option&gt; is:
    </para>
    <variablelist>
     <varlistentry><term>--admin (-a)</term>
      <listitem><para>
       Enables the administration interface and specifies its listening port number.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--admin-terminate (-Q)</term>
      <listitem><para>
       Enables the terminate command on the admin interface.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--anonymous (-A)</term>
      <listitem><para>
       Disables the smtp vrfy command and sends less verbose smtp responses.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--as-client (-q)</term>
      <listitem><para>
       Runs as a client, forwarding all spooled mail to &lt;host&gt;: equivalent to <emphasis>--log --no-syslog --no-daemon --dont-serve --forward --forward-to</emphasis>.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--as-proxy (-y)</term>
      <listitem><para>
       Runs as a proxy server, forwarding each mail immediately to &lt;host&gt;: equivalent to <emphasis>--log --close-stderr --poll=0 --forward-to</emphasis>.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--as-server (-d)</term>
      <listitem><para>
       Runs as a server, storing mail in the spool directory: equivalent to <emphasis>--log --close-stderr</emphasis>.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--client-auth (-C)</term>
      <listitem><para>
       Enables smtp authentication with the remote server, using the given secrets file.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--client-filter (-Y)</term>
      <listitem><para>
       Specifies an external program to process messages when they are forwarded.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--client-tls (-j)</term>
      <listitem><para>
       Enables negotiated tls/ssl for smtp client (if openssl built in).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--client-tls-connection (-b)</term>
      <listitem><para>
       Enables smtp over tls/ssl for smtp client (if openssl built in).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--close-stderr (-e)</term>
      <listitem><para>
       Closes the standard error stream soon after start-up.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--connection-timeout (-U)</term>
      <listitem><para>
       Sets the timeout (in seconds) when connecting to a remote server (default is 40).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--debug (-g)</term>
      <listitem><para>
       Generates debug-level logging if built in.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--domain (-D)</term>
      <listitem><para>
       Sets an override for the host's fully qualified domain name.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--dont-serve (-x)</term>
      <listitem><para>
       Disables acting as a server on any port (part of --as-client and usually used with --forward).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--filter (-z)</term>
      <listitem><para>
       Specifies an external program to process messages as they are stored.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--filter-timeout (-W)</term>
      <listitem><para>
       Sets the timeout (in seconds) for running the --filter processor (default is 300).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--forward (-f)</term>
      <listitem><para>
       Forwards stored mail on startup (requires --forward-to).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--forward-to (-o)</term>
      <listitem><para>
       Specifies the remote smtp server (required by --forward, --poll, --immediate and --admin).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--help (-h)</term>
      <listitem><para>
       Displays help text and exits.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--immediate (-m)</term>
      <listitem><para>
       Enables immediate forwarding of messages as soon as they are received (requires --forward-to).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--interface (-I)</term>
      <listitem><para>
       Defines the listening interface(s) for incoming connections (comma-separated list with optional smtp=,pop=,admin= qualifiers).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--log (-l)</term>
      <listitem><para>
       Writes log information on standard error and syslog (but see --close-stderr and --no-syslog).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--log-time (-L)</term>
      <listitem><para>
       Adds a timestamp to the logging output.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--no-daemon (-t)</term>
      <listitem><para>
       Does not detach from the terminal.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--no-smtp (-X)</term>
      <listitem><para>
       Disables listening for smtp connections (usually used with --admin or --pop).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--no-syslog (-n)</term>
      <listitem><para>
       Disables syslog output (always overridden by --syslog).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pid-file (-i)</term>
      <listitem><para>
       Defines a file for storing the daemon process-id.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--poll (-O)</term>
      <listitem><para>
       Enables polling of the spool directory for messages to be forwarded with the specified period (zero means on client disconnection) (requires --forward-to).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop (-B)</term>
      <listitem><para>
       Enables the pop server.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-auth (-F)</term>
      <listitem><para>
       Defines the pop server secrets file (default is <emphasis>/etc/emailrelay.auth</emphasis>).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-by-name (-J)</term>
      <listitem><para>
       Modifies the pop spool directory according to the pop user name (requires --pop).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-no-delete (-G)</term>
      <listitem><para>
       Disables message deletion via pop (requires --pop).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-port (-E)</term>
      <listitem><para>
       Specifies the pop listening port number (default is 110) (requires --pop).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--port (-p)</term>
      <listitem><para>
       Specifies the smtp listening port number (default is 25).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--prompt-timeout (-w)</term>
      <listitem><para>
       Sets the timeout (in seconds) for getting an initial prompt from the server (default is 20).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--remote-clients (-r)</term>
      <listitem><para>
       Allows remote clients to connect.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--response-timeout (-T)</term>
      <listitem><para>
       Sets the response timeout (in seconds) when talking to a remote server (default is 1800).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--server-auth (-S)</term>
      <listitem><para>
       Enables authentication of remote clients, using the given secrets file.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--server-tls (-K)</term>
      <listitem><para>
       Enables negotiated tls/ssl for smtp server using the given openssl certificate file (which must be in the directory trusted by openssl).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--size (-M)</term>
      <listitem><para>
       Limits the size of submitted messages.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--spool-dir (-s)</term>
      <listitem><para>
       Specifies the spool directory (default is <emphasis>/var/spool/emailrelay</emphasis>).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--syslog (-k)</term>
      <listitem><para>
       Forces syslog output if logging is enabled (overrides --no-syslog).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--tls-config (-0)</term>
      <listitem><para>
       Sets tls configuration flags (eg. 2 for SSLv2 support).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--user (-u)</term>
      <listitem><para>
       Names the effective user to switch to if started as root (default is <emphasis>daemon</emphasis>).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--verbose (-v)</term>
      <listitem><para>
       Generates more verbose output (works with --help and --log).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--verifier (-Z)</term>
      <listitem><para>
       Specifies an external program for address verification.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--version (-V)</term>
      <listitem><para>
       Displays version information and exits.
      </para></listitem>
    </varlistentry>
     </variablelist>
    <para>
     Under Windows there are a few minor differences. Use <emphasis>--help --verbose</emphasis> to see
     the complete list.
    </para>
   </section>
   <section><title>Message store</title>
    <para>
     Mail messages are stored as text files in the configured spool directory. Each
     message is represented as an envelope file and a content file. The envelope
     file contains parameters relevant to the SMTP dialogue, and the content file
     contains the RFC822 headers and body text.
    </para>

    <para>
     The filenames used in the message store have a prefix of <emphasis>emailrelay</emphasis>, followed
     by a process-id, timestamp and sequence number, and then <emphasis>envelope</emphasis> or
     <emphasis>content</emphasis>. The envelope files then have an additional suffix to implement a
     simple locking scheme.
    </para>

    <para>
     The envelope file suffixes are:
    </para>

    <itemizedlist>
     <listitem><para><emphasis>.new</emphasis> -- while the envelope is first being written</para></listitem>
     <listitem><para>&lt;none&gt; -- while the message is spooled</para></listitem>
     <listitem><para><emphasis>.busy</emphasis> -- while the message is being forwarded</para></listitem>
     <listitem><para><emphasis>.bad</emphasis> -- if the message cannot be forwarded</para></listitem>
     <listitem><para><emphasis>.local</emphasis> -- for copies of the envelope file for delivery to local recipients</para></listitem>
    </itemizedlist>

    <para>
     If a message cannot be forwarded the envelope file is given a <emphasis>.bad</emphasis> suffix,
     and the failure reason is written into the file.
    </para>
   </section>
   <section><title>Forwarding</title>
    <para>
     Spooled messages can be forwarded at various times, depending on the
     command-line options:
    </para>

    <itemizedlist>
     <listitem><para>when E-MailRelay first starts up (<emphasis>--as-client</emphasis> or <emphasis>--forward</emphasis>)</para></listitem>
     <listitem><para>as each message is submitted, just before receipt is acknowledged (<emphasis>--immediate</emphasis>)</para></listitem>
     <listitem><para>as soon as the submitting client connection disconnects (<emphasis>--poll=0</emphasis>)</para></listitem>
     <listitem><para>periodically (<emphasis>--poll=&lt;seconds&gt;</emphasis>)</para></listitem>
     <listitem><para>on demand using the administration interface's <emphasis>flush</emphasis> command (<emphasis>--admin=&lt;port&gt;</emphasis>)</para></listitem>
    </itemizedlist>

    <para>
     These modes of operation can be mixed, although more than one <emphasis>--poll</emphasis> option is
     not allowed.
    </para>

    <para>
     When using <emphasis>--as-client</emphasis> the spooled messages begin to be forwarded as soon as
     the program starts up, and the program terminates once they have all been sent.
    </para>

    <para>
     A pending <emphasis>--poll</emphasis> timer can be forced to expire immediately if a <emphasis>--filter</emphasis>
     script exits with a special value of 103, as described below.
    </para>

    <para>
     All receipent addresses must be accepted by the remote server when E-MailRelay
     forwards a message. If any one recipient is rejected then the message will be
     left in the spool directory with a <emphasis>.bad</emphasis> suffix on the envelope file.
    </para>
   </section>
   <section><title>Mail processing</title>
    <para>
     The <emphasis>--filter</emphasis> command-line option allows you to specify a mail pre-processor
     program which operates on mail messages as they pass through the E-MailRelay
     system. The mail pre-processor program is run as soon as the mail message has
     been stored in the spool directory, with the full path of the content file
     added onto the end of the given command-line.
    </para>

    <para>
     For example, the following command will start a proxy server on port 10025
     which processes mail using the specified filter program, and then forwards the
     mail on to the system's default MTA (on port 25):
    </para>

      <programlisting>emailrelay --as-proxy=localhost:smtp --port=10025 --no-syslog \
  --filter=$HOME/myfilter --spool-dir=$HOME/spool
</programlisting>
    <para>
     The pre-processor program should terminate with an exit code of zero to
     indicate success, or a value between 1 and 99 to indicate failure. Exit codes
     between 100 and 107 are reserved for special processing: 100 is used to cancel
     all further processing of the message, and 103 has the effect of immediately
     expiring any <emphasis>--poll</emphasis> timer.
    </para>

    <para>
     If the pre-processor program terminates with a non-zero exit code then the
     first few thousand characters of the standard output stream are searched for a
     line starting with <emphasis>&lt;&lt;</emphasis> or <emphasis>[[</emphasis> followed by <emphasis>&gt;&gt;</emphasis> or <emphasis>]]</emphasis> respectively. The text
     in between is taken as a failure reason, and passed back to the SMTP client.
    </para>

    <para>
     The pre-processor program can edit any part of the message's envelope file or
     content file: E-MailRelay remembers nothing about the message while the
     pre-processor is running except the filename. But if the message is deleted
     by the pre-processor then E-MailRelay may be upset, so to avoid the error
     message use an exit code of 100.
    </para>

    <para>
     If the pre-processor program creates completely new messages in the spool
     directory then they may not be processed immediately, or they may be completely
     ignored. To get E-MailRelay to pick up any new messages you create in the spool
     directory use the <emphasis>--poll</emphasis> option, or run <emphasis>emailrelay --as-client</emphasis> from within
     the pre-processor program.
    </para>

    <para>
     As an example of a simple pre-processor this shell script examines the sending
     client's IP address and conditionally passes the message into <emphasis>sendmail</emphasis> (using
     the sendmail command-line interface rather than SMTP):
    </para>

      <programlisting>#!/bin/sh
# filter.sh
content="${1}"
envelope="`echo \"${content}\" | sed 's/content/envelope.new/'`"
ip="`awk '/MailRelay-Client:/ {print $2;exit}' \"${envelope}\"`"
if test "${ip}" = "192.168.0.2"
then
	cat "${content}" | /usr/sbin/sendmail -t
	rm -f "${envelope}" "${content}"
	exit 100 # &lt;= cancel further processing by emailrelay
fi
exit 0
</programlisting>
    <para>
     The first thing this script does is convert the path of the content file which
     it is given, into the corresponding envelope file. It then extracts the
     client's IP address out of the envelope file using <emphasis>awk</emphasis>. If this matches the
     fixed address then it pipes the message content into sendmail, deletes the
     message and exits with a value of 100. The exit value of 100 tells E-MailRelay
     to forget the message, and not to complain about the files disappearing.
    </para>

    <para>
     For Windows this example can be rewritten in JavaScript:
    </para>

      <programlisting>// filter.js
var content = WScript.Arguments(0) ;
var envelope = content.substr(0,content.length-7) + "envelope.new" ;
var fs = WScript.CreateObject( "Scripting.FileSystemObject" ) ;
var ts = fs.OpenTextFile( envelope , 1 , false ) ;
var e = ts.ReadAll() ;
ts.Close() ;
var re = new RegExp( "MailRelay-Client: \(.*\)" ) ;
var ip = e.match(re)[1] ;
if( ip == "192.168.0.2" )
{
	var sh = WScript.CreateObject( "Wscript.Shell" ) ;
	sh.Run( "sendmail " + content ) ; // bogus
	fs.DeleteFile( content ) ;
	fs.DeleteFile( envelope ) ;
	WScript.Quit( 100 )
}
WScript.Quit( 0 ) ;
</programlisting>
    <para>
     Windows pre-processor programs written in JavaScript can be run using
     <emphasis>cscript</emphasis>, with an E-MailRelay <emphasis>--filter</emphasis> option something like this:
    </para>

      <programlisting>--filter="c:/program\ files/emailrelay/filter.js"
</programlisting>
    <para>
     Note how the space character in <emphasis>program files</emphasis> is escaped with a backslash.
    </para>

    <para>
     Example <emphasis>--filter</emphasis> scripts are included in the distribution, including
     <emphasis>emailrelay-process.sh</emphasis> which does rot-13 masking of messages. This script also
     does some simple MIME encoding, so that the masked message appears as an
     attachment within a plaintext bearer message.
    </para>

    <para>
     E-MailRelay also has a <emphasis>--client-filter</emphasis> option that enables pre-processing of
     messages just before they are forwarded, rather then after they are stored. The
     disadvantage is that by then it is too late to notify the submitting SMTP client
     of any processing failures, so in many applications using <emphasis>--filter</emphasis> is more
     useful. The special exit code of 100 can be used to ignore the current message,
     and 102 to stop looking for spooled messages after processing the current one.
    </para>

    <para>
     Bear in mind the following points when writing <emphasis>--filter</emphasis> programs:
    </para>

    <itemizedlist>
     <listitem><para>The standard input and output are not used; the content filename is passed on the command-line.</para></listitem>
     <listitem><para>Programs run with a reduced set of environment variables.</para></listitem>
     <listitem><para>The E-MailRelay process is completely blocked while the <emphasis>--filter</emphasis> program runs so it should be fast.</para></listitem>
     <listitem><para>E-MailRelay files use CR-LF line terminators, as required by the RFCs.</para></listitem>
     <listitem><para>Envelope files will have a file extension of <emphasis>.new</emphasis> or <emphasis>.busy</emphasis> when the program runs.</para></listitem>
     <listitem><para>Windows scripts may need to be run via <emphasis>cscript</emphasis> or a batch file wrapper.</para></listitem>
    </itemizedlist>

    <para>
     It is also possible to do message pre-processing in a separate process by using
     <emphasis>net:&lt;address&gt;:&lt;port&gt;</emphasis> as the <emphasis>--filter</emphasis> or <emphasis>--client-filter</emphasis> option parameter.
     E-MailRelay connects to this address and then uses a simple line-based dialog as
     each e-mail message is processed where it sends the full path of the message
     content file in one line and expects the remote process to respond with an <emphasis>ok</emphasis>
     line if the message is to be accepted or an error message. One advantage of
     using a network pre-processor compared to running a program is that the
     E-MailRelay server is not blocked while the messages are being pre-processed.
    </para>
   </section>
   <section><title>Authentication</title>
    <para>
     E-MailRelay supports the SMTP <emphasis>AUTH</emphasis> extension, as defined in RFC2554, on both
     the server-side and client-side.
    </para>

    <para>
     The authentication mechanisms currently supported are:
    </para>

    <variablelist>
     <varlistentry><term><emphasis>PLAIN</emphasis></term>
      <listitem><para>
       Passwords are stored in clear-text, sent over the network in clear-text, and
       are replayable. Defined in RFC2595.
      </para></listitem>
     </varlistentry>
     <varlistentry><term><emphasis>LOGIN</emphasis></term>
      <listitem><para>
       Similar to <emphasis>PLAIN</emphasis>. Officially obsolete although widely used.
      </para></listitem>
     </varlistentry>
     <varlistentry><term><emphasis>CRAM-MD5</emphasis></term>
      <listitem><para>
       Passwords are not stored in clear-text, not sent over the network, and are
       not replayable. Defined in RFC2195.
      </para></listitem>
    </varlistentry>
     </variablelist>
    <para>
     Authentication is enabled with the <emphasis>--client-auth</emphasis> and <emphasis>--server-auth</emphasis>
     command-line options and the option's parameter is the name of a secrets file,
     containing usernames and passwords:
    </para>

      <programlisting>emailrelay --as-server --server-auth=/etc/emailrelay-clients.auth
emailrelay --as-client=myisp.net:smtp --client-auth=/etc/emailrelay-myisp.auth
</programlisting>
    <para>
     The secrets file has a line-based format: blank lines are ignored and the hash
     character (#) is used for comments.
    </para>

    <para>
     Lines have four white-space delimited fields:
    </para>

    <itemizedlist>
     <listitem><para><emphasis>client-or-server</emphasis></para></listitem>
     <listitem><para><emphasis>mechanism</emphasis></para></listitem>
     <listitem><para><emphasis>userid</emphasis></para></listitem>
     <listitem><para><emphasis>secret</emphasis></para></listitem>
    </itemizedlist>

    <para>
     The <emphasis>mechanism</emphasis> field must be <emphasis>LOGIN</emphasis>, <emphasis>APOP</emphasis> or <emphasis>CRAM-MD5</emphasis> (case-insensitive);
     the <emphasis>client-or-server</emphasis> field must be <emphasis>client</emphasis> or <emphasis>server</emphasis> (also
     case-insensitive); the <emphasis>userid</emphasis> field is xtext-encoded user identifier; and the
     <emphasis>secret</emphasis> field is the xtext-encoded <emphasis>LOGIN</emphasis> password, or the <emphasis>CRAM-MD5</emphasis> digest
     key.
    </para>

    <para>
     The <emphasis>xtext</emphasis> encoding scheme is defined properly in RFC1891, but basically it
     says that non alphanumeric characters, space, <emphasis>+</emphasis> and <emphasis>=</emphasis> should be represented
     in hexadecimal ascii as <emphasis>+XX</emphasis>.
    </para>

    <para>
     The client-side secrets file specified with <emphasis>--client-auth</emphasis> is used when
     E-MailRelay acts as a client to talk to a remove server. The file should contain
     at least one <emphasis>client LOGIN</emphasis> or <emphasis>client CRAM-MD5</emphasis> entry.
    </para>

    <para>
     A server-side secrets file specified with <emphasis>--server-auth</emphasis> is used when a remote
     client tries to authenticate with the E-MailRelay server. The file should
     normally contain several <emphasis>server LOGIN</emphasis> or <emphasis>server CRAM-MD5</emphasis> entries, one for
     each client.
    </para>

    <para>
     The same secrets file may be specified for both <emphasis>--client-auth</emphasis> and
     <emphasis>--server-auth</emphasis> options.
    </para>

    <para>
     The <emphasis>CRAM-MD5</emphasis> keys can be generated using the <emphasis>emailrelay-passwd</emphasis> utility.
    </para>

    <para>
     As an example, the following secrets file defines <emphasis>jsmith</emphasis> as the username to be
     used when E-MailRelay authenticates with a remote SMTP server, and defines two
     usernames (<emphasis>user1</emphasis> and <emphasis>user2</emphasis>) which can be used by clients when they
     authenticate with the E-MailRelay server:
    </para>

      <programlisting>#
# emailrelay secrets file
#
client LOGIN jsmith my+20password
server LOGIN user1 secret
server LOGIN user2 e+3Dmc2
</programlisting>
    <para>
     A <emphasis>CRAM-MD5</emphasis> version would look like this:
    </para>

      <programlisting>#
# emailrelay secrets file
#
client CRAM-MD5 jsmith 688498119.2977922305.1278051807.3015243256.2216875978.2833592318.2902375592.3156808220
server CRAM-MD5 user1 4059553961.2316091643.3282746241.1444639637.3735501773.3404060330.2760590371.1201092398
server CRAM-MD5 user2 2798539199.3144534242.3784876256.2879973305.2327113479.216533878.2436460291.2361831919
</programlisting>
    <para>
     When using the <emphasis>LOGIN</emphasis> mechanism you have to store plaintext passwords in the
     secrets file, so you should make sure that the secrets file has tight
     permissions and the passwords in it are not also used for anything important.
    </para>

    <para>
     On the server side authentication is advertised by E-MailRealy in the response
     to the SMTP <emphasis>EHLO</emphasis> command if the <emphasis>--server-auth</emphasis> command-line option is used.
     Authentication by the client is then mandatory unless the client's IP address is
     configured as a trusted address.
    </para>

    <para>
     Trusted IP addresses are configured with lines in the secrets file having <emphasis>NONE</emphasis>
     in the first field, <emphasis>server</emphasis> in the second field, a wildcarded IP address in
     the third field, and an arbitrary keyword in the fourth field. The keyword field
     is passed to any external address verifier program specified by the <emphasis>--verifier</emphasis>
     command-line option; it is not used for any other purpose. Wildcarded IPv4
     addresses can use a format like 192.168.0.0/24 or 192.168.0.*; wildcarded IPv6
     addresses must have the full set of 32 lowercase hex digits followed by the CIDR
     netmask.
    </para>

    <para>
     For example, this secrets file allows any client connecting from the
     192.168.0.0/24 domain to connect without authentication desipte the
     <emphasis>--server-auth</emphasis> option:
    </para>

      <programlisting>#
# emailrelay secrets file
#
server NONE 192.168.0.* localdomain
server LOGIN user1 secret
server LOGIN user2 e+3Dmc2
</programlisting>
    <para>
     On the client side authentication is performed when E-MailRelay has connected to
     a server which implements the AUTH extension with one of the supported
     mechanisms. If client authentication is enabled (with the <emphasis>--client-auth</emphasis>
     option) but the remote server does not support the AUTH extension, or does not
     support the LOGIN or CRAM-MD5 mechanism, then E-MailRelay will log an error
     and not forward any messages.
    </para>

    <para>
     If E-MailRelay successfully authenticates with the remote server then the
     client's authentication name (if any) is passed as a parameter to the MAIL
     command when the message is forwarded. Some SMTP servers are reported to reject
     the message if the name on the MAIL command does not match the name used to
     authenticate with them. However, the name passed as a parameter to the MAIL
     command is stored in the message's envelope file, so a <emphasis>--filter</emphasis> script can be
     used to change this to match whatever the remote server expects. An example
     script is provided in the distribution.
    </para>

    <para>
     Note that some ISPs require separate POP/IMAP authentication before SMTP access
     from a particular IP address is allowed. This type of POP-before-SMTP
     authentication can be done outside the E-MailRelay system by POP/IMAP utilities
     such as <emphasis>fetchmail</emphasis>.
    </para>
   </section>
   <section><title>TLS/SSL</title>
    <para>
     E-MailRelay can use negotiated TLS/SSL to encrypt SMTP and POP3 sessions: to
     enable TLS/SSL encryption when E-MailRelay is acting as an SMTP client use the
     <emphasis>--client-tls</emphasis> command-line option, and to enable TLS/SSL when E-MailRelay is
     acting as an SMTP or POP3 server use <emphasis>--server-tls</emphasis>. The connections start off
     as unencrypted and use the STARTTLS command to negotiate TSL/SSL encryption
     before any plaintext passwords are exchanged.
    </para>

    <para>
     The <emphasis>--server-tls</emphasis> option requires the name of an X.509 certificate in the <emphasis>PEM</emphasis>
     format. This file must be in a directory that the OpenSSL library considers to
     be secure. On some systems this is <emphasis>/etc/ssl/certs</emphasis>.
    </para>

    <para>
     Certificate files can be created with the <emphasis>openssl</emphasis> utility using the
     <emphasis>req -x509</emphasis> sub-command. Refer to the OpenSSL documentation for the full details
     but something like this might work for testing purposes:
    </para>

      <programlisting>$ cd /etc/ssl/certs
$ openssl req -x509 -nodes -days 365 -subj "/O=`uname -n`/CN=$USER" -newkey rsa:1024 -keyout emailrelay.pem  -out emailrelay.pem
$ ln -s emailrelay.pem `openssl x509 -noout -hash -in emailrelay.pem`.0
</programlisting>
    <para>
     E-MailRelay can also make outgoing SMTP connections using TLS/SSL encryption
     where the whole SMTP dialog is encrypted from the start, without a negotiation
     step (<emphasis>--client-tls-connection</emphasis>). This is sometimes called SMTP-over-TLS or
     secure SMTP (ssmtp) and it is normally used with port number 465.
    </para>

    <para>
     The behaviour of the TLS/SSL layer can be tweaked by using <emphasis>--tls-config</emphasis> option
     with a special number that is made up of the following:
    </para>
    <itemizedlist>
     <listitem><para>2 - allow SSL v2 or later</para></listitem>
     <listitem><para>3 - allow SSL v3 or later</para></listitem>
     <listitem><para>4 - ask for peer certificates but just log them</para></listitem>
     <listitem><para>8 - ask for peer certificates and verify them</para></listitem>
    </itemizedlist>
   </section>
   <section><title>PAM Authentication</title>
    <para>
     E-MailRelay supports the use of PAM (Pluggable Authentication Modules) for
     authentication if it has been built with the <emphasis>--with-pam</emphasis> configure option.
    </para>

    <para>
     PAM authentication can be used by E-MailRelay to authenticate SMTP and POP3
     sessions coming in from remote clients; it cannot be used by E-MailRelay to
     supply passwords when acting as an SMTP client.
    </para>

    <para>
     Use <emphasis>--server-auth=/pam</emphasis> and/or <emphasis>--pop-auth=/pam</emphasis> on the command-line to enable
     PAM authentication at run-time. The E-MailRelay server will then advertise an
     SMTP authentication mechanism of PLAIN and do the actual authentication via PAM.
    </para>

    <para>
     The PAM system itself must be configured with a service of <emphasis>emailrelay</emphasis>. This
     normally involves creating a file <emphasis>/etc/pam.d/emailrelay</emphasis> containing somthing
     like the following:
    </para>

      <programlisting>auth requisite pam_unix.so nullok_secure
session required pam_permit.so
account required pam_permit.so
password required pam_deny.so
</programlisting>
    <para>
     With this configuration the E-MailRelay server will use normal unix system
     account names and passwords to authenticate remote clients, but note that on
     some systems this will require special permissioning to allow the E-MailRelay
     server to read the shadow password database.
    </para>

    <para>
     The passwords for system accounts are usually very sensitive so E-MailRelay
     requires the <emphasis>--server-tls</emphasis> command-line option when using PAM authentication,
     and clients are required to establish a TLS/SSL session before authenticating.
    </para>
   </section>
   <section><title>SOCKS</title>
    <para>
     E-MailRelay can use a SOCKS 4a proxy for establishing outgoing SMTP connections
     if the SOCKS proxy address is appended to the SMTP server's address separated by
     <emphasis>@</emphasis>.
    </para>

    <para>
     For example, this could be used to send e-mails via the Tor network, assuming
     there is a local Tor server listening on port 9050:
    </para>

      <programlisting>emailrelay --forward-to myisp.net:smtp@localhost:9050 ...
</programlisting>
    <para>
     In this example the target SMTP server will receive a connection from the Tor
     exit node rather than from E-MailRelay directly.
    </para>
   </section>
   <section><title>Pop server</title>
    <para>
     E-MailRelay can be used as a POP3 server so that POP clients have access to
     spooled messages.
    </para>

    <para>
     The following command-line options are used:
    </para>

    <variablelist>
     <varlistentry><term>--pop</term>
      <listitem><para>
       Enables the POP3 server. Negotiated TLS/SSL (using <emphasis>STLS</emphasis>) will be enabled if
       the <emphasis>--client-tls</emphasis> or <emphasis>--server-tls</emphasis> options are also given.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-port=&lt;port&gt;</term>
      <listitem><para>
       Changes the POP3 listening port from its default of 110.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-auth=&lt;path&gt;</term>
      <listitem><para>
       Changes the authentication secrets file. The default is typically
       <emphasis>/etc/emailrelay.auth</emphasis>.
       </para><para>
       The format of the authentication secrets file is the same as for
       <emphasis>--server-auth</emphasis> and the same file can be used for both SMTP and POP3
       authentication.
       </para><para>
       <emphasis>server APOP</emphasis> entries are used for <emphasis>APOP</emphasis> authentication, <emphasis>server LOGIN</emphasis>
       entries are used for <emphasis>USER/PASS</emphasis> authentication, and <emphasis>server CRAM-MD5</emphasis> entries
       are used for <emphasis>AUTH</emphasis> authentication.
       </para><para>
       Note that the basic POP3 protocol defines only <emphasis>APOP</emphasis> and <emphasis>USER/PASS</emphasis>
       authentication, so some POP client programs may not be able to cope with
       CRAM-MD5 authentication using the POP3 <emphasis>AUTH</emphasis> extension.
       </para><para>
       The CRAM-MD5 authentication mechanism will only be advertised to clients
       if there are <emphasis>server CRAM-MD5</emphasis> entries in the secrets file.
       </para><para>
       If E-MailRelay was built with PAM support then a special value of <emphasis>/pam</emphasis> can
       be used to enable authentication using the PAM infrastructure rather than a
       secrets file. In this case only the PLAIN authentication mechanism will be
       advertised to the client but transport level encryption using TLS/SSL will be
       mandatory.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-by-name</term>
      <listitem><para>
       Modifies the POP spool directory according to the name used by the client
       to authenticate with the E-MailRelay server. The client name is used as a
       sub-directory off the standard spool directory. So, for example, if a client
       authenticates as <emphasis>bob</emphasis> then the POP3 server will serve messages from the <emphasis>bob</emphasis>
       sub-directory, <emphasis>/var/spool/emailrelay/bob</emphasis>.
       </para><para>
       If E-MailRelay finds only the envelope file in the sub-directory and not the
       content file then it will look for the content file in the main spool
       directory, eg. <emphasis>/var/spool/emailrelay</emphasis>. This feature can be used to save
       disk space if serving the same message to multiple POP clients.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>--pop-no-delete</term>
      <listitem><para>
       Disables message deletion: the POP3 DELE command will appear to succeed, but
       no files will be deleted from the spool directory.
      </para></listitem>
    </varlistentry>
     </variablelist>
   </section>
   <section><title>Address verification</title>
    <para>
     By default the E-MailRelay server will accept all recipient addresses for
     incoming e-mails as valid. This default behaviour can be modified by using an
     external verifier program, specified with the <emphasis>--verifier</emphasis> command-line option,
     so that you get to choose which recipient addresses are accepted as valid and
     which are rejected.
    </para>

    <para>
     Your verifier script is passed a command-line containing: (1) the full e-mail
     address as supplied by the remote client, (2) the user-name part of the address
     in upper-case, (3) the host-name part in upper-case, (4) the local host's fully
     qualified domain name in upper-case, (5) the <emphasis>MAIL</emphasis> command's <emphasis>FROM:</emphasis> address as
     supplied by the client or the empty string in the case of the <emphasis>VRFY</emphasis> command,
    </para>
    <orderedlist>
     <listitem><para>the IP address of the client connection, (7) the authentication mechanism</para></listitem>
    </orderedlist>
    <para>
     used by the client (<emphasis>NONE</emphasis> if trusted), and (8) either the authentication name
     or the fourth field from authentication secrets file if a trusted IP address.
    </para>

    <para>
     So, for example, a verifier script called <emphasis>myverifier</emphasis> might be run with the
     following command-line:
    </para>

      <programlisting>myverifier me@myhost.mydomain ME MYHOST.MYDOMAIN MYHOST.MYDOMAIN bob@other.net 192.168.0.1 LOGIN bob
</programlisting>
    <para>
     The verifier script is expected to generate two lines of output on the standard
     output stream and then terminate with a specific exit code.
    </para>

    <para>
     For valid addresses the first line of output is ignored, the second line should
     be copied from the first command-line argument, and the exit value should be
     one.
    </para>

      <programlisting>#!/bin/sh
# address verifier -- accept all (252)
echo ""
echo $1
exit 1
</programlisting>
    <para>
     If the address is valid but it should be delivered to a local mailbox rather
     than forwarded then the verifier script should write two lines to the standard
     output -- the full name associated with the mailbox, and the canonical mailbox
     name -- and then exit with a value of zero.
    </para>

      <programlisting>#!/bin/sh
# address verifier -- accept as local (250)
echo Local Postmaster '&lt;postmaster@localhost&gt;'
echo postmaster
exit 0
</programlisting>
    <para>
     For E-MailRelay local delivery just means that the message file in the spool
     directory is given a <emphasis>.local</emphasis> filename suffix. This can be used to create a
     separate channel for adminstrative messages such as delivery reports.
    </para>

    <para>
     For invalid addresses the exit value should be non-zero and anything written to
     the standard output is taken as the reason for the failure.
    </para>

      <programlisting>#!/bin/sh
# address verifier -- reject as invalid (550)
echo invalid address: $1
exit 2
</programlisting>
    <para>
     To indicate a temporary failure this can be changed to an exit code of 3.
    </para>

      <programlisting>#!/bin/sh
# address verifier -- reject as temporarily invalid (450)
echo address unavailable: $1
exit 3
</programlisting>
    <para>
     If the verifier exit code is 100 then the connection is aborted immediately,
     which may be useful in limiting the impact of denial of service attacks:
    </para>

      <programlisting>#!/bin/sh
# address verifier -- abort
exit 100
</programlisting>
    <para>
     In this more complete example the verifier script accepts all addresses as valid
     as long as they contain an <emphasis>at</emphasis> character:
    </para>

      <programlisting>#!/bin/sh
# address verifier -- accept only if containing an at sign
address="$1"
expr "${address}" : ".*@" &gt; /dev/null || exit 2
echo ""
echo "${address}"
exit 1 # accept
</programlisting>
    <para>
     As another example, this verifier script accepts all recipient addresses by
     default but rejects remote addresses if the client has bypassed authentication
     by connecting on a trusted IP address:
    </para>

      <programlisting>#!/bin/sh
# address verifier
address="$1"
host="$3"
local_domain="$4"
auth_mechanism="$7"
if test -z "${auth_mechanism}" ; then auth_mechanism="NONE" ; fi
if test "${auth_mechanism}" = "NONE" -a "${host}" != "${local_domain}"
then
	echo "cannot relay without authentication"
	exit 2 # reject the recipient address
fi
echo ""
echo "${address}"
exit 1 # accept the recipient address
</programlisting>
    <para>
     or written in JavaScript for Windows:
    </para>

      <programlisting>// verifier.js
var address = WScript.Arguments(0) ;
var host = WScript.Arguments(2) ;
var local_domain = WScript.Arguments(3) ;
var auth_mechanism = WScript.Arguments(6) ;
if( ( auth_mechanism == "NONE" || auth_mechanism == "" ) &amp;&amp; host != local_domain )
{
	WScript.Stdout.WriteLine( "cannot relay without authentication" ) ;
	WScript.Quit( 2 ) ;
}
WScript.Stdout.WriteLine( "" ) ;
WScript.Stdout.WriteLine( address ) ;
WScript.Quit( 1 ) ;
</programlisting>
    <para>
     If this verifier script is used with a suitable <emphasis>--server-auth</emphasis> file then it can
     be used to prevent open relay without restricting authenticated clients.
    </para>

    <para>
     It is also possible to verify addresses in a separate daemon process by using a
     <emphasis>--verifier</emphasis> option of the form <emphasis>net:&lt;address&gt;:&lt;port&gt;</emphasis>. In this case E-MailRelay
     will connect to the specified verifier daemon over the network and send address
     verification requests as lines with pipe-delimited fields. The expected response
     is another pipe-delimited line containing the same information as returned by
     verifier scripts but in reverse, such as <emphasis>3|address unavailable</emphasis> or
     <emphasis>0|postmaster|Local Postmaster &lt;postmaster@localhost&gt;</emphasis>. The <emphasis>inetd</emphasis> super-server
     daemon would be a convenient way to connect up the pieces in this case.
    </para>
   </section>
   <section><title>Security issues</title>
    <para>
     The following are some security issues that have been taken into consideration:
    </para>

    <variablelist>
     <varlistentry><term>Effective userid</term>
      <listitem><para>
       Suid privileges are revoked at start-up, switching the effective
       userid/groupid to be the real userid/groupid values. If started as <emphasis>root</emphasis>
       then the effective userid/groupid are switched at start-up to those of user
       <emphasis>daemon</emphasis>. Special privileges are only reclaimed when needed to bind sockets
       and do file i/o. Normally this means temporarily switching the userid and
       groupid back to what they were at start-up. However, when writing spool files
       after being started as <emphasis>root</emphasis> only the effective userid is changed, not the
       groupid, so that new files have group ownership corresponding to the
       <emphasis>daemon</emphasis> user.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Execution environment</term>
      <listitem><para>
       The external pre-processor programs are run with an almost empty set of
       environment variables (<emphasis>PATH</emphasis> and <emphasis>IFS</emphasis>), and with no open file descriptors
       other than <emphasis>stdin</emphasis> and <emphasis>stderr</emphasis> open onto <emphasis>/dev/null</emphasis>, and <emphasis>stdout</emphasis> open onto a
       pipe.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Configuration</term>
      <listitem><para>
       The mail pre-processor filenames have to be configured using a full path, so
       there is no dependence on the current working directory or the PATH
       environment variable.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Umask</term>
      <listitem><para>
       The program runs for most of the time with a <emphasis>umask</emphasis> of 177, switching to 117
       when creating spool files.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Buffer overflow</term>
      <listitem><para>
       Strings are dynamically allocated in c++, so buffer overflow/truncation issues
       are avoided.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Remote clients</term>
      <listitem><para>
       By default connections will be rejected if they come from remote machines.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Remote configuration</term>
      <listitem><para>
       No configuration parameters can be changed through the administrative
       interface.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Use of <literal>exec()</literal> and <literal>system()</literal></term>
      <listitem><para>
       No <literal>exec()</literal>, <literal>system()</literal> or <literal>popen()</literal> calls are used other than <literal>execve()</literal> to spawn the
       mail pre-processor and/or address verifier.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>File permissions</term>
      <listitem><para>
       After a normal installation the spool directory is has ownership of
       <emphasis>root.daemon</emphasis> with permissions of <emphasis>-rwxrwxr-x</emphasis> and messages files are created
       with permissions of <emphasis>-rw-rw----</emphasis>. This allows normal users to list messages
       files but not read them.
       </para><para>
       The <emphasis>emailrelay-submit</emphasis> program is given group ownership of <emphasis>daemon</emphasis> with its
       group set-user-id flag set. This allows it to create message files in the
       spool directory, and the files created end up owned by the submitter but with
       group ownership of <emphasis>daemon</emphasis>.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Logging</term>
      <listitem><para>
       Logging output is conditioned so that ANSI escape sequences cannot appear
       in the log.
       </para><para>
       Passwords and message content are not logged (except if using the <emphasis>--debug</emphasis>
       option at run time with debug logging enabled at build time).
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Information leakage</term>
      <listitem><para>
       The <emphasis>--anonymous</emphasis> option can be used to reduce the amount of information
       released to remote clients, especially with an empty <emphasis>--domain</emphasis>.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>Mandatory encryption</term>
      <listitem><para>
       When using Linux PAM for authentication all clients are required to use
       TLS/SSL encryption.
      </para></listitem>
    </varlistentry>
     </variablelist>
    <para>
     Security issues which relate to the SMTP protocol itself are beyond the scope of
     this document, but RFC2821 makes the following observation: "SMTP mail is
     inherently insecure in that it is feasible for even [..] casual users to [..]
     create messages that will trick a [..] recipient into believing that they came
     from somewhere else. [..] Real [..] security lies [..] in end-to-end methods
     [..] such as those which use digital signatures."
    </para>

    <para>
     The <emphasis>Authentication</emphasis> and <emphasis>Linux PAM</emphasis> sections above also relate to security.
    </para>
   </section>
   <section><title>Administration interface</title>
    <para>
     If enabled with the <emphasis>--admin</emphasis> command-line option, the E-MailRelay server will
     provide a network interface for performing administration tasks. This is a
     simple command-line interface which is compatible with <emphasis>telnet</emphasis>:
    </para>

      <programlisting>$ emailrelay --as-server --port=125 --forward-to=localhost:25 --admin=10026
$ telnet localhost 10026
E-MailRelay&gt; help
E-MailRelay&gt; quit
</programlisting>
    <para>
     The <emphasis>flush</emphasis> command is used to get the E-MailRelay server to forward spooled
     mail to the next SMTP server, as an alternative to running
     <emphasis>emailrelay --as-client</emphasis> as a separate process. In proxy mode it is a way of
     getting the proxy server to scan the spool-directory for new messages.
    </para>

    <para>
     The <emphasis>list</emphasis> command lists the messages in the spool directory, <emphasis>info</emphasis> provides
     network status information and activity statistics, and <emphasis>notify</emphasis> enables
     asynchronous event notification.
    </para>
   </section>
   <section><title>Files and directories</title>
    <para>
     Following a normal build from source, a <emphasis>make install</emphasis> puts files in the
     following locations:
    </para>
    <itemizedlist>
     <listitem><para>/usr/local/etc/emailrelay.conf</para></listitem>
     <listitem><para>/usr/local/etc/emailrelay.conf.template</para></listitem>
     <listitem><para>/usr/local/etc/pam.d/emailrelay</para></listitem>
     <listitem><para>/usr/local/libexec/emailrelay/emailrelay-filter-copy</para></listitem>
     <listitem><para>/usr/local/libexec/emailrelay/emailrelay-poke</para></listitem>
     <listitem><para>/usr/local/libexec/emailrelay/examples/*</para></listitem>
     <listitem><para>/usr/local/libexec/emailrelay/init/emailrelay</para></listitem>
     <listitem><para>/usr/local/man/man1/emailrelay*.1.gz</para></listitem>
     <listitem><para>/usr/local/sbin/emailrelay</para></listitem>
     <listitem><para>/usr/local/sbin/emailrelay-passwd</para></listitem>
     <listitem><para>/usr/local/sbin/emailrelay-submit</para></listitem>
     <listitem><para>/usr/local/share/emailrelay/doc/*</para></listitem>
     <listitem><para>/usr/local/share/emailrelay/doc/index.html</para></listitem>
     <listitem><para>/usr/local/share/emailrelay/doc/README</para></listitem>
     <listitem><para>/usr/local/var/spool/emailrelay/emailrelay.*.content</para></listitem>
     <listitem><para>/usr/local/var/spool/emailrelay/emailrelay.*.envelope</para></listitem>
    </itemizedlist>

    <para>
     For finer control of the directory structure the following can be specified on
     the <emphasis>configure</emphasis> command-line:
    </para>
    <itemizedlist>
     <listitem><para>--mandir=&lt;dir&gt;</para></listitem>
     <listitem><para>--sbindir=&lt;dir&gt;</para></listitem>
     <listitem><para>--datadir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_libexecdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_sysconfdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_docdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_examplesdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_initdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_spooldir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_pamdir=&lt;dir&gt;</para></listitem>
     <listitem><para>e_icondir=&lt;dir&gt;</para></listitem>
    </itemizedlist>

    <para>
     For example, running <emphasis>./configure --prefix=/usr e_spooldir=/tmp/spool</emphasis> will
     install to a directory structure under <emphasis>/usr</emphasis> rather than <emphasis>/usr/local</emphasis>,
     and create the E-MailRelay spool directory as <emphasis>/tmp/spool</emphasis> rather than
     <emphasis>/usr/local/var/spool/emailrelay</emphasis>.
    </para>

    <para>
     For a directory structure conforming more closely to the FHS use this configure
     command:
    </para>

      <programlisting>./configure --prefix=/usr --localstatedir=/var --libexecdir=/usr/lib --sysconfdir=/etc e_init_dir=/etc/init.d
</programlisting>
    <para>
     As usual, it is possible to change the installation root directory after
     building by using <emphasis>make DESTDIR=&lt;root&gt; install</emphasis> or
     <emphasis>DESTDIR=&lt;root&gt; make -e install</emphasis>. However, this will not affect the default
     spool directory path built into the scripts and executables so the correct spool
     directory will have to be specified at run-time with the <emphasis>--spool-dir</emphasis> option.
    </para>




    <para>
     Copyright (C) 2001-2013 Graeme Walker &lt;graeme_walker@users.sourceforge.net&gt;. All rights reserved.
    </para>
   </section>
  </section>
  <section><title>E-MailRelay Internals</title>
   <section><title>Module structure</title>
    <para>
     The main C++ libraries in the E-MailRelay code are: <emphasis>glib</emphasis>, providing low-level
     classes for file-system abstraction, date and time representation, string
     utility functions, logging, command line parsing etc.; <emphasis>gssl</emphasis>, which is a thin
     abstraction over OpenSSL; <emphasis>gnet</emphasis>, which provides network classes using the
     Berkley socket and Winsock APIs; <emphasis>gauth</emphasis>, which implements various
     authentication mechanisms; <emphasis>gsmtp</emphasis>, containing SMTP and message-store classes;
     and <emphasis>gpop</emphasis>, which contains POP3 classes. All of these libraries are portable
     between POSIX-like systems (eg. Linux) and Windows.
    </para>

    <para>
     Under Windows there is an additional library for event handling. Windows has
     historically built network event processing on top of the GUI event system which
     means that the <emphasis>gnet</emphasis> library has to be able to create GUI windows in order to
     process network events. The extra GUI and event classes are put into a separate
     library in the <emphasis>src/win32</emphasis> directory, using the namespace <emphasis>GGui</emphasis>.
    </para>

    <para>
     There is also a separate configuration GUI program which uses the <emphasis>glib</emphasis> library
     together with TrollTech's Qt.
    </para>
   </section>
   <section><title>Event model</title>
    <para>
     The E-MailRelay server uses non-blocking socket i/o, with a <literal>select()</literal> event loop.
     This event model means that the server can handle multiple clients
     simultaneously from a single thread and the only significant blocking occurs
     when external programs are executed (see <emphasis>--filter</emphasis> and <emphasis>--verifier</emphasis>).
    </para>

    <para>
     In some ways this makes the implementation more complicated than the equivalent
     multi-threaded approach since (for example) it is not possible to wait for a
     complete line of input to be received from a remote SMTP client because there
     might be other connection that need servicing.
    </para>

    <para>
     See <ulink url="http://www.kegel.com/c10k.html">C10K Problem</ulink> for a discussion of
     different network event models.
    </para>

    <para>
     At higher levels the C++ slot/signal design pattern is used to propagate events
     between objects (not to be confused with operating system signals). The
     slot/signal implementation has been simplified compared to Qt or boost by not
     supporting signal multicasting, so each signal connects to no more than one
     slot. For historical reasons the slot/signal pattern is not used in the lowest
     layers of the network library.
    </para>
   </section>
   <section><title>Event handling and exceptions</title>
    <para>
     The use of non-blocking i/o in the network library means that most processing
     operates within the context of an i/o event or timeout callback so the top level
     of the call stack is nearly always the event loop code. This can make using C++
     exceptions a bit awkward compared to a multi-threaded approach because it is not
     possible to put a single catch block around a particular high-level feature.
    </para>

    <para>
     The event loop delivers all asynchronous events to the abstract <emphasis>EventHandler</emphasis>
     and <emphasis>AbstractTimer</emphasis> interfaces. If these callbacks throw exceptions then the
     event loop will catch them and deliver them back to the same interface through
     the virtual functions <literal>onException()</literal> and <literal>onTimerException()</literal> respectively. If
     exceptions are thrown out of _these_ callbacks then the event loop code lets
     them propagate back to <literal>main()</literal>, typically terminating the program.
    </para>

    <para>
     The two callback interfaces are brought together by having a concrete <emphasis>Timer</emphasis>
     class that requires an <emphasis>EventHandler</emphasis> object to be associated with each timer.
     The <emphasis>Timer</emphasis> class routes any exceptions thrown out of the timeout callback to
     the designated <emphasis>EventHandler</emphasis> interface so that both i/o and timeout exceptions
     are delivered to the same place.
    </para>

    <para>
     In common with other event-driven frameworks this leads to a programming
     model where objects are instantiated on the heap and the objects delete
     themselves when they receive certain events from the framework. In the
     <emphasis>gnet</emphasis> library the <emphasis>ServerPeer</emphasis> and <emphasis>HeapClient</emphasis> classes do this lifetime
     management; instances of these classes delete themselves when the associated
     network connection goes away or when an exception is thrown out their
     event-handling code.
    </para>
   </section>
   <section><title>Core class structure</title>
    <para>
     The message-store functionality uses three abstract interfaces: <emphasis>MessageStore</emphasis>,
     <emphasis>NewMessage</emphasis> and <emphasis>StoredMessage</emphasis>. The <emphasis>NewMessage</emphasis> interface is used to create
     messages within the store, and the <emphasis>StoredMessage</emphasis> interface is used for
     reading and extracting messages from the store. The concrete implementation
     classes based on these interfaces are respectively <emphasis>FileStore</emphasis>, <emphasis>NewFile</emphasis> and
     <emphasis>StoredFile</emphasis>.
    </para>

    <para>
     Protocol classes such as <emphasis>GSmtp::ServerProtocol</emphasis> receive network and timer
     events from their container and use an abstract <emphasis>Sender</emphasis> interface to send
     network data. This means that the protocols can be largely independent of the
     network and event loop framework.
    </para>

    <para>
     The interaction between the SMTP server protocol class and the message store is
     mediated by the <emphasis>ProtocolMessage</emphasis> interface. Two main implementations of this
     interface are available: one for normal spooling (<emphasis>ProtocolMessageStore</emphasis>), and
     another for immediate forwarding (<emphasis>ProtocolMessageForward</emphasis>). The <emphasis>Decorator</emphasis>
     pattern is used whereby the forwarding class uses an instance of the storage
     class to do the message storing and pre-processing, while adding in an instance
     of the <emphasis>GSmtp::Client</emphasis> class to do the forwarding.
    </para>

    <para>
     Message pre-processing (see <emphasis>--filter</emphasis>) is implemented via an abstract
     <emphasis>Processor</emphasis> interface. Concrete implementations are provided for doing nothing,
     running an external executable program and talking to an external network server.
    </para>

    <para>
     The protocol, processor and message-store interfaces are brought together by the
     high-level <emphasis>GSmtp::Server</emphasis> and <emphasis>GSmtp::Client</emphasis> classes. Dependency injection is
     used to create the concrete instances of the <emphasis>ProtocolMessage</emphasis> and <emphasis>Processor</emphasis>
     interfaces.
    </para>

    <para>
     Simplified class diagrams for the <ulink url="gnet-classes.png">GNet</ulink> and
     <ulink url="gsmtp-classes.png">GSmtp</ulink> namespaces are available.
    </para>
   </section>
   <section><title>Windows service</title>
    <para>
     To get E-MailRelay to run as a Windows service there is a service wrapper
     program called <emphasis>emailrelay-service.exe</emphasis>. This program registers itself as
     a service when run with the <emphasis>--install</emphasis> commandline option. When the service
     runs the wrapper starts the actual E-MailRelay server by looking for a batch
     file called <emphasis>emailrelay-start.bat</emphasis> in the same directory as service wrapper
     executable. It reads the contents of this batch file in order to construct the
     E-MailRelay command-line, adding <emphasis>--no-daemon</emphasis> and <emphasis>--hidden</emphasis> options if they
     are not there already.
    </para>

    <para>
     The service name and display name can be added to the wrapper's <emphasis>--install</emphasis>
     command-line, and it is the service name that is used to derive the name of the
     <emphasis>start</emphasis> batch file. This allows more than one server to be run as services,
     using different server command-line options on each one.
    </para>
   </section>
   <section><title>Diagrams</title>
    <para>
     Class diagrams:
    </para>
    <itemizedlist>
     <listitem><para><ulink url="gnet-classes.png">GNet namespace</ulink></para></listitem>
     <listitem><para><ulink url="gsmtp-classes.png">GSmtp namespace</ulink></para></listitem>
    </itemizedlist>

    <para>
     State transition diagrams:
    </para>
    <itemizedlist>
     <listitem><para><ulink url="gnet-client.png">GNet::Client</ulink></para></listitem>
     <listitem><para><ulink url="gsmtp-serverprotocol.png">GSmtp::ServerProtocol</ulink></para></listitem>
    </itemizedlist>

    <para>
     Sequence diagrams:
    </para>
    <itemizedlist>
     <listitem><para><ulink url="sequence-3.png">Proxy mode forwarding</ulink></para></listitem>
    </itemizedlist>
   </section>
   <section><title>E-MailRelay GUI</title>
    <para>
     The optional GUI program <emphasis>emailrelay-gui</emphasis> uses TrollTech Qt v4 for its user
     interface components. The GUI can run as a stand-alone configuration helper
     (<emphasis>--as-configure</emphasis>) or as part of a self-extracting installation
     (<emphasis>--as-install</emphasis>). When it runs it checks whether it has a payload of packed
     files. If it has then it runs as an installer; if it does not then it runs as a
     configuration helper. Refer to the comments in <emphasis>src/gui/guimain.cpp</emphasis> for more
     details.
    </para>

    <para>
     The user interface is structured as a <emphasis>wizard</emphasis> having a dialog box with the
     forward and back buttons at the bottom and a single Qt layout object for the
     main area. A stack of Qt widgets representing the various pages of the wizard
     are installed into the main layout object in turn as the user navigates from
     one page to the next.
    </para>

    <para>
     Once the wizard is completed it asks each page to dump its state as a set of
     key-value pairs into a stringstream (see <emphasis>src/gui/pages.cpp</emphasis>). These key-value
     pairs are processed by an installer class into a list of action objects (in the
     <emphasis>Command</emphasis> design pattern) and then the action objects are run in turn. In order
     to display the progress of the installation each action object is run within a
     timer callback so that the Qt framework gets a chance to update the GUI between
     each one.
    </para>

    <para>
     During development the user interface pages and the installer can be tested
     separately since the interface between them is a simple text stream containing
     key-value pairs.
    </para>

    <para>
     When run in <emphasis>--as-configure</emphasis> mode the GUI normally ends up simply editing
     the <emphasis>emailrelay.conf</emphasis> file and/or the <emphasis>emailrelay.auth</emphasis> secrets file.
    </para>

    <para>
     When run in <emphasis>--as-install</emphasis> mode the GUI expects to unpack all the E-MailRelay
     files from a <emphasis>payload</emphasis> archive into target directories.
    </para>

    <para>
     The packing scheme used for a payload archive is a simple concatenation of the
     <emphasis>stub</emphasis> executable followed by a table of contents for the payload files,
     followed by the payload files themselves (possibly compressed by <emphasis>zlib</emphasis>), and
     ending with an twelve-byte ascii representation of the offset of the table of
     contents.
    </para>

    <para>
     The payload may be appended to the GUI executable to make a self-extracting
     installer, usually then called <emphasis>emailrelay-setup</emphasis>.
    </para>

    <para>
     However, on Windows two levels of packing are required: the <emphasis>emailrelay-setup</emphasis>
     program has a stub executable written in <emphasis>C</emphasis> that prints an <emphasis>extracting...</emphasis>
     message to the standard output, with a payload comprising another packed
     executable and a small number of <emphasis>C++</emphasis> runtime library files. The inner packed
     executable has the emailrelay GUI program as its stub and all the other
     installable files, including the main emailrelay executable, as its payload.
    </para>

    <para>
     On unix-like operating systems it is more natural to use some sort of package
     derived from the <emphasis>make install</emphasis> process rather than an installer program, so
     <emphasis>emailrelay-setup</emphasis> ia typically never built.
    </para>

    <para>
     On Mac OS X the payload is better stored in the installer's application
     bundle rather than simply appended to the binary. This is desribed in the next
     section.
    </para>
   </section>
   <section><title>Windows build</title>
    <para>
     On Windows E-MailRelay can be built using MinGW or Visual Studio. Makefiles and
     Visual Studio 2012 project files are provided in the <emphasis>src</emphasis> directory.
    </para>

    <para>
     For a MinGW build of the E-MailRelay server without TLS/SSL support it should
     be sufficient to run make from the <emphasis>src</emphasis> directory:
    </para>

      <programlisting>C:\emailrelay\src&gt; PATH=c:\mingw\bin;%PATH%
C:\emailrelay\src&gt; mingw32-make -f mingw.mak
</programlisting>
    <para>
     To add TLS/SSL support first install ActiveState perl and make sure that your
     MinGW installation contains the MSYS subsystem. Unpack the OpenSSL tarball and
     build it as follows:
    </para>

      <programlisting>C:\openssl&gt; PATH=c:\perl\bin;c:\mingw\msys\1.0\bin;c:\mingw\bin;%PATH%
C:\openssl&gt; bash -l
$ ./config
$ mingw32-make
</programlisting>
    <para>
     Then edit the E-MailRelay <emphasis>src/mingw-common.mak</emphasis> file to enable openssl and run
     <emphasis>mingw32-make</emphasis> as above.
    </para>

    <para>
     If building the E-MailRelay GUI then it is best to use MinGW with Qt 5 static
     libraries. Start by installing zlib source (eg. to c:/zlib) and then build Qt
     using the following <emphasis>configure</emphasis> options:
    </para>

      <programlisting>-prefix /c/qt/qt5-static
-I c:/zlib
-L c:/zlib
-static
-release
-force-debug-info
-separate-debug-info
-opensource
-confirm-license
-no-c++11
-fully-process
-no-largefile
-accessibility
-no-sql-sqlite
-no-sql-sqlite2
-no-javascript-jit
-no-qml-debug
-platform win32-g++
-no-sse2
-no-sse3
-no-ssse3
-no-sse4.1
-no-sse4.2
-no-avx
-no-avx2
-no-neon
-no-mips_dsp
-no-mips_dspr2
-no-pkg-config
-system-zlib
-no-gif
-qt-libpng
-no-libjpeg
-no-openssl
-qt-pcre
-qt-xcb
-qt-xkbcommon
-gui
-widgets
-no-rpath
-no-optimized-qmake
-no-nis
-no-cups
-no-iconv
-no-icu
-strip
-no-pch
-no-dbus
-no-xcb
-no-eglfs
-no-directfb
-no-linuxfb
-no-kms
-no-opengl
-no-system-proxies
-no-glib
</programlisting>
    <para>
     Start the Qt build by running <emphasis>mingw32-make</emphasis> from the <emphasis>qtbase</emphasis> directory and
     finish off with <emphasis>mingw32-make install</emphasis>.
    </para>

    <para>
     Edit the E-MailRelay GUI makefile <emphasis>src/gui/mingw.mak</emphasis> so that the E-MailRelay
     build uses similar compiler options to the Qt examples and then then build with:
    </para>

      <programlisting>$ mingw32-make -f mingw.mak</programlisting>
   </section>
   <section><title>Mac OS X packaging</title>
    <para>
     On Mac OS X the standard <emphasis>configure ; make ; make install</emphasis> procedure works best
     if the <emphasis>configure</emphasis> script is given Mac-like directories on its command-line. The
     script <emphasis>bin/configure-mac.sh</emphasis> can be used to do this.
    </para>

    <para>
     The <emphasis>make</emphasis> step in <emphasis>src/main</emphasis> on Mac OS X additionally builds a simple wrapper
     program <emphasis>emailrelay-start</emphasis> from <emphasis>start.cpp</emphasis> that runs the E-MailRelay server
     using a command-line assembled from the <emphasis>emailrelay.conf</emphasis> file. This is then
     used from the <emphasis>E-MailRelay-Start</emphasis> application bundle to provide a Mac-friendly
     way of running the server.
    </para>

    <para>
     Similary the <emphasis>make</emphasis> in <emphasis>src/gui</emphasis> builds a wrapper program <emphasis>emailrelay-start-gui</emphasis>
     from <emphasis>guistart.cpp</emphasis> that runs <emphasis>emailrelay-gui.real</emphasis> and this is used from the
     <emphasis>E-MailRelay-Configure</emphasis> application bundle.
    </para>

    <para>
     The self-extracting installer scheme (described above) does work on Mac OS X,
     but it is more sensible to use a Mac application bundle (E-MailRelay-Install) to
     hold the payload and then wrap the whold thing up in a <emphasis>.dmg</emphasis> disk image. The
     GUI code supports this by looking for a separate file called <emphasis>payload</emphasis> and using
     that in preference to any payload archive it finds appended to its own executable.
    </para>

    <para>
     The format of the <emphasis>payload</emphasis> file in the application bundle is the same as is used
     in a self-extracting installer.
    </para>

    <para>
     The makefile in the <emphasis>src/gui</emphasis> directory provides the <emphasis>image</emphasis> target to create
     the E-MailRelay-Install application bundle and the disk image.
    </para>
   </section>
   <section><title>Source control</title>
    <para>
     The source code is stored in the SourceForge <emphasis>svn</emphasis> repository. A working
     copy can be checked out as follows:
    </para>

      <programlisting>$ svn co https://svn.code.sf.net/p/emailrelay/code/trunk</programlisting>
   </section>
   <section><title>Directory structure</title>
    <variablelist>
     <varlistentry><term>src</term>
      <listitem><para>
       Parent directory for source code.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/glib</term>
      <listitem><para>
       A low-level class library, including classes for file-system abstraction,
       date and time, string utility functions, logging, command line parsing etc.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gnet</term>
      <listitem><para>
       A network library using Berkley sockets or Winsock.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gssl</term>
      <listitem><para>
       A library for using OpenSSL.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gauth</term>
      <listitem><para>
       A library for SASL and PAM authentication.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gsmtp</term>
      <listitem><para>
       An SMTP library.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gpop</term>
      <listitem><para>
       A POP3 library.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/win32</term>
      <listitem><para>
       Additional classes for windows event processing.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/main</term>
      <listitem><para>
       Application-level classes for E-MailRelay.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>src/gui</term>
      <listitem><para>
       Installation and configuration GUI program using Qt v4.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>lib</term>
      <listitem><para>
       Parent directory for ISO C++ fixups for various older compilers.
      </para></listitem>
     </varlistentry>
     <varlistentry><term>test</term>
      <listitem><para>
       Test scripts and utilities.
      </para></listitem>
    </varlistentry>
     </variablelist>
   </section>
   <section><title>Source file names</title>
    <para>
     Generally the source file names are follow the name of the principal class,
     (often including the namespace) but all in lowercase. Any underscores in the
     name indicate a choice of implementation, so class <emphasis>G::Foo</emphasis> might have two
     implementations in the files <emphasis>gfoo_main.cpp</emphasis> and <emphasis>gfoo_alternate.cpp</emphasis>.
     The choice is normally made by the makefile.
    </para>
   </section>
   <section><title>Portability</title>
    <para>
     The E-MailRelay code is written in ISO C++, although avoiding less-widely
     supported language features such as <emphasis>mutable</emphasis>, templated methods and <emphasis>export</emphasis>.
    </para>

    <para>
     The header files <emphasis>gdef.h</emphasis> in <emphasis>src/glib</emphasis>, and <emphasis>gnet.h</emphasis> in <emphasis>src/gnet</emphasis> are intended
     to be used to fix up compiler portability issues such as missing standard types,
     non-standard system headers etc. Conditional compilation directives (<emphasis>#if</emphasis>
     etc.) are confined to these headers as far as possible in order to improve
     readability.
    </para>

    <para>
     Deficiencies in the standard headers files provided by older compilers are fixed
     up by files in the <emphasis>lib</emphasis> directory tree. For example, the msvc6.0 compiler
     sometimes does not put its names into the <emphasis>std</emphasis> namespace, even though the
     std-namespace headers are used. This can be worked round by additional <emphasis>using</emphasis>
     declarations in the <emphasis>lib/msvc6.0</emphasis> headers.  These work-rounds are kept out of
     the <emphasis>src</emphasis> tree because they are not necessary for more modern compilers.
    </para>

    <para>
     Windows/unix portability is generally addressed by providing a common class
     declaration with two implementations. Where necessary a <emphasis>pimple</emphasis> (or <emphasis>Bridge</emphasis>)
     pattern is used to hide the system-specific parts of the declaration.
    </para>

    <para>
     A good example is the <emphasis>G::Directory</emphasis> class used for iterating through files in
     a directory. The header file <emphasis>src/glib/gdirectory.h</emphasis> is common to both systems,
     but two implementations are provided in <emphasis>gdirectory_unix.cpp</emphasis> and
     <emphasis>gdirectory_win32.cpp</emphasis>. The unix implementation uses <literal>opendir()</literal> and <literal>glob()</literal>,
     while the windows implementation uses <literal>FindFirstFile()</literal>.
    </para>

    <para>
     Sometimes only small parts of the implementation are system-specific. In
     these cases there are three source files per header. For example, <emphasis>gsocket.cpp</emphasis>,
     <emphasis>gsocket_win32.cpp</emphasis> and <emphasis>gsocket_unix.cpp</emphasis> in the <emphasis>src/gnet</emphasis> directory.
    </para>
   </section>
   <section><title>Compile-time features</title>
    <para>
     Compile-time features can be selected with options passed to the <emphasis>configure</emphasis>
     script. These include the following:
    </para>

    <itemizedlist>
     <listitem><para>Debug-level logging (<emphasis>--enable-debug</emphasis>)</para></listitem>
     <listitem><para>IPv6 (Linux only) (<emphasis>--enable-ipv6</emphasis>)</para></listitem>
     <listitem><para>Configuration GUI (<emphasis>--enable-gui</emphasis>)</para></listitem>
     <listitem><para>PAM support (<emphasis>--with-pam</emphasis>)</para></listitem>
    </itemizedlist>

    <para>
     Some functionality can be disabled at compile-time in order to reduce the size
     of the executable, typically when building for embedded systems:
    </para>

    <itemizedlist>
     <listitem><para>Disable POP3 protocol, <emphasis>--disable-pop</emphasis></para></listitem>
     <listitem><para>Disable authentication, <emphasis>--disable-auth</emphasis> (requires <emphasis>--disable-pop</emphasis>)</para></listitem>
     <listitem><para>Disable administration interface, <emphasis>--disable-admin</emphasis></para></listitem>
     <listitem><para>Disable execution of external programs, <emphasis>--disable-exec</emphasis></para></listitem>
    </itemizedlist>

    <para>
     The <emphasis>--enable-small-config</emphasis> option can be used to change the command-line
     parsing code to use a configuration file instead, resulting in a smaller
     executable. This also removes a lot of the configuration checking code, so it is
     not recommended unless size is critical. (The format of the configuration file
     is similar to the command-line using the long-form options without the
     double-dash and using '=' to separate the option from the option value.)
    </para>

    <para>
     Use <emphasis>./configure --help</emphasis> to see a complete list of options and refer to
     <emphasis>acinclude.m4</emphasis> for more detailed comments.
    </para>
   </section>
   <section><title>Idioms</title>
    <para>
     The <emphasis>&lt;&lt;=</emphasis> operator defined in <emphasis>src/glib/gmemory.h</emphasis> is used idiomatically
     to reassign a std::auto_ptr&lt;&gt; since <literal>reset()</literal> is not always available.
    </para>



    <para>
     Copyright (C) 2001-2013 Graeme Walker &lt;graeme_walker@users.sourceforge.net&gt;. All rights reserved.
    </para>
   </section>
  </section>
</article>
