Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a4080654d049ad31b216b761b9173c1f > files > 145

exim-doc-4.69-4mdv2010.0.i586.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
<html>
<!-- Created on September, 10 2009 by texi2html 1.78 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
            Karl Berry  <karl@freefriends.org>
            Olaf Bachmann <obachman@mathematik.uni-kl.de>
            and many others.
Maintained by: Many creative people.
Send bugs and suggestions to <texi2html-bug@nongnu.org>

-->
<head>
<title>Specification of the Exim Mail Transfer Agent: 41. Content scanning at ACL time</title>

<meta name="description" content="Specification of the Exim Mail Transfer Agent: 41. Content scanning at ACL time">
<meta name="keywords" content="Specification of the Exim Mail Transfer Agent: 41. Content scanning at ACL time">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="texi2html 1.78">
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
pre.display {font-family: serif}
pre.format {font-family: serif}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: serif; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: serif; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.roman {font-family:serif; font-weight:normal;}
span.sansserif {font-family:sans-serif; font-weight:normal;}
ul.toc {list-style: none}
-->
</style>


</head>

<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">

<a name="Content-scanning-at-ACL-time"></a>
<a name="SEC358"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="spec_40.html#SEC357" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC359" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec_40.html#SEC308" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h1 class="chapter"> 41. Content scanning at ACL time </h1>

<p>The extension of Exim to include content scanning at ACL time, formerly known
as &quot;exiscan&quot;, was originally implemented as a patch by Tom Kistner. The code
was integrated into the main source for Exim release 4.50, and Tom continues to
maintain it. Most of the wording of this chapter is taken from Tom's
specification.
</p>
<p>It is also possible to scan the content of messages at other times. The
<code>local_scan()</code> function (see chapter <a href="spec_42.html#SEC365">Adding a local scan function to Exim</a>) allows for content
scanning after all the ACLs have run. A transport filter can be used to scan
messages at delivery time (see the <code>transport_filter</code> option, described in
chapter <a href="spec_24.html#SEC220">Generic options for transports</a>).
</p>
<p>If you want to include the ACL-time content-scanning features when you compile
Exim, you need to arrange for WITH_CONTENT_SCAN to be defined in your
&lsquo;<tt>Local/Makefile</tt>&rsquo;. When you do that, the Exim binary is built with:
</p>
<ul class="toc">
<li>
Two additional ACLs (<code>acl_smtp_mime</code> and <code>acl_not_smtp_mime</code>) that are run
for all MIME parts for SMTP and non-SMTP messages, respectively.

</li><li>
Additional ACL conditions and modifiers: <code>decode</code>, <code>malware</code>,
<code>mime_regex</code>, <code>regex</code>, and <code>spam</code>. These can be used in the ACL that is
run at the end of message reception (the <code>acl_smtp_data</code> ACL).

</li><li>
An additional control feature (&quot;no_mbox_unspool&quot;) that saves spooled copies
of messages, or parts of messages, for debugging purposes.

</li><li>
Additional expansion variables that are set in the new ACL and by the new
conditions.

</li><li>
Two new main configuration options: <code>av_scanner</code> and <code>spamd_address</code>.
</li></ul>

<p>There is another content-scanning configuration option for &lsquo;<tt>Local/Makefile</tt>&rsquo;,
called WITH_OLD_DEMIME. If this is set, the old, deprecated <code>demime</code> ACL
condition is compiled, in addition to all the other content-scanning features.
</p>
<p>Content-scanning is continually evolving, and new features are still being
added. While such features are still unstable and liable to incompatible
changes, they are made available in Exim by setting options whose names begin
EXPERIMENTAL_ in &lsquo;<tt>Local/Makefile</tt>&rsquo;. Such features are not documented in
this manual. You can find out about them by reading the file called
&lsquo;<tt>doc/experimental.txt</tt>&rsquo;.
</p>
<p>All the content-scanning facilities work on a MBOX copy of the message that is
temporarily created in a file called:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">&lt;spool_directory&gt;/scan/&lt;message_id&gt;/&lt;message_id&gt;.eml
</pre></td></tr></table>

<p>The &lsquo;<tt>.eml</tt>&rsquo; extension is a friendly hint to virus scanners that they can
expect an MBOX-like structure inside that file. The file is created when the
first content scanning facility is called. Subsequent calls to content
scanning conditions open the same file again. The directory is recursively
removed when the <code>acl_smtp_data</code> ACL has finished running, unless
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">control = no_mbox_unspool
</pre></td></tr></table>

<p>has been encountered. When the MIME ACL decodes files, they are put into the
same directory by default.
</p>
<table class="menu" border="0" cellspacing="0">
<tr><td align="left" valign="top"><a href="#SEC359">41.1 Scanning for viruses</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC360">41.2 Scanning with SpamAssassin</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC361">41.3 Calling SpamAssassin from an Exim ACL</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC362">41.4 Scanning MIME parts</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC363">41.5 Scanning with regular expressions</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC364">41.6 The demime condition</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
</table>

<hr size="6">
<a name="Scanning-for-viruses"></a>
<a name="SEC359"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC358" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC360" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.1 Scanning for viruses </h2>

<p>The <code>malware</code> ACL condition lets you connect virus scanner software to Exim.
It supports a &quot;generic&quot; interface to scanners called via the shell, and
specialized interfaces for &quot;daemon&quot; type virus scanners, which are resident
in memory and thus are much faster.
</p>
<a name="IDX2657"></a>
<p>You can set the <code>av_scanner</code> option in first part of the Exim configuration
file to specify which scanner to use, together with any additional options that
are needed. The basic syntax is as follows:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">av_scanner = &lt;scanner-type&gt;:&lt;option1&gt;:&lt;option2&gt;:[...]
</pre></td></tr></table>

<p>If you do not set <code>av_scanner</code>, it defaults to
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = sophie:/var/run/sophie
</pre></td></tr></table>

<p>If the value of <code>av_scanner</code> starts with dollar character, it is expanded
before use. The following scanner types are supported in this release:
</p>
<dl compact="compact">
<dt> <code>aveserver</code></dt>
<dd><a name="IDX2658"></a>
<p>This is the scanner daemon of Kaspersky Version 5. You can get a trial version
at <strong><a href="http://www.kaspersky.com">http://www.kaspersky.com</a></strong>. This scanner type takes one option,
which is the path to the daemon's UNIX socket. The default is shown in this
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = aveserver:/var/run/aveserver
</pre></td></tr></table>

</dd>
<dt> <code>clamd</code></dt>
<dd><a name="IDX2659"></a>
<p>This daemon-type scanner is GPL and free. You can get it at
<strong><a href="http://www.clamav.net/">http://www.clamav.net/</a></strong>. Some older versions of clamd do not seem to
unpack MIME containers, so it used to be recommended to unpack MIME attachments
in the MIME ACL. This no longer believed to be necessary. One option is
required: either the path and name of a UNIX socket file, or a hostname or IP
number, and a port, separated by space, as in the second of these examples:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = clamd:/opt/clamd/socket
av_scanner = clamd:192.168.2.100 1234
</pre></td></tr></table>

<p>If the option is unset, the default is &lsquo;<tt>/tmp/clamd</tt>&rsquo;. Thanks to David Saez for
contributing the code for this scanner.
</p>
</dd>
<dt> <code>cmdline</code></dt>
<dd><a name="IDX2660"></a>
<p>This is the keyword for the generic command line scanner interface. It can be
used to attach virus scanners that are invoked from the shell. This scanner
type takes 3 mandatory options:
</p>
<ol>
<li>
The full path and name of the scanner binary, with all command line options,
and a placeholder (&lsquo;<samp>%s</samp>&rsquo;) for the directory to scan.

</li><li>
A regular expression to match against the STDOUT and STDERR output of the
virus scanner. If the expression matches, a virus was found. You must make
absolutely sure that this expression matches on &quot;virus found&quot;. This is called
the &quot;trigger&quot; expression.

</li><li>
Another regular expression, containing exactly one pair of parentheses, to
match the name of the virus found in the scanners output. This is called the
&quot;name&quot; expression.
</li></ol>

<p>For example, Sophos Sweep reports a virus on a line like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">Virus 'W32/Magistr-B' found in file ./those.bat
</pre></td></tr></table>

<p>For the trigger expression, we can match the phrase &quot;found in file&quot;. For the
name expression, we want to extract the W32/Magistr-B string, so we can match
for the single quotes left and right of it. Altogether, this makes the
configuration setting:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = cmdline:\
             /path/to/sweep -ss -all -rec -archive %s:\
             found in file:'(.+)'
</pre></td></tr></table>

</dd>
<dt> <code>drweb</code></dt>
<dd><a name="IDX2661"></a>
<p>The DrWeb daemon scanner (<strong><a href="http://www.sald.com/">http://www.sald.com/</a></strong>) interface takes one
argument, either a full path to a UNIX socket, or an IP address and port
separated by white space, as in these examples:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = drweb:/var/run/drwebd.sock
av_scanner = drweb:192.168.2.20 31337
</pre></td></tr></table>

<p>If you omit the argument, the default path &lsquo;<tt>/usr/local/drweb/run/drwebd.sock</tt>&rsquo;
is used. Thanks to Alex Miller for contributing the code for this scanner.
</p>
</dd>
<dt> <code>fsecure</code></dt>
<dd><a name="IDX2662"></a>
<p>The F-Secure daemon scanner (<strong><a href="http://www.f-secure.com">http://www.f-secure.com</a></strong>) takes one
argument which is the path to a UNIX socket. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = fsecure:/path/to/.fsav
</pre></td></tr></table>

<p>If no argument is given, the default is &lsquo;<tt>/var/run/.fsav</tt>&rsquo;. Thanks to Johan
Thelmen for contributing the code for this scanner.
</p>
</dd>
<dt> <code>kavdaemon</code></dt>
<dd><a name="IDX2663"></a>
<p>This is the scanner daemon of Kaspersky Version 4. This version of the
Kaspersky scanner is outdated. Please upgrade (see <code>aveserver</code> above). This
scanner type takes one option, which is the path to the daemon's UNIX socket.
For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = kavdaemon:/opt/AVP/AvpCtl
</pre></td></tr></table>

<p>The default path is &lsquo;<tt>/var/run/AvpCtl</tt>&rsquo;.
</p>
</dd>
<dt> <code>mksd</code></dt>
<dd><a name="IDX2664"></a>
<p>This is a daemon type scanner that is aimed mainly at Polish users, though some
parts of documentation are now available in English. You can get it at
<strong><a href="http://linux.mks.com.pl/">http://linux.mks.com.pl/</a></strong>. The only option for this scanner type is
the maximum number of processes used simultaneously to scan the attachments,
provided that the demime facility is employed and also provided that mksd has
been run with at least the same number of child processes. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = mksd:2
</pre></td></tr></table>

<p>You can safely omit this option (the default value is 1).
</p>
</dd>
<dt> <code>sophie</code></dt>
<dd><a name="IDX2665"></a>
<p>Sophie is a daemon that uses Sophos' <code>libsavi</code> library to scan for viruses.
You can get Sophie at <strong><a href="http://www.clanfield.info/sophie/">http://www.clanfield.info/sophie/</a></strong>. The only option
for this scanner type is the path to the UNIX socket that Sophie uses for
client communication. For example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = sophie:/tmp/sophie
</pre></td></tr></table>

<p>The default path is &lsquo;<tt>/var/run/sophie</tt>&rsquo;, so if you are using this, you can omit
the option.
</p></dd>
</dl>

<p>When <code>av_scanner</code> is correctly set, you can use the <code>malware</code> condition in
the DATA ACL. <strong>Note</strong>: You cannot use the <code>malware</code> condition in the MIME
ACL.
</p>
<p>The <code>av_scanner</code> option is expanded each time <code>malware</code> is called. This
makes it possible to use different scanners. See further below for an example.
The <code>malware</code> condition caches its results, so when you use it multiple times
for the same message, the actual scanning process is only carried out once.
However, using expandable items in <code>av_scanner</code> disables this caching, in
which case each use of the <code>malware</code> condition causes a new scan of the
message.
</p>
<p>The <code>malware</code> condition takes a right-hand argument that is expanded before
use. It can then be one of
</p>
<ul class="toc">
<li>
&quot;true&quot;, &quot;*&quot;, or &quot;1&quot;, in which case the message is scanned for viruses.
The condition succeeds if a virus was found, and fail otherwise. This is the
recommended usage.

</li><li>
&quot;false&quot; or &quot;0&quot; or an empty string, in which case no scanning is done and
the condition fails immediately.

</li><li>
A regular expression, in which case the message is scanned for viruses. The
condition succeeds if a virus is found and its name matches the regular
expression. This allows you to take special actions on certain types of virus.
</li></ul>

<p>You can append &lsquo;<samp>/defer_ok</samp>&rsquo; to the <code>malware</code> condition to accept messages
even if there is a problem with the virus scanner. Otherwise, such a problem
causes the ACL to defer.
</p>
<a name="IDX2666"></a>
<p>When a virus is found, the condition sets up an expansion variable called
<code>$malware_name</code> that contains the name of the virus. You can use it in a
<code>message</code> modifier that specifies the error returned to the sender, and/or in
logging data.
</p>
<p>If your virus scanner cannot unpack MIME and TNEF containers itself, you should
use the <code>demime</code> condition (see section <a href="#SEC364">The demime condition</a>) before the
<code>malware</code> condition.
</p>
<p>Here is a very simple scanning example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message contains malware ($malware_name)
     demime = *
     malware = *
</pre></td></tr></table>

<p>The next example accepts messages when there is a problem with the scanner:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message contains malware ($malware_name)
     demime = *
     malware = */defer_ok
</pre></td></tr></table>

<p>The next example shows how to use an ACL variable to scan with both sophie and
aveserver. It assumes you have set:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">av_scanner = $acl_m0
</pre></td></tr></table>

<p>in the main Exim configuration.
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message contains malware ($malware_name)
     set acl_m0 = sophie
     malware = *

deny message = This message contains malware ($malware_name)
     set acl_m0 = aveserver
     malware = *
</pre></td></tr></table>

<hr size="6">
<a name="Scanning-with-SpamAssassin"></a>
<a name="SEC360"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC359" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC361" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.2 Scanning with SpamAssassin </h2>

<p>The <code>spam</code> ACL condition calls SpamAssassin's <code>spamd</code> daemon to get a spam
score and a report for the message. You can get SpamAssassin at
<strong><a href="http://www.spamassassin.org">http://www.spamassassin.org</a></strong>, or, if you have a working Perl
installation, you can use CPAN by running:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">perl -MCPAN -e 'install Mail::SpamAssassin'
</pre></td></tr></table>

<p>SpamAssassin has its own set of configuration files. Please review its
documentation to see how you can tweak it. The default installation should work
nicely, however.
</p>
<a name="IDX2667"></a>
<p>After having installed and configured SpamAssassin, start the <code>spamd</code> daemon.
By default, it listens on 127.0.0.1, TCP port 783. If you use another host or
port for <code>spamd</code>, you must set the <code>spamd_address</code> option in the global
part of the Exim configuration as follows (example):
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">spamd_address = 192.168.99.45 387
</pre></td></tr></table>

<p>You do not need to set this option if you use the default. As of version 2.60,
<code>spamd</code> also supports communication over UNIX sockets. If you want to use
these, supply <code>spamd_address</code> with an absolute file name instead of a
address/port pair:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">spamd_address = /var/run/spamd_socket
</pre></td></tr></table>

<p>You can have multiple <code>spamd</code> servers to improve scalability. These can
reside on other hardware reachable over the network. To specify multiple
<code>spamd</code> servers, put multiple address/port pairs in the <code>spamd_address</code>
option, separated with colons:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">spamd_address = 192.168.2.10 783 : \
                192.168.2.11 783 : \
                192.168.2.12 783
</pre></td></tr></table>

<p>Up to 32 <code>spamd</code> servers are supported. The servers are queried in a random
fashion. When a server fails to respond to the connection attempt, all other
servers are tried until one succeeds. If no server responds, the <code>spam</code>
condition defers.
</p>
<p><strong>Warning</strong>: It is not possible to use the UNIX socket connection method with
multiple <code>spamd</code> servers.
</p>
<hr size="6">
<a name="Calling-SpamAssassin-from-an-Exim-ACL"></a>
<a name="SEC361"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC360" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC362" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.3 Calling SpamAssassin from an Exim ACL </h2>

<p>Here is a simple example of the use of the <code>spam</code> condition in a DATA ACL:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message was classified as SPAM
     spam = joe
</pre></td></tr></table>

<p>The right-hand side of the <code>spam</code> condition specifies a name. This is
relevant if you have set up multiple SpamAssassin profiles. If you do not want
to scan using a specific profile, but rather use the SpamAssassin system-wide
default profile, you can scan for an unknown name, or simply use &quot;nobody&quot;.
However, you must put something on the right-hand side.
</p>
<p>The name allows you to use per-domain or per-user antispam profiles in
principle, but this is not straightforward in practice, because a message may
have multiple recipients, not necessarily all in the same domain. Because the
<code>spam</code> condition has to be called from a DATA ACL in order to be able to
read the contents of the message, the variables <code>$local_part</code> and <code>$domain</code>
are not set.
</p>
<p>The right-hand side of the <code>spam</code> condition is expanded before being used, so
you can put lookups or conditions there. When the right-hand side evaluates to
&quot;0&quot; or &quot;false&quot;, no scanning is done and the condition fails immediately.
</p>
<p>Scanning with SpamAssassin uses a lot of resources. If you scan every message,
large ones may cause significant performance degradation. As most spam messages
are quite small, it is recommended that you do not scan the big ones. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message was classified as SPAM
     condition = ${if &lt; {$message_size}{10K}}
     spam = nobody
</pre></td></tr></table>

<p>The <code>spam</code> condition returns true if the threshold specified in the user's
SpamAssassin profile has been matched or exceeded. If you want to use the
<code>spam</code> condition for its side effects (see the variables below), you can make
it always return &quot;true&quot; by appending &lsquo;<samp>:true</samp>&rsquo; to the username.
</p>
<a name="IDX2668"></a>
<p>When the <code>spam</code> condition is run, it sets up a number of expansion
variables. With the exception of <code>$spam_score_int</code>, these are usable only
within ACLs; their values are not retained with the message and so cannot be
used at delivery time.
</p>
<dl compact="compact">
<dt> <code>$spam_score</code></dt>
<dd><p>The spam score of the message, for example &quot;3.4&quot; or &quot;30.5&quot;. This is useful
for inclusion in log or reject messages.
</p>
</dd>
<dt> <code>$spam_score_int</code></dt>
<dd><p>The spam score of the message, multiplied by ten, as an integer value. For
example &quot;34&quot; or &quot;305&quot;. This is useful for numeric comparisons in
conditions. This variable is special; its value is saved with the message, and
written to Exim's spool file. This means that it can be used during the whole
life of the message on your Exim system, in particular, in routers or
transports during the later delivery phase.
</p>
</dd>
<dt> <code>$spam_bar</code></dt>
<dd><p>A string consisting of a number of &quot;+&quot; or &quot;-&quot; characters, representing the
integer part of the spam score value. A spam score of 4.4 would have a
<code>$spam_bar</code> value of &quot;++++&quot;. This is useful for inclusion in warning
headers, since MUAs can match on such strings.
</p>
</dd>
<dt> <code>$spam_report</code></dt>
<dd><p>A multiline text table, containing the full SpamAssassin report for the
message. Useful for inclusion in headers or reject messages.
</p></dd>
</dl>

<p>The <code>spam</code> condition caches its results. If you call it again with the same
user name, it does not scan again, but rather returns the same values as
before.
</p>
<p>The <code>spam</code> condition returns DEFER if there is any error while running the
message through SpamAssassin. If you want to treat DEFER as FAIL (to pass on to
the next ACL statement block), append &lsquo;<samp>/defer_ok</samp>&rsquo; to the right-hand side of
the spam condition, like this:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = This message was classified as SPAM
     spam    = joe/defer_ok
</pre></td></tr></table>

<p>This causes messages to be accepted even if there is a problem with <code>spamd</code>.
</p>
<p>Here is a longer, commented example of the use of the <code>spam</code>
condition:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example"># put headers in all messages (no matter if spam or not)
warn  spam = nobody:true
      add_header = X-Spam-Score: $spam_score ($spam_bar)
      add_header = X-Spam-Report: $spam_report

# add second subject line with *SPAM* marker when message
# is over threshold
warn  spam = nobody
      add_header = Subject: *SPAM* $h_Subject:

# reject spam at high scores (&gt; 12)
deny  message = This message scored $spam_score spam points.
      spam = nobody:true
      condition = ${if &gt;{$spam_score_int}{120}{1}{0}}
</pre></td></tr></table>

<hr size="6">
<a name="Scanning-MIME-parts"></a>
<a name="SEC362"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC361" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC363" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.4 Scanning MIME parts </h2>

<p>The <code>acl_smtp_mime</code> global option specifies an ACL that is called once for
each MIME part of an SMTP message, including multipart types, in the sequence
of their position in the message. Similarly, the <code>acl_not_smtp_mime</code> option
specifies an ACL that is used for the MIME parts of non-SMTP messages. These
options may both refer to the same ACL if you want the same processing in both
cases.
</p>
<p>These ACLs are called (possibly many times) just before the <code>acl_smtp_data</code>
ACL in the case of an SMTP message, or just before the <code>acl_not_smtp</code> ACL in
the case of a non-SMTP message. However, a MIME ACL is called only if the
message contains a <em>Content-Type:</em> header line. When a call to a MIME
ACL does not yield &quot;accept&quot;, ACL processing is aborted and the appropriate
result code is sent to the client. In the case of an SMTP message, the
<code>acl_smtp_data</code> ACL is not called when this happens.
</p>
<p>You cannot use the <code>malware</code> or <code>spam</code> conditions in a MIME ACL; these can
only be used in the DATA or non-SMTP ACLs. However, you can use the <code>regex</code>
condition to match against the raw MIME part. You can also use the
<code>mime_regex</code> condition to match against the decoded MIME part (see section
<a href="#SEC363">Scanning with regular expressions</a>).
</p>
<p>At the start of a MIME ACL, a number of variables are set from the header
information for the relevant MIME part. These are described below. The contents
of the MIME part are not by default decoded into a disk file except for MIME
parts whose content-type is &quot;message/rfc822&quot;. If you want to decode a MIME
part into a disk file, you can use the <code>decode</code> condition. The general
syntax is:
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">decode = [/&lt;path&gt;/]&lt;filename&gt;
</pre></td></tr></table>

<p>The right hand side is expanded before use. After expansion,
the value can be:
</p>
<ol>
<li>
&quot;0&quot; or &quot;false&quot;, in which case no decoding is done.

</li><li>
The string &quot;default&quot;. In that case, the file is put in the temporary
&quot;default&quot; directory &lt;<em>spool_directory</em>&gt;&lsquo;<tt>/scan/</tt>&rsquo;&lt;<em>message_id</em>&gt;&lsquo;<tt>/</tt>&rsquo; with
a sequential file name consisting of the message id and a sequence number. The
full path and name is available in <code>$mime_decoded_filename</code> after decoding.

</li><li>
A full path name starting with a slash. If the full name is an existing
directory, it is used as a replacement for the default directory. The filename
is then sequentially assigned. If the path does not exist, it is used as
the full path and file name.

</li><li>
If the string does not start with a slash, it is used as the
filename, and the default path is then used.
</li></ol>

<p>The <code>decode</code> condition normally succeeds. It is only false for syntax
errors or unusual circumstances such as memory shortages. You can easily decode
a file with its original, proposed filename using
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">decode = $mime_filename
</pre></td></tr></table>

<p>However, you should keep in mind that <code>$mime_filename</code> might contain
anything. If you place files outside of the default path, they are not
automatically unlinked.
</p>
<p>For RFC822 attachments (these are messages attached to messages, with a
content-type of &quot;message/rfc822&quot;), the ACL is called again in the same manner
as for the primary message, only that the <code>$mime_is_rfc822</code> expansion
variable is set (see below). Attached messages are always decoded to disk
before being checked, and the files are unlinked once the check is done.
</p>
<p>The MIME ACL supports the <code>regex</code> and <code>mime_regex</code> conditions. These can be
used to match regular expressions against raw and decoded MIME parts,
respectively. They are described in section <a href="#SEC363">Scanning with regular expressions</a>.
</p>
<a name="IDX2669"></a>
<p>The following list describes all expansion variables that are
available in the MIME ACL:
</p>
<dl compact="compact">
<dt> <code>$mime_boundary</code></dt>
<dd><p>If the current part is a multipart (see <code>$mime_is_multipart</code>) below, it should
have a boundary string, which is stored in this variable. If the current part
has no boundary parameter in the <em>Content-Type:</em> header, this variable
contains the empty string.
</p>
</dd>
<dt> <code>$mime_charset</code></dt>
<dd><p>This variable contains the character set identifier, if one was found in the
<em>Content-Type:</em> header. Examples for charset identifiers are:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">us-ascii
gb2312 (Chinese)
iso-8859-1
</pre></td></tr></table>

<p>Please note that this value is not normalized, so you should do matches
case-insensitively.
</p>
</dd>
<dt> <code>$mime_content_description</code></dt>
<dd><p>This variable contains the normalized content of the <em>Content-Description:</em>
header. It can contain a human-readable description of the parts content. Some
implementations repeat the filename for attachments here, but they are usually
only used for display purposes.
</p>
</dd>
<dt> <code>$mime_content_disposition</code></dt>
<dd><p>This variable contains the normalized content of the <em>Content-Disposition:</em>
header. You can expect strings like &quot;attachment&quot; or &quot;inline&quot; here.
</p>
</dd>
<dt> <code>$mime_content_id</code></dt>
<dd><p>This variable contains the normalized content of the <em>Content-ID:</em> header.
This is a unique ID that can be used to reference a part from another part.
</p>
</dd>
<dt> <code>$mime_content_size</code></dt>
<dd><p>This variable is set only after the <code>decode</code> modifier (see above) has been
successfully run. It contains the size of the decoded part in kilobytes. The
size is always rounded up to full kilobytes, so only a completely empty part
has a <code>$mime_content_size</code> of zero.
</p>
</dd>
<dt> <code>$mime_content_transfer_encoding</code></dt>
<dd><p>This variable contains the normalized content of the
<em>Content-transfer-encoding:</em> header. This is a symbolic name for an encoding
type. Typical values are &quot;base64&quot; and &quot;quoted-printable&quot;.
</p>
</dd>
<dt> <code>$mime_content_type</code></dt>
<dd><p>If the MIME part has a <em>Content-Type:</em> header, this variable contains its
value, lowercased, and without any options (like &quot;name&quot; or &quot;charset&quot;). Here
are some examples of popular MIME types, as they may appear in this variable:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">text/plain
text/html
application/octet-stream
image/jpeg
audio/midi
</pre></td></tr></table>

<p>If the MIME part has no <em>Content-Type:</em> header, this variable contains the
empty string.
</p>
</dd>
<dt> <code>$mime_decoded_filename</code></dt>
<dd><p>This variable is set only after the <code>decode</code> modifier (see above) has been
successfully run. It contains the full path and file name of the file
containing the decoded data.
</p></dd>
</dl>

<a name="IDX2670"></a>

<dl compact="compact">
<dt> <code>$mime_filename</code></dt>
<dd><p>This is perhaps the most important of the MIME variables. It contains a
proposed filename for an attachment, if one was found in either the
<em>Content-Type:</em> or <em>Content-Disposition:</em> headers. The filename will be
RFC2047 decoded, but no additional sanity checks are done. If no filename was
found, this variable contains the empty string.
</p>
</dd>
<dt> <code>$mime_is_coverletter</code></dt>
<dd><p>This variable attempts to differentiate the &quot;cover letter&quot; of an e-mail from
attached data. It can be used to clamp down on flashy or unnecessarily encoded
content in the cover letter, while not restricting attachments at all.
</p>
<p>The variable contains 1 (true) for a MIME part believed to be part of the
cover letter, and 0 (false) for an attachment. At present, the algorithm is as
follows:
</p>
<ol>
<li>
The outermost MIME part of a message is always a cover letter.

</li><li>
If a multipart/alternative or multipart/related MIME part is a cover letter,
so are all MIME subparts within that multipart.

</li><li>
If any other multipart is a cover letter, the first subpart is a cover letter,
and the rest are attachments.

</li><li>
All parts contained within an attachment multipart are attachments.
</li></ol>

<p>As an example, the following will ban &quot;HTML mail&quot; (including that sent with
alternative plain text), while allowing HTML files to be attached. HTML
coverletter mail attached to non-HMTL coverletter mail will also be allowed:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = HTML mail is not accepted here
!condition = $mime_is_rfc822
condition = $mime_is_coverletter
condition = ${if eq{$mime_content_type}{text/html}{1}{0}}
</pre></td></tr></table>

</dd>
<dt> <code>$mime_is_multipart</code></dt>
<dd><p>This variable has the value 1 (true) when the current part has the main type
&quot;multipart&quot;, for example &quot;multipart/alternative&quot; or &quot;multipart/mixed&quot;.
Since multipart entities only serve as containers for other parts, you may not
want to carry out specific actions on them.
</p>
</dd>
<dt> <code>$mime_is_rfc822</code></dt>
<dd><p>This variable has the value 1 (true) if the current part is not a part of the
checked message itself, but part of an attached message. Attached message
decoding is fully recursive.
</p>
</dd>
<dt> <code>$mime_part_count</code></dt>
<dd><p>This variable is a counter that is raised for each processed MIME part. It
starts at zero for the very first part (which is usually a multipart). The
counter is per-message, so it is reset when processing RFC822 attachments (see
<code>$mime_is_rfc822</code>). The counter stays set after <code>acl_smtp_mime</code> is
complete, so you can use it in the DATA ACL to determine the number of MIME
parts of a message. For non-MIME messages, this variable contains the value -1.
</p></dd>
</dl>

<hr size="6">
<a name="Scanning-with-regular-expressions"></a>
<a name="SEC363"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC362" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC364" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.5 Scanning with regular expressions </h2>

<p>You can specify your own custom regular expression matches on the full body of
the message, or on individual MIME parts.
</p>
<p>The <code>regex</code> condition takes one or more regular expressions as arguments and
matches them against the full message (when called in the DATA ACL) or a raw
MIME part (when called in the MIME ACL). The <code>regex</code> condition matches
linewise, with a maximum line length of 32K characters. That means you cannot
have multiline matches with the <code>regex</code> condition.
</p>
<p>The <code>mime_regex</code> condition can be called only in the MIME ACL. It matches up
to 32K of decoded content (the whole content at once, not linewise). If the
part has not been decoded with the <code>decode</code> modifier earlier in the ACL, it
is decoded automatically when <code>mime_regex</code> is executed (using default path
and filename values). If the decoded data is larger than  32K, only the first
32K characters are checked.
</p>
<p>The regular expressions are passed as a colon-separated list. To include a
literal colon, you must double it. Since the whole right-hand side string is
expanded before being used, you must also escape dollar signs and backslashes
with more backslashes, or use the &lsquo;<samp>\N</samp>&rsquo; facility to disable expansion.
Here is a simple example that contains two regular expressions:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = contains blacklisted regex ($regex_match_string)
     regex = [Mm]ortgage : URGENT BUSINESS PROPOSAL
</pre></td></tr></table>

<p>The conditions returns true if any one of the regular expressions matches. The
<code>$regex_match_string</code> expansion variable is then set up and contains the
matching regular expression.
</p>
<p><strong>Warning</strong>: With large messages, these conditions can be fairly
CPU-intensive.
</p>
<hr size="6">
<a name="The-demime-condition"></a>
<a name="SEC364"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC363" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC358" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h2 class="section"> 41.6 The demime condition </h2>

<p>The <code>demime</code> ACL condition provides MIME unpacking, sanity checking and file
extension blocking. It is usable only in the DATA and non-SMTP ACLs. The
<code>demime</code> condition uses a simpler interface to MIME decoding than the MIME
ACL functionality, but provides no additional facilities. Please note that this
condition is deprecated and kept only for backward compatibility. You must set
the WITH_OLD_DEMIME option in &lsquo;<tt>Local/Makefile</tt>&rsquo; at build time to be able to
use the <code>demime</code> condition.
</p>
<p>The <code>demime</code> condition unpacks MIME containers in the message. It detects
errors in MIME containers and can match file extensions found in the message
against a list. Using this facility produces files containing the unpacked MIME
parts of the message in the temporary scan directory. If you do antivirus
scanning, it is recommended that you use the <code>demime</code> condition before the
antivirus (<code>malware</code>) condition.
</p>
<p>On the right-hand side of the <code>demime</code> condition you can pass a
colon-separated list of file extensions that it should match against. For
example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">deny message = Found blacklisted file attachment
     demime  = vbs:com:bat:pif:prf:lnk
</pre></td></tr></table>

<p>If one of the file extensions is found, the condition is true, otherwise it is
false. If there is a temporary error while demimeing (for example, &quot;disk
full&quot;), the condition defers, and the message is temporarily rejected (unless
the condition is on a <code>warn</code> verb).
</p>
<p>The right-hand side is expanded before being treated as a list, so you can have
conditions and lookups there. If it expands to an empty string, &quot;false&quot;, or
zero (&quot;0&quot;), no demimeing is done and the condition is false.
</p>
<p>The <code>demime</code> condition set the following variables:
</p>
<dl compact="compact">
<dt> <code>$demime_errorlevel</code></dt>
<dd><a name="IDX2671"></a>
<p>When an error is detected in a MIME container, this variable contains the
severity of the error, as an integer number. The higher the value, the more
severe the error (the current maximum value is 3). If this variable is unset or
zero, no error occurred.
</p>
</dd>
<dt> <code>$demime_reason</code></dt>
<dd><a name="IDX2672"></a>
<p>When <code>$demime_errorlevel</code> is greater than zero, this variable contains a
human-readable text string describing the MIME error that occurred.
</p></dd>
</dl>

<dl compact="compact">
<dt> <code>$found_extension</code></dt>
<dd><a name="IDX2673"></a>
<p>When the <code>demime</code> condition is true, this variable contains the file
extension it found.
</p></dd>
</dl>

<p>Both <code>$demime_errorlevel</code> and <code>$demime_reason</code> are set by the first call of
the <code>demime</code> condition, and are not changed on subsequent calls.
</p>
<p>If you do not want to check for file extensions, but rather use the <code>demime</code>
condition for unpacking or error checking purposes, pass &quot;*&quot; as the
right-hand side value. Here is a more elaborate example of how to use this
facility:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example"># Reject messages with serious MIME container errors
deny  message = Found MIME error ($demime_reason).
      demime = *
      condition = ${if &gt;{$demime_errorlevel}{2}{1}{0}}

# Reject known virus spreading file extensions.
# Accepting these is pretty much braindead.
deny  message = contains $found_extension file (blacklisted).
      demime  = com:vbs:bat:pif:scr

# Freeze .exe and .doc files. Postmaster can
# examine them and eventually thaw them.
deny  log_message = Another $found_extension file.
      demime = exe:doc
      control = freeze
</pre></td></tr></table>

<a name="IDX2674"></a>

<hr size="6">
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC358" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="spec_42.html#SEC365" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="spec.html#SEC_Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[Contents]</td>
<td valign="middle" align="left">[<a href="spec_55.html#SEC493" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="spec_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<p>
 <font size="-1">
  This document was generated on <i>September, 10 2009</i> using <a href="http://www.nongnu.org/texi2html/"><i>texi2html 1.78</i></a>.
 </font>
 <br>

</p>
</body>
</html>