
The exiscan scanner patch for exim 4 
------------------------------------------------------------------------------
by Tom Kistner <tom@duncanthrax.net>
http://duncanthrax.net/exiscan/



INTRODUCTION & OVERVIEW
------------------------------------------------------------------------------

exiscan is a patch against exim version 4, providing support for content
scanning in email messages received by exim. It works after the sending
client has completed the SMTP data phase and waits for an answer from the
server. Messages containing unwanted content can be rejected at that stage,
so the job of generating a bounce message is the job of the sending host.

exiscan supports 5 different 'scanning' facilities:

  - virus scanning, using an external scanner. Generic support for all
    command line scanners is available. The 'sophie', 'kavdaemon' (v3 or v4),
    'openav', 'clamav' and 'mksd' scanner daemons are supported too.
  - spam scoring with Spamassassin.
  - a MIME "validator" that checks MIME encapsulated messages for
    basic sanity and unpacks them.
  - regular expression scanning.
  - file extension scanning (block vbs/pif/bat/scr/exe/com).

Each of the facilities can be used conditionally per-message. Of course,
each facility can be switched off completely if you do not need it.

For each of the facilities, you can set an "action" that will be taken
when a message is intercepted:

  - reject (the message is rejected, stating a cause)
  - freeze (the message is accepted but frozen)
  - blackhole (the message is accepted and destroyed)
  - redirect (the message is accepted, but the envelope recipient(s)
              will be replaced with a configurable address)
  - pass (the message is accepted, but carries an "X-" header with
          a proper warning)
         
Every facility puts headers with information into the message. End users
can use this information in their MUAs to automatically sort or "treat"
messages accordingly.



INSTALLATION
------------------------------------------------------------------------------

exiscan is distributed as a patch file, to be applied to the exim source
tree with the 'patch' program:

	[tom@foobar exim-4.01]$ patch -p1 < exiscan-4.01-1.patch

This will install all required files inside the source tree.

exiscans version numbers are the same as the corresponding exim version it
must be applied against, plus a postfix with a release number.

Call exim as "exim -bV" to see which version of exim and exiscan you are
running.

Exiscan is generally updated more often than exim itself since it depends
on a lot of third party software. It is therefore a good idea to keep your
configured source tree, to re-patch and quickly recompile when a new exiscan
version is released.

To remove an old version of the patch from the source tree, call the 'patch'
command with the '-R' flag and the old patch file, like

[tom@foobar exim-4.01]$ patch -p1 -R < exiscan-4.01-1.patch

It is no problem to apply the patch to an already configured source tree.
In that case, you MUST delete the build directory and run the command

	[tom@foobar exim-4.01]$ make makefile

on the source tree to re-create the exim makefile.

You can then proceed to compile exim as described in its installation
manual.



CONFIGURATION OVERVIEW
------------------------------------------------------------------------------

exiscan uses the main exim config file. All exiscan entries go into
Section 1 of that file. All of the exiscan options start with "exiscan_".

Here is an "overview" list of all available options. Options that are
"expandable" can contain lookups or other constructs of exim's expansion
language.

Global options: 

                exiscan_condition (expandable)
                exiscan_crypt_salt
                exiscan_timeout
                exiscan_loglevel

De-MIME facility (demime) options:

                exiscan_demime_condition (expandable)
                exiscan_demime_action (expandable) 
                exiscan_demime_rejectmsg (expandable)
                exiscan_demime_pickyness (expandable)

Antivirus facility (av) options:

                exiscan_av_condition (expandable)
                exiscan_av_action (expandable)
                exiscan_av_rejectmsg (expandable)
                exiscan_av_scanner
                exiscan_av_scanner_path
                exiscan_av_scanner_options
                exiscan_av_scanner_regexp_description
                exiscan_av_scanner_regexp_trigger
                exiscan_av_sophie_socket
                exiscan_av_kavdaemon_socket
                exiscan_av_openav_host
                exiscan_av_openav_port
                exiscan_av_clamd_socket
                exiscan_av_mksd_maxproc

Spamassassin facility (spamd) options:

                exiscan_spamd_condition (expandable)
                exiscan_spamd_action (expandable)
                exiscan_spamd_rejectmsg (expandable)
                exiscan_spamd_address
                exiscan_spamd_threshold (expandable)
                exiscan_spamd_header_style (expandable)
                exiscan_spamd_subject_tag (expandable)

Regular expression facility (regex) options:

                exiscan_regex_condition (expandable)
                exiscan_regex_action (expandable)
                exiscan_regex_rejectmsg (expandable)
                exiscan_regex_data (expandable)

File extension facility (extension) options:

                exiscan_extension_condition (expandable)
                exiscan_extension_action (expandable)
                exiscan_extension_rejectmsg (expandable)
                exiscan_extension_data (expandable)


CONFIGURATION OPTIONS EXPLAINED
------------------------------------------------------------------------------

  Global options
  -------------------------------------------------------------------------
  These options apply to all facilities.
  
    exiscan_condition   (string, expandable, mantadory, default unset)
    ------------------------------------------------------------------
    This option is the "master condition" that is evaluated to see if 
    ANY exiscan facility should be used to scan the current message. If
    the condition does not apply, exiscan just skips over the message (no
    facilities are used). When this options is not set, exiscan will
    be disabled. Note: facilities have individual conditions as well.
    
    Example: to make exiscan only work on messages coming in with SMTP or
             ESMTP, use
             
             exiscan_condition = \ 
                ${if or {{eq{$received_protocol}{esmtp}} \
                         {eq{$received_protocol}{smtp}}} \
                            {1}{0} }

    Please read the "Setting Conditions" section below for more information
    on setting conditions.
    
  

    exiscan_crypt_salt   (string, mantadory, default unset)
    -------------------------------------------------------
    exiscan inserts a crypt()ed version of the message ID into the header
    when it has successfully scanned a message. This 'tag' is used to
    determine if the message is 'clean' if it should be re-sent or delayed.
    The exiscan_crypt_salt setting defines a 2-character string to be used
    as a "seed" for the crypt process. You MUST set this option to a
    2-character string, otherwise exiscan will be disabled.
    NOTE: this is NOT a security measure ! It is just to make sure that you
    do not have to trust the exiscan implementations of other people. You
    cannot have real security with automated scanners.

    Example: 
    
             exiscan_crypt_salt = fo

    
    exiscan_timeout   (time, optional, default "15m")
    -------------------------------------------------
    To cope with mishaps in the scanner process, exim uses a timeout on
    the exiscan function call. If exiscan does not return in the given
    timeframe, exim will assume a local problem and temporarily reject
    the message. This timeout tells exim how long it will wait for
    exiscan to return. The default is 900 seconds (15 minutes).
    
    Example: This will set a timeout of 5 minutes
    
             exiscan_timeout = 5m


    exiscan_loglevel  (integer, optional, default "1")
    --------------------------------------------------
    This option defines how much log output exiscan will produce.
    Exiscan uses exims internal logging functions, so it will
    log to the same location as exim. A value of "0" will not
    produce ANY logging output (rejects will still be logged by exim
    itself). The default value of "1" will produce reasonable output
    when a facility scores a "hit". You can set the value to "2" to
    see warnings, mostly from the demime facility.
    
    Example: 
    
             exiscan_loglevel = 2


  De-MIME facility (demime) options
  ---------------------------------------------------------------------
  

    exiscan_demime_condition    (string, expandable, default unset)
    ---------------------------------------------------------------
    If this condition evaluates to "true", exiscan will unpack MIME
    and UUENCODE containers in the message, while doing basic syntax
    checks. This includes check for overlong file names and other known
    MIME "exploits" that target faulty email clients.
    Please see the "exiscan_demime_pickyness" option below for a list
    of checks.
    IMPORTANT: Most modern virus scanners can scan inside MBOX-style
    files. This should make it unneccessary to unpack MIME containers
    for them. Unfortunately, their MIME implementations are not as
    tolerant as the typical Microsoft MUA, making them vulnerable to
    certain exploits.
    It is recommended to set this condition to "1", unless you absolutely
    trust your AV products MIME implementation.
    Note: This facility will automatically be switched on if the condition
    exiscan_extension_condition (see further below) evaluates to true,
    since scanning for MIME filenames requires parsing of the MIME con-
    tainers.

    Example: Unpack MIME containers in all messages
    
             exiscan_demime_condition = 1
             
    
    exiscan_demime_pickyness   (string, expandable, default "1")
    ------------------------------------------------------------
    This option must expand to a numeric value from 0 to 2. It defines
    how "picky" the MIME parser behaves when it finds anomalies in MIME
    containers. Here is how the value is treated:
    
    "0": No MIME error checking. The facility will try a "best effort" to
         unpack files.
         
    "1": Normal MIME error checking (default)
         This will check and trigger on the following:
          - line length exceeds MIME_SANITY_MAX_LINE_LENGTH bytes
          - message/partial content type
          - proposed filename exceeds MIME_SANITY_MAX_FILENAME bytes
          - boundary string length exceeds
            MIME_SANITY_MAX_BOUNDARY_LENGTH bytes
          - wrote more than MIME_SANITY_MAX_DUMP_FILES (number of MIME
            parts) for one message
          - BASE64 line contains characters not in the BASE64 alphabet
    
    "2": Extra MIME error checking (recommended for security aware admins)
         This will check those in addition to the "1" setting:
          - double headers of type Content-type, Content-Disposition,
            Content-Transfer-Encoding
          - uuencode line not a multiple of 4 characters
          - uuencode line is longer or shorter then proposed data length
          - base64 line is longer than MIME_SANITY_MAX_B64_LINE_LENGTH
            (76 by RFC)
          - base64 line is not a multiple of 4 bytes long (usually wrong
            number of padding chars)
          - illegal character in quoted-printable encodings
         
    The constants shown in CAPS in the text above can be found in
    exiscan.h. You can tweak them before compiling, but that is only
    recommended if you know what you are doing.
 
    When one of the activated conditions match a message, the delivery
    outcome is determined by exiscan_demime_action (see below).

    Example: Set extra MIME sanity checking
    
             exiscan_demime_pickyness = 2


    exiscan_demime_action     (string, expandable, default 'reject')
    ----------------------------------------------------------------
    This defines the action exiscan should take when it finds a malformed
    MIME container or other known MIME "exploits" in the message, according
    to the exiscan_demime_pickyness setting.
    Possible values are 'pass','reject','blackhole','freeze' or
    'redirect <address>'. When this option is unset, it defaults to
    'reject'.
    Important: Please read the "Setting Actions" section below for more
    information on actions. 

    Example: Reject broken MIME messages
    
             exiscan_demime_action = reject


    exiscan_demime_rejectmsg    (expandable, see default below)
    -----------------------------------------------------------
    This variable contains a string that will be given as the cause
    for a 5xx error message when this faciliy has its action set to
    "reject". This text serves as a human-digestable "wrapper" for
    exiscan's real reject reason, which is very brief. You should
    include an occurence of "%s" in this string, which will be
    replaced with the brief reason mentioned before. You can use
    "\n" in the string to have multiline error messages.
    It is a good idea to also include a link to your postmaster
    website where you explain your email policy.
    
    The default for this variable is
      "This message contains a broken MIME container (%s)."


  Antivirus facility (av) options
  ---------------------------------------------------------------------
  These options are used by the antivirus facility. You need an
  external virus scanner on your system.
  

    exiscan_av_condition   (string, expandable, default unset)
    ----------------------------------------------------------
    If this condition evaluates to "true", exiscan will call the virus
    scanner facility on that message.
    Please read the "Setting Conditions" section below for more
    information on setting conditions.

    Example: To scan ALL messages, just set this variable to "1"
    
             exiscan_av_condition = 1


    exiscan_av_action   (string, expandable, default 'reject')
    ----------------------------------------------------------
    This defines the action exiscan should take when it finds a virus
    in the message.
    Possible values are 'pass','reject','blackhole','freeze' or
    'redirect <address>'. When this option is unset, it defaults to
    'reject'.
    Important: Please read the "Setting Actions" section below for more
    information on actions. 
    
    Example: redirect messages with viruses to postmaster
    
             exiscan_av_action = redirect postmaster@mydomain.com
        
  
    exiscan_av_rejectmsg    (expandable, see default below)
    -------------------------------------------------------
    This variable contains a string that will be given as the cause
    for a 5xx error message when this faciliy has its action set to
    "reject". This text serves as a human-digestable "wrapper" for
    exiscan's real reject reason, which is very brief. You should
    include an occurence of "%s" in this string, which will be
    replaced with the brief reason mentioned before. You can use
    "\n" in the string to have multiline error messages.
    It is a good idea to also include a link to your postmaster
    website where you explain your email policy.
    
    The default for this variable is
      "This message contains a virus or other harmful content (%s)."


    exiscan_av_scanner   (string, default unset)
    --------------------------------------------
    This option tells exiscan what type of virus scanner to use. It
    can be one of
    
      keyword   | scanner
      -------------------------------------------------------------
      cmdline   | generic command line scanner
      sophie    | sophie AV daemon (http://www.vanja.com/tools/sophie/)
      kavdaemon | Kapersky AVP Daemon 3.x (http://www.kapersky.com)
      openav    | OpenAV scanner daemon (http://www.openantivirus.org)
      clamav    | ClamAV scanner daemon (http://clamav.elektrapro.com)
      mksd      | mks scanner daemon (http://linux.mks.com.pl)
      
    Depending on the scanner type you choose with this option, you
    need to declare one or more further options below.
    
    Example: To use the (generic) cmdline scanner type, use
    
             exiscan_av_scanner = cmdline
    
        
    exiscan_av_scanner_path   (string, default unset)
    -------------------------------------------------
    This option is needed ONLY for the cmdline av scanner type.
    It contains the path to the virus scanner executable
    That means FULL ABSOLUTE PATH AND EXECUTABLE !
    Sorry for the caps but people keep messing this up.
    
    Example: Sophos Sweep in /usr/local/bin
    
             exiscan_av_scanner_path = /usr/local/bin/sweep


    exiscan_av_scanner_options   (string, default unset)
    ----------------------------------------------------
    This option is needed ONLY for the cmdline av scanner type.
    It containts the options to be passed to the scanner on the command
    line.
    ATTENTION: the given string MUST containe ONE pipe ('|') symbol,
    which will be replaced by exiscan with the path to be scanned.
    Normally, the pipe will be at the end of the string, but some
    scanners may also expect it somewhere else.

    Example: this works for Sophos Sweep
    
              exiscan_av_scanner_options = -all -archive -ss |


    exiscan_av_scanner_regexp_trigger   (string, default unset)
    -----------------------------------------------------------
    This option is needed ONLY for the cmdline av scanner type.
    exiscan parses both STDOUT and STDERR output of the scanner, line
    by line. To determine if a virus was found, we use a perl-compatible
    regular expression. In the simplest case, this will simply be a
    string just like the example below which will work with Sophos Sweep.

    Example: this works for Sophos Sweep
    
             exiscan_av_scanner_regexp_trigger = found in
    

    exiscan_av_scanner_regexp_description   (string, default unset)
    ---------------------------------------------------------------
    This option is needed ONLY for the cmdline av scanner type.
    It contains a regular expression to fish the viruses' name out
    of the scanner output.
    IMPORTANT: this expression MUST contain exactly ONE pair of braces,
    matching the substring with the virus info.
    Typically, the braces will contain '.*', to match any number
    of any character inside. To the left and right of the braces, you
    should place other matching criteria, of course !
    
    Example: Sophos Sweep reports a virus on a line like this:

              >>> Virus 'W32/Magistr-B' found in file ./those.bat

             We want to get the W32/Magistr-B string, so we can match
             for the single quotes left and right of it, resulting in
             the regex '(.*)' (WITH the quotes!)

             exiscan_av_scanner_regexp_description = '(.*)'
              
              
    exiscan_av_sophie_socket  (string, default unset)
    -------------------------------------------------
    This option is needed ONLY for the sophie av scanner type.
    Sophie opens a unix socket in your file system. The default is
    /var/run/sophie.
    Please make sure that exim can access that socket (permissions!).
    Also make sure that the user that Sophie runs with (./configure
    option !!) is allowed to read the exim queue directory.
    Sophie drops privileges, so while it may show up as running as root
    in 'ps', it may have set its effective UID to another user !
    Ideally, exims and sophies effective user settings should be the
    same.
                   
    Example:

             exiscan_av_sophie_socket = /var/run/sophie


    exiscan_av_kavdaemon_socket   (string, default unset)
    -----------------------------------------------------
    This option is needed ONLY for the kavdaemon av scanner type.
    kavdaemon opens a unix socket in your file system. The default
    is /opt/AVP/AvpCtl.
    Please make sure that exim can access that socket (permissions!).
    Also make sure that the user that kavdaemon runs with is allowed
    to read the exim queue directory.
    
    Attention: you need to run kavdaemon with the disinfection option
    disabled, and with proper path settings, like this:
     
      ./kavdaemon -E -f=/opt/AVP /

    Note the slash at the end, it is important. /opt/AVP is the
    default AVP base directory.

    Example:
     
             exiscan_av_kavdaemon_socket = /opt/AVP/AvpCtl
      
    
    exiscan_av_openav_host   (string, default unset)
    -----------------------------------------------------
    This option is needed ONLY for the openav av scanner type.
    It must be set to the IP address or hostname your openav
    scanner daemon is operating on.
    You must also set exiscan_av_openav_host along with this
    option.
    
    Example: to use the openav daemon on the local host, use
    
             exiscan_av_openav_host = 127.0.0.1
             
    
    exiscan_av_openav_port   (string, default unset)
    -----------------------------------------------------
    This option is needed ONLY for the openav av scanner type.
    It must be set to the port number your openav scanner daemon
    is operating on. It is usually '8127'.
    You must also set exiscan_av_openav_host along with this
    option.
    
    Example: to use the openav daemon on the port 8127, set
    
             exiscan_av_openav_port = 8127
    
   
    exiscan_av_clamd_socket  (string, default unset)
    -----------------------------------------------------
    This option is needed ONLY for the clamav av scanner type.
    You must set this either to the IP address and port where
    clamd is listening, or to the full path to clamd's UNIX
    socket (starting with a slash), it clamd is running on the
    local machine.
    
    Example: to use the clamav daemon on the local host, use
    
             exiscan_av_clamd_socket = /path/and/name/of/unix/socket
             
             or to use clamd on another server with IP
             192.168.0.2 and port 3310
             
             exiscan_av_clamd_socket = 192.168.0.2 3310
    
    
    exiscan_av_mksd_maxproc   (integer, default 1)
    -----------------------------------------------------
    This option is needed ONLY for the mksd av scanner type.
    It specifies the maximum number of processes used simultaneously
    to scan the attachments, provided that exiscan_demime_condition
    evaluates to "true" and also mks daemon has been run with
    at least the same number of child processes.
    
    Example: on a dual-processor system you might want to set
    
             exiscan_av_mksd_maxproc = 2



Antispam facility (spamd) options
  ---------------------------------------------------------------------
  These options are used by the antispam facility. You need to install
  SpamAssassin on your system. You can get it at
    
    http://www.spamassassin.org
    
  exiscan uses the 'spamd' daemon directly, it needs to run in order for
  this facility to work.
  
  Please read the section on header lines and actions further below to
  learn what you can do with this facility.
  
  
    exiscan_spamd_condition   (string, expandable, default unset)
    -------------------------------------------------------------
    If this condition evaluates to "true", exiscan will call the
    antispam facility on that message.
    Please read the "Setting Conditions" section below for more
    information on setting conditions.

    Example: To scan ALL messages, just set this variable to "1"
    
             exiscan_spamd_condition = 1
  
  
    exiscan_spamd_action   (string, expandable, default unset)
    ----------------------------------------------------------
    This defines the action exiscan should take when a message
    exceeds the defined spam score treshold (see below).
    Possible values are 'pass','reject','blackhole','freeze' or
    'redirect <address>'. When this option is unset, it defaults to
    'pass' (meaning that only a header with spam info is added to
    the message - see section "Header Lines" below).
    Important: Please read the "Setting Actions" section below for more
    information on actions. 
    
    Example: reject messages exceeding the spam score treshold
    
             exiscan_spamd_action = reject
    
    
    exiscan_spamd_rejectmsg    (expandable, see default below)
    ----------------------------------------------------------
    This variable contains a string that will be given as the cause
    for a 5xx error message when this faciliy has its action set to
    "reject". This text serves as a human-digestable "wrapper" for
    exiscan's real reject reason, which is very brief. You should
    include an occurence of "%s" in this string, which will be
    replaced with the brief reason mentioned before. You can use
    "\n" in the string to have multiline error messages.
    It is a good idea to also include a link to your postmaster
    website where you explain your email policy.
    
    The default for this variable is
      "This message scored %s spam points."
    
    
    exiscan_spamd_header_style   (string, expandable, default "single")
    -------------------------------------------------------------------
    This setting defines how much information the spamd facility
    will add to the headers of the message. The following settings
    are available:
    
     none   - This will not add any spam info header to the message.
              When not using exiscan_spamd_treshold, this is quite
              useless.
     single - This will add the X-Spam-Score header (see the HEADERS
              section below)
     flag   - This will add the X-Spam-Score header and, if the
              messages' score is over the treshold, the X-Spam-Flag
              header. (see the HEADERS section below)
     full   - This will add the X-Spam-Score header and, if the
              messages' score is over the treshold, the X-Spam-Flag
              header and the FULL spamassassin report in clear text
              as a multiline header called "X-Spam-Report".
              
    Example:  exiscan_spamd_header_style = full
    

    exiscan_spamd_subject_tag  (string, expandable, default unset)
    --------------------------------------------------------------
    If you want to "tag" the subject of messages which have a spam
    score greater than the exiscan_spamd_treshold, you can set this
    option to a string that will be prepended to the subject.
    This is only useful if exiscan_spamd_action is "pass".
    End-user MUAs can then filter on that string in the subject.
    
    Example: if you set
    
             exiscan_spamd_subject_tag = *SPAM*
             
             the subject "URGENT BUSINESS PROPOSAL" will be
             changed into "*SPAM* URGENT BUSINESS PROPOSAL".
    
    
    exiscan_spamd_threshold   (string, expandable, default 999)
    -----------------------------------------------------------
    This defines the number of "spam score" points a message must
    exceed to be classified as "spam" by exiscan. The default value
    is very high, so if you only want to add headers to messages,
    you do not need to set this option. Sensible value ranges
    are 4-20. The lower you set this value, the more spam you may
    catch, however the possibility of false positives is also higher.
    You can use float values, like "4.3", but the value must be
    greater than zero. Negative values are not allowed.
    For historic reasons, the misspelling "exiscan_spamd_treshold"
    is also allowed.
    
    Example: set spam score treshold to 6 points
    
             exiscan_spamd_treshold = 6
    
    
    exiscan_spamd_address   (string, default unset)
    -----------------------------------------------
    This contains the IP address and port where the spamd is listening,
    separated by a whitespace. By default, it resides on localhost port
    783. You can also run it on another machine to decrease the load on
    the mail server. Uncommenting this option turns off the antispam
    facility.
    
    Example: spamd running on localhost with default port
    
             exiscan_spamd_address = 127.0.0.1 783



  Regular expression scanning facility (regex) options
  ---------------------------------------------------------------------
  This facility can be used to scan a message for a set of regular
  expressions. The scanning will be done line-by-line on the complete
  message, including all headers, except for exiscan's own X- header.
  
  This facility is handy for blocking content that cannot yet be caught
  by your AV scanner, or to crack down on spam (try 'mortgage' :).
  
  To prevent double bounces, this facility will not scan bounce messages
  (messages with an empty envelope sender)
  
    exiscan_regex_condition   (string, expandable, default unset)
    -------------------------------------------------------------
    If this condition evaluates to "true", exiscan will call the
    regex facility on that message.
    Please read the "Setting Conditions" section below for more
    information on setting conditions.

    Example: To regex scan ALL messages, just set this variable to "1"
    
             exiscan_regex_condition = 1
  
  
    exiscan_regex_action   (string, expandable, default 'reject')
    -------------------------------------------------------------
    This defines the action exiscan should take when a message
    matches a defined regular expression.
    Possible values are 'pass','reject','blackhole','freeze' or
    'redirect <address>'. When this option is unset, it defaults to
    'reject'.
    Important: Please read the "Setting Actions" section below for more
    information on actions. 
    
    Example: blackhole messages matching a regular expression
    
             exiscan_regex_action = blackhole
    
    
    exiscan_regex_rejectmsg    (expandable, see default below)
    ----------------------------------------------------------
    This variable contains a string that will be given as the cause
    for a 5xx error message when this faciliy has its action set to
    "reject". This text serves as a human-digestable "wrapper" for
    exiscan's real reject reason, which is very brief. You should
    include an occurence of "%s" in this string, which will be
    replaced with the brief reason mentioned before. You can use
    "\n" in the string to have multiline error messages.
    It is a good idea to also include a link to your postmaster
    website where you explain your email policy.
    
    The default for this variable is
      "This message matches a blacklisted regular expression (%s)."
    
    
    exiscan_regex_data   (string, expandable, default unset)
    --------------------------------------------------------
    This option contains the regular expressions you wish to match
    against messages, as a colon-separated list.
    To put a colon inside a regular expression, you need to double
    it (::).
    
    Example: Match 'mortgate' with case-insensitive 'm' and
             'make money'
    
             exiscan_regex_data = [Mm]ortage : make money
             
    
    
  File extension scanning facility (extension) options
  --------------------------------------------------------------------
  This facility can be used to block mails containing files with
  specific extensions, mostly those that may cause harm on the Windows
  platform (vbs,pif,bat,exe,com etc.).
  
  To prevent double bounces, this facility will not scan bounce messages
  (messages with an empty envelope sender)
  
    exiscan_extension_condition   (string, expandable, default unset)
    -----------------------------------------------------------------
    If this condition evaluates to "true", exiscan will call the
    extension facility on that message.
    Please read the "Setting Conditions" section below for more
    information on setting conditions.

    Example: To regex scan ALL messages, just set this variable to "1"
    
             exiscan_extension_condition = 1
  
  
    exiscan_extension_action   (string, expandable, default 'reject')
    -----------------------------------------------------------------
    This defines the action exiscan should take when a message
    contains one of the defined file types.
    Possible values are 'pass','reject','blackhole','freeze' or
    'redirect <address>'. When this option is unset, it defaults to
    'reject'.
    Important: Please read the "Setting Actions" section below for more
    information on actions. 
    
    Example: freeze messages containing an unwanted file type
    
             exiscan_extension_action = freeze
    
    
    exiscan_extension_rejectmsg    (expandable, see default below)
    --------------------------------------------------------------
    This variable contains a string that will be given as the cause
    for a 5xx error message when this faciliy has its action set to
    "reject". This text serves as a human-digestable "wrapper" for
    exiscan's real reject reason, which is very brief. You should
    include an occurence of "%s" in this string, which will be
    replaced with the brief reason mentioned before. You can use
    "\n" in the string to have multiline error messages.
    It is a good idea to also include a link to your postmaster
    website where you explain your email policy.
    
    The default for this variable is
      "This message contains a file with a blacklisted extension (%s)."
      
    
    exiscan_extension_data   (string, expandable, default unset)
    ------------------------------------------------------------
    This option contains the file extension for which you would like
    to scan messages, as a colon-separated list.
    
    Example: Match 'exe', 'com', and 'vbs'
    
             exiscan_extension_data = exe:com:vbs
    


SETTING CONDITIONS
------------------------------------------------------------------------------

exiscan has six 'condition' options (see above): one 'master' condition and
one per facility. Each of these conditions is a string that may contain
'expandable' components. Read chapter 11 of the exim 4 spec to learn more
about string expansion in exim. Please note that not all of exim's expansion
variables are filled in at exiscan's operation point. Exiscan itself makes
sure you can use the $recipient variable, which contains a list of all
envelope recipient addresses, separated by comma and space, and $received_for,
which contains only a single recipient address, and is only set if the message
has exactly one envelope recipient.

A condition is 'false' when it

  - is unset
  - expands to 0 (string or number)
  
All other values result in a 'true' condition.

The master condition (option exiscan_condition) decides if exiscan is run
on a message. You should use it to skip messages that do not need to be
scanned. Typically, you will only want to scan messages that come in via
smtp or esmtp:

  exiscan_condition = \ 
                ${if or {{eq{$received_protocol}{esmtp}} \
                         {eq{$received_protocol}{smtp}}} \
                            {1}{0} }
                            
This will skip scanning messages coming from local sources or from authen-
ticated senders (asmtp).

Each facility has its own condition to decide if it should be applied to
a message (exiscan-<facility>-condition). For example, you can use those
with file lookups to use a facility only on specific sender or recipient
domains. The excercise is left up to the reader :)

To make a condition always true, just set it to '1'.



SETTING ACTIONS
------------------------------------------------------------------------------

Every facility in exiscan that 'matches' a message (found a virus, spam over
treshold, found regex/extension) can trigger a configurable action. Each
facility has an "action" option (exiscan_<facility>_action) where you can set
the action identifier for that facility.

The following actions are available:

  - reject    The message is rejected with a permanent error (5xx), stating
              the cause including information for the sender of the message.
  
  - freeze    The message is accepted and immediately frozen, with the cause
              saved in the header file. The postmaster can then review the
              frozen messages and eventually thaw or delete them.
              (NB: does someone want to write a web frontend for that task ?
              Submissions welcome ;)
              IMPORTANT: If you use an automatic unfreeze timer in your exim
              config, exim will automatically thaw these messages after the
              specified time, resulting in delivery !
              It might also be a good idea to use exim's 'move_frozen_messages'
              option in conjunction with this action.
              
  - blackhole The message is accepted and then destroyed by removing all reci-
              pients. I do not recommended to use this action unless you have
              a good cause to do so.
              
  - redirect <newaddress>  The messages' envelope recipients are replaced by
                           an address stated behind the 'redirect' parameter.
                           Example:
                           
                             exiscan_spamd_action = redirect the@new.address
                          
                           Since the original envelope addresses are destroyed
                           by that action, you must rely on the headers to
                           figure out the intended original recipients.
                           
  - pass      No action is taken on the message, except that the facility
              will add it's X- header line to the message. This is especially
              useful for the spamd facility, if you only want to "mark" spam.
              See the "added headers" section below to learn what headers
              exiscan adds to messages.
              
The facilities are called in the following order:

  1 - demime
  2 - av
  3 - extension
  4 - regex
  5 - spamd
  
When a facility "matches" a message, processing is stopped and the proper return
code is passed to exim, except if the action for this facility is set to "pass".
The "spamd" facility is called last, since it takes the most processing time. The
"av" facility is called first, since both "extension" and "regex" may block the
same message too, only without giving valuable information.



ADDED HEADERS
------------------------------------------------------------------------------

exiscan can add the following headers to a message when it is processed:

 - X-Scanner       This header is always added when exiscan_condition was
                   true, no matter if any facilities were run. It contains
                   an "ad" banner and a tag that exiscan can use to determine
                   if it has already scanned a message.


 - X-Infected      This header is added by the antivirus facility. It states
                   the name of the virus found.

               
 - X-Spam-Score    This header is added by the antispam facility and looks
                   like this:

                   X-Spam-Score: <num> (<bar>)

                   Where <num> is a floating point number which may be null,
                   positive or negative. The higher this number, the higher
                   is the possibility of that message being spam. The <bar>
                   is a textual representation of the number, consisting of
                   a number of '+' signs for a positive score, and '-' signs
                   for negative scores. 
                   For example, a message with a score of 6.5 will have a
                   header like this:
                   
                   X-Spam-Score: 6.5 (++++++)

                   The <bar> makes it easier to have filters in MUAs and
                   processors like procmail, since you can just say "anything
                   with six plus signs goes to the Trash folder". Such a
                   filter will then match on six OR MORE "spam points".

 - X-Spam-Flag     This header is only added when a messages' spam score is
                   over the treshold, and the appropriate
                   exiscan_spamd_header_style option is set. It will always
                   have the value YES:
                   
                   X-Spam-Flag: YES
                   
                   This header is a "de-facto" standard for spam flagging
                   nowadays.

 - X-Spam-Report   This is a multiline header, containing the full human-readable
                   report from SpamAssassin. It is only added if
                   exiscan_spamd_header_style is set to "full".


 - X-Contains-File This header is added by the file extension scanning faci-
                   lity. It contains the extension of the file included in
                   the message. 


 - X-Regex-Match   This header is added by the regular expression matching
                   facility. It contains the regular expression that a line
                   of the email has matched.
                   
 - X-Broken-MIME   This header is added by the "demime" facility, and is set
                   when the message contains a broken MIME container. The con-
                   tent of the header is a cause.


When a header is added to a message, exiscan will remove already existing
headers of the same type.




CREDITS
------------------------------------------------------------------------------

Philip Hazel for exim

For Patches, suggestions and help:
Andreas Piesk <a.piesk@gmx.net>
Nico Erfurth <masta@perlgolf.de>


Thanks a lot !



CONTACT
------------------------------------------------------------------------------

Tom Kistner
<tom@duncanthrax.net>
ICQ 1501527
dcanthrax@efnet
