Mail-SpamAssassin
view release on metacpan or search on metacpan
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
# </@LICENSE>
=head1 NAME
Mail::SpamAssassin::Conf - SpamAssassin configuration file
=head1 SYNOPSIS
# a comment
rewrite_header Subject *****SPAM*****
full PARA_A_2_C_OF_1618 /Paragraph .a.{0,10}2.{0,10}C. of S. 1618/i
describe PARA_A_2_C_OF_1618 Claims compliance with senate bill 1618
header FROM_HAS_MIXED_NUMS From =~ /\d+[a-z]+\d+\S*@/i
describe FROM_HAS_MIXED_NUMS From: contains numbers mixed in with letters
score A_HREF_TO_REMOVE 2.0
lang es describe FROM_FORGED_HOTMAIL Forzado From: simula ser de hotmail.com
lang pt_BR report O programa detetor de Spam ZOE [...]
=head1 DESCRIPTION
SpamAssassin is configured using traditional UNIX-style configuration files,
loaded from the C</usr/share/spamassassin> and C</etc/mail/spamassassin>
directories.
The following web page lists the most important configuration settings
used to configure SpamAssassin; novices are encouraged to read it first:
https://wiki.apache.org/spamassassin/ImportantInitialConfigItems
=head1 FILE FORMAT
The C<#> character starts a comment, which continues until end of line.
B<NOTE:> if the C<#> character is to be used as part of a rule or
configuration option, it must be escaped with a backslash. i.e.: C<\#>
Whitespace in the files is not significant, but please note that starting a
line with whitespace is deprecated, as we reserve its use for multi-line rule
definitions, at some point in the future.
Currently, each rule or configuration setting must fit on one-line; multi-line
settings are not supported yet.
File and directory paths can use C<~> to refer to the user's home
directory, but no other shell-style path extensions such as globing or
C<~user/> are supported.
Where appropriate below, default values are listed in parentheses.
Test names ("SYMBOLIC_TEST_NAME") can only contain alphanumerics/underscores,
can not start with digit, and must be less than 128 characters.
=head1 USER PREFERENCES
The following options can be used in both site-wide (C<local.cf>) and
user-specific (C<user_prefs>) configuration files to customize how
SpamAssassin handles incoming email messages.
=cut
package Mail::SpamAssassin::Conf;
use strict;
use warnings;
# use bytes;
use re 'taint';
use Mail::SpamAssassin::NetSet;
use Mail::SpamAssassin::Constants qw(:sa :ip);
use Mail::SpamAssassin::Conf::Parser;
use Mail::SpamAssassin::Logger;
use Mail::SpamAssassin::Util qw(untaint_var idn_to_ascii compile_regexp);
use File::Spec;
our @ISA = qw();
our $COLLECT_REGRESSION_TESTS; # Used only for unit tests.
# odd => eval test. Not constants so they can be shared with Parser
# TODO: move to Constants.pm?
our $TYPE_HEAD_TESTS = 0x0008;
our $TYPE_HEAD_EVALS = 0x0009;
our $TYPE_BODY_TESTS = 0x000a;
our $TYPE_BODY_EVALS = 0x000b;
our $TYPE_FULL_TESTS = 0x000c;
our $TYPE_FULL_EVALS = 0x000d;
our $TYPE_RAWBODY_TESTS = 0x000e;
our $TYPE_RAWBODY_EVALS = 0x000f;
our $TYPE_URI_TESTS = 0x0010;
our $TYPE_URI_EVALS = 0x0011;
our $TYPE_META_TESTS = 0x0012;
our $TYPE_RBL_EVALS = 0x0013;
our $TYPE_EMPTY_TESTS = 0x0014;
my @rule_types = ("body_tests", "uri_tests", "uri_evals",
"head_tests", "head_evals", "body_evals", "full_tests",
"full_evals", "rawbody_tests", "rawbody_evals",
"rbl_evals", "meta_tests");
# Map internal ruletype to descriptive ruletype string
our %TYPE_AS_STRING = (
$TYPE_HEAD_TESTS => 'header',
$TYPE_HEAD_EVALS => 'header',
$TYPE_BODY_TESTS => 'body',
$TYPE_BODY_EVALS => 'body',
$TYPE_FULL_TESTS => 'full',
$TYPE_FULL_EVALS => 'full',
$TYPE_RAWBODY_TESTS => 'rawbody',
$TYPE_RAWBODY_EVALS => 'rawbody',
$TYPE_URI_TESTS => 'uri',
$TYPE_URI_EVALS => 'uri',
$TYPE_META_TESTS => 'meta',
$TYPE_RBL_EVALS => 'header',
$TYPE_EMPTY_TESTS => 'empty',
);
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
});
=back
=head2 WELCOMELIST AND BLOCKLIST OPTIONS
=over 4
=item welcomelist_from user@example.com
Previously whitelist_from which will work interchangeably until 4.1.
Used to welcomelist sender addresses which send mail that is often tagged
(incorrectly) as spam.
Use of this setting is not recommended, since it blindly trusts the message,
which is routinely and easily forged by spammers and phish senders. The
recommended solution is to instead use C<welcomelist_auth> or other authenticated
welcomelisting methods, or C<welcomelist_from_rcvd>.
Welcomelist and blocklist addresses are now file-glob-style patterns, so
C<friend@somewhere.com>, C<*@isp.com>, or C<*.domain.net> will all work.
Specifically, C<*> and C<?> are allowed, but all other metacharacters
are not. Regular expressions are not used for security reasons.
Matching is case-insensitive.
Multiple addresses per line, separated by spaces, is OK. Multiple
C<welcomelist_from> lines are also OK.
The headers checked for welcomelist addresses are as follows: if C<Resent-From>
is set, use that; otherwise check all addresses taken from the following
set of headers:
Envelope-Sender
Resent-Sender
X-Envelope-From
From
In addition, the "envelope sender" data, taken from the SMTP envelope data
where this is available, is looked up. See C<envelope_sender_header>.
e.g.
welcomelist_from joe@example.com fred@example.com
welcomelist_from *@example.com
=cut
push (@cmds, {
setting => 'welcomelist_from',
aliases => ['whitelist_from'], # backward compatible - to be removed for 4.1
type => $CONF_TYPE_ADDRLIST,
});
=item unwelcomelist_from user@example.com
Previously unwelcomelist_from which will work interchangeably until 4.1.
Used to remove a default welcomelist_from entry, so for example a distribution
welcomelist_from can be overridden in a local.cf file, or an individual user can
override a welcomelist_from entry in their own C<user_prefs> file.
The specified email address has to match exactly (although case-insensitively)
the address previously used in a welcomelist_from line, which implies that a
wildcard only matches literally the same wildcard (not 'any' address).
e.g.
unwelcomelist_from joe@example.com fred@example.com
unwelcomelist_from *@example.com
=cut
push (@cmds, {
command => 'unwelcomelist_from',
aliases => ['unwhitelist_from'], # backward compatible - to be removed for 4.1
setting => 'welcomelist_from',
type => $CONF_TYPE_ADDRLIST,
code => \&Mail::SpamAssassin::Conf::Parser::remove_addrlist_value
});
=item welcomelist_from_rcvd addr@lists.sourceforge.net sourceforge.net
Previously whitelist_from_rcvd which will work interchangeably until 4.1.
Works similarly to welcomelist_from, except that in addition to matching
a sender address, a relay's rDNS name or its IP address must match too
for the welcomelisting rule to fire. The first parameter is a sender's e-mail
address to welcomelist, and the second is a string to match the relay's rDNS,
or its IP address. Matching is case-insensitive.
This second parameter is matched against a TCP-info information field as
provided in a FROM clause of a trace information (i.e. in a Received header
field, see RFC 5321). Only the Received header fields inserted by trusted
hosts are considered. This parameter can either be a full hostname, or a
domain component of that hostname, or an IP address (optionally followed
by a slash and a prefix length) in square brackets. The address prefix
(mask) length with a slash may stand within brackets along with an address,
or may follow the bracketed address. Reverse DNS lookup is done by an MTA,
not by SpamAssassin.
For backward compatibility as an alternative to a CIDR notation, an IPv4
address in brackets may be truncated on classful boundaries to cover whole
subnets, e.g. C<[10.1.2.3]>, C<[10.1.2]>, C<[10.1]>, C<[10]>.
In other words, if the host that connected to your MX had an IP address
192.0.2.123 that mapped to 'sendinghost.example.org', you should specify
C<sendinghost.example.org>, or C<example.org>, or C<[192.0.2.123]>, or
C<[192.0.2.0/24]>, or C<[192.0.2]> here.
Note that this requires that C<internal_networks> be correct. For simple
cases, it will be, but for a complex network you may get better results
by setting that parameter.
It also requires that your mail exchangers be configured to perform DNS
reverse lookups on the connecting host's IP address, and to record the
result in the generated Received header field according to RFC 5321.
e.g.
welcomelist_from_rcvd joe@example.com example.com
welcomelist_from_rcvd *@* mail.example.org
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
push (@cmds, {
setting => 'def_welcomelist_from_rcvd',
aliases => ['def_whitelist_from_rcvd'], # backward compatible - to be removed for 4.1
type => $CONF_TYPE_ADDRLIST,
code => sub {
my ($self, $key, $value, $line) = @_;
unless (defined $value && $value !~ /^$/) {
return $MISSING_REQUIRED_VALUE;
}
unless ($value =~ /^\S+\s+\S+$/) {
return $INVALID_VALUE;
}
$self->{parser}->add_to_addrlist_rcvd ('def_welcomelist_from_rcvd',
split(/\s+/, $value));
}
});
=item welcomelist_allows_relays user@example.com
Previously whitelist_allows_relays which will work interchangeably until 4.1.
Specify addresses which are in C<welcomelist_from_rcvd> that sometimes
send through a mail relay other than the listed ones. By default mail
with a From address that is in C<welcomelist_from_rcvd> that does not match
the relay will trigger a forgery rule. Including the address in
C<welcomelist_allows_relay> prevents that.
Welcomelist and blocklist addresses are now file-glob-style patterns, so
C<friend@somewhere.com>, C<*@isp.com>, or C<*.domain.net> will all work.
Specifically, C<*> and C<?> are allowed, but all other metacharacters
are not. Regular expressions are not used for security reasons.
Matching is case-insensitive.
Multiple addresses per line, separated by spaces, is OK. Multiple
C<welcomelist_allows_relays> lines are also OK.
The specified email address does not have to match exactly the address
previously used in a welcomelist_from_rcvd line as it is compared to the
address in the header.
e.g.
welcomelist_allows_relays joe@example.com fred@example.com
welcomelist_allows_relays *@example.com
=cut
push (@cmds, {
setting => 'welcomelist_allows_relays',
aliases => ['whitelist_allows_relays'], # backward compatible - to be removed for 4.1
type => $CONF_TYPE_ADDRLIST,
});
=item unwelcomelist_from_rcvd user@example.com
Previously unwhitelist_from_rcvd which will work interchangeably until 4.1.
Used to remove a default welcomelist_from_rcvd or def_welcomelist_from_rcvd
entry, so for example a distribution welcomelist_from_rcvd can be overridden
in a local.cf file, or an individual user can override a welcomelist_from_rcvd
entry in their own C<user_prefs> file.
The specified email address has to match exactly the address previously
used in a welcomelist_from_rcvd line.
e.g.
unwelcomelist_from_rcvd joe@example.com fred@example.com
unwelcomelist_from_rcvd *@axkit.org
=cut
push (@cmds, {
setting => 'unwelcomelist_from_rcvd',
aliases => ['unwhitelist_from_rcvd'], # backward compatible - to be removed for 4.1
type => $CONF_TYPE_ADDRLIST,
code => sub {
my ($self, $key, $value, $line) = @_;
unless (defined $value && $value !~ /^$/) {
return $MISSING_REQUIRED_VALUE;
}
unless ($value =~ /^(?:\S+(?:\s+\S+)*)$/) {
return $INVALID_VALUE;
}
$self->{parser}->remove_from_addrlist_rcvd('welcomelist_from_rcvd',
split (/\s+/, $value));
$self->{parser}->remove_from_addrlist_rcvd('def_welcomelist_from_rcvd',
split (/\s+/, $value));
}
});
=item blocklist_from user@example.com
Used to specify addresses which send mail that is often tagged (incorrectly) as
non-spam, but which the user doesn't want. Same format as C<welcomelist_from>.
=cut
push (@cmds, {
setting => 'blocklist_from',
aliases => ['blacklist_from'], # backward compatible - to be removed for 4.1
type => $CONF_TYPE_ADDRLIST,
});
=item unblocklist_from user@example.com
Previously unblacklist_from which will work interchangeably until 4.1.
Used to remove a default blocklist_from entry, so for example a
distribution blocklist_from can be overridden in a local.cf file, or
an individual user can override a blocklist_from entry in their own
C<user_prefs> file. The specified email address has to match exactly
the address previously used in a blocklist_from line.
e.g.
unblocklist_from joe@example.com fred@example.com
unblocklist_from *@spammer.com
=cut
push (@cmds, {
command => 'unblocklist_from',
aliases => ['unblacklist_from'], # backward compatible - to be removed for 4.1
setting => 'blocklist_from',
type => $CONF_TYPE_ADDRLIST,
code => \&Mail::SpamAssassin::Conf::Parser::remove_addrlist_value
});
=item welcomelist_to user@example.com
Previously whitelist_to which will work interchangeably until 4.1.
If the given address appears as a recipient in the message headers
(Resent-To, To, Cc, obvious envelope recipient, etc.) the mail will
be listed as allowed. Useful if you're deploying SpamAssassin system-wide,
and don't want some users to have their mail filtered. Same format
as C<welcomelist_from>.
There are three levels of To-welcomelisting, C<welcomelist_to>, C<more_spam_to>
and C<all_spam_to>. Users in the first level may still get some spammish
mails blocked, but users in C<all_spam_to> should never get mail blocked.
The headers checked for welcomelist addresses are as follows: if C<Resent-To> or
C<Resent-Cc> are set, use those; otherwise check all addresses taken from the
following set of headers:
To
Cc
Apparently-To
Delivered-To
Envelope-Recipients
Apparently-Resent-To
X-Envelope-To
Envelope-To
X-Delivered-To
X-Original-To
X-Rcpt-To
X-Real-To
=item more_spam_to user@example.com
See above.
=item all_spam_to user@example.com
See above.
=cut
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
If the header in question contains C<E<lt>> or C<E<gt>> characters at the start
and end of the email address in the right-hand side, as in the SMTP
transaction, these will be stripped.
If the header is not found in a message, or if it's value does not contain an
C<@> sign, SpamAssassin will issue a warning in the logs and fall back to its
default heuristics.
(Note for MTA developers: we would prefer if the use of a single header be
avoided in future, since that precludes 'downstream' spam scanning.
C<https://wiki.apache.org/spamassassin/EnvelopeSenderInReceived> details a
better proposal, storing the envelope sender at each hop in the C<Received>
header.)
example:
envelope_sender_header X-SA-Exim-Mail-From
=cut
push (@cmds, {
setting => 'envelope_sender_header',
default => undef,
type => $CONF_TYPE_STRING,
});
=item describe SYMBOLIC_TEST_NAME description ...
Used to describe a test. This text is shown to users in the detailed report.
Note that test names which begin with '__' are reserved for meta-match
sub-rules, and are not scored or listed in the 'tests hit' reports.
Also note that by convention, rule descriptions should be limited in
length to no more than 50 characters.
=cut
push (@cmds, {
command => 'describe',
setting => 'descriptions',
type => $CONF_TYPE_HASH_KEY_VALUE,
});
=item report_charset CHARSET (default: UTF-8)
Set the MIME Content-Type charset used for the text/plain report which
is attached to spam mail messages.
=cut
push (@cmds, {
setting => 'report_charset',
default => 'UTF-8',
type => $CONF_TYPE_STRING,
});
=item report ...some text for a report...
Set the report template which is attached to spam mail messages. See the
C<10_default_prefs.cf> configuration file in C</usr/share/spamassassin> for an
example.
If you change this, try to keep it under 78 columns. Each C<report>
line appends to the existing template, so use C<clear_report_template>
to restart.
Tags can be included as explained above.
=cut
push (@cmds, {
command => 'report',
setting => 'report_template',
default => '',
type => $CONF_TYPE_TEMPLATE,
});
=item clear_report_template
Clear the report template.
=cut
push (@cmds, {
command => 'clear_report_template',
setting => 'report_template',
type => $CONF_TYPE_NOARGS,
code => \&Mail::SpamAssassin::Conf::Parser::set_template_clear
});
=item report_contact ...text of contact address...
Set what _CONTACTADDRESS_ is replaced with in the above report text.
By default, this is 'the administrator of that system', since the hostname
of the system the scanner is running on is also included.
=cut
push (@cmds, {
setting => 'report_contact',
default => 'the administrator of that system',
type => $CONF_TYPE_STRING,
});
=item report_hostname ...hostname to use...
Set what _HOSTNAME_ is replaced with in the above report text.
By default, this is determined dynamically as whatever the host running
SpamAssassin calls itself.
=cut
push (@cmds, {
setting => 'report_hostname',
default => '',
type => $CONF_TYPE_STRING,
});
=item unsafe_report ...some text for a report...
Set the report template which is attached to spam mail messages which contain a
non-text/plain part. See the C<10_default_prefs.cf> configuration file in
C</usr/share/spamassassin> for an example.
Each C<unsafe-report> line appends to the existing template, so use
C<clear_unsafe_report_template> to restart.
Tags can be used in this template (see above for details).
=cut
push (@cmds, {
command => 'unsafe_report',
setting => 'unsafe_report_template',
default => '',
type => $CONF_TYPE_TEMPLATE,
});
=item clear_unsafe_report_template
Clear the unsafe_report template.
=cut
push (@cmds, {
command => 'clear_unsafe_report_template',
setting => 'unsafe_report_template',
type => $CONF_TYPE_NOARGS,
code => \&Mail::SpamAssassin::Conf::Parser::set_template_clear
});
=item mbox_format_from_regex
Set a specific regular expression to be used for mbox file From separators.
For example, this setting will allow sa-learn to process emails stored in
a kmail 2 mbox:
mbox_format_from_regex /^From \S+ ?[[:upper:]][[:lower:]]{2}(?:, \d\d [[:upper:]][[:lower:]]{2} \d{4} [0-2]\d:\d\d:\d\d [+-]\d{4}| [[:upper:]][[:lower:]]{2} [ 1-3]\d [ 0-2]\d:\d\d:\d\d \d{4})/
=cut
push (@cmds, {
setting => 'mbox_format_from_regex',
type => $CONF_TYPE_STRING
});
=item parse_dkim_uris ( 0 | 1 ) (default: 1)
If this option is set to 1 and the message contains DKIM headers, the headers will be parsed for URIs to process alongside URIs found in the body with some rules and modules (ex. URIDNSBL)
=cut
push (@cmds, {
setting => 'parse_dkim_uris',
default => 1,
type => $CONF_TYPE_BOOL,
});
=back
=head1 RULE DEFINITIONS AND PRIVILEGED SETTINGS
These settings differ from the ones above, in that they are considered
'privileged'. Only users running C<spamassassin> from their procmailrc's or
forward files, or sysadmins editing a file in C</etc/mail/spamassassin>, can
use them. C<spamd> users cannot use them in their C<user_prefs> files, for
security and efficiency reasons, unless C<allow_user_rules> is enabled (and
then, they may only add rules from below).
=over 4
=item allow_user_rules ( 0 | 1 ) (default: 0)
This setting allows users to create rules (and only rules) in their
C<user_prefs> files for use with C<spamd>. It defaults to off, because
this could be a severe security hole. It may be possible for users to
gain root level access if C<spamd> is run as root. It is NOT a good
idea, unless you have some other way of ensuring that users' tests are
safe. Don't use this unless you are certain you know what you are
doing. Furthermore, this option causes spamassassin to recompile all
the tests each time it processes a message for a user with a rule in
his/her C<user_prefs> file, which could have a significant effect on
server load. It is not recommended.
Note that it is not currently possible to use C<allow_user_rules> to modify an
existing system rule from a C<user_prefs> file with C<spamd>.
=cut
push (@cmds, {
setting => 'allow_user_rules',
is_priv => 1,
default => 0,
type => $CONF_TYPE_BOOL,
code => sub {
my ($self, $key, $value, $line) = @_;
if ($value eq '') {
return $MISSING_REQUIRED_VALUE;
}
elsif ($value !~ /^[01]$/) {
return $INVALID_VALUE;
}
$self->{allow_user_rules} = $value+0;
dbg("config: " . ($self->{allow_user_rules} ? "allowing":"not allowing") . " user rules!");
}
});
=item redirector_pattern /pattern/modifiers
A regex pattern that matches both the redirector site portion, and
the target site portion of a URI.
Note: The target URI portion must be surrounded in parentheses and
no other part of the pattern may create a backreference.
Example: http://chkpt.zdnet.com/chkpt/whatever/spammer.domain/yo/dude
redirector_pattern /^https?:\/\/(?:opt\.)?chkpt\.zdnet\.com\/chkpt\/\w+\/(.*)$/i
=cut
push (@cmds, {
setting => 'redirector_pattern',
is_priv => 1,
default => [],
type => $CONF_TYPE_STRINGLIST,
code => sub {
my ($self, $key, $value, $line) = @_;
$value =~ s/^\s+//;
if ($value eq '') {
return $MISSING_REQUIRED_VALUE;
}
my ($rec, $err) = compile_regexp($value, 1);
if (!$rec) {
dbg("config: invalid redirector_pattern '$value': $err");
return $INVALID_VALUE;
}
push @{$self->{main}->{conf}->{redirector_patterns}}, $rec;
}
});
=item header SYMBOLIC_TEST_NAME header op /pattern/modifiers [if-unset: STRING]
Define a test. C<SYMBOLIC_TEST_NAME> is a symbolic test name, such as
'FROM_ENDS_IN_NUMS'. C<header> is the name of a mail header field,
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
is_priv => 1,
type => $CONF_TYPE_HASH_KEY_VALUE,
code => sub {
my ($self, $key, $value, $line) = @_;
my ($rulename, $priority) = split(/\s+/, $value, 2);
unless (defined $priority) {
return $MISSING_REQUIRED_VALUE;
}
unless ($rulename =~ IS_RULENAME) {
return $INVALID_VALUE;
}
unless ($priority =~ /^-?\d+$/) {
return $INVALID_VALUE;
}
$self->{priority}->{$rulename} = $priority;
}
});
=back
=head2 CAPTURING TAGS USING REGEX NAMED CAPTURE GROUPS
SpamAssassin 4.0 supports capturing template tags from regex rules. The
captured tags, along with other standard template tags, can be used in other
rules as a matching string. See B<TEMPLATE TAGS> section for more info on
tags.
Capturing can be done in any body/rawbody/header/uri/full rule that uses a
regex for matching (not eval rules). Standard Perl named capture group
format C<(?E<lt>NAMEE<gt>pattern)> must be used, as described in
L<https://perldoc.perl.org/perlre#(?%3CNAME%3Epattern)>.
Example, capturing a tag named C<BODY_HELLO_NAME>:
body __HELLO_NAME /\bHello, (?<BODY_HELLO_NAME>\w+)\b/
The tag can then be used in another rule for matching, using a %{TAGNAME}
template. This would search the captured name in From-header:
header HELLO_NAME_IN_FROM From =~ /\b%{BODY_HELLO_NAME}\b/i
If any tag that a rule depends on is not found, then the rule is not run at
all. To prevent a literal %{NAME} string from being parsed as a template,
it can be escaped with a backslash: \%{NAME}.
Captured tags can also be used in reports and in other plugins like AskDNS,
with the standard C<_BODY_HELLO_NAME_> notation.
Note that at this time there is no automatic dependency tracking for rule
running order. All rules that use named capture groups are automatically
set to priority -10000, so that the tags should always be ready for any
normal rules to use. When rule depends on a tag that might be set at later
stage by a plugin for example, it's priority should be set manually to a
higher value.
=head1 ADMINISTRATOR SETTINGS
These settings differ from the ones above, in that they are considered 'more
privileged' -- even more than the ones in the B<PRIVILEGED SETTINGS> section.
No matter what C<allow_user_rules> is set to, these can never be set from a
user's C<user_prefs> file when spamc/spamd is being used. However, all
settings can be used by local programs run directly by the user.
=over 4
=item version_tag string
This tag is appended to the SA version in the X-Spam-Status header. You should
include it when you modify your ruleset, especially if you plan to distribute it.
A good choice for I<string> is your last name or your initials followed by a
number which you increase with each change.
The version_tag will be lowercased, and any non-alphanumeric or period
character will be replaced by an underscore.
e.g.
version_tag myrules1 # version=2.41-myrules1
=cut
push (@cmds, {
setting => 'version_tag',
is_admin => 1,
code => sub {
my ($self, $key, $value, $line) = @_;
if ($value eq '') {
return $MISSING_REQUIRED_VALUE;
}
my $tag = lc($value);
$tag =~ tr/a-z0-9./_/c;
foreach (@Mail::SpamAssassin::EXTRA_VERSION) {
if($_ eq $tag) { $tag = undef; last; }
}
push(@Mail::SpamAssassin::EXTRA_VERSION, $tag) if($tag);
}
});
=item test SYMBOLIC_TEST_NAME (ok|fail) Some string to test against
Define a regression testing string. You can have more than one regression test
string per symbolic test name. Simply specify a string that you wish the test
to match.
These tests are only run as part of the test suite - they should not affect the
general running of SpamAssassin.
=cut
push (@cmds, {
setting => 'test',
is_admin => 1,
code => sub {
return unless defined $COLLECT_REGRESSION_TESTS;
my ($self, $key, $value, $line) = @_;
local ($1,$2,$3);
if ($value !~ /^(\S+)\s+(ok|fail)\s+(.*)$/) { return $INVALID_VALUE; }
$self->{parser}->add_regression_test($1, $2, $3);
}
});
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
The password for the database username, for the above DSN.
=cut
push (@cmds, {
setting => 'user_scores_sql_password',
is_admin => 1,
default => '',
type => $CONF_TYPE_STRING,
});
=item user_scores_sql_custom_query query
This option gives you the ability to create a custom SQL query to
retrieve user scores and preferences. In order to work correctly your
query should return two values, the preference name and value, in that
order. In addition, there are several "variables" that you can use
as part of your query, these variables will be substituted for the
current values right before the query is run. The current allowed
variables are:
=over 4
=item _TABLE_
The name of the table where user scores and preferences are stored. Currently
hardcoded to userpref, to change this value you need to create a new custom
query with the new table name.
=item _USERNAME_
The current user's username.
=item _MAILBOX_
The portion before the @ as derived from the current user's username.
=item _DOMAIN_
The portion after the @ as derived from the current user's username, this
value may be null.
=back
The query must be one continuous line in order to parse correctly.
Here are several example queries, please note that these are broken up
for easy reading, in your config it should be one continuous line.
=over 4
=item Current default query:
C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' ORDER BY username ASC>
=item Use global and then domain level defaults:
C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' OR username = '@~'||_DOMAIN_ ORDER BY username ASC>
=item Maybe global prefs should override user prefs:
C<SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '@GLOBAL' ORDER BY username DESC>
=back
=cut
push (@cmds, {
setting => 'user_scores_sql_custom_query',
is_admin => 1,
default => undef,
type => $CONF_TYPE_STRING,
});
=item user_scores_ldap_username
This is the Bind DN used to connect to the LDAP server. It defaults
to the empty string (""), allowing anonymous binding to work.
Example: C<cn=master,dc=koehntopp,dc=de>
=cut
push (@cmds, {
setting => 'user_scores_ldap_username',
is_admin => 1,
default => '',
type => $CONF_TYPE_STRING,
});
=item user_scores_ldap_password
This is the password used to connect to the LDAP server. It defaults
to the empty string ("").
=cut
push (@cmds, {
setting => 'user_scores_ldap_password',
is_admin => 1,
default => '',
type => $CONF_TYPE_STRING,
});
=item user_scores_fallback_to_global (default: 1)
Fall back to global scores and settings if userprefs can't be loaded
from SQL or LDAP, instead of passing the message through unprocessed.
=cut
push (@cmds, {
setting => 'user_scores_fallback_to_global',
is_admin => 1,
default => 1,
type => $CONF_TYPE_BOOL,
});
=item loadplugin [Mail::SpamAssassin::Plugin::]ModuleName [/path/module.pm]
Load a SpamAssassin plugin module. The C<ModuleName> is the perl module
name, used to create the plugin object itself.
Module naming is strict, name must only contain alphanumeric characters or
underscores. File must have .pm extension.
C</path/module.pm> is the file to load, containing the module's perl code;
if it's specified as a relative path, it's considered to be relative to the
current configuration file. If it is omitted, the module will be loaded
using perl's search path (the C<@INC> array).
See C<Mail::SpamAssassin::Plugin> for more details on writing plugins.
=cut
push (@cmds, {
setting => 'loadplugin',
is_admin => 1,
code => sub {
my ($self, $key, $value, $line) = @_;
if ($value eq '') {
return $MISSING_REQUIRED_VALUE;
}
my ($package, $path);
local ($1,$2);
if ($value =~ /^((?:\w+::){0,10}\w+)(?:\s+(\S+\.pm))?$/i) {
($package, $path) = ($1, $2);
} else {
return $INVALID_VALUE;
}
# trunk Dmarc.pm was renamed to DMARC.pm
# (same check also in Conf/Parser.pm handle_conditional)
if ($package eq 'Mail::SpamAssassin::Plugin::Dmarc') {
$package = 'Mail::SpamAssassin::Plugin::DMARC';
}
# backwards compatible - removed in 4.1
# (same check also in Conf/Parser.pm handle_conditional)
elsif ($package eq 'Mail::SpamAssassin::Plugin::WhiteListSubject') {
$package = 'Mail::SpamAssassin::Plugin::WelcomeListSubject';
}
$self->load_plugin ($package, $path);
}
});
=item tryplugin ModuleName [/path/module.pm]
Same as C<loadplugin>, but silently ignored if the .pm file cannot be found in
lib/Mail/SpamAssassin/Conf.pm view on Meta::CPAN
the long option shows that the first token appeared in zero
ham messages and four spam messages, and that it was last
seen four days ago. The second token appeared in two ham messages,
25 spam messages and was last seen one day ago.
(Unlike the C<compact> option, the long option shows declassification
distances that are greater than 9.)
=back
=cut
return \@cmds;
}
###########################################################################
# settings that were once part of core, but are now in (possibly-optional)
# bundled plugins. These will be warned about, but do not generate a fatal
# error when "spamassassin --lint" is run like a normal syntax error would.
our @MIGRATED_SETTINGS = qw{
ok_languages
};
###########################################################################
sub new {
my $class = shift;
$class = ref($class) || $class;
my $self = {
main => shift,
registered_commands => [],
}; bless ($self, $class);
$self->{parser} = Mail::SpamAssassin::Conf::Parser->new($self);
$self->{parser}->register_commands($self->set_default_commands());
$self->{errors} = 0;
$self->{plugins_loaded} = { };
$self->{tests} = { };
$self->{test_types} = { };
$self->{scoreset} = [ {}, {}, {}, {} ];
$self->{scoreset_current} = 0;
$self->set_score_set (0);
$self->{tflags} = { };
$self->{source_file} = { };
# keep descriptions in a slow but space-efficient single-string
# data structure
# NOTE: Deprecated usage of TieOneStringHash as of 10/2018, it's an
# absolute pig, doubling config parsing time, while benchmarks indicate
# no difference in resident memory size!
$self->{descriptions} = { };
#tie %{$self->{descriptions}}, 'Mail::SpamAssassin::Util::TieOneStringHash'
# or warn "tie failed";
$self->{subjprefix} = { };
# after parsing, tests are refiled into these hashes for each test type.
# this allows e.g. a full-text test to be rewritten as a body test in
# the user's user_prefs file.
$self->{body_tests} = { };
$self->{uri_tests} = { };
$self->{uri_evals} = { }; # not used/implemented yet
$self->{head_tests} = { };
$self->{head_evals} = { };
$self->{body_evals} = { };
$self->{full_tests} = { };
$self->{full_evals} = { };
$self->{rawbody_tests} = { };
$self->{rawbody_evals} = { };
$self->{meta_tests} = { };
$self->{eval_plugins} = { };
$self->{eval_plugins_types} = { };
# meta dependencies
$self->{meta_dependencies} = {};
$self->{meta_deprules} = {};
$self->{meta_nodeps} = {};
# map eval function names to rulenames
$self->{eval_to_rule} = {};
# regex capture template rules
$self->{capture_rules} = {};
$self->{capture_template_rules} = {};
# testing stuff
$self->{regression_tests} = { };
$self->{rewrite_header} = { };
$self->{want_rebuild_for_type} = { };
$self->{user_defined_rules} = { };
$self->{headers_spam} = [ ];
$self->{headers_ham} = [ ];
$self->{bayes_ignore_header} = { };
$self->{bayes_ignore_from} = { };
$self->{bayes_ignore_to} = { };
$self->{welcomelist_auth} = { };
$self->{def_welcomelist_auth} = { };
$self->{welcomelist_from} = { };
$self->{welcomelist_allows_relays} = { };
$self->{welcomelist_from_rcvd} = { };
$self->{def_welcomelist_from_rcvd} = { };
$self->{blocklist_to} = { };
$self->{welcomelist_to} = { };
$self->{more_spam_to} = { };
$self->{all_spam_to} = { };
$self->{trusted_networks} = $self->new_netset('trusted_networks',1);
$self->{internal_networks} = $self->new_netset('internal_networks',1);
$self->{msa_networks} = $self->new_netset('msa_networks',0); # no loopback IP
$self->{trusted_networks_configured} = 0;
$self->{internal_networks_configured} = 0;
# Make sure we add in X-Spam-Checker-Version
{ my $r = [ "Checker-Version",
"SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_" ];
( run in 1.406 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )