NAME
    ispMailGate - a general purpose filtering MDA for sendmail

WARNING! WARNING! WARNING!
    This is an alpha release! What you are using now is tested by
    using a comparatively small test suite in our local environment.
    You are perhaps planning to include this software in a
    production environment. We don't discourage to do so, but we
    strongly advise you to be extremely carefull. In particular,
    start by filtering only mails for a very small number of email
    adresses, perhaps your own and something similar. That is, be
    extremely cautios when modifying your sendmail configuration.

    See INSTALLATION and SENDMAIL CONFIGURATION below for a detailed
    description of your sendmail setup.

SYNOPSIS
    For running standalone:

        ispMailGateD -f <sender> <recipient1> [... <recipientN>]

    For running as a daemon (not yet possible, as the wrapper is
    still missing):

        ispMailGateD -s [-d] [-t <tmpdir>] [-a <facility>] [-p <pidfile>]
            [-u <unixsock>]

DESCRIPTION
    IspMailGate is a general purpose email filtering system. The
    program gets included into a sendmail configuration as a
    delivery agent (MDA) and the usual sendmail rules can be applied
    for deciding which emails to feed into ispMailGate. The true
    filters are implemented as modules, so its easy to extend the
    possibilities of ispMailGate. Current modules offer automatic
    compression and decompression, encryption, decryption and
    certification with PGP or virus scanning.

    The program can run in a usual standalone mode, but that's not
    recommended, except for debugging and similar tasks. The
    recommended mode will be running the program as a server,
    completely independent from sendmail. A small C program (called
    a wrapper) will instead be configured as sendmails MDA. This
    wrapper connects to the server via a well known Unix socket (by
    default ), passes its command line arguments and standard input
    to the server and disconnects. Obviously this second solution
    has much better performance as you load the Perl interpreter
    only once.

    Unfortunately the wrapper is not yet available, due to some
    problems with Perl's I/O. (Perl won't notice EOF on the socket
    as long as the client doesn't close the connection. On the other
    hand the client has to hold the connection open for receiving
    error messages which will be written to stderr so that sendmail
    recognizes them. We are thankfull for any suggestion to solve
    this.

  Command Line Interface

    The following options affect ispMailGate's behaviour:

    -a <fac>, -facilty <fac>, --facility <fac>
        Advices the ispMailGate to use syslog facility <fac>. By
        default syslog entries are written as facility mail.

    -d, -debug, --debug
        The program runs in debugging mode, logging information into
        the syslog. Perhaps more information than you like ... :-)

    -f <sender>, -from <sender>, --from <sender>
        Sets a mails sender.

    -s, -server, --server
        Tells the program not to run in standalone mode and instead
        detach from the shell to enter server mode. This mode is
        currently not usable, as the wrapper is not yet available.

    -t <dir>, -tmpdir <dir>, --tmpdir <dir>
        Sets the programs directory for temporary files to <dir>.
        When unpacking a complex and big multipart mail, the
        ispMailGate may need surprisingly much space. By default
        /var/spool/ispmailgate is used.

    -u <sock>, -unixsock <sock>, --unixsocket <sock>
        Tells the server to listen on file <sock> for unix socket
        connections. By default the server uses
        /var/run/ispMailGate.sock.

INSTALLATION
  Requirements

    To start with the requirements: You need

    1.) A running sendmail (recommended: 8.8.5 or later); if you
    don't have sendmail or an older version, you find the current
    release at

        ftp://ftp.sendmail.org/pub/sendmail

    2.) A late version of Perl (recommended: 5.004 or later); if you
    don't have Perl, shoot yourself in the foot (;-) or get it from
    any CPAN mirror, for example

        ftp://ftp.funet.fi/pub/languages/perl/CPAN/src/5.0

    3.) The MIME-tools module (version 4.116 or later), its
    prerequired modules (MailTools, MIME-Base64 and IO-Stringy) and
    the IO::Tee module (version 0.61 or later). All these modules
    are available from any CPAN mirror, for example

        ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/Mail
        ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/MIME
        ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/IO

    Installing a Perl module is quite easy, btw. Either you use the
    automatic CPAN interface (requires an Internet connection or
    something similar) by executing

        perl -MCPAN -e shell

    or you fetch the modules with FTP, extract the tar.gz files, go
    into the distribution directory (for example MIME-tools-4.116)
    and do a

        perl Makefile.PL
        make
        make test
        make install

    You'll like it! :-)

  System preparation

    Although ispMailGate is usually started as root, because certain
    initialization setting need root permissions, it must not
    continue running as root. Instead it impersonates itself to a
    user ID that you select. I recommend creating a separate user
    `ispmailgate' and a separate group `ispmailgate'.

    IspMailGate needs its own directory for creating temporary
    files. Usually this could be `/var/spool/IspMailGate' or
    something similar. Make sure that the ispmailgate user (but
    noone else) has access to this directory:

        mkdir /var/spool/IspMailGate
        chown ispmailgate /var/spool/IspMailGate
        chgrp ispmailgate /var/spool/IspMailGate
        chmod 700 /var/spool/IspMailGate

  Program installation

    The program is installable like any other Perl module. However,
    you cannot use the automatic CPAN installation in that case.
    Instead, fetch the current archive from any CPAN mirror, for
    example

        ftp://ftp.funet.fi/pub/languages/perl/CPAN/authors/id/JWIED

    extract the archive with

        gzip -cd Mail-IspMailGate-<version>.tar.gz | tar xf -

    After that, do a

        cd Mail-IspMailGate-<version>

    and start with editing the Configuration module

        lib/Mail/IspMailGate/Config.pm

    In particular you might like to modify the installation
    directories. For example, to install into
    /usr/local/IspMailGate/sbin, /usr/local/IspMailGate/lib and so
    on, you'd change the variable

        $PREFIX = "/usr/local/IspMailGate";

    For a detailed description of the configuration file see the
    section on "CONFIGURATION FILE" below. Once this is done,
    install the program with

        perl -Ilib Makefile.PL
        make
        make test
        make install

    Finally make sure that the ispMailGate binary can connect to the
    server. Assuming that you have installed in
    /usr/local/IspMailGate and that your sendmail is running as
    group `mail', do the following:

        chown ispmailgate /usr/local/IspMailGate/sbin/ispMailGate
        chgrp mail /usr/local/IspMailGate/sbin/ispMailGate
        chmod 4750 /usr/local/IspMailGate/sbin/ispMailGate

SENDMAIL CONFIGURATION
    Before modifying your sendmail configuration, think about the
    following: The crucial problem of using IspMailGate without
    damage is that you are working in a number of different steps.
    For example:

    second sendmail.cf
        In the first step you leave your /etc/sendmail.cf completely
        untouched. Instead you create a second file
        /etc/sendmail.cf.new, create files containing email messages
        (for example by saving them from your preferred email
        client) and then feed them into sendmail by using the
        following command:

            cat mymail | sendmail -v -i -f<sender> <recipient>

    single user action
        If the first step seems to look good, you can go on
        modifying your true sendmail.cf. But don't let all mails be
        filtered! Instead let sendmail filter only mails for or from
        some selected people, that are aware of potential problems,
        for example your own mail. (You know of things that might
        happen, don't you? :-)

        Stay in this stage for at least a week or two. Contact
        different kind of people using all sort of email clients,
        send them mails and advise them to reply with all possible
        kinds of emails: Simple text documents, multipart messages,
        word documents (interesting thing if you verify the virus
        scanner ... ;-)

    Final stage
        Finally if all seems to be working well, you can enter the
        final stage and do the things you really want.

  Selecting the mails to feed into sendmail

    The main problem with sendmail is that ruleset 0 (the set of
    rules deciding about how to handle an email) decides by looking
    at the recipient only. (At least I don't know of other
    possibilities, perhaps someone can tell?) IspMailGate is smarter
    and can make decisions based on both sender and recipients.
    However, it cannot decide on mails that don't reach it, thus you
    probably must feed mails into IspMailGate that aren't really
    interesting for it. For example, if you have an IspMailGate rule
    concerning mails sent from joe@ispsoft.de to *@perl.com then you
    must feed all mails into IspMailGate that have *@perl.com as
    recipient, regardless of the sender. IspMailGate fixes this
    problem by just ignoring such mails and just feeding them back
    into sendmail. However, a performance problem is still
    remaining.

    Another problem is, that IspMailGate rules are based on Perl
    regular expressions. Of course they have a much finer
    granularity than sendmail rules have, but that may rarely be a
    problem in practice.

    To sum it up: Sendmail must be configured to feed any mail into
    IspMailGate that has a recipient which *might* receive a mail
    that ought to be filtered via IspMailGate. In the extreme case
    this can mean that sendmail must feed all email traffic into
    IspMailGate before really delivering it.

    Now for the real stuff. In what follows I assume some knowledge
    of sendmail configuration. In particular you should be able to
    configure sendmail based on m4 macros, a detailed explanation of
    this process is contained in the file cf/README of the sendmail
    sources. Additionally you should know the concept of sendmail
    classes and how to work with them.

    We start with creating a file that holds a new sendmail class,
    called IMGR. The file might look as follows:

        # perlbug@perl.org is a possible IspMailGate recipient.
        perlbug@perl.org    :ispmailgate
        # Any mail going to *@ispsoft.de will be feed into IspMailGate
        @ispsoft.de         :ispmailgate
        # And finally *@*.uni-tuebingen.de
        .uni-tuebingen.de   :ispmailgate

    In what follows I assume that this file is stored as
    /etc/ispMailGateRecipients. Now we add the following section to
    sendmail.mc:

        define(`ISPMAILGATE_MAILER_PATH', `/usr/local/bin/ispMailGateD')
        define(`ISPMAILGATE_MAILER_FLAGS', `fgmDFMu')
        define(`ISPMAILGATE_MAILER_ARGS', `ispMailGateD $f $u')

        MAILER_DEFINITIONS
        ##################################################
        ###   IspMailGate Mailer specification         ###
        ##################################################

        Mispmailgate, P=ISPMAILGATE_MAILER_PATH, F=ISPMAILGATE_MAILER_FLAGS,
            S=11/31, R=21/31, T=DNS/RFC822/X-Unix, A=ISPMAILGATE_MAILER_ARGS

        LOCAL_CONFIG
        KIMGR hash -o /etc/mail/ispMailGateRecipients
        CPISPMAILGATE

        LOCAL_RULE_0
        # Make "user < @ host >" to "<user @ host > user < @ host . >"
        R$* < @ $+ > $*                     $: < $1 @ $2 > $1 < @ $2 > $3
        # At this point we might have "< user @ host . > user < @ host . >"
        # Remove the dot from the host part, if any.
        R< $+ . > $* < $+ > $*              $: < $1 > $2 < $3 > $4

        # Is "user@host" in /etc/mail/ispMailGateRecipients?
        R< $* @ $+ > $* < $+ > $*
                    $: < $1 @ $2 $(IMGR $1 @ $2 $: $) > $3 < $4 > $5
        # Is "@host" in /etc/mail/ispMailGateRecipients?
        R< $* @ $+ > $* < $+ > $*
                    $: < $1 @ $2 $(IMGR @ $2 $: $) > $3 < $4 > $5
        # Is "host" = "@any.domain" with "domain" in
        # /etc/mail/ispMailGateRecipients?
        R< $* @ $+ . $+ > $* < $+ > $*
                    $: < $1 @ $2 . $3 $(IMGR . $3 $: $) > $4 < $5 > $6
        # Did any of the last three rules match? If so, call IspMailGate
        R< $* @ $+ : ispmailgate > $* < $+ > $*
                    $# ispmailgate $@ $2 $: $1 < @ $2 >

        # Remove the preceding < user @ host >
        R< $* @ $+ > $* < $+ > $*   $: $3 < $4 > $5
        # Remove a .ISPMAILGATE, if present; call ruleset 3 for
        # canonicalization
        R$* < @ $+ .ISPMAILGATE. > $*       $: $>3 $1 @ $2

    If you do not know too much about sendmail.cf, you should at
    least note the following: In the above example we have typically
    three kinds of lines: Lines beginning with a '#' are comments.
    The LOCAL_CONFIG and LOCAL_RULE_0 lines are m4 macros, the rest
    are so-called sendmail rules. These consist of a left hand and a
    right hand side (LHS and RHS), separated by tabs. If the lines
    become too long, you may use continutation lines, starting with
    a blank or tab. In the above example there are three rules using
    line continuation: The LHS is on the first line, the RHS
    (introduced with two tabs) is on the second line.

    But what does the above example mean? For understanding that,
    you have two know that sendmail starts with bringing the
    recipient address into a canonical form, looking like

        user<@host> other information

    The host part might have a trailing dot, so the above may indeed
    be

        user<@host.> other information

    So the first lines modify the above to

        <user@host>user<@host> other information

    or

        <user@host>user<@host.> other information

    The idea is that we work with the first part and may fall back
    to the original information by just dropping the part
    <user@host>.

    The three rules using the IMGR map verify whether "user@host"
    has a match in the recipient list of IspMailGate. If so, the RHS
    of the map in /etc/mail/ispMailGateRecipients is added and we
    receive

        <user@host:ispmailgate>user<@host.> other information

    which will be sent to the ispmailgate mailer. Finally the first
    part is removed. But what does the last rule do?

    When a mail is sent to IspMailGate, it may do something with the
    mail, but finally it is passed back to sendmail for true
    delivery. To avoid loops, we have to tell sendmail that the mail
    must not be processed by IspMailGate a second time. To achieve
    that we modify the recipient from user@host to
    user@host.ispmailgate. That guarantees, that the maps in
    /etc/mail/ispMailGateRecipients don't match thus we are
    guaranteed that the last rule of the above example will be
    applied finally. All it does is removing this .ispmailgate, if
    any. (Sometimes I agree, that sendmail configuration is a
    tedious thing ...)

CONFIGURATION FILE
    The program depends on a local configuration file, read as the
    Mail::IspMailGate::Config module. In other words, this
    configuration file is pure Perl code defining certain variables
    under the name space Mail::IspMailGate::Config. The module is
    read from the file /usr/local/IspMailGate-
    1.002/lib/Mail/IspMailGate/Config.pm.

    The following variables are meaningfull to the program:

    $VERSION
        The programs version; do not modify without a good reason.

    $PREFIX
        The installation prefix; typically the program files are
        stored in the directories $PREFIX/sbin, $PREFIX/lib,
        $PREFIX/man and so on. (Modifiable, see below.) The current
        prefix is /usr/local/IspMailGate-1.002.

    $LIBDIR
        The directory where the program's own perl modules are
        stored, currently /usr/local/IspMailGate-1.002/lib.

    $SCRIPTDIR
        A directory for storing the executable Perl files, currently
        /usr/local/IspMailGate-1.002/sbin.

    $MANDIR
        The program's man pages are stored here, currently
        /usr/local/IspMailGate-1.002/man.

    $TMPDIR
        Set's the default directory for creating temporary files,
        currently /var/spool/ispmailgate. You can modify this with
        the `--tmpdir' directive, see above.

    $UNIXSOCK
        The unix socket that the client connects to, currently
        /var/run/ispMailGate.sock. You can use the `--unixsock'
        argument for overwriting the default.

    $PIDFILE
        The PID file where a running server stores its PID,
        currently /var/run/ispMailGate.pid. You can use the `--
        pidfile' argument for overwriting the default.

    $USER
    $GROUP
        IspMailGate is running as this user and group, daemon and
        mail.

    $MAILHOST
        The host to use for passing mails after processing them by
        the mail filter. By default 'localhost' is used, in other
        words, the mails are immediately passed back to sendmail.

        To omit a possible loop problem, sendmail must be ready for
        handling email addresses like user@domain.ispmailgate. For
        such addresses it must rip off the .ispmailgate and
        guarantee not to feed the mails back into ispMailGate. See
        the section on "SENDMAIL CONFIGURATION" below.

    @RECIPIENTS
        A list of possible recipients/senders and filter lists that
        describe how to handle mails being sent from the senders to
        the recipients.

        Each element of the list is a hash ref with the following
        elements:

    recipient
            A regular expression (Perl regular expression, that is)
            for matching the recipient address. An empty string
            matches any recipient.

    sender  A regular expression (Perl regular expression, again) for
            matching the sender address. An empty string matches any
            sender.

    filters An array ref to a list of filters. A mail will be fed into
            that list (from the left to the right) and the final
            result will be returned to sendmail. See the
            Mail::IspMailGate::Filter(3) manpage for a description
            of creating filters.

        The recipient list will be read top to bottom, the first
        match decides which rule to choose. See the example
        configuration below for some example rules.

    @DEFAULT_FILTER
        If no element of the @RECIPIENTS list matches an emails
        senders and recipients, the filters from this variable will
        be choosen. By default it contains a dummy filter.

    %PACKER
        This variable belongs to the Packer module. See the
        Mail::IspMailGate::Packer(3) manpage for details.

    $VIRSCAN
    %DEFLATER
    $HAS_VIRUS
        These belong to the VirScan module. See the
        Mail::IspMailGate::VirScan(3) manpage.

    $PGP_UID
    $PGP_UIDS
    $PGP_ENCRYPT_COMMAND
    $PCP_DECRYPT_COMMAND
        These belong to the PGP module. See the
        Mail::IspMailGate::PGP(3) manpage for details.

  Example Configuration

    It might help to look at a commented example of the
    configuration file:

        # Yes, this is a module. Thus we have to introduce the file with
        # forcing the modules namespace.
        package Mail::IspMailGate::Config;

        # We load the modules here that will later be used for
        # creating recipient lists.
        require Mail::IspMailGate::Filter::Packer;
        require Mail::IspMailGate::Filter::Dummy;
        require Mail::IspMailGate::Filter::VirScan;
        require Mail::IspMailGate::Filter::PGP;

        # Directory settings and the like
        $VERSION = '1.000';
        $PREFIX = "/usr/local/IspMailGate-${VERSION}";
        $LIBDIR = "${PREFIX}/lib";
        $ETCDIR = "${PREFIX}/etc";
        $SCRIPTDIR = "${PREFIX}/sbin";
        $MANDIR = "${PREFIX}/man";
        $TMPDIR = '/var/spool/IspMailgate';
        $UNIXSOCK = '/var/run/ispMailGate.sock';
        $PIDFILE = '/var/run/ispMailGate.pid';
        $USER = 'daemon';
        $GROUP = 'mail';
        $MAILHOST = 'localhost';

        #
        # The packer module's configuration
        #
        %PACKER = ( 'gzip' => { 'pos' => '/bin/gzip -c',
                                'neg' => '/bin/gzip -cd' } );

        #
        # The virus scanner's configuration
        #
        $VIRSCAN = '/usr/local/bin/virusx $ipaths';
        @DEFLATER = ( { pattern => '\\.(tgz|tar\\.gz|tar\\.[zZ])$',
                        cmd => '/bin/gzip -cd $ipath | /bin/tar -xf -C $odir'
                      },
                      { pattern => '\\.tar$',
                        cmd => '/bin/tar -xf -C $odir'
                      },
                      { pattern => '\\.(gz|[zZ])$',
                        cmd => '/bin/gzip -cd $ipath >$opath'
                      },
                      { pattern => '\\.zip$',
                        cmd => '/usr/bin/unzip $ifile -d $odir'
                      }
                    );

        #
        # sub which determines by a given string if a virus has been found.
        # It returns a non-empty string if a virus has been found, else it
        # returns ''
        #
        $HASVIRUS = sub ($) {
            my($str) = @_;
            if($str ne '') {
                return "Virus has been found: $str";
            } else {
                return '';
            }
        };

        #
        # The list of recpients; first match will be used. Any recipient not
        # matching one of the elements will be filtered through the
        # DEFAULT_FILTER.
        #
        @DEFAULT_FILTER = (Mail::IspMailGate::Filter::Dummy->new({}));

        #
        # Now the list of email senders/recipients that will handled by the
        # filter.
        #
        my($pgp) = 'Mail::IspMailGate::Filter::PGP';
        my($packer) = 'Mail::IspMailGate::Filter::Packer';
        @RECIPIENTS = (
            # Mail to hamburg.company.com (our branch in Hamburg, say)
            # will be compressed with gzip and encrypted with PGP, key
            # 'stuttgart.company.com'
            { 'recipient' => '\\@muenchen\\.company\\.com$',
              'filters' => [ $packer->new({'packer' => 'gzip',
                                           'direction' => 'pos'}),
                             $pgp->new({'uid' => 'stuttgart\\.company\\.com',
                                        'direction' => 'pos'}) ]
            },

            # The departure in munich doesn't use IspMailGate, but all
            # clients have AK-Mail installed. Mail to muenchen.company.com
            # (our branch in munich, say) will be encrypted with PGP, user
            # ID 'stuttgart.company.com'.
            { 'recipient' => '\\@muenchen\\.company\\.com$',
              'filters' => [ $pgp->new({'uid' => 'stuttgart\\.company\\.com',
                                        'direction' => 'pos'}) ]
            },

            # Mail from muenchen.company.com or hamburg.company.com to
            # stuttgart.company.com (incoming mail from the munich branch,
            # say) will be decompressed and decrypted. Note we handle both
            # sources with a single rule: The Packer module detects if a
            # mail is not compressed.
            { 'recipient' => '\\@stuttgart\\.company\\.com',
              'sender'    => '\\@(muenchen|hamburg)\\.company\\.com',
              'filters'   => [ $packer->new({'direction' => 'neg'}),
                               $pgp->new({'direction' => 'neg'}) ]
            },

            # joe@ispsoft.de is a very special user. We send him an
            # email bomb. (Filter to be being written. :-)
            { 'recipient' => 'joe\\@ispsoft\\.de'
              'filters'   => [ Mail::IspMailGate::Filter::Bomb->new({
                                   'file' => 'X11R6.tar.gz' }) ]
            }
        );

        1;

AUTHORS, COPYRIGHT AND LICENSE
    This module is

        Copyright (C) 1998         Amar Subramanian
                                   Grundstr. 32
                                   72810 Gomaringen
                                   Germany

                                   Email: amar@neckar-alb.de
                                   Phone: +49 7072 920696

                           and     Jochen Wiedmann
                                   Am Eisteich 9
                                   72555 Metzingen
                                   Germany

                                   Email: joe@ispsoft.de
                                   Phone: +49 7123 14887

        All Rights Reserved.

    Permission to use, copy and modify this software and its
    documentation, is hereby granted to non-commercial entities
    without fee, provided that this license information and
    copyright notice appear in all copies.

    A "non-commercial entity" is defined within the scope of this
    license as an educational institution (excluding a commercial
    training organisation), non-commercial research organisation,
    registered charity, registered not-for-profit organisation, or
    full-time student.

    Use of this software by any other person or organisation for any
    purpose requires that a usage license be obtained from the
    authors for that person or organisation.

    Commercial redistribution of this software, by itself or as part
    of another application is allowed only under express written
    permission of the authors.

    AMAR SUBRAMANIAN AND JOCHEN WIEDMANN DISCLAIM ALL WARRANTIES
    WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
    OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL AMAR
    SUBRAMANIAN OR JOCHEN WIEDMANN BE LIABLE FOR ANY SPECIAL,
    INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
    RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
    OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    SOFTWARE.

  The Plain English Version

    You can use this software free of charge if you are an
    educational institution (excluding commercial training
    organisations), non-commercial research organisation, registered
    charity, registered not-for-profit organisation, or full-time
    student.

    If you want to use it and you do not fit into any of the above
    listed categories, you must register your copy using the invoice
    form provided.

    You cannot sell IspMailGate or bundle it with a product you
    develop without obtaining written persmission and a "Commercial
    Redistribution License" from us.

    If something goes wrong and you lose data, system uptime, CPU
    cycles, profits or anything else, neither of us is responsible.

  The future of this license

    It might well happen that this program will be distributed under
    the GPL or the Perl Artistic License in a future version. Even
    (Even? No, cut that word. :-) as professional software
    developers we are using and recommending a lot of free software,
    including sendmail, Perl or the MIME::Entity modules which are
    the base of this product. We beg to understand, that we first
    would like to be payed for the time we have put into
    IspMailGate. We'll see what happens.

SEE ALSO
    the Mail::IspMailGate::Filter(3) manpage, the
    Mail::IspMailGate::Packer(3) manpage, the
    Mail::IspMailGate::VirScan(3) manpage, the
    Mail::IspMailGate::PGP(3) manpage and the MIME::Entity(3)
    manpage