You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by km...@apache.org on 2015/04/29 19:04:11 UTC
svn commit: r1676792 [11/17] - in /spamassassin/site/full/3.4.x: ./ doc/
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Razor2.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Razor2.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Razor2.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Razor2.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,27 @@
+NAME
+ Mail::SpamAssassin::Plugin::Razor2 - perform Razor check of messages
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::Razor2
+
+DESCRIPTION
+ Vipul's Razor is a distributed, collaborative, spam detection and
+ filtering network based on user submissions of spam. Detection is done
+ with signatures that efficiently spot mutating spam content and user
+ input is validated through reputation assignments.
+
+ See http://razor.sourceforge.net/ for more information about Razor.
+
+USER SETTINGS
+ use_razor2 (0|1) (default: 1)
+ Whether to use Razor2, if it is available.
+
+ADMINISTRATOR SETTINGS
+ razor_timeout n (default: 5)
+ How many seconds you wait for Razor to complete before you go on
+ without the results
+
+ razor_config filename
+ Define the filename used to store Razor's configuration settings.
+ Currently this is left to Razor to decide.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,56 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>RelayCountry - add message metadata indicating the country code of each relay</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+ <li><a href="#requirement">REQUIREMENT</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>RelayCountry - add message metadata indicating the country code of each relay</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::RelayCountry</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>The RelayCountry plugin attempts to determine the domain country codes
+of each relay used in the delivery path of messages and add that information
+to the message metadata as "X-Relay-Countries", or the <code>_RELAYCOUNTRY_</code>
+header markup.</p>
+<p>
+</p>
+<hr />
+<h1><a name="requirement">REQUIREMENT</a></h1>
+<p>This plugin requires the Geo::IP module from CPAN. For backward
+compatibility IP::Country::Fast is used if Geo::IP is not installed.</p>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_RelayCountry.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,17 @@
+NAME
+ RelayCountry - add message metadata indicating the country code of each
+ relay
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::RelayCountry
+
+DESCRIPTION
+ The RelayCountry plugin attempts to determine the domain country codes
+ of each relay used in the delivery path of messages and add that
+ information to the message metadata as "X-Relay-Countries", or the
+ "_RELAYCOUNTRY_" header markup.
+
+REQUIREMENT
+ This plugin requires the Geo::IP module from CPAN. For backward
+ compatibility IP::Country::Fast is used if Geo::IP is not installed.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,107 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::ReplaceTags - tags for SpamAssassin rules</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#rule_definitions_and_privileged_settings">RULE DEFINITIONS AND PRIVILEGED SETTINGS</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::ReplaceTags - tags for SpamAssassin rules</p>
+<p>The plugin allows rules to contain regular expression tags to be used in
+regular expression rules. The tags make it much easier to maintain
+complicated rules.</p>
+<p>Warning: This plugin relies on data structures specific to this version of
+SpamAssasin; it is not guaranteed to work with other versions of SpamAssassin.</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::ReplaceTags</pre>
+<pre>
+ replace_start <
+ replace_end ></pre>
+<pre>
+ replace_tag A [a@]
+ replace_tag G [gk]
+ replace_tag I [il|!1y\?\xcc\xcd\xce\xcf\xec\xed\xee\xef]
+ replace_tag R [r3]
+ replace_tag V (?:[vu]|\\\/)
+ replace_tag SP [\s~_-]</pre>
+<pre>
+ body VIAGRA_OBFU /(?!viagra)<V>+<SP>*<I>+<SP>*<A>+<SP>*<G>+<SP>*<R>+<SP>*<A>+/i
+ describe VIAGRA_OBFU Attempt to obfuscate "viagra"</pre>
+<pre>
+ replace_rules VIAGRA_OBFU</pre>
+<p>
+</p>
+<hr />
+<h1><a name="rule_definitions_and_privileged_settings">RULE DEFINITIONS AND PRIVILEGED SETTINGS</a></h1>
+<dl>
+<dt><strong><a name="replace_tag_tagname_expression" class="item">replace_tag tagname expression</a></strong></dt>
+
+<dd>
+<p>Assign a valid regular expression to tagname.</p>
+<p>Note: It is not recommended to put quantifiers inside the tag, it's better to
+put them inside the rule itself for greater flexibility.</p>
+</dd>
+<dt><strong><a name="replace_pre_tagname_expression" class="item">replace_pre tagname expression</a></strong></dt>
+
+<dd>
+<p>Assign a valid regular expression to tagname. The expression will be
+placed before each tag that is replaced.</p>
+</dd>
+<dt><strong><a name="replace_inter_tagname_expression" class="item">replace_inter tagname expression</a></strong></dt>
+
+<dd>
+<p>Assign a valid regular expression to tagname. The expression will be
+placed between each two immediately adjacent tags that are replaced.</p>
+</dd>
+<dt><strong><a name="replace_post_tagname_expression" class="item">replace_post tagname expression</a></strong></dt>
+
+<dd>
+<p>Assign a valid regular expression to tagname. The expression will be
+placed after each tag that is replaced.</p>
+</dd>
+<dt><strong><a name="replace_rules_list_of_tests" class="item">replace_rules list_of_tests</a></strong></dt>
+
+<dd>
+<p>Specify a list of symbolic test names (separated by whitespace) of tests which
+should be modified using replacement tags. Only simple regular expression
+body, header, uri, full, rawbody tests are supported.</p>
+</dd>
+<dt><strong><a name="replace_start_string" class="item">replace_start string</a></strong></dt>
+
+<dt><strong><a name="replace_end_string" class="item">replace_end string</a></strong></dt>
+
+<dd>
+<p>String(s) which indicate the start and end of a tag inside a rule. Only tags
+enclosed by the start and end strings are found and replaced.</p>
+</dd>
+</dl>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_ReplaceTags.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,60 @@
+NAME
+ Mail::SpamAssassin::Plugin::ReplaceTags - tags for SpamAssassin rules
+
+ The plugin allows rules to contain regular expression tags to be used in
+ regular expression rules. The tags make it much easier to maintain
+ complicated rules.
+
+ Warning: This plugin relies on data structures specific to this version
+ of SpamAssasin; it is not guaranteed to work with other versions of
+ SpamAssassin.
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::ReplaceTags
+
+ replace_start <
+ replace_end >
+
+ replace_tag A [a@]
+ replace_tag G [gk]
+ replace_tag I [il|!1y\?\xcc\xcd\xce\xcf\xec\xed\xee\xef]
+ replace_tag R [r3]
+ replace_tag V (?:[vu]|\\\/)
+ replace_tag SP [\s~_-]
+
+ body VIAGRA_OBFU /(?!viagra)<V>+<SP>*<I>+<SP>*<A>+<SP>*<G>+<SP>*<R>+<SP>*<A>+/i
+ describe VIAGRA_OBFU Attempt to obfuscate "viagra"
+
+ replace_rules VIAGRA_OBFU
+
+RULE DEFINITIONS AND PRIVILEGED SETTINGS
+ replace_tag tagname expression
+ Assign a valid regular expression to tagname.
+
+ Note: It is not recommended to put quantifiers inside the tag, it's
+ better to put them inside the rule itself for greater flexibility.
+
+ replace_pre tagname expression
+ Assign a valid regular expression to tagname. The expression will be
+ placed before each tag that is replaced.
+
+ replace_inter tagname expression
+ Assign a valid regular expression to tagname. The expression will be
+ placed between each two immediately adjacent tags that are replaced.
+
+ replace_post tagname expression
+ Assign a valid regular expression to tagname. The expression will be
+ placed after each tag that is replaced.
+
+ replace_rules list_of_tests
+ Specify a list of symbolic test names (separated by whitespace) of
+ tests which should be modified using replacement tags. Only simple
+ regular expression body, header, uri, full, rawbody tests are
+ supported.
+
+ replace_start string
+ replace_end string
+ String(s) which indicate the start and end of a tag inside a rule.
+ Only tags enclosed by the start and end strings are found and
+ replaced.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,54 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::Reuse - For reusing old rule hits during a mass-check</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::Reuse - For reusing old rule hits during a mass-check</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::Reuse</pre>
+<pre>
+ ifplugin Mail::SpamAssassin::Plugin::Reuse</pre>
+<pre>
+ reuse NETWORK_RULE [ NETWORK_RULE_OLD_NAME ]</pre>
+<pre>
+ endif</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>The purpose of this plugin is to work in conjunction with <strong>mass-check
+--reuse</strong> to map rules hit in input messages to rule hits in the
+mass-check output.</p>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Reuse.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,18 @@
+NAME
+ Mail::SpamAssassin::Plugin::Reuse - For reusing old rule hits during a
+ mass-check
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::Reuse
+
+ ifplugin Mail::SpamAssassin::Plugin::Reuse
+
+ reuse NETWORK_RULE [ NETWORK_RULE_OLD_NAME ]
+
+ endif
+
+DESCRIPTION
+ The purpose of this plugin is to work in conjunction with mass-check
+ --reuse to map rules hit in input messages to rule hits in the
+ mass-check output.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,50 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::Rule2XSBody - speed up SpamAssassin by compiling regexps</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::Rule2XSBody - speed up SpamAssassin by compiling regexps</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This plugin will use native-code object files representing the ruleset,
+in order to provide significant speedups in rule evaluation.</p>
+<p>Note that <code>sa-compile</code> must be run in advance, in order to compile the
+ruleset using <code>re2c</code> and the C compiler. See the <code>sa-compile</code>
+documentation for more details.</p>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Rule2XSBody.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,15 @@
+NAME
+ Mail::SpamAssassin::Plugin::Rule2XSBody - speed up SpamAssassin by
+ compiling regexps
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody
+
+DESCRIPTION
+ This plugin will use native-code object files representing the ruleset,
+ in order to provide significant speedups in rule evaluation.
+
+ Note that "sa-compile" must be run in advance, in order to compile the
+ ruleset using "re2c" and the C compiler. See the "sa-compile"
+ documentation for more details.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,769 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::SPF - perform SPF verification tests</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+ <li><a href="#user_settings">USER SETTINGS</a></li>
+ <li><a href="#administrator_options">ADMINISTRATOR OPTIONS</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::SPF - perform SPF verification tests</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::SPF</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This plugin checks a message against Sender Policy Framework (SPF)
+records published by the domain owners in DNS to fight email address
+forgery and make it easier to identify spams.</p>
+<p>
+</p>
+<hr />
+<h1><a name="user_settings">USER SETTINGS</a></h1>
+<dl>
+<dt><strong><a name="whitelist_from_spf_user_example_com" class="item">whitelist_from_spf <a href="mailto:user@example.com">user@example.com</a></a></strong></dt>
+
+<dd>
+<p>Works similarly to whitelist_from, except that in addition to matching
+a sender address, a check against the domain's SPF record must pass.
+The first parameter is an address to whitelist, and the second is a string
+to match the relay's rDNS.</p>
+<p>Just like whitelist_from, multiple addresses per line, separated by spaces,
+are OK. Multiple <code>whitelist_from_spf</code> lines are also OK.</p>
+<p>The headers checked for whitelist_from_spf addresses are the same headers
+used for SPF checks (Envelope-From, Return-Path, X-Envelope-From, etc).</p>
+<p>Since this whitelist requires an SPF check to be made, network tests must be
+enabled. It is also required that your trust path be correctly configured.
+See the section on <code>trusted_networks</code> for more info on trust paths.</p>
+<p>e.g.</p>
+<pre>
+ whitelist_from_spf joe@example.com fred@example.com
+ whitelist_from_spf *@example.com</pre>
+</dd>
+<dt><strong><a name="def_whitelist_from_spf_user_example_com" class="item">def_whitelist_from_spf <a href="mailto:user@example.com">user@example.com</a></a></strong></dt>
+
+<dd>
+<p>Same as <code>whitelist_from_spf</code>, but used for the default whitelist entries
+in the SpamAssassin distribution. The whitelist score is lower, because
+these are often targets for spammer spoofing.</p>
+</dd>
+</dl>
+<p>
+</p>
+<hr />
+<h1><a name="administrator_options">ADMINISTRATOR OPTIONS</a></h1>
+<dl>
+<dt><strong><a name="n" class="item">spf_timeout n (default: 5)</a></strong></dt>
+
+<dd>
+<p>How many seconds to wait for an SPF query to complete, before scanning
+continues without the SPF result. A numeric value is optionally suffixed
+by a time unit (s, m, h, d, w, indicating seconds (default), minutes, hours,
+days, weeks).</p>
+</dd>
+<dt><strong><a name="do_not_use_mail_spf" class="item">do_not_use_mail_spf (0|1) (default: 0)</a></strong></dt>
+
+<dd>
+<p>By default the plugin will try to use the Mail::SPF module for SPF checks if
+it can be loaded. If Mail::SPF cannot be used the plugin will fall back to
+using the legacy Mail::SPF::Query module if it can be loaded.</p>
+<p>Use this option to stop the plugin from using Mail::SPF and cause it to try to
+use Mail::SPF::Query instead.</p>
+</dd>
+<dt><strong><a name="do_not_use_mail_spf_query" class="item">do_not_use_mail_spf_query (0|1) (default: 0)</a></strong></dt>
+
+<dd>
+<p>As above, but instead stop the plugin from trying to use Mail::SPF::Query and
+cause it to only try to use Mail::SPF.</p>
+</dd>
+<dt><strong><a name="ignore_received_spf_header" class="item">ignore_received_spf_header (0|1) (default: 0)</a></strong></dt>
+
+<dd>
+<p>By default, to avoid unnecessary DNS lookups, the plugin will try to use the
+SPF results found in any <code>Received-SPF</code> headers it finds in the message that
+could only have been added by an internal relay.</p>
+<p>Set this option to 1 to ignore any <code>Received-SPF</code> headers present and to have
+the plugin perform the SPF check itself.</p>
+<p>Note that unless the plugin finds an <code>identity=helo</code>, or some unsupported
+identity, it will assume that the result is a mfrom SPF check result. The
+only identities supported are <code>mfrom</code>, <code>mailfrom</code> and <code>helo</code>.</p>
+</dd>
+<dt><strong><a name="use_newest_received_spf_header" class="item">use_newest_received_spf_header (0|1) (default: 0)</a></strong></dt>
+
+<dd>
+<p>By default, when using <code>Received-SPF</code> headers, the plugin will attempt to use
+the oldest (bottom most) <code>Received-SPF</code> headers, that were added by internal
+relays, that it can parse results from since they are the most likely to be
+accurate. This is done so that if you have an incoming mail setup where one
+of your primary MXes doesn't know about a secondary MX (or your MXes don't
+know about some sort of forwarding relay that SA considers trusted+internal)
+but SA is aware of the actual domain boundary (internal_networks setting) SA
+will use the results that are most accurate.</p>
+<p>Use this option to start with the newest (top most) <code>Received-SPF</code> headers,
+working downwards until results are successfully parsed.</p>
+</dd>
+<dt><strong><a name="has_check_for_spf_errors" class="item">has_check_for_spf_errors</a></strong></dt>
+
+<dd>
+<p>Adds capability check for "if can()" for check_for_spf_permerror, check_for_spf_temperror, check_for_spf_helo_permerror and check_for_spf_helo_permerror</p>
+<pre>
+
+=cut</pre>
+<p>sub has_check_for_spf_errors { 1 }</p>
+<p># SPF support
+sub check_for_spf_pass {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_pass};
+}</p>
+<p>sub check_for_spf_neutral {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_neutral};
+}</p>
+<p>sub check_for_spf_none {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_none};
+}</p>
+<p>sub check_for_spf_fail {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ if ($scanner->{spf_failure_comment}) {
+ $scanner->test_log ($scanner->{spf_failure_comment});
+ }
+ $scanner->{spf_fail};
+}</p>
+<p>sub check_for_spf_softfail {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_softfail};
+}</p>
+<p>sub check_for_spf_permerror {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_permerror};
+}</p>
+<p>sub check_for_spf_temperror {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 0) unless $scanner->{spf_checked};
+ $scanner->{spf_temperror};
+}</p>
+<p>sub check_for_spf_helo_pass {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_pass};
+}</p>
+<p>sub check_for_spf_helo_neutral {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_neutral};
+}</p>
+<p>sub check_for_spf_helo_none {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_none};
+}</p>
+<p>sub check_for_spf_helo_fail {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ if ($scanner->{spf_helo_failure_comment}) {
+ $scanner->test_log ($scanner->{spf_helo_failure_comment});
+ }
+ $scanner->{spf_helo_fail};
+}</p>
+<p>sub check_for_spf_helo_softfail {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_softfail};
+}</p>
+<p>sub check_for_spf_helo_permerror {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_permerror};
+}</p>
+<p>sub check_for_spf_helo_temperror {
+ my ($self, $scanner) = @_;
+ $self->_check_spf ($scanner, 1) unless $scanner->{spf_helo_checked};
+ $scanner->{spf_helo_temperror};
+}</p>
+<p>sub check_for_spf_whitelist_from {
+ my ($self, $scanner) = @_;
+ $self-><code>_check_spf_whitelist($scanner)</code> unless $scanner->{spf_whitelist_from_checked};
+ $scanner->{spf_whitelist_from};
+}</p>
+<p>sub check_for_def_spf_whitelist_from {
+ my ($self, $scanner) = @_;
+ $self-><code>_check_def_spf_whitelist($scanner)</code> unless $scanner->{def_spf_whitelist_from_checked};
+ $scanner->{def_spf_whitelist_from};
+}</p>
+<p>sub _check_spf {
+ my ($self, $scanner, $ishelo) = @_;</p>
+<pre>
+ my $timer = $self->{main}->time_method("check_spf");</pre>
+<pre>
+ # we can re-use results from any *INTERNAL* Received-SPF header in the message...
+ # we can't use results from trusted but external hosts since (i) spf checks are
+ # supposed to be done "on the domain boundary", (ii) even if an external header
+ # has a result that matches what we would get, the check was probably done on a
+ # different envelope (like the apache.org list servers checking the ORCPT and
+ # then using a new envelope to send the mail from the list) and (iii) if the
+ # checks are being done right and the envelope isn't being changed it's 99%
+ # likely that the trusted+external host really should be defined as part of your
+ # internal network
+ if ($scanner->{conf}->{ignore_received_spf_header}) {
+ dbg("spf: ignoring any Received-SPF headers from internal hosts, by admin setting");
+ } elsif ($scanner->{checked_for_received_spf_header}) {
+ dbg("spf: already checked for Received-SPF headers, proceeding with DNS based checks");
+ } else {
+ $scanner->{checked_for_received_spf_header} = 1;
+ dbg("spf: checking to see if the message has a Received-SPF header that we can use");</pre>
+<pre>
+ my @internal_hdrs = split("\n", $scanner->get('ALL-INTERNAL'));
+ unless ($scanner->{conf}->{use_newest_received_spf_header}) {
+ # look for the LAST (earliest in time) header, it'll be the most accurate
+ @internal_hdrs = reverse(@internal_hdrs);
+ } else {
+ dbg("spf: starting with the newest Received-SPF headers first");
+ }</pre>
+<pre>
+ foreach my $hdr (@internal_hdrs) {
+ local($1,$2);
+ if ($hdr =~ /^received-spf:/i) {
+ dbg("spf: found a Received-SPF header added by an internal host: $hdr");</pre>
+<pre>
+ # old version:
+ # Received-SPF: pass (herse.apache.org: domain of spamassassin@dostech.ca
+ # designates 69.61.78.188 as permitted sender)</pre>
+<pre>
+ # new version:
+ # Received-SPF: pass (dostech.ca: 69.61.78.188 is authorized to use
+ # 'spamassassin@dostech.ca' in 'mfrom' identity (mechanism 'mx' matched))
+ # receiver=FC5-VPC; identity=mfrom; envelope-from="spamassassin@dostech.ca";
+ # helo=smtp.dostech.net; client-ip=69.61.78.188</pre>
+<pre>
+ # Received-SPF: pass (dostech.ca: 69.61.78.188 is authorized to use 'dostech.ca'
+ # in 'helo' identity (mechanism 'mx' matched)) receiver=FC5-VPC; identity=helo;
+ # helo=dostech.ca; client-ip=69.61.78.188</pre>
+<pre>
+ # <a href="http://www.openspf.org/RFC_4408#header-field">http://www.openspf.org/RFC_4408#header-field</a>
+ # wtf - for some reason something is sticking an extra space between the header name and field value
+ if ($hdr =~ /^received-spf:\s*(pass|neutral|(?:soft)?fail|none)\b(?:.*\bidentity=(\S+?);?\b)?/i) {
+ my $result = lc($1);</pre>
+<pre>
+ my $identity = ''; # we assume it's a mfrom check if we can't tell otherwise
+ if (defined $2) {
+ $identity = lc($2);
+ if ($identity eq 'mfrom' || $identity eq 'mailfrom') {
+ next if $scanner->{spf_checked};
+ $identity = '';
+ } elsif ($identity eq 'helo') {
+ next if $scanner->{spf_helo_checked};
+ $identity = 'helo_';
+ } else {
+ dbg("spf: found unknown identity value, cannot use: $identity");
+ next; # try the next Received-SPF header, if any
+ }
+ } else {
+ next if $scanner->{spf_checked};
+ }</pre>
+<pre>
+ # we'd set these if we actually did the check
+ $scanner->{"spf_${identity}checked"} = 1;
+ $scanner->{"spf_${identity}pass"} = 0;
+ $scanner->{"spf_${identity}neutral"} = 0;
+ $scanner->{"spf_${identity}none"} = 0;
+ $scanner->{"spf_${identity}fail"} = 0;
+ $scanner->{"spf_${identity}softfail"} = 0;
+ $scanner->{"spf_${identity}failure_comment"} = undef;</pre>
+<pre>
+ # and the result
+ $scanner->{"spf_${identity}${result}"} = 1;
+ dbg("spf: re-using %s result from Received-SPF header: %s",
+ ($identity ? 'helo' : 'mfrom'), $result);</pre>
+<pre>
+ # if we've got *both* the mfrom and helo results we're done
+ return if ($scanner->{spf_checked} && $scanner->{spf_helo_checked});</pre>
+<pre>
+ } else {
+ dbg("spf: could not parse result from existing Received-SPF header");
+ }</pre>
+<pre>
+ } elsif ($hdr =~ /^Authentication-Results:.*;\s*SPF\s*=\s*([^;]*)/i) {
+ dbg("spf: found an Authentication-Results header added by an internal host: $hdr");</pre>
+<pre>
+ # RFC 5451 header parser - added by D. Stussy 2010-09-09:
+ # Authentication-Results: mail.example.com; SPF=none smtp.mailfrom=example.org (comment)</pre>
+<pre>
+ my $tmphdr = $1;
+ if ($tmphdr =~ /^(pass|neutral|(?:hard|soft)?fail|none)(?:[^;]*?\bsmtp\.(\S+)\s*=[^;]+)?/i) {
+ my $result = lc($1);
+ $result = 'fail' if $result eq 'hardfail'; # RFC5451 permits this</pre>
+<pre>
+ my $identity = ''; # we assume it's a mfrom check if we can't tell otherwise
+ if (defined $2) {
+ $identity = lc($2);
+ if ($identity eq 'mfrom' || $identity eq 'mailfrom') {
+ next if $scanner->{spf_checked};
+ $identity = '';
+ } elsif ($identity eq 'helo') {
+ next if $scanner->{spf_helo_checked};
+ $identity = 'helo_';
+ } else {
+ dbg("spf: found unknown identity value, cannot use: $identity");
+ next; # try the next Authentication-Results header, if any
+ }
+ } else {
+ next if $scanner->{spf_checked};
+ }</pre>
+<pre>
+ # we'd set these if we actually did the check
+ $scanner->{"spf_${identity}checked"} = 1;
+ $scanner->{"spf_${identity}pass"} = 0;
+ $scanner->{"spf_${identity}neutral"} = 0;
+ $scanner->{"spf_${identity}none"} = 0;
+ $scanner->{"spf_${identity}fail"} = 0;
+ $scanner->{"spf_${identity}softfail"} = 0;
+ $scanner->{"spf_${identity}failure_comment"} = undef;</pre>
+<pre>
+ # and the result
+ $scanner->{"spf_${identity}${result}"} = 1;
+ dbg("spf: re-using %s result from Authentication-Results header: %s",
+ ($identity ? 'helo' : 'mfrom'), $result);</pre>
+<pre>
+ # if we've got *both* the mfrom and helo results we're done
+ return if ($scanner->{spf_checked} && $scanner->{spf_helo_checked});</pre>
+<pre>
+ } else {
+ dbg("spf: could not parse result from existing Authentication-Results header");
+ }
+ }
+ }
+ # we can return if we've found the one we're being asked to get
+ return if ( ($ishelo && $scanner->{spf_helo_checked}) ||
+ (!$ishelo && $scanner->{spf_checked}) );
+ }</pre>
+<pre>
+ # abort if dns or an spf module isn't available
+ return unless $scanner->is_dns_available();
+ return if $self->{no_spf_module};</pre>
+<pre>
+ # select the SPF module we're going to use
+ unless (defined $self->{has_mail_spf}) {
+ my $eval_stat;
+ eval {
+ die("Mail::SPF disabled by admin setting\n") if $scanner->{conf}->{do_not_use_mail_spf};</pre>
+<pre>
+ require Mail::SPF;
+ if (!defined $Mail::SPF::VERSION || $Mail::SPF::VERSION < 2.001) {
+ die "Mail::SPF 2.001 or later required, this is ".
+ (defined $Mail::SPF::VERSION ? $Mail::SPF::VERSION : 'unknown')."\n";
+ }
+ # Mail::SPF::Server can be re-used, and we get to use our own resolver object!
+ $self->{spf_server} = Mail::SPF::Server->new(
+ hostname => $scanner->get_tag('HOSTNAME'),
+ dns_resolver => $self->{main}->{resolver},
+ max_dns_interactive_terms => 15);
+ # Bug 7112: max_dns_interactive_terms defaults to 10, but even 14 is
+ # not enough for ebay.com, setting it to 15
+ 1;
+ } or do {
+ $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ };</pre>
+<pre>
+ if (!defined($eval_stat)) {
+ dbg("spf: using Mail::SPF for SPF checks");
+ $self->{has_mail_spf} = 1;
+ } else {
+ # strip the @INC paths... users are going to see it and think there's a problem even though
+ # we're going to fall back to Mail::SPF::Query (which will display the same paths if it fails)
+ $eval_stat =~ s#^Can't locate Mail/SPFd.pm in \@INC .*#Can't locate Mail/SPFd.pm#;
+ dbg("spf: cannot load Mail::SPF module or create Mail::SPF::Server object: $eval_stat");
+ dbg("spf: attempting to use legacy Mail::SPF::Query module instead");</pre>
+<pre>
+ undef $eval_stat;
+ eval {
+ die("Mail::SPF::Query disabled by admin setting\n") if $scanner->{conf}->{do_not_use_mail_spf_query};</pre>
+<pre>
+ require Mail::SPF::Query;
+ if (!defined $Mail::SPF::Query::VERSION || $Mail::SPF::Query::VERSION < 1.996) {
+ die "Mail::SPF::Query 1.996 or later required, this is ".
+ (defined $Mail::SPF::Query::VERSION ? $Mail::SPF::Query::VERSION : 'unknown')."\n";
+ }
+ 1;
+ } or do {
+ $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ };</pre>
+<pre>
+ if (!defined($eval_stat)) {
+ dbg("spf: using Mail::SPF::Query for SPF checks");
+ $self->{has_mail_spf} = 0;
+ } else {
+ dbg("spf: cannot load Mail::SPF::Query module: $eval_stat");
+ dbg("spf: one of Mail::SPF or Mail::SPF::Query is required for SPF checks, SPF checks disabled");
+ $self->{no_spf_module} = 1;
+ return;
+ }
+ }
+ }</pre>
+<pre>
+ # skip SPF checks if the A/MX records are nonexistent for the From
+ # domain, anyway, to avoid crappy messages from slowing us down
+ # (bug 3016)
+ return if $scanner->check_for_from_dns();</pre>
+<pre>
+ if ($ishelo) {
+ # SPF HELO-checking variant
+ $scanner->{spf_helo_checked} = 1;
+ $scanner->{spf_helo_pass} = 0;
+ $scanner->{spf_helo_neutral} = 0;
+ $scanner->{spf_helo_none} = 0;
+ $scanner->{spf_helo_fail} = 0;
+ $scanner->{spf_helo_softfail} = 0;
+ $scanner->{spf_helo_permerror} = 0;
+ $scanner->{spf_helo_temperror} = 0;
+ $scanner->{spf_helo_failure_comment} = undef;
+ } else {
+ # SPF on envelope sender (where possible)
+ $scanner->{spf_checked} = 1;
+ $scanner->{spf_pass} = 0;
+ $scanner->{spf_neutral} = 0;
+ $scanner->{spf_none} = 0;
+ $scanner->{spf_fail} = 0;
+ $scanner->{spf_softfail} = 0;
+ $scanner->{spf_permerror} = 0;
+ $scanner->{spf_temperror} = 0;
+ $scanner->{spf_failure_comment} = undef;
+ }</pre>
+<pre>
+ my $lasthop = $self->_get_relay($scanner);
+ if (!defined $lasthop) {
+ dbg("spf: no suitable relay for spf use found, skipping SPF%s check",
+ $ishelo ? '-helo' : '');
+ return;
+ }</pre>
+<pre>
+ my $ip = $lasthop->{ip}; # always present
+ my $helo = $lasthop->{helo}; # could be missing
+ $scanner->{sender} = '' unless $scanner->{sender_got};</pre>
+<pre>
+ if ($ishelo) {
+ unless ($helo) {
+ dbg("spf: cannot check HELO, HELO value unknown");
+ return;
+ }
+ dbg("spf: checking HELO (helo=$helo, ip=$ip)");
+ } else {
+ $self->_get_sender($scanner) unless $scanner->{sender_got};</pre>
+<pre>
+ # TODO: we're supposed to use the helo domain as the sender identity (for
+ # mfrom checks) if the sender is the null sender, however determining that
+ # it's the null sender, and not just a failure to get the envelope isn't
+ # exactly trivial... so for now we'll just skip the check</pre>
+<pre>
+ if (!$scanner->{sender}) {
+ # we already dbg'd that we couldn't get an Envelope-From and can't do SPF
+ return;
+ }
+ dbg("spf: checking EnvelopeFrom (helo=%s, ip=%s, envfrom=%s)",
+ ($helo ? $helo : ''), $ip, $scanner->{sender});
+ }</pre>
+<pre>
+ # this test could probably stand to be more strict, but try to test
+ # any invalid HELO hostname formats with a header rule
+ if ($ishelo && ($helo =~ /^[\[!]?\d+\.\d+\.\d+\.\d+[\]!]?$/ || $helo =~ /^[^.]+$/)) {
+ dbg("spf: cannot check HELO of '$helo', skipping");
+ return;
+ }</pre>
+<pre>
+ if ($helo && $scanner->server_failed_to_respond_for_domain($helo)) {
+ dbg("spf: we had a previous timeout on '$helo', skipping");
+ return;
+ }</pre>
+<pre>
+ my ($result, $comment, $text, $err);</pre>
+<pre>
+ # use Mail::SPF if it was available, otherwise use the legacy Mail::SPF::Query
+ if ($self->{has_mail_spf}) {</pre>
+<pre>
+ # TODO: currently we won't get to here for a mfrom check with a null sender
+ my $identity = $ishelo ? $helo : ($scanner->{sender}); # || $helo);</pre>
+<pre>
+ unless ($identity) {
+ dbg("spf: cannot determine %s identity, skipping %s SPF check",
+ ($ishelo ? 'helo' : 'mfrom'), ($ishelo ? 'helo' : 'mfrom') );
+ return;
+ }
+ $helo ||= 'unknown'; # only used for macro expansion in the mfrom explanation</pre>
+<pre>
+ my $request;
+ eval {
+ $request = Mail::SPF::Request->new( scope => $ishelo ? 'helo' : 'mfrom',
+ identity => $identity,
+ ip_address => $ip,
+ helo_identity => $helo );
+ 1;
+ } or do {
+ my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ dbg("spf: cannot create Mail::SPF::Request object: $eval_stat");
+ return;
+ };</pre>
+<pre>
+ my $timeout = $scanner->{conf}->{spf_timeout};</pre>
+<pre>
+ my $timer = Mail::SpamAssassin::Timeout->new(
+ { secs => $timeout, deadline => $scanner->{master_deadline} });
+ $err = $timer->run_and_catch(sub {</pre>
+<pre>
+ my $query = $self->{spf_server}->process($request);</pre>
+<pre>
+ $result = $query->code;
+ $comment = $query->authority_explanation if $query->can("authority_explanation");
+ $text = $query->text;</pre>
+<pre>
+ });</pre>
+<pre>
+ } else {</pre>
+<pre>
+ if (!$helo) {
+ dbg("spf: cannot get HELO, cannot use Mail::SPF::Query, consider installing Mail::SPF");
+ return;
+ }</pre>
+<pre>
+ # TODO: if we start doing checks on the null sender using the helo domain
+ # be sure to fix this so that it uses the correct sender identity
+ my $query;
+ eval {
+ $query = Mail::SPF::Query->new (ip => $ip,
+ sender => $scanner->{sender},
+ helo => $helo,
+ debug => 0,
+ trusted => 0);
+ 1;
+ } or do {
+ my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
+ dbg("spf: cannot create Mail::SPF::Query object: $eval_stat");
+ return;
+ };</pre>
+<pre>
+ my $timeout = $scanner->{conf}->{spf_timeout};</pre>
+<pre>
+ my $timer = Mail::SpamAssassin::Timeout->new(
+ { secs => $timeout, deadline => $scanner->{master_deadline} });
+ $err = $timer->run_and_catch(sub {</pre>
+<pre>
+ ($result, $comment) = $query->result();</pre>
+<pre>
+ });</pre>
+<pre>
+ } # end of differences between Mail::SPF and Mail::SPF::Query</pre>
+<pre>
+ if ($err) {
+ chomp $err;
+ warn("spf: lookup failed: $err\n");
+ return 0;
+ }</pre>
+<pre>
+ $result ||= 'timeout'; # bug 5077
+ $comment ||= '';
+ $comment =~ s/\s+/ /gs; # no newlines please
+ $text ||= '';
+ $text =~ s/\s+/ /gs; # no newlines please</pre>
+<pre>
+ if ($ishelo) {
+ if ($result eq 'pass') { $scanner->{spf_helo_pass} = 1; }
+ elsif ($result eq 'neutral') { $scanner->{spf_helo_neutral} = 1; }
+ elsif ($result eq 'none') { $scanner->{spf_helo_none} = 1; }
+ elsif ($result eq 'fail') { $scanner->{spf_helo_fail} = 1; }
+ elsif ($result eq 'softfail') { $scanner->{spf_helo_softfail} = 1; }
+ elsif ($result eq 'permerror') { $scanner->{spf_helo_permerror} = 1; }
+ elsif ($result eq 'temperror') { $scanner->{spf_helo_temperror} = 1; }
+ elsif ($result eq 'error') { $scanner->{spf_helo_temperror} = 1; }</pre>
+<pre>
+ if ($result eq 'fail') { # RFC 4408 6.2
+ $scanner->{spf_helo_failure_comment} = "SPF failed: $comment";
+ }
+ } else {
+ if ($result eq 'pass') { $scanner->{spf_pass} = 1; }
+ elsif ($result eq 'neutral') { $scanner->{spf_neutral} = 1; }
+ elsif ($result eq 'none') { $scanner->{spf_none} = 1; }
+ elsif ($result eq 'fail') { $scanner->{spf_fail} = 1; }
+ elsif ($result eq 'softfail') { $scanner->{spf_softfail} = 1; }
+ elsif ($result eq 'permerror') { $scanner->{spf_permerror} = 1; }
+ elsif ($result eq 'temperror') { $scanner->{spf_temperror} = 1; }
+ elsif ($result eq 'error') { $scanner->{spf_temperror} = 1; }</pre>
+<pre>
+ if ($result eq 'fail') { # RCF 4408 6.2
+ $scanner->{spf_failure_comment} = "SPF failed: $comment";
+ }
+ }</pre>
+<pre>
+ dbg("spf: query for $scanner->{sender}/$ip/$helo: result: $result, comment: $comment, text: $text");
+}</pre>
+<p>sub _get_relay {
+ my ($self, $scanner) = @_;</p>
+<pre>
+ # dos: first external relay, not first untrusted
+ return $scanner->{relays_external}->[0];
+}</pre>
+<p>sub _get_sender {
+ my ($self, $scanner) = @_;
+ my $sender;</p>
+<pre>
+ $scanner->{sender_got} = 1;
+ $scanner->{sender} = '';</pre>
+<pre>
+ my $relay = $self->_get_relay($scanner);
+ if (defined $relay) {
+ $sender = $relay->{envfrom};
+ }</pre>
+<pre>
+ if ($sender) {
+ dbg("spf: found Envelope-From in first external Received header");
+ }
+ else {
+ # We cannot use the env-from data, since it went through 1 or more relays
+ # since the untrusted sender and they may have rewritten it.
+ if ($scanner->{num_relays_trusted} > 0 && !$scanner->{conf}->{always_trust_envelope_sender}) {
+ dbg("spf: relayed through one or more trusted relays, cannot use header-based Envelope-From, skipping");
+ return;
+ }</pre>
+<pre>
+ # we can (apparently) use whatever the current Envelope-From was,
+ # from the Return-Path, X-Envelope-From, or whatever header.
+ # it's better to get it from Received though, as that is updated
+ # hop-by-hop.
+ $sender = $scanner->get("EnvelopeFrom:addr");
+ }</pre>
+<pre>
+ if (!$sender) {
+ dbg("spf: cannot get Envelope-From, cannot use SPF");
+ return; # avoid setting $scanner->{sender} to undef
+ }</pre>
+<pre>
+ return $scanner->{sender} = lc $sender;
+}</pre>
+<p>sub _check_spf_whitelist {
+ my ($self, $scanner) = @_;</p>
+<pre>
+ $scanner->{spf_whitelist_from_checked} = 1;
+ $scanner->{spf_whitelist_from} = 0;</pre>
+<pre>
+ # if we've already checked for an SPF PASS and didn't get it don't waste time
+ # checking to see if the sender address is in the spf whitelist
+ if ($scanner->{spf_checked} && !$scanner->{spf_pass}) {
+ dbg("spf: whitelist_from_spf: already checked spf and didn't get pass, skipping whitelist check");
+ return;
+ }</pre>
+<pre>
+ $self->_get_sender($scanner) unless $scanner->{sender_got};</pre>
+<pre>
+ unless ($scanner->{sender}) {
+ dbg("spf: spf_whitelist_from: could not find useable envelope sender");
+ return;
+ }</pre>
+<pre>
+ $scanner->{spf_whitelist_from} = $self->_wlcheck($scanner,'whitelist_from_spf');
+ if (!$scanner->{spf_whitelist_from}) {
+ $scanner->{spf_whitelist_from} = $self->_wlcheck($scanner, 'whitelist_auth');
+ }</pre>
+<pre>
+ # if the message doesn't pass SPF validation, it can't pass an SPF whitelist
+ if ($scanner->{spf_whitelist_from}) {
+ if ($self->check_for_spf_pass($scanner)) {
+ dbg("spf: whitelist_from_spf: $scanner->{sender} is in user's WHITELIST_FROM_SPF and passed SPF check");
+ } else {
+ dbg("spf: whitelist_from_spf: $scanner->{sender} is in user's WHITELIST_FROM_SPF but failed SPF check");
+ $scanner->{spf_whitelist_from} = 0;
+ }
+ } else {
+ dbg("spf: whitelist_from_spf: $scanner->{sender} is not in user's WHITELIST_FROM_SPF");
+ }
+}</pre>
+<p>sub _check_def_spf_whitelist {
+ my ($self, $scanner) = @_;</p>
+<pre>
+ $scanner->{def_spf_whitelist_from_checked} = 1;
+ $scanner->{def_spf_whitelist_from} = 0;</pre>
+<pre>
+ # if we've already checked for an SPF PASS and didn't get it don't waste time
+ # checking to see if the sender address is in the spf whitelist
+ if ($scanner->{spf_checked} && !$scanner->{spf_pass}) {
+ dbg("spf: def_spf_whitelist_from: already checked spf and didn't get pass, skipping whitelist check");
+ return;
+ }</pre>
+<pre>
+ $self->_get_sender($scanner) unless $scanner->{sender_got};</pre>
+<pre>
+ unless ($scanner->{sender}) {
+ dbg("spf: def_spf_whitelist_from: could not find useable envelope sender");
+ return;
+ }</pre>
+<pre>
+ $scanner->{def_spf_whitelist_from} = $self->_wlcheck($scanner,'def_whitelist_from_spf');
+ if (!$scanner->{def_spf_whitelist_from}) {
+ $scanner->{def_spf_whitelist_from} = $self->_wlcheck($scanner, 'def_whitelist_auth');
+ }</pre>
+<pre>
+ # if the message doesn't pass SPF validation, it can't pass an SPF whitelist
+ if ($scanner->{def_spf_whitelist_from}) {
+ if ($self->check_for_spf_pass($scanner)) {
+ dbg("spf: def_whitelist_from_spf: $scanner->{sender} is in DEF_WHITELIST_FROM_SPF and passed SPF check");
+ } else {
+ dbg("spf: def_whitelist_from_spf: $scanner->{sender} is in DEF_WHITELIST_FROM_SPF but failed SPF check");
+ $scanner->{def_spf_whitelist_from} = 0;
+ }
+ } else {
+ dbg("spf: def_whitelist_from_spf: $scanner->{sender} is not in DEF_WHITELIST_FROM_SPF");
+ }
+}</pre>
+<p>sub _wlcheck {
+ my ($self, $scanner, $param) = @_;
+ if (defined ($scanner->{conf}->{$param}->{$scanner->{sender}})) {
+ return 1;
+ } else {
+ study $scanner->{sender}; # study is a no-op since perl 5.16.0
+ foreach my $regexp (values %{$scanner->{conf}->{$param}}) {
+ if ($scanner->{sender} =~ qr/$regexp/i) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}</p>
+<p>###########################################################################</p>
+<p>1;</p>
+</dd>
+</dl>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SPF.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,92 @@
+NAME
+ Mail::SpamAssassin::Plugin::SPF - perform SPF verification tests
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::SPF
+
+DESCRIPTION
+ This plugin checks a message against Sender Policy Framework (SPF)
+ records published by the domain owners in DNS to fight email address
+ forgery and make it easier to identify spams.
+
+USER SETTINGS
+ whitelist_from_spf user@example.com
+ Works similarly to whitelist_from, except that in addition to
+ matching a sender address, a check against the domain's SPF record
+ must pass. The first parameter is an address to whitelist, and the
+ second is a string to match the relay's rDNS.
+
+ Just like whitelist_from, multiple addresses per line, separated by
+ spaces, are OK. Multiple "whitelist_from_spf" lines are also OK.
+
+ The headers checked for whitelist_from_spf addresses are the same
+ headers used for SPF checks (Envelope-From, Return-Path,
+ X-Envelope-From, etc).
+
+ Since this whitelist requires an SPF check to be made, network tests
+ must be enabled. It is also required that your trust path be
+ correctly configured. See the section on "trusted_networks" for more
+ info on trust paths.
+
+ e.g.
+
+ whitelist_from_spf joe@example.com fred@example.com
+ whitelist_from_spf *@example.com
+
+ def_whitelist_from_spf user@example.com
+ Same as "whitelist_from_spf", but used for the default whitelist
+ entries in the SpamAssassin distribution. The whitelist score is
+ lower, because these are often targets for spammer spoofing.
+
+ADMINISTRATOR OPTIONS
+ spf_timeout n (default: 5)
+ How many seconds to wait for an SPF query to complete, before
+ scanning continues without the SPF result. A numeric value is
+ optionally suffixed by a time unit (s, m, h, d, w, indicating
+ seconds (default), minutes, hours, days, weeks).
+
+ do_not_use_mail_spf (0|1) (default: 0)
+ By default the plugin will try to use the Mail::SPF module for SPF
+ checks if it can be loaded. If Mail::SPF cannot be used the plugin
+ will fall back to using the legacy Mail::SPF::Query module if it can
+ be loaded.
+
+ Use this option to stop the plugin from using Mail::SPF and cause it
+ to try to use Mail::SPF::Query instead.
+
+ do_not_use_mail_spf_query (0|1) (default: 0)
+ As above, but instead stop the plugin from trying to use
+ Mail::SPF::Query and cause it to only try to use Mail::SPF.
+
+ ignore_received_spf_header (0|1) (default: 0)
+ By default, to avoid unnecessary DNS lookups, the plugin will try to
+ use the SPF results found in any "Received-SPF" headers it finds in
+ the message that could only have been added by an internal relay.
+
+ Set this option to 1 to ignore any "Received-SPF" headers present
+ and to have the plugin perform the SPF check itself.
+
+ Note that unless the plugin finds an "identity=helo", or some
+ unsupported identity, it will assume that the result is a mfrom SPF
+ check result. The only identities supported are "mfrom", "mailfrom"
+ and "helo".
+
+ use_newest_received_spf_header (0|1) (default: 0)
+ By default, when using "Received-SPF" headers, the plugin will
+ attempt to use the oldest (bottom most) "Received-SPF" headers, that
+ were added by internal relays, that it can parse results from since
+ they are the most likely to be accurate. This is done so that if you
+ have an incoming mail setup where one of your primary MXes doesn't
+ know about a secondary MX (or your MXes don't know about some sort
+ of forwarding relay that SA considers trusted+internal) but SA is
+ aware of the actual domain boundary (internal_networks setting) SA
+ will use the results that are most accurate.
+
+ Use this option to start with the newest (top most) "Received-SPF"
+ headers, working downwards until results are successfully parsed.
+
+ has_check_for_spf_errors
+ Adds capability check for "if can()" for check_for_spf_permerror,
+ check_for_spf_temperror, check_for_spf_helo_permerror and
+ check_for_spf_helo_permerror
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,153 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::Shortcircuit - short-circuit evaluation for certain rules</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+ <li><a href="#configuration_settings">CONFIGURATION SETTINGS</a></li>
+ <li><a href="#tags">TAGS</a></li>
+ <li><a href="#see_also">SEE ALSO</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::Shortcircuit - short-circuit evaluation for certain rules</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::Shortcircuit</pre>
+<pre>
+ report Content analysis details: (_SCORE_ points, _REQD_ required, s/c _SCTYPE_)</pre>
+<pre>
+ add_header all Status "_YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ shortcircuit=_SCTYPE_ autolearn=_AUTOLEARN_ version=_VERSION_"</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This plugin implements simple, test-based shortcircuiting. Shortcircuiting a
+test will force all other pending rules to be skipped, if that test is hit.
+In addition, a symbolic rule, <code>SHORTCIRCUIT</code>, will fire.</p>
+<p>Recomended usage is to use <code>priority</code> to set rules with strong S/O values (ie.
+1.0) to be run first, and make instant spam or ham classification based on
+that.</p>
+<p>
+</p>
+<hr />
+<h1><a name="configuration_settings">CONFIGURATION SETTINGS</a></h1>
+<p>The following configuration settings are used to control shortcircuiting:</p>
+<dl>
+<dt><strong><a name="shortcircuit_symbolic_test_name_ham_spam_on_off" class="item">shortcircuit SYMBOLIC_TEST_NAME {ham|spam|on|off}</a></strong></dt>
+
+<dd>
+<p>Shortcircuiting a test will force all other pending rules to be skipped, if
+that test is hit.</p>
+<p>Recomended usage is to use <code>priority</code> to set rules with strong S/O values (ie.
+1.0) to be run first, and make instant spam or ham classification based on
+that.</p>
+<p>To override a test that uses shortcircuiting, you can set the classification
+type to <a href="#off"><code>off</code></a>.</p>
+<dl>
+<dt><strong><a name="on" class="item">on</a></strong></dt>
+
+<dd>
+<p>Shortcircuits the rest of the tests, but does not make a strict classification
+of spam or ham. Rather, it uses the default score for the rule being
+shortcircuited. This would allow you, for example, to define a rule such as</p>
+<pre>
+ body TEST /test/
+ describe TEST test rule that scores barely over spam threshold
+ score TEST 5.5
+ priority TEST -100
+ shortcircuit TEST on</pre>
+<p>The result of a message hitting the above rule would be a final score of 5.5,
+as opposed to 100 (default) if it were classified as spam.</p>
+</dd>
+<dt><strong><a name="off" class="item">off</a></strong></dt>
+
+<dd>
+<p>Disables shortcircuiting on said rule.</p>
+</dd>
+<dt><strong><a name="spam" class="item">spam</a></strong></dt>
+
+<dd>
+<p>Shortcircuit the rule using a set of defaults; override the default score of
+this rule with the score from <code>shortcircuit_spam_score</code>, set the
+<code>noautolearn</code> tflag, and set priority to <code>-100</code>. In other words,
+equivalent to:</p>
+<pre>
+ shortcircuit TEST on
+ priority TEST -100
+ score TEST 100
+ tflags TEST noautolearn</pre>
+</dd>
+<dt><strong><a name="ham" class="item">ham</a></strong></dt>
+
+<dd>
+<p>Shortcircuit the rule using a set of defaults; override the default score of
+this rule with the score from <code>shortcircuit_ham_score</code>, set the <code>noautolearn</code>
+and <code>nice</code> tflags, and set priority to <code>-100</code>. In other words, equivalent
+to:</p>
+<pre>
+ shortcircuit TEST on
+ priority TEST -100
+ score TEST -100
+ tflags TEST noautolearn nice</pre>
+</dd>
+</dl>
+</dd>
+<dt><strong><a name="nn" class="item">shortcircuit_spam_score n.nn (default: 100)</a></strong></dt>
+
+<dd>
+<p>When shortcircuit is used on a rule, and the shortcircuit classification type
+is set to <a href="#spam"><code>spam</code></a>, this value should be applied in place of the default score
+for that rule.</p>
+</dd>
+<dt><strong>shortcircuit_ham_score n.nn (default: -100)</strong></dt>
+
+<dd>
+<p>When shortcircuit is used on a rule, and the shortcircuit classification type
+is set to <a href="#ham"><code>ham</code></a>, this value should be applied in place of the default score
+for that rule.</p>
+</dd>
+</dl>
+<p>
+</p>
+<hr />
+<h1><a name="tags">TAGS</a></h1>
+<p>The following tags are added to the set available for use in reports, headers
+etc.:</p>
+<pre>
+ _SC_ shortcircuit status (classification and rule name)
+ _SCRULE_ rulename that caused the shortcircuit
+ _SCTYPE_ shortcircuit classification ("spam", "ham", "default", "none")</pre>
+<p>
+</p>
+<hr />
+<h1><a name="see_also">SEE ALSO</a></h1>
+<p><code>http://issues.apache.org/SpamAssassin/show_bug.cgi?id=3109</code></p>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Shortcircuit.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,95 @@
+NAME
+ Mail::SpamAssassin::Plugin::Shortcircuit - short-circuit evaluation for
+ certain rules
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::Shortcircuit
+
+ report Content analysis details: (_SCORE_ points, _REQD_ required, s/c _SCTYPE_)
+
+ add_header all Status "_YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ shortcircuit=_SCTYPE_ autolearn=_AUTOLEARN_ version=_VERSION_"
+
+DESCRIPTION
+ This plugin implements simple, test-based shortcircuiting.
+ Shortcircuiting a test will force all other pending rules to be skipped,
+ if that test is hit. In addition, a symbolic rule, "SHORTCIRCUIT", will
+ fire.
+
+ Recomended usage is to use "priority" to set rules with strong S/O
+ values (ie. 1.0) to be run first, and make instant spam or ham
+ classification based on that.
+
+CONFIGURATION SETTINGS
+ The following configuration settings are used to control
+ shortcircuiting:
+
+ shortcircuit SYMBOLIC_TEST_NAME {ham|spam|on|off}
+ Shortcircuiting a test will force all other pending rules to be
+ skipped, if that test is hit.
+
+ Recomended usage is to use "priority" to set rules with strong S/O
+ values (ie. 1.0) to be run first, and make instant spam or ham
+ classification based on that.
+
+ To override a test that uses shortcircuiting, you can set the
+ classification type to "off".
+
+ on Shortcircuits the rest of the tests, but does not make a strict
+ classification of spam or ham. Rather, it uses the default score
+ for the rule being shortcircuited. This would allow you, for
+ example, to define a rule such as
+
+ body TEST /test/
+ describe TEST test rule that scores barely over spam threshold
+ score TEST 5.5
+ priority TEST -100
+ shortcircuit TEST on
+
+ The result of a message hitting the above rule would be a final
+ score of 5.5, as opposed to 100 (default) if it were classified
+ as spam.
+
+ off Disables shortcircuiting on said rule.
+
+ spam
+ Shortcircuit the rule using a set of defaults; override the
+ default score of this rule with the score from
+ "shortcircuit_spam_score", set the "noautolearn" tflag, and set
+ priority to -100. In other words, equivalent to:
+
+ shortcircuit TEST on
+ priority TEST -100
+ score TEST 100
+ tflags TEST noautolearn
+
+ ham Shortcircuit the rule using a set of defaults; override the
+ default score of this rule with the score from
+ "shortcircuit_ham_score", set the "noautolearn" and "nice"
+ tflags, and set priority to -100. In other words, equivalent to:
+
+ shortcircuit TEST on
+ priority TEST -100
+ score TEST -100
+ tflags TEST noautolearn nice
+
+ shortcircuit_spam_score n.nn (default: 100)
+ When shortcircuit is used on a rule, and the shortcircuit
+ classification type is set to "spam", this value should be applied
+ in place of the default score for that rule.
+
+ shortcircuit_ham_score n.nn (default: -100)
+ When shortcircuit is used on a rule, and the shortcircuit
+ classification type is set to "ham", this value should be applied in
+ place of the default score for that rule.
+
+TAGS
+ The following tags are added to the set available for use in reports,
+ headers etc.:
+
+ _SC_ shortcircuit status (classification and rule name)
+ _SCRULE_ rulename that caused the shortcircuit
+ _SCTYPE_ shortcircuit classification ("spam", "ham", "default", "none")
+
+SEE ALSO
+ "http://issues.apache.org/SpamAssassin/show_bug.cgi?id=3109"
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,84 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::SpamCop - perform SpamCop reporting of messages</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+ <li><a href="#user_options">USER OPTIONS</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::SpamCop - perform SpamCop reporting of messages</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::SpamCop</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>SpamCop is a service for reporting spam. SpamCop determines the origin
+of unwanted email and reports it to the relevant Internet service
+providers. By reporting spam, you have a positive impact on the
+problem. Reporting unsolicited email also helps feed spam filtering
+systems, including, but not limited to, the SpamCop blacklist used in
+SpamAssassin as a DNSBL.</p>
+<p>Note that spam reports sent by this plugin to SpamCop each include the
+entire spam message.</p>
+<p>See <a href="http://www.spamcop.net/">http://www.spamcop.net/</a> for more information about SpamCop.</p>
+<p>
+</p>
+<hr />
+<h1><a name="user_options">USER OPTIONS</a></h1>
+<dl>
+<dt><strong><a name="com" class="item">spamcop_from_address <a href="mailto:user@example.com">user@example.com</a> (default: none)</a></strong></dt>
+
+<dd>
+<p>This address is used during manual reports to SpamCop as the From:
+address. You can use your normal email address. If this is not set, a
+guess will be used as the From: address in SpamCop reports.</p>
+</dd>
+<dt><strong>spamcop_to_address <a href="mailto:user@example.com">user@example.com</a> (default: generic reporting address)</strong></dt>
+
+<dd>
+<p>Your customized SpamCop report submission address. You need to obtain
+this address by registering at <code>http://www.spamcop.net/</code>. If this is
+not set, SpamCop reports will go to a generic reporting address for
+SpamAssassin users and your reports will probably have less weight in
+the SpamCop system.</p>
+</dd>
+<dt><strong><a name="spamcop_max_report_size" class="item">spamcop_max_report_size (default: 50)</a></strong></dt>
+
+<dd>
+<p>Messages larger than this size (in kilobytes) will be truncated in
+report messages sent to SpamCop. The default setting is the maximum
+size that SpamCop will accept at the time of release.</p>
+</dd>
+</dl>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_SpamCop.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,38 @@
+NAME
+ Mail::SpamAssassin::Plugin::SpamCop - perform SpamCop reporting of
+ messages
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::SpamCop
+
+DESCRIPTION
+ SpamCop is a service for reporting spam. SpamCop determines the origin
+ of unwanted email and reports it to the relevant Internet service
+ providers. By reporting spam, you have a positive impact on the problem.
+ Reporting unsolicited email also helps feed spam filtering systems,
+ including, but not limited to, the SpamCop blacklist used in
+ SpamAssassin as a DNSBL.
+
+ Note that spam reports sent by this plugin to SpamCop each include the
+ entire spam message.
+
+ See http://www.spamcop.net/ for more information about SpamCop.
+
+USER OPTIONS
+ spamcop_from_address user@example.com (default: none)
+ This address is used during manual reports to SpamCop as the From:
+ address. You can use your normal email address. If this is not set,
+ a guess will be used as the From: address in SpamCop reports.
+
+ spamcop_to_address user@example.com (default: generic reporting address)
+ Your customized SpamCop report submission address. You need to
+ obtain this address by registering at "http://www.spamcop.net/". If
+ this is not set, SpamCop reports will go to a generic reporting
+ address for SpamAssassin users and your reports will probably have
+ less weight in the SpamCop system.
+
+ spamcop_max_report_size (default: 50)
+ Messages larger than this size (in kilobytes) will be truncated in
+ report messages sent to SpamCop. The default setting is the maximum
+ size that SpamCop will accept at the time of release.
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,48 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Test - test plugin</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Test - test plugin</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::Test
+ header MY_TEST_PLUGIN eval:check_test_plugin()</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>To try this plugin, write the above two lines in the synopsis to
+<code>/etc/mail/spamassassin/plugintest.cf</code>.</p>
+
+</body>
+
+</html>
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.txt
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.txt?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.txt (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_Test.txt Wed Apr 29 17:04:09 2015
@@ -0,0 +1,11 @@
+NAME
+ Test - test plugin
+
+SYNOPSIS
+ loadplugin Mail::SpamAssassin::Plugin::Test
+ header MY_TEST_PLUGIN eval:check_test_plugin()
+
+DESCRIPTION
+ To try this plugin, write the above two lines in the synopsis to
+ "/etc/mail/spamassassin/plugintest.cf".
+
Added: spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_TextCat.html
URL: http://svn.apache.org/viewvc/spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_TextCat.html?rev=1676792&view=auto
==============================================================================
--- spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_TextCat.html (added)
+++ spamassassin/site/full/3.4.x/doc/Mail_SpamAssassin_Plugin_TextCat.html Wed Apr 29 17:04:09 2015
@@ -0,0 +1,264 @@
+<?xml version="1.0" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Mail::SpamAssassin::Plugin::TextCat - TextCat language guesser</title>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<link rev="made" href="mailto:root@localhost" />
+</head>
+
+<body style="background-color: white">
+
+
+<!-- INDEX BEGIN -->
+<div name="index">
+<p><a name="__index__"></a></p>
+
+<ul>
+
+ <li><a href="#name">NAME</a></li>
+ <li><a href="#synopsis">SYNOPSIS</a></li>
+ <li><a href="#description">DESCRIPTION</a></li>
+ <li><a href="#user_options">USER OPTIONS</a></li>
+</ul>
+
+<hr name="index" />
+</div>
+<!-- INDEX END -->
+
+<p>
+</p>
+<h1><a name="name">NAME</a></h1>
+<p>Mail::SpamAssassin::Plugin::TextCat - TextCat language guesser</p>
+<p>
+</p>
+<hr />
+<h1><a name="synopsis">SYNOPSIS</a></h1>
+<pre>
+ loadplugin Mail::SpamAssassin::Plugin::TextCat</pre>
+<p>
+</p>
+<hr />
+<h1><a name="description">DESCRIPTION</a></h1>
+<p>This plugin will try to guess the language used in the message body text.</p>
+<p>You can use the "ok_languages" directive to set which languages are
+considered okay for incoming mail and if the guessed language is not okay,
+<code>UNWANTED_LANGUAGE_BODY</code> is triggered.</p>
+<p>It will always add the results to a "X-Language" name-value pair in the
+message metadata data structure. This may be useful as Bayes tokens and
+can also be used in rules for scoring. The results can also be added to
+marked-up messages using "add_header", with the _LANGUAGES_ tag. See
+<a href="/Mail/SpamAssassin/Conf.html">the Mail::SpamAssassin::Conf manpage</a> for details.</p>
+<p>Note: the language cannot always be recognized with sufficient confidence.
+In that case, no action is taken.</p>
+<p>
+</p>
+<hr />
+<h1><a name="user_options">USER OPTIONS</a></h1>
+<dl>
+<dt><strong><a name="ok_languages_xx_yy_zz_default_all" class="item">ok_languages xx [ yy zz ... ] (default: all)</a></strong></dt>
+
+<dd>
+<p>This option is used to specify which languages are considered okay for
+incoming mail. SpamAssassin will try to detect the language used in the
+message body text.</p>
+<p>Note that the language cannot always be recognized with sufficient
+confidence. In that case, no action is taken.</p>
+<p>The rule <code>UNWANTED_LANGUAGE_BODY</code> is triggered if none of the languages
+detected are in the "ok" list. Note that this is the only effect of the
+"ok" list. It does not act as a whitelist against any other form of spam
+scanning.</p>
+<p>In your configuration, you must use the two or three letter language
+specifier in lowercase, not the English name for the language. You may
+also specify <code>all</code> if a desired language is not listed, or if you want to
+allow any language. The default setting is <code>all</code>.</p>
+<p>Examples:</p>
+<pre>
+ ok_languages all (allow all languages)
+ ok_languages en (only allow English)
+ ok_languages en ja zh (allow English, Japanese, and Chinese)</pre>
+<p>Note: if there are multiple ok_languages lines, only the last one is used.</p>
+<p>Select the languages to allow from the list below:</p>
+<dl>
+<dt><strong><a name="af_afrikaans" class="item">af - Afrikaans</a></strong></dt>
+
+<dt><strong><a name="am_amharic" class="item">am - Amharic</a></strong></dt>
+
+<dt><strong><a name="ar_arabic" class="item">ar - Arabic</a></strong></dt>
+
+<dt><strong><a name="be_byelorussian" class="item">be - Byelorussian</a></strong></dt>
+
+<dt><strong><a name="bg_bulgarian" class="item">bg - Bulgarian</a></strong></dt>
+
+<dt><strong><a name="bs_bosnian" class="item">bs - Bosnian</a></strong></dt>
+
+<dt><strong><a name="ca_catalan" class="item">ca - Catalan</a></strong></dt>
+
+<dt><strong><a name="cs_czech" class="item">cs - Czech</a></strong></dt>
+
+<dt><strong><a name="cy_welsh" class="item">cy - Welsh</a></strong></dt>
+
+<dt><strong><a name="da_danish" class="item">da - Danish</a></strong></dt>
+
+<dt><strong><a name="de_german" class="item">de - German</a></strong></dt>
+
+<dt><strong><a name="el_greek" class="item">el - Greek</a></strong></dt>
+
+<dt><strong><a name="en_english" class="item">en - English</a></strong></dt>
+
+<dt><strong><a name="eo_esperanto" class="item">eo - Esperanto</a></strong></dt>
+
+<dt><strong><a name="es_spanish" class="item">es - Spanish</a></strong></dt>
+
+<dt><strong><a name="et_estonian" class="item">et - Estonian</a></strong></dt>
+
+<dt><strong><a name="eu_basque" class="item">eu - Basque</a></strong></dt>
+
+<dt><strong><a name="fa_persian" class="item">fa - Persian</a></strong></dt>
+
+<dt><strong><a name="fi_finnish" class="item">fi - Finnish</a></strong></dt>
+
+<dt><strong><a name="fr_french" class="item">fr - French</a></strong></dt>
+
+<dt><strong><a name="fy_frisian" class="item">fy - Frisian</a></strong></dt>
+
+<dt><strong><a name="ga_irish_gaelic" class="item">ga - Irish Gaelic</a></strong></dt>
+
+<dt><strong><a name="gd_scottish_gaelic" class="item">gd - Scottish Gaelic</a></strong></dt>
+
+<dt><strong><a name="he_hebrew" class="item">he - Hebrew</a></strong></dt>
+
+<dt><strong><a name="hi_hindi" class="item">hi - Hindi</a></strong></dt>
+
+<dt><strong><a name="hr_croatian" class="item">hr - Croatian</a></strong></dt>
+
+<dt><strong><a name="hu_hungarian" class="item">hu - Hungarian</a></strong></dt>
+
+<dt><strong><a name="hy_armenian" class="item">hy - Armenian</a></strong></dt>
+
+<dt><strong><a name="id_indonesian" class="item">id - Indonesian</a></strong></dt>
+
+<dt><strong><a name="is_icelandic" class="item">is - Icelandic</a></strong></dt>
+
+<dt><strong><a name="it_italian" class="item">it - Italian</a></strong></dt>
+
+<dt><strong><a name="ja_japanese" class="item">ja - Japanese</a></strong></dt>
+
+<dt><strong><a name="ka_georgian" class="item">ka - Georgian</a></strong></dt>
+
+<dt><strong><a name="ko_korean" class="item">ko - Korean</a></strong></dt>
+
+<dt><strong><a name="la_latin" class="item">la - Latin</a></strong></dt>
+
+<dt><strong><a name="lt_lithuanian" class="item">lt - Lithuanian</a></strong></dt>
+
+<dt><strong><a name="lv_latvian" class="item">lv - Latvian</a></strong></dt>
+
+<dt><strong><a name="mr_marathi" class="item">mr - Marathi</a></strong></dt>
+
+<dt><strong><a name="ms_malay" class="item">ms - Malay</a></strong></dt>
+
+<dt><strong><a name="ne_nepali" class="item">ne - Nepali</a></strong></dt>
+
+<dt><strong><a name="nl_dutch" class="item">nl - Dutch</a></strong></dt>
+
+<dt><strong><a name="no_norwegian" class="item">no - Norwegian</a></strong></dt>
+
+<dt><strong><a name="pl_polish" class="item">pl - Polish</a></strong></dt>
+
+<dt><strong><a name="pt_portuguese" class="item">pt - Portuguese</a></strong></dt>
+
+<dt><strong><a name="qu_quechua" class="item">qu - Quechua</a></strong></dt>
+
+<dt><strong><a name="rm_rhaeto_romance" class="item">rm - Rhaeto-Romance</a></strong></dt>
+
+<dt><strong><a name="ro_romanian" class="item">ro - Romanian</a></strong></dt>
+
+<dt><strong><a name="ru_russian" class="item">ru - Russian</a></strong></dt>
+
+<dt><strong><a name="sa_sanskrit" class="item">sa - Sanskrit</a></strong></dt>
+
+<dt><strong><a name="sco_scots" class="item">sco - Scots</a></strong></dt>
+
+<dt><strong><a name="sk_slovak" class="item">sk - Slovak</a></strong></dt>
+
+<dt><strong><a name="sl_slovenian" class="item">sl - Slovenian</a></strong></dt>
+
+<dt><strong><a name="sq_albanian" class="item">sq - Albanian</a></strong></dt>
+
+<dt><strong><a name="sr_serbian" class="item">sr - Serbian</a></strong></dt>
+
+<dt><strong><a name="sv_swedish" class="item">sv - Swedish</a></strong></dt>
+
+<dt><strong><a name="sw_swahili" class="item">sw - Swahili</a></strong></dt>
+
+<dt><strong><a name="ta_tamil" class="item">ta - Tamil</a></strong></dt>
+
+<dt><strong><a name="th_thai" class="item">th - Thai</a></strong></dt>
+
+<dt><strong><a name="tl_tagalog" class="item">tl - Tagalog</a></strong></dt>
+
+<dt><strong><a name="tr_turkish" class="item">tr - Turkish</a></strong></dt>
+
+<dt><strong><a name="uk_ukrainian" class="item">uk - Ukrainian</a></strong></dt>
+
+<dt><strong><a name="vi_vietnamese" class="item">vi - Vietnamese</a></strong></dt>
+
+<dt><strong><a name="yi_yiddish" class="item">yi - Yiddish</a></strong></dt>
+
+<dt><strong><a name="chinese" class="item">zh - Chinese (both Traditional and Simplified)</a></strong></dt>
+
+<dt><strong>zh.big5 - Chinese (Traditional only)</strong></dt>
+
+<dt><strong>zh.gb2312 - Chinese (Simplified only)</strong></dt>
+
+</dl>
+<p></p>
+</dd>
+<dt><strong><a name="inactive_languages_xx_yy_zz_default_see_below" class="item">inactive_languages xx [ yy zz ... ] (default: see below)</a></strong></dt>
+
+<dd>
+<p>This option is used to specify which languages will not be considered
+when trying to guess the language. For performance reasons, supported
+languages that have fewer than about 5 million speakers are disabled by
+default. Note that listing a language in <code>ok_languages</code> automatically
+enables it for that user.</p>
+<p>The default setting is:</p>
+<dl>
+<dt><strong><a name="bs_cy_eo_et_eu_fy_ga_gd_is_la_lt_lv_rm_sa_sco_sl_yi" class="item">bs cy eo et eu fy ga gd is la lt lv rm sa sco sl yi</a></strong></dt>
+
+</dl>
+<p>That list is Bosnian, Welsh, Esperanto, Estonian, Basque, Frisian, Irish
+Gaelic, Scottish Gaelic, Icelandic, Latin, Lithuanian, Latvian,
+Rhaeto-Romance, Sanskrit, Scots, Slovenian, and Yiddish.</p>
+</dd>
+<dt><strong><a name="n" class="item">textcat_max_languages N (default: 3)</a></strong></dt>
+
+<dd>
+<p>The maximum number of languages any one message can simultaneously match
+before its classification is considered unknown.</p>
+</dd>
+<dt><strong>textcat_optimal_ngrams N (default: 0)</strong></dt>
+
+<dd>
+<p>If the number of ngrams is lower than this number then they will be removed. This
+can be used to speed up the program for longer inputs. For shorter inputs, this
+should be set to 0.</p>
+</dd>
+<dt><strong>textcat_max_ngrams N (default: 400)</strong></dt>
+
+<dd>
+<p>The maximum number of ngrams that should be compared with each of the languages
+models (note that each of those models is used completely).</p>
+</dd>
+<dt><strong>textcat_acceptable_score N (default: 1.02)</strong></dt>
+
+<dd>
+<p>Include any language that scores at least <code>textcat_acceptable_score</code> in the
+returned list of languages.</p>
+</dd>
+</dl>
+
+</body>
+
+</html>