DSPAM v3.0 <jonathan@nuclearelephant.com>
Copyright (c) 2003 Network Dweebs Corporation
http://www.nuclearelephant.com/projects/dspam/

LICENSE

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

TABLE OF CONTENTS

General DSPAM Information

  1.0 About DSPAM
  1.1 Installation
  1.2 Testing
  1.3 Troubleshooting
  1.4 DSPAM Tools
  1.5 Agent Commandline Arguments

Advancced DSPAM functionality

  2.0 Linking with libdspam
  2.1 Configuring groups
  2.2 External Inoculation Theory

Miscellaneous

  3.0 Bugs, Ports, and the like 
  3.1 Known Bugs
  3.2 Adding the dspam logo button to your website
  3.3 CVS Access

1.0 ABOUT DSPAM

DSPAM is an open-source, freely available anti-spam solution designed to combat
unsolicited commercial email using an advanced implementation of statistical
analysis coupled with deobfuscation techniques and other related approaches.

DSPAM is capable of learning each user's individual mail behavior based on
what they tell the filter spam is and isn't. This allows DSPAM to provide
highly-accurate, personalized filtering for each user on even a large
system. This provides an administratively maintenance free system capable of 
learning each user's email behaviors with very few false positives.  

DSPAM is among one of the more popular and successful attempts at truly 
accurate spam filtering, and is rapidly gaining a large support forum.  
Contributions to the project are welcome via the dspam-dev mailing list. 

DSPAM can be implemented in one of two ways:

1. The DSPAM mailer-agent provides server-side spam filtering, quarantine
box, and a mechanism for forwarding spams into the system to be automatically
analyzed.  Advanced features, such as opt-in/opt-out filtering, inoculation,
and shared groups are supported.

2. Developers may link their projects to the dspam core engine (libdspam) in
accordance with the GPL license agreement.  This enables developers to
incorporate libdspam as a "drop-in" for instant spam filtering within their
applications - such as mail clients, other anti-spam tools, and so on.

Many of the foundational principles incorporated into this agent were 
contributed by Paul Graham's white paper on combatting SPAM, which can be 
found at http://paulgraham.com/spam.html.  Many new approaches have been 
layered on top of the original core, some of which may be explained in
white papers on the DSPAM home page.

The DSPAM Solution is split up into the following pieces:

DSPAM CORE ENGINE

The DSPAM core engine, also known as libdspam, provides all major spam
filtering functions.  The engine is linked to other dspam components (or
shells) to provide functionality.  The core engine is capable of being linked
in with any other application as a "drop-in" to provide spam filtering to
mail clients, other anti-spam tools, and other such type projects that
would benefit from its use.  Both static and shared versions are built by
libtool into .libs. 

libdspam provides a storage driver abstraction layer, enabling developers to 
easily change how information is stored on the system (for example Berkeley 
DB, MySQL, Oracle, etc.) with enough flexibility to write a storage
driver utilizing stone tablets and chisels.   

DSPAM AGENT

The DSPAM agent is a shell for libdspam providing a direct interface to
mail servers or other tools for server-side spam filtering. The agent 
is normally integrated into one of two places:

1. The agent can masquerade as a mail server's local delivery agent. DSPAM then
processes email piped to it from the mail server and then either delivers it 
using the real delivery agent (procmail, mail.local, or a proxy to pass it 
along to another server), or will quarantine it if the message is spam (DSPAM 
can optionally tag and deliver spams as well). 

2. As a POP3 proxy, DSPAM can be configured to processes email when the user 
checks theirs, and tags spam accordingly. This allows DSPAM to front-end
any mail system without the need for integration.

The agent is also responsible for correcting misclassifications (missed spams
or false positives). This is critical to the learning operations of DSPAM. 

The MTA (sendmail, exim, qmail, etc) or the POP3 proxy calls DSPAM with 
parameters identifying the destination user and other operational parameters.
DSPAM performs its internal calculations and will then perform the appropriate 
action based on the result.

When an email is delivered to the end-user, the agent appends a serial number
to each email. This serial number references temporary information stored on
the server which contains the original training data for the message, and is
used to re-learn the original message in the event DSPAM made a mistake. This
allows DSPAM to accurately learn without having to provide the full headers
of the message - making life much easier for end-users.

CGI CLIENT

The CGI client is an end-user tool enabling a mail user to view their
quarantine box, reverse the occasional false positive, view their historical
activity, and most importantly to delete their spams permanently.
The CGI client works in conjunction with the DSPAM agent.  It is possible to 
eliminate the quarantine box in lieu of an alternative solution, such as 
client-filtering/forwarding, but many users will appreciate not having to
download all of their spam, and being able to view usage graphs and other
useful information.

TOOLS

Some basic tools which have been provided to manage dictionaries, automate 
corpus feeding, and create seeded [composite] dictionaries.  

1.1 INSTALLATION

UPGRADING

   ------------------------------------------------------
   IMPORTANT UPGRADE STEPS FOR USERS UPGRADING FROM < 3.0
   ------------------------------------------------------

   Version 3.0 incorporates many changes to the user interface, but preserves
   the general data structure so that users don't need to re-train in order
   to upgrade.

   Step 1: Shut down the existing DSPAM installation.
     The existing DSPAM installation should be shut down prior to any upgrade
     changes.  The easiest way to do this is to turn off the MTA and web
     server serving the DSPAM CGI.  No mail should be processed while the
     changes are being made.

   Step 2: Data Storage Changes
     If you are using a SQL-Based driver, a few minor changes will need to
     be made.  These changes are only necessary to SQL-Based drivers; no
     changes need to be made if you are using the BerkeleyDB storage drivers.

     The following SQL code should upgrade both MySQL and Oracle databases to
     the v3.0 format.  Be sure to log into the schema used by DSPAM to apply
     these changes.

     alter table dspam_stats add spam_learned int;
     alter table dspam_stats add innocent_learned int;
     alter table dspam_stats add spam_classified int;
     alter table dspam_stats add innocent_classified int;
     update dspam_stats set spam_learned = total_spam;
     update dspam_stats set innocent_learned = total_innocent;
     update dspam_stats set spam_classified = 0, innocent_classified = 0;
     alter table dspam_stats drop column total_spam;
     alter table dspam_stats drop column total_innocent;
     alter table dspam_stats add spam_misclassified int;
     alter table dspam_stats add innocent_misclassified int;
     update dspam_stats set spam_misclassified = spam_misses;
     update dspam_stats set innocent_misclassified = false_positives;
     alter table dspam_stats drop column spam_misses;
     alter table dspam_stats drop column false_positives;

   Step 3: Compile DSPAM v3.0
     DSPAM v3.0 has moved many features out to the commandline.  Other
     configure-time arguments have also been changed or removed.  The following
     is a list of configure-time changes that have been made:

     --with-userdir-*			changed 'userdir' to 'dspam-home'
     --with-local-delivery-agent	changed to --with-delivery-agent
     --enable/disable-chained-tokens    removed from configure
     --enable/disable-bnr               removed from configure
     --enable/disable-whitelist         removed from configure
     --enable/disable-toe               removed from configure
     --enable/disable-tum               removed from configure
     --enable/disable-spam-delivery     removed from configure
     --enable/disable-deliver-fp        removed from configure

     once you have configured DSPAM, run: make && make install
     to build and install the software.

     NOTE: The default DSPAM home has been changed from /etc/mail/dspam to
           /var/dspam. If you would like to use the old path, specify it using
           --with-dspam-home=/etc/mail/dspam.

   Step 4: Upgrade the CGI
     The DSPAM CGI has been updated, and should be upgraded.  Many calling
     arguments have been changed.

   Step 5: Reconfigure your MTA
     DSPAM's commandline arguments have been rewritten.  You'll want to
     consult the 'AGENT COMMANDLINE ARGUMENTS' section for a full explanation
     of all the new commandline components.  Some of the basic changes are:

     --addspam, --falsepositive, --corpus, and --inoculate have been
     replaced with two flags to specify a pre-classification and a 
     classification source:

       --addspam becomes: 
           --class=spam --source=error

       --falsepositive becomes: 
           --class=innocent --source=error

       --corpus becomes:
           --class=innocent --source=corpus
           --class=spam --source=corpus

       --inoculate becomes:
           --class=spam --source=inoculation

     It will also be necessary to specify the training mode, delivery
     preferences, and feature selection on the commandline as well.  For
     example:

       --mode=teft --deliver=innocent --feature=chained,bnr

     Or if you prefer delivery of both innocent and spam messages, you should
     use --deliver=innocent,spam.  Keep in mind that these preferences will
     be applied to whatever operation you are calling.  For example, if you
     are retraining a false positive or forwarding in a spam, the --deliver
     argument will specify whether or not you want to deliver it, so you have
     the luxury of defining different commandline arguments between your MTA,
     aliases, and CGI.

   Step 6: The directory structure has been changed so that all user directories
           go into $DSPAM_HOME/data. You'll want to either delete all user
           directories (the .stats files and such will be rebuilt, but the
           quarantine boxes won't), or move them into $DSPAM_HOME/data.

   Step 7: Turn your MTA and CGIs back on, and TEST EVERYTHING.

FRESH INSTALLATION

First you will need to download a few prerequisite tools:

   Depending on which storage driver you want to use, you will need:
 
   libdb4_drv: Berkeley DB-4. 
   libdb3_drv: Berkeley DB-3.
   mysql_drv:  MySQL client libraries (and a server to connect to) 
   ora_drv:    Oracle Call Interface (and a server to connect to)
   pgsql_drv:  PostgreSQL client libraries (and a server to connect to)

   MySQL is the recommended storage driver, even for small implementations, as
   it is more stable and tested than the other drivers. If you are incapable
   of running a stateful server, the libdb drivers should suffice, but please
   be aware that libdb can occasionally result in some problems including
   data corruption and lock contention. As a result, you'll want to maintain
   a backup of your dictionary in the event such problems arise.

   In general, MySQL is a faster solution with a smaller storage footprint, 
   and is well suited for both small and large-scale implementations.

   You can download Berkeley DB from http://www.sleepycat.com.  
   You can download MySQL from http://www.mysql.com.
   You can download PostgreSQL from http://www.postgresql.com
   You can obtain more information about Oracle at http://www.oracle.com.

   Be sure the necessary libraries are available to root, the MTA user, and 
   the CGI user. The easiest way to do this is to copy them to /usr/lib or 
   /lib.


   Documentation for the setup of your selected storage driver can be found
   in the tools.[storage driver]/ directory.

   NOTE: Some operating system distributions include their own version of
         libdb3_drv and libdb4_drv.  A majority of these packaged versions
         do work correctly with DSPAM, however a few do not.  If you experience
         problems with one of the libdb storage drivers, consider downloading
         and compiling the official source tree from http://www.sleepycat.com.

1. CONFIGURATION

   ./configure [options]

   DSPAM supports the configuration options below. 

   PATH SWITCHES

   --with-dspam-home=DIR
   Specify an alternative storage directory for dspam user information.  The
   default is /var/dspam.

   --prefix=DIR
   Specify an alternative root prefix for installation.  The default is
   /usr/local.  This does not affect DSPAM_HOME.

   FILESYSTEM SCALE
                                                                                
   The default filesystem scale is "small-scale", and writes each user to
   its own directory in the top-level DSPAM_HOME/data directory.  
   The following two switches allow the scale to be changed to be more 
   suitable for larger installations.

   --enable-large-scale
   Switch for large-scale implementation.  User data will be stored as
   $DSPAM_HOME/data/u/s/user instead of $DSPAM_HOME/data/user

   --enable-domain-scale
   Switch for domain-scale implementation.  When used, username@domain should
   be passed in as the user id and user data will be stored as
   $DSPAM_HOME/data/domain.com/user and $DSPAM_HOME/opt-in/domain/user.dspam
   instead of $DSPAM_HOME/data/user

   INTEGRATION SWITCHES

   --with-delivery-agent=PROG
   The delivery agent is the tool called to deliver messages.

   Use this to specify an alternative delivery agent, other than the one 
   specific to your operating system.  If you are building on an unsupported 
   platform, you will need to specify this.  You may use quotes if you wish to 
   include additional commandline flags.  DSPAM will automatically relay the 
   commandline parameters it was initially given, with the exception of any
   DSPAM-specific parameters (such as --user, --process, etc.).  This does
   not necessarily need to be a local agent, but can be configured to call
   a proxy pass-through.

   Currently, DSPAM has a default delivery agent selected for Linux, 
   FreeBSD, Solaris, and Cygwin platforms.

   NOTE: When specifying a series of arguments, you will need to use quotes
   around PROG.  You may also use the $u identifier to specify that you
   with DSPAM to place the destination user's ID in the corresponding space
   in the arguments list. For example: 

       --with-delivery-agent="/path/to/lda -d \$u" 

   Where $u will be replaced by the destination user prior to calling the LDA.
   This could potentially cause problems, however, if your MTA requires the
   user argument list to come last, which is why DSPAM, by default, will allow
   you to set this in the MTA configuration.

   NOTE: be sure to escape the $ in $u. Only do this when specifying $u on the 
   commandline.  This will prevent $u from being overwritten with the shell's 
   environment variable 'u'. You may alternatively use %u.

   --with-quarantine-agent=PROG
   By default, DSPAM automatically quarantines spams in its internal
   user quarantine box.  If you wish to override this default behavior,
   however, you may do so by specifying your own quarantine agent.  The same
   notes from the --with-delivery-agent option apply here. The quarantine agent
   will be called whenever a message is believed to be spam, with the message
   provided as stdin into the tool.

   --enable-broken-mta
   You should enable this if your MTA is broken and passes messages into DSPAM
   with CTRL-M's (^M) in them.

   --enable-broken-return-codes
   Causes DSPAM to return an exit code of 99 if a message is spam, 0 if
   innocent, and any other code if an error has occured. The default is to
   return 0 whenever the operation is successful, regardless of outcome.  Only
   use this if you know what you're doing!

   --with-storage-driver=DRIVER
   Specify an alternative storage driver.  A storage driver is a driver
   written specifically for DSPAM to store tokens, signature data, and
   perform other proprietary operations.  The default driver is libdb4_drv,
   which incorporates Berkeley DB v4.  The following drivers have been provided:

     libdb4_drv: Berkeley DB4 Library
     libdb3_drv: Berkeley DB3 Library
     mysql_drv:  MySQL Drivers
     ora_drv:    Oracle Drivers (BETA)
     pgsql_drv:  PostgreSQL Drivers (BETA)

   You may also need to use some of the driver-specific configure flags
   (discussed later).

   --enable-client-compression
   Enables data source client compression for storage drivers where it is
   available (presently only mysql_drv).  This causes data between the
   data source and its clients to be compressed.  You should use this option
   if your data source is on a separate machine from the DSPAM agent(s) as it
   conserves bandwidth, but at the expense of a few CPU cycles.

   --disable-trusted-user-security
   Administrators who wish to disable trusted user security may do so by
   using this configure flag.  This will cause DSPAM to treat each user as
   if they were "trusted" which could allow them to potentially execute
   arbitrary commands on the server via DSPAM.  Because of this, administrators
   should only use this option on either a closed server, or configure their
   DSPAM binary to be executable only by users who can be trusted.  This
   option SHOULD NOT be used as a solution to your MTA dropping privileges
   prior to calling DSPAM.  Instead, see the TRUSTED SECURITY section of this
   document.

   --enable-homedir-dotfiles
   When enabled, instead of checking for $DSPAM_HOME/$USER/opt-in/
   $USER[.nodspam|.dspam], DSPAM will check for a .nodspam|.dspam file in the 
   user's home directory.  These two dotfiles are used for opt-out or opt-in 
   filtering.

   --enable-opt-in
   Causes DSPAM to filter mail only for users with a .dspam dotfile.  The
   default is opt-out, which requires a .nodspam file to exist to bypass
   filtering.
                                                                                
   DEBUGGING SWITCHES

   --enable-debug
   Turns on support for debugging output to DSPAM_HOME/dspam.debug and
   DSPAM_HOME/dspam.messages (see desription of --with-dspam-home option for
   details about DSPAM_HOME).  This option allows you to turn on debugging
   messages for specific users by dropping a DSPAM_HOME/userpath/user.debug
   file or for all users by dropping a DSPAM_HOME/.debug file.  Enabling
   debug only enables support for this feature, dotfiles must still be
   dropped in order to turn messages on.  

   --enable-verbose-debug
   Turns on extremely verbose debugging output to DSPAM_HOME/dspam.debug
   and DSPAM_HOME/dspam.messages (see desription of --with-dspam-home option
   for details about DSPAM_HOME).  dotfiles must still be dropped in order to
   activate messages, just like with --enable-debug.

   TRAINING SET IDENTIFICATION SWITCHES

   The default behavior for DSPAM is to store all original training data
   on the server-side as temporary information, and embed a serial number
   into the body of each message referencing the data.  This is used for
   misclassifications and providing a true 1:1 retraining.  Some 
   implementations may call for a slightly different approach to training set 
   identification.

   --enable-signature-attachments
   Instead of storing the DSPAM signatures on the server (which could take
   up considerable disk space), this option will cause DSPAM to rewrite
   each message to include a dspam.dat attachment, which contains all of
   the tokens used to calculate the original message.  When the spam or
   false positive is processed back into the system, this signature will
   be read.  May increase bandwidth on an average between 2k-32k per
   message, depending on the original message's size.

   NOTE: This option doesn't work correctly with mail clients that quote an
   embedded, forwarded message (such as some or all versions of elm) and 
   should only be used on networks where all clients can properly understand 
   an embedded multipart message (Outlook, Ximian Evolution, Etcetera), and 
   forward the attachment as an attachment instead of quoted text.  In othe  
   words, this breaks a lot of stuff if you're not on a standardized GUI-based 
   client network.  Server-side signatures is still the most reliable method 
   and works for all known clients.

   This also puts a "paper clip" on every message you receive.

   --enable-signature-headers
   This option will cause the DSPAM signature to be written to the message
   header instead of body.  

   IMPORTANT: This option requires that all users either bounce their messages
   into DSPAM, forward as an attachment, or implement some macro that will
   retain the X-DSPAM-Signature header, which will NORMALLY BE DROPPED by
   standard forwarding.

   --enable-webmail
   The webmail switch is designed for systems where the original message 
   remains server side and can therefore be presented in pristine format for 
   retraining.  This option will cause DSPAM to cease all writing of 
   signatures and DSPAM headers to the message, and deliver the message in as 
   pristine format as possible.  This mode REQUIRES that the original message 
   in its pristine format (as of delivery) be presented for retraining, as in 
   the case of webmail or other applications where the message is actually 
   kept server-side during reading, and is preserved.  DO NOT use this switch 
   unless the original message can be presented for retraining with the 
   ORIGINAL HEADERS and NO MODIFICATIONS.

   --with-signature-life=DAYS
   Specifies the default length (in days) a signature should remain stored on
   the server.  The default is 14 days.  This value should accurately represent
   the maximum amount of time a user would need to identify and forward
   a missed spam, or mark a false positive.  Consider vacations.  This can
   be changed in calls to dspam_clean on the commandline.

   FEATURE ACTIVATION

   --enable-neural-networking (EXPERIMENTAL)
   Enables neural networking support (see the section NEURAL NETWORKING).  This
   feature is only presently supported by the mysq_drv and pgsql_drv 
   storage drivers, and is still considered experimental.

   --enable-source-address-tracking
   Logs the source address of spams and innocent messages via syslog.
   You can create a file DSPAM_HOME/mta.whitelist which can contain a list of
   local MTA IPs, which will cause DSPAM to skip to the next 'Received' header.
   Each IP should be on a new line.

   Also writes SBL blacklist files for use with the Streamlined Blackhole
   Server (http://www.nuclearelephant.com/projects/sbl/).

   --enable-spam-subject
   Prepends [SPAM] to the subject header of any messages suspected to be spam.
   This is sometimes more useful than the X-DSPAM-Result field, because not
   all mail clients support mail rules with custom headers.

   --disable-user-logging
   Disables the writing of per-user .log files.  Users will not be able to
   view graphs or history with this feature disabled.

   --disable-system-logging
   Disables the writing of the system.log.  Admins will not be able to view
   graphs or other related information with this feature disabled.

   ALGORITHM ACTIVATION

   The default algorithms enabled are quite sufficient, and represent the most
   well-tested algorithms in DSPAM. It is not necessary to change any of
   these options unless you are interested in altering DSPAM's default behavior.

   --disable-traditional-bayesian
   Disables the traditional Bayesian algorithm (it is enabled by default).

   --disable-alternative-bayesian
   Disables Brian Burton's alternative Bayesian algorithm.  The differences are:
     - 27 Samples are used instead of 15
     - Tokens appearing more than once may take up to 2 slots in the
       calculation.  This is ideal when there is very limited data

       (it is enabled by default)

   --enable-robinson
   Enables Robinson's geometric mean test.  The differences are:
     - A window-size of 25 is used instead of 15 
     - The combination algorithm is different.  See:
       http://radio.weblogs.com/0101454/stories/2002/09/16/spamDetection.html
       for more information.

       This algorithm is obsolete, and not recommended for production builds. 

   --enable-chi-square
   Enables Fisher-Robinson's Inverse Chi-Square
     Defaults in libdspam.c:
     - Exclusionary radius of 0.45
     - Ham/Spam Cutoff of 0.5
     - Strength: 0.1
     - Assumed probability: 0.5

   NOTE: You may have multiple algorithms enabled simultaneously; if any of
     the enabled algorithms believe the message is spam, it will be marked
     accordingly.  Naturally, you also have the potential problem of any
     false positives generated by the enabled algorithms, so it is recommended
     to either stick with a single algorithm, or use only Bayesian or only
     Robinson's type algorithms.  Bayesian+Alt-Bayesian seems to be the most
     effective combination (not using Robinson's at all).

     For this reason, if you plan on enabling any algorithms which are 
     disabled by default, it is strongly recommended that you also:

     --disable-traditional-bayesian --disable-alternative-bayesian

     Generally, the alternative-Bayesian algorithm appears to catch some spams
     that the traditional Bayesian algorithm does not, however it also misses
     far more spams than the traditional algorithm.  Therefore, an 
     implementation using both Bayesian algorithms appears to be the most
     effective in catching spam.

   --disable-bias
   When bias is disabled, dspam no longer biases the statistics in favor of
   innocent mail, but measures both spam and innocent tokens equally in the 
   calculation equally.  This may provide more effective spam filtering,
   but has shown to increase the number of false positives.

   --enable-robinson-pvalues
   Enable's robinson's technique for combining p-values. This is an alternative
   approach to generating word probabilities described here:

   http://www.linuxjournal.com/article.php?sid=6467

   Robinson's p-values are presently used in Chi-Square calculations, but
   enabling them with this flag will use them for *all* calculations effectively
   replacing (or rather building upon) Graham's tokenization approach. This
   flag may also be used without enabling Chi-Square.

   --disable-test-conditional
   Disables test-conditional training.  Test-conditional training is a more
   agressive approach to training than traditional training, and provides more
   inoculous results rapidly.  

   Enabled by default, this mode of training will automatically re-train the 
   user's dictionary on spam or false positive until the training condition is 
   met (e.g. until the user's dictionary no longer results in 
   misclassification of the message being retrained).  This training has a 
   maximum number of 5 iterations, and will only invoke when:
                                                                                
   - The user has > 1000 innocent messages in their corpus, and is reporting
     a spam
                                                                                
   - The user is reporting a false positive (regardless of the number of 
     messages in their corpus)

   This method of training has its controversial points as well.  All of these
   issues revolve around the assumption this approach to training makes that
   you are likely to receive the same (or very similar) again one or more times
   in the future.

   - Since the message is being retrained repeatedly, the learning curve is
     going to be based solely on that one message rather than the natural flow
     of similar messages that may contain slightly different text.

   - It's possible a user may agressively train a spam they will only receive
     once but could potentially increase their risk of false positives by
     training this agressively.

   - If there is a significant overlap of dictionary tokens between a user's
     regular mail and the incoming spams being agressively trained, the user
     could potentially end up retraining with spam, then retraining with
     false positives, then retraining with spam again.

   In spite of these controversial points, this approach to training has had
   successful results with several implementations.

   DRIVER SPECIFIC CONFIGURE SWITCHES

   libdb4_drv:
     --with-db4-includes=DIR
     Specify a path to the Berkeley db4 includes

     --with-db4-libraries=DIR
     Specify a path to the Berkeley db4 libraries

   libdb3_drv:
     --with-db3-includes=DIR
     Specify a path to the Berkeley db3 includes

     --with-db3-libraries=DIR
     Specify a path to the Berkeley db3 libraries
     (Currently links to -ldb3, to you may need to symlink libdb-3.3.so to
      libdb3.so if it doesn't exist)

   mysql_drv:
     --with-mysql-includes=DIR
     Specify a path to the MySQL includes

     --with-mysql-libraries=DIR
     Specify a path to the MySQL libraries
     (Currently links to -lmysqlclient, also -lcrypto on some systems)

     --enable-virtual-users
     Tells DSPAM to create virtual user ids.  Use this if your users don't
     actually exist on the system (e.g. in /etc/passwd if using a password file)

     NOTE: Please see the file tools.mysql_drv/README for more information
     about configuring the mysql_drv storage driver.

   pgsql_drv:
     --with-pgsql-includes=DIR
     Specify a path to the PgSQL includes

     --with-pgsql-libraries=DIR
     Specify a path to the PgSQL libraries
     (Currently links to -lpq, and netlibs on some systems)

     --enable-virtual-users
     Tells DSPAM to create virtual user ids.  Use this if your users don't
     actually exist on the system (e.g. in /etc/passwd if using a password file)

     NOTE: Please see the file tools.pgsql_drv/README for more information
     about configuring the pgsql_drv storage driver.

   ora_drv:
     --with-oracle-home=DIR
     Specify the Oracle Home (or client home)

     --enable-virtual-users
     Tells DSPAM to create virtual user ids.  Use this if your users don't
     actually exist on the system (e.g. in /etc/passwd if using a password file)                                                                                
     NOTE: Please see the file tools.ora_drv/README for more information
     about configuring the ora_drv storage driver.

2. BUILDING AND INSTALLING

   After you have run configure with the correct options, build and install
   DSPAM by performing:

   make && make install

   If you are a developer wanting to link to the core engine of dspam,
   libdspam will be built during this process.  Please see the
   example.c file for examples of how to link to and use libdspam.  Static
   and dynamic libraries are built in the .libs directory.  Needed headers
   will be installed in $prefix$/include/dspam.

3. PERMISSIONS

   After install, the DSPAM_HOME will have been created for you automatically
   (the default is /var/dspam).  Insure the permissions of the directory
   are writable by both your MTA and CGI user.

   You may need to add root and your MTA user to the directory's [mail] group
   in /etc/group.  The MTA user is usually 'daemon' or 'smmsp' although on 
   FreeBSD the default is 'mailnull'.  This is very important, as your MTA 
   user needs to be able to lock and work with files.

   IMPORTANT!!!

   FreeBSD's mail.local changes its effective uid, and so in order to use it
   dspam must be installed as setuid root to work on the commandline properly.
   This is done automatically on install.

   If you find that DSPAM is erroneously processing all operations as a single 
   user, chances are that user should be added to trusted.users as an 
   administrative user,

   TRUSTED USERS SECURITY

   DSPAM has tighter security for untrusted users on the system, to prevent
   them from being able to spoof other users or specify their own passthru
   arguments to potentially hijack the delivery agent.  This method
   of security has been implemented due to the fact that some implementations
   (such as those using procmail) may require the DSPAM agent to be setuid or
   setgid.

   The trusted.users file should be created in $DSPAM_HOME (defaulted to
   /var/dspam).  This file should contain a list of trusted users who 
   should be allowed to set the dspam user, passthru parameters, and other 
   information that would be potentially dangerous for a malicious user to 
   be able to set.  The file should contain one username per line, and will
   generally the usernames of the MTA and CGI users.  Example:

   root
   smmsp
   daemon
   cgi
   mailnull

   Where cgi represents the special CGI user you configure Apache to
   run your dspam.cgi as.

   Be sure to examine DSPAM_HOME/dspam.debug to insure that you don't get any
   untrusted user warnings when submitting spam or a false positive, as both
   of these actions frequently call dspam from a different user than
   standard mail delivery.

   If you are using an MTA that changes its userid before calling DSPAM to
   match the destination user, you should NOT add each user to the trusted
   users file, but instead configure a preset commandline.  DSPAM will see
   that the user is not trusted and automatically set their DSPAM user id
   and optionally the passthru delivery agent arguments.
   
   To override an untrusted user's passthru delivery agent arguments
   (arguments which could be used to hijack the delivery agent to gain
   privileged access to the system) you will need to set up a file called 
   untrusted.mailer_args in the same directory ($DSPAM_HOME).  The first line 
   should contain the path to the delivery agent followed by a list of 
   all the LDA arguments to pass through (including a user identity flag if 
   necessary).  This file's information will override any passthru commandline 
   parameters specified by the user.  For example:

   /bin/mail -d $u

   The variable $u informs DSPAM that you would like the destination username
   to be used in the position $u is specified, so when DSPAM calls your LDA
   for user 'bob', it will call it with:

   /bin/mail -d bob

   NOTE: In the event that ALL of the following are true:

    - Your MTA performs a setuid() to the destination user prior to calling
      DSPAM

    - There are additional _dynamically assigned_ parameters that must be
      passed to DSPAM which cannot be specified in configuration

    - The delivery agent has no potentially dangerous commandline
      options, or you are placing a wrapper around the delivery
      agent

    Then you may want to remove the untrusted.mailer_args file all together.
    If the file cannot be found, dspam will permit the user to specify their 
    own passthru arguments to the preconfigured LDA (with some basic sanity 
    checking) which COULD POTENTIALLY BE INSECURE if improperly set up..  It
    is strongly recommended you use this file to override the user.

    DSPAM warns you (over log record) when unable to open
    untrusted.mailer_args file.

    If you don't want to see this warning then make untrusted.mailer_args
    file exists but empty.

4. SERVER CONFIGURATION

   There are two ways DSPAM can be configured:

   Mail Server: The default approach integrates DSPAM directly with the mail 
        server and filters spam as mail comes in. 

   POP3 Proxy: The alternative approach implements a POP3 proxy where users
        connect to the proxy to check their email, and email is filtered when
        being downloaded.  The POP3 proxy is a much easier approach, as it
        requires much less integration work with the mail server (and is ideal 
        for implementing DSPAM on Exchange, etcetera). 

   The big difference is that the mail server configuration filters mail at 
   MTA time, while the POP3 proxy approach filters mail at MUA time, while
   the POP3 proxy has the added benefit of not needing to worry about virtual
   users and such.

   MAIL SERVER CONFIGURATION
   -------------------------

   Modify your mail server configuration to use /usr/local/bin/dspam as the
   default delivery agent.  

   SENDMAIL EXAMPLES
   If you are using sendmail, modify the Mlocal tag, as shown below:

Mlocal,		P=/usr/local/bin/dspam, F=lsDFMAw5:/|@qfSmn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
		T=DNS/RFC822/X-Unix,
		A=dspam "--mode=teft" "--feature=chained,noise" "--deliver=innocent" --user $u -d %u

   You may also need to add this to DSPAM_ARGS in dspam.cgi:

   $CONFIG{'DSPAM_ARGS'} = "--user $ENV{'REMOTE_USER'} --deliver=innocent --class=innocent --source=error --feature=chained,noise --mode=teft -d \$u";

   If you are using procmail with sendmail, you can preserve the existing
   procmail flags with the exception of LMTP.  For example:

Mlocal,		P=/usr/local/bin/dspam, F=lsDFMAw5:/|@qSPfhn9, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL,
		T=DNS/RFC822/X-Unix,
		A=dspam -t -Y -a $h "--feature=chained,noise" "--deliver=innocent" "--mode=teft" --user $u -d %u

   The --user flag identifies the user to DSPAM, and does not actually get
   passed through to the LDA.  The same is true for other DSPAM-specific flags
   such as those in our example beginning with --.  Be sure 
   to change "-d $u" to "-d %u" to let DSPAM supply the username to the LDA.

   NOTE: be sure to escape the $ in $u ONLY when specifying it on the 
   commandline.  This will prevent $u from being overwritten with the shell's 
   environment variable 'u'.
                                                                                
   Finally, if you are using sendmail restricted shell (smrsh), you will
   need to either disable it, or add /usr/local/bin/dspam to the allow list. 
   Some people have experienced problems using smrsh with DSPAM.

   It is required that dspam be called with the --user flag followed by the user
   name of the local recipient.  A training mode and operating mode must also
   be specified at a minimum.  

   EXIM
   To integrate DSPAM with exim, you'll need to create a new director in the
   exim configuration.  First, add the following code to the directors :

spamscan:
  no_verify
  condition = "${if and { {!eq {$received_protocol}{spam-scanned}} } {1}{0}}"
  driver = localuser
  transport = spamcheck
  require_files = ${local_part}:\
    +/path/to/dspam-home:\
    +/path/to/dspam/binary

  Then add the following code to the transports:

spamcheck:
  driver = pipe
  command = /usr/local/bin/dspam --mode=teft --deliver=innocent --feature=chained,noise --user $local_part -d %u 
  user = mail
  group = mail
  return_path_add = false
  log_output = true
  return_fail_output = true

   Finally, you will need to configure your delivery agent into dspam.
   This may end up calling exim again, if you are using maildir
   format for example.  An example of calling back to exim for delivery might
   look like:

   ./configure --with-delivery-agent="/usr/sbin/exim -oMr spam-scanned"

   Of course, any parameters you pass to DSPAM will also get passed onto
   the delivery agent, so you can safely locate the parameters in
   your exim configuration incase you want to change them later:

   command = /usr/local/bin/dspam --mode=teft --feature=chained,noise --deliver=innocent --user $local_part -d $local_part -oMr spam-scanned

   then configure with just:

   ./configure --with-delivery-agent=/usr/sbin/exim

   This was tested under Debian Sarge with Exim 3.36-6.

   Some Notes added by Philipp Lehman <plehman@gmx.net>:

   As to the condition, one could also write a line to the header and 
   check for that instead of looking at the protocol:

   condition = "${if and {\
                         {!def:h_X-DSPAM-Check:}\
                 }{1}{0}}"
   headers_add = "X-DSPAM-Check: by $primary_hostname on $tod_full"

   The problem with setting $received_protocol in the transport is that only 
   priviledged Exim users are allowed to do so. With this setup, DSPAM could 
   be built with:  --with-delivery-agent="/usr/sbin/exim"

   Also, -d clutters the log file quite a bit so I went with:  

   command = "/path/to/dspam/binary --mode=teft --feature=chained,noise --deliver=innocent --user $local_part -bm %u"

   When changing the user/group it is highly advisable to set "home_directory" 
   and "current_directory" accordingly:  

     home_directory = "/path/to/dspam/dspam-home" # or "/tmp"  
     current_directory = "/path/to/dspam/dspam-home" # or "/tmp

   Otherwise, the transport might try to run DSPAM in something like /home/bob 
   under certain circumstances. This will most likely fail if DSPAM runs as 
   "mail".

   For a pass-through setup where DSPAM feeds all processed messages back to 
   Exim it is also a good idea to set "prefix" and "suffix" to an empty 
   string:  
     prefix = ""  
     suffix = ""

   There is no need to create aliases for every user on the system in order to 
   handle spam reports and false positives. They can be handled by directors 
   and transports, using the following directors:

   dspam_addspam:  
     prefix = spam-
     driver = localuser
     transport = addspam

   dspam_falsepositive:  
     prefix = falsepos-
     driver = localuser
     transport = falsepositive

   For every $user on the system, these directors will handle messages 
   addressed to "spam-$user@localhost" and "falsepos-$user@localhost", strip 
   the prefix from the address, and pass the message to the respective 
   transport. This requires two additional transports:

   addspam:
     driver = pipe
     command = "/path/to/dspam/binary --user $local_part --class=spam --source=error --mode=toe"
     return_path_add = false  
     return_fail_output = true  
     log_output = true  
     home_directory = "/path/to/dspam/dspam-home" # or "/tmp"
     current_directory = "/path/to/dspam/dspam-home" # or "/tmp"  
     user = mail  
     group = mail  
     prefix = ""  
     suffix = ""

   falsepositive:  
     driver = pipe  
     command = "/path/to/dspam/binary --user $local_part --mode=toe --class=innocent --source=error --deliver=innocent"
     return_path_add = false  
     return_fail_output = true  
     log_output = true  
     home_directory = "/path/to/dspam-home" # or "/tmp"  
     current_directory = "/path/to/dspam-home" # or "/tmp"  
     user = mail  
     group = mail  
     prefix = ""  
     suffix = ""

   NOTE: --feature is not necessary when retraining, because the original
         training data is used from the signature to retrain, instantiating
         whatever features (such as chained tokens and whitelisting) were
         active at the time of the initial classification.

   This way, all users are handled transparently. No fiddling with aliases is 
   required as you add or remove users.  
 
   COURIER

   Step 1: Configuring Courier to use DSPAM

   To set Courier to use DSPAM as its delivery agent, you'll want to
   change the DEFAULTDELIVERY parameter.  In the file /etc/courier/courierd,
   find the line for DEFAULTDELIVERY and change it to:

   DEFAULTDELIVERY="| /usr/local/bin/dspam --mode=teft --deliver=innocent --feature=chained,noise --user $USER"

   Step 2: Setting DSPAM to use Maildrop as LDA
   Maildrop is Courier's native equivalent of procmail.  To configure DSPAM
   to use it, use the following configure flags:

   --with-delivery-agent="/usr/bin/maildrop -d \$u"

   You'll also need to configure untrusted.mailer_args as Courier drops to the
   uid of the destination user and changes to that users homedir before calling
   the LDA.  Accomplish this by using the following parameters in your
   untrusted.mailer_args file:

   /usr/bin/maildrop -d $u

   Step 3: Configuring DSPAM aliases for missed spam/false positives

   The aliases for missed spam/false positives should be added to the file
   /etc/courier/aliases/system.  After adding new aliases, run 'makealiases'
   and restart Courier.

   POSTFIX

   Contributed by John Locke <mail@freelock.com>

   Postfix delivers fine to DSPAM, but you need to use a separate LDA for
   the final delivery to your mailbox. Two good LDAs to use for this
   purpose are Procmail and Maildrop. The first step in getting DSPAM to
   work is to get mail delivery to work with one of these external LDAs
   before adding DSPAM.
  
   Procmail is pretty standard on most Linux distributions. It works fine
   for delivery to local users, but if you need to support virtual users
   (email accounts that do not correspond to a local Unix user), it can be
   difficult to figure out how to get Procmail to deliver to the right
   place.
  
   So after you have an LDA working correctly (other than the Postfix local
   or virtual delivery agents), then you can insert DSPAM into the mix.
  
   The simplest way to configure DSPAM support for local users is to set the 
   mailbox_command directive to point to DSPAM in /etc/postfix/main.cf:
  
   mailbox_command = /usr/local/bin/dspam --mode=teft --deliver=innocent --feature=chained,noise --user $USER -d %u
  
   Configure DSPAM with
   "--with-delivery-agent=/usr/local/bin/maildrop" 
   (or the path to Procmail).
  
   You can also add this to a new $DSPAM_HOME/untrusted.mailer_args:
   /usr/local/bin/maildrop -d $u
  
   I haven't tested adding a spam address to Postfix, but you should be
   able to add the output from the "dspam_genaliases" command straight into
   an alias file (you can create a new one for the purpose), run
   "postalias" on your alias file, and add it to the alias_maps directive.
  
   That's it! DSPAM should start working as soon as you have this all set
   up.
  
   OTHER MAIL SERVERS

   Consult your mail server's documentation on how to replace the local 
   delivery agent.  It may be necessary to recompile the software.  Worst 
   case scenario, you may have to symlink dspam to the filename of the local 
   delivery agent, and rename the delivery agent.  If you do this, be 
   sure the change is reflected in your configuration of dspam using
   the --with-delivery-agent= flag.  We have reports of dspam working 
   with postfix, and will post documentation for configuring it as soon as 
   its available.


   POP3 PROXY CONFIGURATION
   ------------------------

   pop3filter is an open-source POP3 proxy tool which can be used to provide
   spam filtering without the need for inbound mail server integration.  The
   software is configured to run as a "proxy"; that is, users are directed to
   check their email using the proxy's ip address (or are transparently
   redirected there) at which point the proxy will open up a connection to
   the mail server and filter mail as it is being downloaded by the user.

   pop3filter can be downloaded from http://pop3filter.sourceforge.net/.

   The easiest way to set up pop3filter is to have it call DSPAM using the
   --stdout command, at which point DSPAM will check the message and return
   it with X-DSPAM headers identifying the message as spam or innocent.  To
   do this, follow these steps:

   1. Compile and install pop3filter
   2. Compile and install DSPAM on the same machine

      You may optionally wish to use --enable-spam-subject so that [SPAM] 
      will be prepended to the subject header of messages suspected to be spam.

   3. Configure pop3filter to run as follows:

   pop3filter --fork [mail server IP] 110 110 "/usr/local/bin/dspam --user \
     \$POP3_USERNAME --mode=[training mode] --stdout --deliver=innocent,spam \
     --feature=[feature list]"

   a full blown example would look like:

   pop3filter --fork 10.0.0.1 110 110 "/usr/local/bin/dspam --user \
     \$POP3_USERNAME --mode=teft --stdout --deliver=innocent,spam \
     --feature=ch,no,wh"

   The POP3_USERNAME variable will be automatically replaced with the username
   provided by the client at connect time.

   Mail will then be checked by DSPAM and an X-DSPAM-Result field will be
   appended to the message headers identifying the classification of the
   message.

5. ALIASES

   Users must have an alias to forward/bounce spams to in order for DSPAM to
   learn. Since DSPAM learns each user's specific email behavior, it is
   necessary to identify the end-user to program their specific dictionary.  
   This can be done in two ways:

   System-Wide Alias
   -----------------

   DSPAM can be compiled with --enable-parse-to-header which will parse the
   To: header of all messages forwarded by a user to obtain their username.
   This can be configured in conjunction with a wildcard subdomain, such
   as spam.yourdomain.com, so that only one alias will be necessary for the
   entire system.

   For example, if @spam.yourdomain.com is configured to be delivered to
   'spamuser', then spamuser can be configured to pipe into DSPAM without
   a user:

   spamuser:	"|/usr/local/bin/dspam --class=spam --source=error --mode=toe"

   When a user forwards a message in as spam, they will email 
   spam-username@spam.yourdomain.com. For example:

   To: Spam Account <spam-bob@spam.yourdomain.com>

   DSPAM will then parse 'bob' from the To: header and identify that the user
   reporting the spam is bob. This is protected from spoofing because the
   signature in the message is looked up in the database. If the signature
   doesn't exist under that user's name, the message is ignored.

   Per-User Aliases
   ----------------

   Sometimes it may be appropriate to set up an alias for each user on the
   system instead of having a system-wide alias. For each user, you will need 
   to create an email address the user can send spam to, so that DSPAM can 
   analyze and learn.  The easiest way to do this is to create a new alias.  
   For example:

   spam-bob:      "|/usr/local/bin/dspam --user bob --class=spam --source=error --mode=teft"

   NOTE: --feature is not necessary when retraining, because the original
         training data is used from the signature to retrain, instantiating
         whatever features (such as chained tokens and whitelisting) were
         active at the time of the initial classification.

   You will end up having one alias per mail user on the system.  Be sure the
   aliases are unique and each username matches the name after the --user flag.
   A tool has been provided called dspam_genaliases.  This tool will read the
   /etc/passwd file and write out a dspam aliases file that can be included
   in your master aliases table.  

   To report spams, the user should be instructed to forward each spam to
   spam-user@yourhost

   If you will be using the --enable-spam-delivery mechanism, you will also
   need an alias to forward false positives into.  The following example should
   suffice:

   fp-bob:	"|/usr/local/bin/dspam --user bob --class=innocent --source=error --mode=teft --deliver=innocent"

   It doesn't really matter what you name these aliases, so long as the flags
   being passed to dspam are correct for each user.  It might be a good idea
   to create an alias custom to your network, so that spammers don't forward
   spam into it.  For example, fp-yourcompany-bob or something.  

6. DRIVER SPECIFIC TOOLS

   Depending on the storage driver you are using, there may be tools specific
   to that driver that will be built.
   
THE CLEANUP AND PURGE TOOLS

   CLEANUP

   You should configure dspam_clean to run under cron nightly.

   This clean tool will read all signature databases and purge signatures that
   are older than 14 days (configurable), purge abandoned tokens, and remove
   unimportant tokens.  Without this tool, old signatures will continue to 
   pile up.  A cron should suffice.  Be sure the user running cleanup has full 
   read/write permissions on the DSPAM data files.

   0 0 * * * /usr/local/bin/dspam_clean [options]

   See the dspam_clean description for more information

   PURGE

   Depending on which storage driver you choose, it may be beneficial to run
   a purge tool that will recreate the database nightly.  This is expecially
   true to the BDB drivers.  Using db_dump and db_load in a shell script,
   for example, can very easily reclaim free space in a BDB database if run
   once a week or so.

   Obviously if you are using a SQL-based driver, you will not need to compress
   files, but may want to run some basic SQL commands to delete unused tokens, 
   etc.  You can find a purge.sql script in the driver's directory to
   conduct basic maintenance.  dspam_clean can provide even finer tuning.

7. NOTIFICATIONS

   DSPAM is capable of sending three different notifications:

   - A "First Run" message sent to each user when they receive their first 
     message through DSPAM.

   - A "First Spam" message sent to each user when they receive their first
     spam

   - A "Quarantine Full" message sent to each user when their quarantine box
     is > 2MB in size.

   These notifications can be activated by copying the txt/ directory from the
   distribution into DSPAM_HOME (by default /var/dspam).  You will want to
   modify these templates prior to installing them to reflect the correct
   email addresses and URLs (look for 'configureme' and 'yourdomain').

   NOTE: The quarantine warning is reset when the user clicks 'Delete All', but
   is not reset if they use "Delete Selected".  If the user doesn't wish to
   receive reminders, they should use the "Delete Selected" function instead
   of "Delete All".

THE CGI CLIENT

   The CGI client (dspam.cgi) can be run from any executable location on
   a web server, and detects its user's identity from the REMOTE_USER
   environment variable.  This means you'll need to use HTTP password
   authentication to access the CGI (Any type of authentication will work,
   so long as Apache supports the module).  You'll want the usernames to match
   the actual username on the system.  A copy of the shadow password file
   will suffice for authentication.

   The accompanying files in the cgi/ folder should be copied into the same
   location as dspam.cgi, as they are needed by the tool to generate output.
   Be sure to copy the templates and graphics into the cgi-bin as well.

   NOTE: Some authentication mechanisms are case insensitive and will
   authenticate the user regardless of the case they type it in.  DSPAM,
   on the other hand, is case sensitive and the case of the username used
   will need to match the case on the system.  If you suffer from this
   authentication problem, and are certain all of your users' usernames are
   in lowercase, you can add the following line of code to the CGI right
   after the call to &ReadParse...

   $ENV{'REMOTE_USER'} = lc($ENV{'REMOTE_USER'});

   The CGI will need to function in the same group as the dspam agent in order
   to work with the files in /var/dspam.  The best way to do this is to create 
   a separate virtualhost specifically for the CGI and assign it to run in the 
   MTA group using Apache's suexec.  If you are using procmail, additional 
   configuration may also be necessary (see below).  Please note that Apache 
   users do NOT take on the identity of the groups specified in /etc/group; 
   e.g. you will need to specifically assign the group in httpd.conf.

   NOTE: Because the DSPAM CGI is a script, DSPAM will not retain its 
         privileges when called. If you are running procmail, this will become
         a problem as procmail requires root privileges to deliver. The easiest
         hack around this is to create a procmail.dspam binary and make it
         setuid root, then make it executable only by the mail group (or 
         whatever group DSPAM and the CGI run in).

   The DSPAM CGI has a minimal configuration inside the dspam.cgi file. You'll
   want to check dspam.cgi and make sure all of the settings are correct. In
   most cases, the only that will be necessary to change are the large-scale
   or domain-scale flags.

   Once you've configured the CGI, there are two more things you'll want to do.
   
   1. Edit templates/nav_performance.html
      Change yourdomain to whatever your domain name is.

   2. Make any changes to default.prefs. This will set the default preferences
      for a user. The file should reflect your system wide defaults. An example
      is provided in the cgi directory...

trainingMode=TEFT
spamAction=quarantine
spamSubject=[SPAM]
enableBNR=on
enableWhitelist=on

     By default, the parameters specified on the commandline will be used. If,
     however, a preference is found for the particular user those preferences
     will override the commandline. As a result, you'll want to remove any
     options from the CGI that you don't want users to set (possibly
     training mode).

   If you plan on leaving DSPAM's logging function enabled, and would like to
   produce pretty graphs for your users, the graph.cgi script requires the
   following be installed on your machine:

   - GD Graphics Library (http://www.boutell.com/gd/)
   - The following PERL modules:
     (http://www.perl.com/CPAN/modules/by-module/GD/)

     . GD
     . GD-Graph3d
     . GDGraph
     . GDTextUtil

  NOTE ON CGI USERS:  It is far more secure to create a separate virtual
  host for the DSPAM CGI running as a different user than any other
  scripts on the system.  This avoids giving trusted user privileges to
  another CGI.  If you do this, be sure to add the CGI user to the trusted
  users list.

  Once you've configured the CGI, you'll want to edit the 'admins' file to
  contain a list of users who are permitted to use the administration suite.

1.2 TESTING

  Most software packages are supplied with a test suite to determine if the
  software is functioning properly.  Since dspam's correct function relies 
  primarily on having the correct permissions and mail server configuration,
  a test script fails to provide the level of testing required for such a
  package.  The following exercise has been provided to test dspam's correct
  functioning on your system.  This exercise does not test the CGI, but only
  the core dspam agent.
  
  Before running the test, you should have completed section 1.1's instructions
  for compiling and installing dspam as well as configured your mail server
  to support dspam.

  1. Create a new user account on your system.  It is important that this be a 
  new account to prevent any unrelated email from being delivered during 
  testing.  Be sure to configure a spam alias for the test account.

  2. Send a short (10 words or less) email to the account, and pick it up 
  using your favorite mail client.  

  3. Run dspam_stats [username] on the server.  You should see a value of 1 
  for "TI" or "Total Innocent" as shown below:

  dspam-test            0 TS       1 TI       0 TM       0 FP

  If you receive an error such as "unable to open /var/dspam/... for
  reading", then the dspam agent is not configured correctly.  The problem
  could lie in either your mail server configuration or one or more of the
  permissions on the directory or agent.  Check your configuration and
  permissions, and repeat this step until the correct results are experienced.

  4. Run dspam_dump [username] to get a complete list of tokens and their 
  statistics.  Each token should have an I: (innocent) hit count of 1. The 
  tokens will be represented as 64-bit values, for example:

3126549390380922317              S:    0  I:    1  LH: Mon Aug  4 11:40:12 2003
13884833415944681423             S:    0  I:    1  LH: Mon Aug  4 11:40:12 2003
14519792632472852948             S:    0  I:    1  LH: Mon Aug  4 11:40:12 2003
8851970219880318167              S:    0  I:    1  LH: Mon Aug  4 11:40:12 2003

  To view statistics for a particular token, run dspam_dump [username] [token]
  where token is the plain-text token value.  For example:

  % dspam_dump bill FREE
  7717766825815048192  S: 00265  I: 00068  P: 0.7358

  5. Forward the test message to the spam alias you've created for the test 
  account.  Provide enough time for the message to have processed.

  6. Run dspam_stats [username] on the server again.  Now, the value for TI 
  should be zero and the value for TM (total misses) should be 1 as shown
  below:

dspam-test            0 TS       0 TI       1 TM       0 FP

  If this is not the case, check the group permissions of the dspam agent as
  well as the permissions your MTA uses when piping to aliases.
  
  7. Run dspam_dump [username] again.  make sure that _EVERY_ token now has an 
  I: of zero and a S: of 1:

3126549390380922317              S:    1  I:    0  LH: Mon Aug  4 11:44:29 2003
13884833415944681423             S:    1  I:    0  LH: Mon Aug  4 11:44:29 2003
14519792632472852948             S:    1  I:    0  LH: Mon Aug  4 11:44:29 2003
8851970219880318167              S:    1  I:    0  LH: Mon Aug  4 11:44:29 2003

  If you have some tokens that do not have an S: of 1 or an I: of 0, the dspam
  signature was not found on the email, and this could be due to a lot of
  things.

1.3 TROUBLESHOOTING

    Problem: I get an error similar to 'cannot find -ldb-4.1'
   Solution: Your compiler can't locate your db libraries.  Try installing
             them into /usr/lib, or add them to your (and your MTA's)
             LD_LIBRARY_PATH.  You may also use --with-db4-includes and
             --with-db4-libraries as configure flags.  If you are using libdb3,
             use the db3-specific configure parameters.
 
    Problem: Dictionary isn't updating
   Solution: Check the file permissions of both the .dict and the .mbox files.
             These files will need to be writable by the dspam agent as well
             as the CGI user.

    Problem: No files are being created in the user directory
   Solution: Check the directory permissions of the directory.  The user 
             directory must be writable by the user the dspam agent is running
             as as well as the CGI user.

    Problem: False positives are never being delivered
   Solution: Your CGI most likely doesn't have the privileges required by
             the LDA to deliver the messages.  Make sure the CGI user is in
             the correct group.  Also consider setting the dspam agent to
             setuid or setgid with the correct permissions.

1.4 DSPAM TOOLS

  A few useful tools have been provided to make DSPAM management a bit easier. 
  These tools include:

  dspam_corpus - Used to feed an existing corpus of mail (in mailbox format)
    into the dspam system.  
    Syntax: dspam_corpus [username] [filename] [--addspam]
    where username is the username of the user to apply the corpus to,
    filename represents the filename of the mailbox, and the optional flag
    to specify if this corpus is known spam (to add as spam into the user's
    dictionary).  
 
  dspam_dump - Dumps a DSPAM dictionary. This can be used to view the 
    entire contents of a user's dictionary, or used in combination 
    with grep to view a subset of data.  Syntax: dspam_dump [username] [token] 
    where username is the DSPAM user's username.  If a token is specified,
    statistics only for that token will be printed.

  dspam_clean - Performs nightly housecleaning by deleting old or useless
    data from user data.  dspam_clean performs the following operations:

    1. Using the -s flag, dspam_clean will continue to perform stale signature
     purging.  If an age is specified, for example -s14, the age defined as the
     default will be overridden.  Specifying an age of 0 will delete all
     signatures for the users processed.
                                                                                
    2. Using the -p flag, dspam_clean will delete all tokens from a user's 
     database whose probability is between 0.35 and 0.65 (fairly neutral, 
     useless tokens) that fall beyond the default age.  If an age is specified,
     for example -p30, the age defined as the default will be overridden.  It 
     is a good idea to use this type of clean with an age of 0 on users after
     a lot of corpus training.
                                                                                
    3. Using the -u flag, dspam_clean will delete all unused tokens from a 
     user's database.  There are four different types of unused tokens:
                                                                                
     - Tokens which have not been used for a long time
     - Tokens which have a total hit count below 5
     - Tokens which have only one spam hit
     - Tokens which have only one innocent hit
                                                                                
   Ages may be overridden by specifying a format such as -u30,15,10,10
   where each number represents the respective age.  Specifying an age of
   zero will delete all unused tokens in the category.
                                                                                
   Optionally, usernames may be specified to override the default behavior of
   processing all users.

   Examples:

   Process all users on the system using all clean operations:
     dspam_clean -s -p15 -u90,30,15,15

   Delete all of user 'dick' and 'jane's signatures:
     dspam_clean -s0 dick jane

   Perform a post-corpus training clean on user 'spot':
     dspam_clean -p0 -u0,0,0,0 spot

   Run dspam_clean with all default options, all clean modes enabled, on all
   users on the system:
     dspam_clean -s -p -u

  NOTE: You may wish to only run certain cleaning modes depending on the type 
  of storage driver you are using.  For example, the MySQL storage driver
  includes a purge.sql script which performs signature and unused token 
  operations, leaving only probability operations as useful.  If you are
  using a SQL-based storage driver, it is strongly recommended that you use
  the maintenace scripts wherever possible for optimum efficiency.

  dspam_stats - Displays the spam statistics for one or all users on the system.
    Syntax: dspam_stats [username].  If no username is provided, all users 
    will be displayed.  Displays TS (Total Spams), TI (Total Innocent), TM
    (Total Spam Misses) and FP (Total False Positives).  Spam misses are
    spams that were forwarded in by the user.  To calculate the total number
    of spams caught by DSPAM, subtract TM from TS. 

  dspam_genaliases - Reads the /etc/passwd file and outputs a dspam aliases
    table which can be included in the master aliases table.  You may try
    Art Sackett's generate_dspam_aliases tool at 
    http://www.artsackett.com/freebies/generate_dspam_aliases/ if you need
    some better functionality.  This will eventually be merged in as a
    replacement for the existing tool.
 
  dspam_merge - Merges multiple users' dictionaries together into one user's
    dictionary (does not affect the merge users).  This can be used to create
    a seeded dictionary for a new user, or to copy a single user's dictionary
    to a new file.  This is great for building global dictionaries, but
    crunches a lot of time and disk.

1.5 AGENT COMMANDLINE ARGUMENTS

  The DSPAM agent (dspam) recognizes the following commandline arguments:

  --user [user1 user2 ... userN]
  Specifies the destination user(s) of the incoming message.  DSPAM then 
  processes the message once for each user individually.  If the message is to
  be delivered, the $u (or %u) parameters of the arguments string will be
  interpolated for the current user being processed.

  --class=[spam|innocent]
  Tells DSPAM that the message being presented has already been classified by
  the user.  This flag should be used when a misclassification has occured, 
  when the user is corpus-feeding a message, or an inoculation is being 
  presented.  This flag must be used in conjunction with the --source flag.
  Providing no classification invokes the SOP of DSPAM, which is to determine
  the message's nature on its own.

  --source=[error|corpus|inoculation]
  Wherever --class is used, the source of the user-provided
  classification must also be provided.  The source is very important and
  dramatically affects DSPAM's training behavior:

    error: The message being presented was a message previously misclassified
           by DSPAM.  When 'error' is provided as a source, DSPAM requires that
           the DSPAM signature be present in the message, and will use the
           signature to recall the original training metadata.  If the signature
           is not present, the message will be rejected.  In this source mode,
           DSPAM will also decrement each token's previous classification's
           count as well as the user totals.

           You should use error only when DSPAM has made an error in 
           classifying the message, and should present the modified version of
           the message with the DSPAM signature when doing so.

   corpus: The message being presented is from a mail corpus, and should be
           trained as a new message, rather than re-trained based on a
           signature.  The message's full headers and body will be analyzed and
           the correct classification will be incremented, without its
           opposite being decremented.

           You should use corpus only when feeding messages in from corpus.

   inoculation: The message being presented is in pristine form, and should
                be trained as an inoculation.  Inoculations are a more 
                intense mode of training designed to cause DSPAM to 
                train the user's metadata repeatedly on previoulsy unknown
                tokens, in an attepmt to vaccinate the user from future
                messages similar to the one being presented.

                You should use inoculation only on honeypots and the like.

  --deliver=[innocent,spam]
  Tells DSPAM to deliver the message if its result falls within the criteria
  specified.  For example, --deliver=innocent will cause DSPAM to only 
  deliver the message if it classifies as innocent.  Providing
  --deliver=innocent,spam will cause DSPAM to deliver the message regardless
  of its classification.  This flag provides a significant amount of 
  flexibility for nonstandard implementations, where false positives may not
  be delivered but spam is, and etecetera.
  
  --stdout
  If the message is indeed deemed "deliverable" by the --deliver flag, this
  flag will cause DSPAM to deliver the message to stdout, rather than 
  the configured delivery agent.

  --process
  Tells DSPAM to process the message.  This is the default behavior, and the
  flag is implied unless --classify is used - but is a good idea to use to 
  avoid ambiguity.

  --classify
  Tells DSPAM only to classify the message, and not make any writes to the
  user's metadata or attempt to deliver/quarantine the message.  

  NOTE: The output of the classification is specific to the user, not including
        the output of any groups they might be affiliated with, so it is 
        entirely possible that the message would be caught as spam by the group,
        even if it didn't appear in the classification.  If you want to get
        the classification for the GROUP, use the group name as the user
        instead of an individual.

  --mode=[toe|tum|teft|notrain]
  Configures the training mode to be used for this process:

    teft: Train-Everything.  Trains on all messages processed.  This is
          a very thorough training approach and should be considered the 
          standard training approach for most users.  TEFT may, however,
          prove too volatile on installations with extremely high per-user
          traffic, or prove not very scalable on systems with extremely large
          user-bases.  In the event that TEFT is proving ineffective, one of
          the other modes is recommended.

          NOTE: Until a user reaches 2500 innocent messages in their
                metadata, train-on-error will also be teft-based, even if
                otherwise specified on the commandline.

     toe: Train-on-Error.  Trains only on a classification error, once the
          user's metadata has matured to 2500 innocent messages.  This
          training mode is much less resource intensive, as only occasional
          metadata writes are necessary.  It is also far less volatile than
          the TEFT mode of training.  One drawback, however, is that TOE only
          learns when DSPAM has made a mistake - which means the data is
          sometimes too static, and unable to "ease into" a different type of
          behavior.


     tum: Train-until-Mature.  This training mode is a hybrid between the other
          two training modes and provides a great balance between volatility
          and static metadata.  TuM will train on a per-token basis only
          tokens which have had fewer than 25 "hits" on them, unless an error
          is being retrained in which case all tokens are trained.  This
          training mode provides a solid core of stable tokens to keep
          accuracy consistent, but also allows for dynamic adaptation to any
          new types of email behavior a user might be experiencing.

 notrain: No training.  Do not train the user's data, and do not keep totals.
          This should only be used in cases where you want to process mail for
          a particular user (based on a group, for example), but don't want
          the user to accumulate any learning data.
 
    RECOMMENDATIONS:
      In general, it is recommended that users begin with TEFT.  If a user
      is experiencing between a 75-85% spam ratio, they may benefit from
      Train-on-Mature mode.  If a user is experiencing over 90% spam, then
      Train-on-Error mode should make a noticeable improvement in accuracy.
      It eventually boils down to what works best for your users.  There is
      no reason a system could not be configured (with a script) to
      analyze a user's *.stats file and determine the best training mode
      for that user.

  --feature=[chained,noise,whitelist]
  Specifies the features that should be activated for this filter instance.
  The following features may be used individually or combined using a comma
  as a delimiter:

    chained: Chained Tokens (also known as biGrams).  Chained Tokens
             combines adjacent tokens, presently with a window size of 2, to
             form token "chains".  Chained tokens uses additional storage
             resources, but greatly improves accuracy.  Recommended as a
             default feature.

     noise:  Bayesian Noise Reduction (BNR).  Bayesian Noise Reduction kicks
             in at 2500 innocent messages and provides an advanced progressive
             noise logic to reduce Bayesian Noise (wordlist attacks) in
             spams.  See http://www.nuclearelephant.com/projects/dspam/bnr.html
             for more information.

      tb=N:  Sets the training loop buffering level.
             Training loop buffering is the amount of statistical sedation
             performed to water down statistics and avoid false positives 
             during the user's training loop.  The training 
             buffer sets the buffer sensitivity, and should be a number
             between 0 (no buffering whatsoever) to 10 (heavy buffering).  The 
             default is 5, half of what previous versions of DSPAM used.  
             To avoid dulling down statistics at all during the training loop, 
             set this to 0.

 whitelist:  Automatic whitelisting.  DSPAM will keep track of the entire
             "From:" line for each message received per user, and automatically
             whitelist messages from senders with more than 20 innocent
             messages and zero spams.  Once the user reports a spam from the
             sender, automatic whitelisting will automatically be deactivated
             for that sender.  Since DSPAM uses the entire "From:" line, and
             not just the sender's email address, automatic whitelisting is
             a very safe approach to improving accuracy especially during
             initial training.
  
   NOTE: None of the present features are necessary when the source is "error",
         because the original training data is used from the signature to 
         retrain, instantiating whatever features (such as chained tokens and 
         whitelisting) were active at the time of the initial classification.
         Since BNR is only necessary when a message is being classified, the
         --feature flag can be safely omitted from error source calls.

2.0 LINKING WITH LIBDSPAM

  Developers are able to link to the DSPAM core engine (libdspam) to provide 
  "drop-in" spam-filtering for their applications.  Examples of the libdspam
   API can be found in the example.c file included with this distribution.

  YOUR PROJECT MUST HAVE A COMPATIBLE OPEN SOURCE LICENSE TO THE GPL TO USE
  THE LIBDSPAM API.  IF YOU ARE DEVELOPING A CLOSED-SOURCE APPLICATION OR
  APPLICATION THAT DOES NOT CONFORM TO GPL STANDARD, YOU MAY NOT USE LIBDSPAM
  WITHOUT A COMMERCIAL LICENSE FROM NETWORK DWEEBS CORPORATION.  

  Please contact info@networkdweebs.com for more information about commercial
  licensing,

  To link to libdspam, follow the instructions for compiling and installing 
  dspam.  When dspam is compiled, the libdspam static and shared libraries are
  also built.  This library contains all the functions necessary to use 
  dspam's filtering in your application. 

  Your application will also need to link to the correct storage driver
  libraries.  

  To build with the dspam API, you will also need the header files from
  the distribution.  You can copy these to /usr/include/dspam for ease of
  use, and then use -I/usr/include/dspam

  Please see example.c for API examples.

  If you are interested in linking libdspam with your project and have 
  questions or concerns, please contact the dspam-dev mailing list.

2.1 CONFIGURING GROUPS

  Groups enable a group of users to share information.  The following
  group types are supported:

  SHARED
  Enables users with similar email behavior to share the same dictionary 
  while still maintaining a private quarantine box.  The benefits of this
  type of group are faster learning, and sharing a single spam alias.  Shared
  groups can have both positive and negative effects on accuracy.  If a shared
  group consists of users with similar, predictable email behavior, the users 
  in the group can benefit from a larger dictionary of spam and faster 
  learning (especially for newcomers in the group).  If a group consists of 
  users with different email behavior, however, the users in the group will 
  experience poor spam filtering and a higher number of false positives.

  SHARED GROUP NOTES:

  1. The SQL-based storage drivers support shared groups, but has one caveat:
     If you are NOT enabling "virtual users" support, you will need to create
     an actual user on your system named after each group you create.

  2. The ora_drv storage driver does not yet support shared groups

  On top of shared group support, a shared group can also be made to be
  'managed'.  Using the group type 'SHARED,MANAGED' will cause the group to
  share a single quarantine mailbox which could be managed by the group's
  administrator.  This would enable one individual to monitor quarantine for
  the entire group, however personal emails marked as false positives could
  potentially be viewed as well.  For this reason, managed groups should only
  be used when this is not an issue.

  INOCULATION
  An inoculation group allows users to maintain their own private dictionaries
  with their own spam alias, but all members of the group will inoculate other
  members with spams they manually forward into their alias.  This allows 
  users to report spams to one another and maintain their own private
  dictionary.  Another advantage to this is that users do not necessarily have
  to share the same email behavior.  

  NOTE: Users should only be added to an inoculation group after their initial
        learning period, to avoid potential false positives due to lack of data.

  To create groups, you'll want to create a file with the filename 'group' 
  located in the DSPAM user directory.  The default is /var/dspam/group.  
  The format of the file should look like this:

  group1:shared:user1,user2,user3
  group2:inoculation:user4,user5,user6

  A user can be a member of multiple inoculation groups, but a user cannot be
  a member of both an inoculation group and a shared group.

  DSPAM will read this file upon startup and determine if the user fits into
  any particular group.  
  
  Use the dspam_stats tool to keep an eye on the effectiveness of shared groups.
  If a shared group experiences poor performance, find the users whose email 
  behavior is inconsistent with that of the group and remove them from the 
  group.

  CLASSIFICATION
  Classification groups allow a group of users to network their results
  together.  If DSPAM is uncertain of whether a message is spam or nonspam for
  a group member, all other members of the group are queried.  If another
  member believes the message to be spam, it will be marked as spam.

  A user can simultaneously be a member of a classification and inoculation
  group, but a user cannot be a member of both a classification group and a
  shared group.

  VERSATILE LANGUAGE INOCULATION MESSAGES

  A new Internet-Draft has been released to the public:

    http://www.ietf.org/internet-drafts/draft-spamfilt-inoculation-00.txt

  To create a message format standard for sending inoculation data via email.
  This will allow users on different servers, and even using different 
  anti-spam tools to share inoculation information with one-another.

  DSPAM presently implements support for this message standard with the 
  following limitations:

  - Only inbound inoculation messages are supported.  DSPAM does not yet send
    out inoculations using this message format.  This should not be confused
    with local inoculation, which *is* supported.
  
  - The message/inoculation format is the only inoculation type presently
    supported.  text/inoculation and multipart/inoculation coming soon.

  - The only supported authentication mechanism is presently md5 verification
    codes/checksums.

  Any unsupported inoculations will simply be dropped.

  A list of identifies and authentication information can be set up in the file
  [username].inoc or in the user's home directory in a .inoc file if
  homedir-dotfiles is enabled.  The format of this file is:

  sender1:shared secret
  sender2:shared secret

  Each sender should specify the correct sender id when sending an 
  inoculation, and should generate their checksum based on the shared secret
  established between both parties.

  NEURAL NETWORK

  Neural networks are similar to classification networks, however with some 
  differences.  First, all nodes in the network are queried sequentially,
  increasing execution time depending on the number of nodes in a network.
  Once the results from all nodes has been returned, the results from the most 
  reliable nodes are used.  Reliable nodes are determined based on how accurate
  they have been in the past.  Depending on the size of the network, the top
  20% of nodes (with a minimum of two nodes) are used. The reliability (and 
  results) are then combined to form a probability based on the results.  

  The advantage to using a neural network over a classification network is 
  that the filter is capable of "learning" which users have dictionaries 
  closer to their own mail behavior therefore providing better results.  
  This data can be used in the future to create dynamic classification of 
  groups.

  Neural networking must be explicitly enabled using the configure flag
  --enable-neural-networking.  Neural networking is presently only
  supported by the mysql_drv and pgsql_drv storage drivers, and is still 
  experimental.

  GLOBAL GROUPS

  Global groups allows DSPAM to provide a "SpamAssassin type out-of-the-box
  filtering" for all new users until they have built their own useful
  dictionaries.  to create a global classification group, add something like
  this to $DSPAM_HOME/group:

  groupname:classification:*globaluser

  This will automatically add globaluser as a classification peer to all users.
  Any user who has less than 1000 innocent messages or 250 spam messages in
  their corpus, or whose filter is uncertain about a particular message will
  consult the global dictionary for an answer.

  Global groups will need to be trained using corpus or other means, or by
  using the dspam_merge tool.  the global user (in this case 'globaluser') is
  treated just as any other user on the system.

  MERGED GROUPS

  Merged groups are similar to global groups in that the entire system uses
  a single global user as a parent.  What's different is that the global
  group is merged with the individual user's training data at run-time,
  instead of switching between the two.  This allows the global group to be
  treated like a base dataset for all users, and provides for quicker
  learning and correction than the previous approach.  It is recommended 
  merged groups are only used with TOE-mode training so that only corrective 
  data is stored, but systems with ample amounts of disk may wish to run in
  TUM mode to learn the user's behavior dynamically.

  groupname:merged:*
  groupname:merged:user1,user2,userN

  groupname represents the name of the global user to merge with all members of
  the group.

  Note: Merged Groups are great for providing out-of-the-box adaptive filtering,
        but allowing users to build their own data from scratch will still 
        result in the best possible accuracy in the longrun.

2.2 EXTERNAL INOCULATION THEORY

  Bill Yerazunis recently expressed his theory of inoculation on an anti-spam
  development list, using the term "vaccination":

  "Part of the problem is that spam isn't stationary, it evolves. That 
   pesky .1% error rate is in some part due to the base mutation rate of spam 
   itself.  Maybe the answer is "vaccination".  Vaccination is using _one_ 
   person's misery be used to generate some protective agent that protects the 
   rest of the population; only the first person to get the spam actually has 
   to read it. 

   My expectation is this: say you have ten friends, and you all agree to share 
   your training errors.  Each of you will (statistically) expect to be the 
   first to see a new mutation of spam about 9% of the time; the other ten 
   friends in this group will have their bayesian filter trained preemptively 
   to prevent this.  Net result: you get a tenfold decrease in error rate - 
   down to 99.99% accuracy.  With a hundred such (trusted) friends, you may be 
   down to 99.999% accuracy."

   DSPAM has taken this concept and rolled it into support for what we call
   "inoculation groups" providing the exact functionality Bill describes.  This
   could be considered an "internal inoculation" practice.

   On top of this, DSPAM has been designed to support external inoculation as 
   a complement to internal inoculation.  This is where instead of your internal
   circle of friends inoculate you, you rely on external elements - namely
   spammers themselves - to inoculate you.

   The theory behind external inoculation is this: why put _anyone_ through
   the misery of being the first to receive a new spam when you can have
   the spammers themselves send it directly to you.  On top of this,
   external inoculation can be combined with internal inoculation by taking
   the spam you received externally and inoculating your friends with it
   internally.

   Inoculation is a little different from learning, as inoculation causes
   tokens to be given additional hit counts in an attempt to learn from a
   single email.  As a result, any form of inoculation should _only_ be
   attempted after an initial learning phase (perhaps when your filtering
   accuracy exceeds 99.0%).  DSPAM inoculates like this:

   1. Every token that doesn't already exist in the database, or have fewer
      than two hits will be hit five times.

   2. All other tokens are hit twice.

   External inoculation is accomplished by creating a covert, external alias
   that is configured to automatically inoculate your dictionary from any
   messages it receives.  The covert alias can then be published onto a series
   of public newsgroups and websites where it is sure to be harvested by
   a spammer's tools.  One could even pro-actively subscribe one's self to
   several different opt-in spam lists, etcetera.

   The first step is to configure an alias.  To do this you would use something
   like:

   bob_c:	"|/path/to/dspam --process --class=spam --source=inoculation --feature=chained,noise --mode=teft --user bob"

   The 'C' in bob is for 'Covert'.  We must use a covert alias because if we
   use something obvious like 'bob-spam', harvester tools will automatically
   strip the -spam off and spam your real account.

   Once the alias is set up, make sure this alias gets out only on lists where
   harvesters will grab it, and nobody will send legitimate email to it.  
   It may even be a good idea to put it at the bottom of your tagline in all
   your publicly archived emails, something like...

   Spammers, send me mail here: bob_c@yourdomain.com

   Finally, you can multiply the effects of this by sharing an inoculation
   group with your friends.  If all of your friends have a public covert
   alias, then you will all be able to inoculate eachother should one of you
   receive a spam to the account.  What a great way to train your filter!

   On top of this, should external inoculation become commonplace to the
   point where harvesters are picking up an equal amount of them as legitimate
   email addresses, spammers will start to realize that harvesters are just
   plain too dumb to tell the difference (the spammers themselves couldn't tell
   if mine was or not).  This could, best case scenario, put an end to
   harvester bots, making them obsolete as counter-productive tools.

3.0 BUGS, PORTS, AND THE LIKE

  Please report any questions, bugs, suggestions, and the like to the 
  dspam-users mailing list.  See the project website for details.

  If you port DSPAM to another platform, or would like to submit changes to
  the distribution, please email a diff along with any other pertinent 
  information to the dspam-dev mailing list.

  If you like DSPAM and want to buy the author pizza (or a ferrari),
  paypals may be sent to jonathan@nuclearelephant.com.

  Thanks =)

3.1 KNOWN BUGS

  - DSPAM presently does _not_ handle a mass forward of emails, but only one
    forward at a time.  Be sure to tell your users not to select multiple
    messages and forward them...this results in a single message being sent
    into DSPAM instead.  Users should individually forward each spam.  

    DSPAM can be made to support this with the help of a little script that
    extracts the signatures from a stream, and calls DSPAM once with every
    signature. Since the content of each message is not necessary, you would
    only need to feed DSPAM something like;

    X-DSPAM-Signature: !DSPAM:1234567890!

    !DSPAM:1234567890! 

  - The Oracle storage driver is slow; this is primarily due to the fact that
    the agent has to establish a new connection with Oracle every time it is
    run.  This adds another 0.5 - 1.5 seconds of delay. Future versions may
    incorporate a proxy type service, but for now if you are looking for
    speed consider the MySQL storage driver.

  - Multiple Contexts cannot be opened for a single user when using a 
    locking storage driver (libdb3, libdb4).  This presents potential problems
    with some third party tools that would need to do such a thing.  Multipe
    contexts to work fine, however, with SQL-based drivers.

  - Neural networking is only supported by the MySQL driver presently, but
    configure will allow you to proceed (to a broken make) using any
    storage driver.  Neural networking is still EXPERIMENTAL and is not yet
    complete.

3.2 ADDING THE DSPAM LOGO BUTTON TO YOUR WEBSITE

  A small button has been included for those who would like to advertise dspam
  on their web page.  To use, copy the graphic (dspam-button.gif) into your
  web page's directory and use the following code wherever you'd like the
  button displayed:

  <A HREF="http://www.networkdweebs.com/software/dspam/">
  <IMG BORDER=0 SRC="dspam-button.gif"></A>

3.3 CVS ACCESS

  The DSPAM source tree can be downloaded via read-only cvs access using the
  following commands:

  cvs -d :pserver:cvs@cvs.nuclearelephant.com:/usr/local/cvsroot login
  cvs -d :pserver:cvs@cvs.nuclearelephant.com:/usr/local/cvsroot co dspam 

  DSPAM has been version-tagged in cvs so that you can checkout a particular
  version by using this format:

  co -r dspam-2_7_4 dspam

