You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by du...@apache.org on 2009/03/02 23:49:51 UTC
svn commit: r749462 - in /spamassassin/trunk: ./ build/ lib/Mail/
lib/Mail/SpamAssassin/ lib/Mail/SpamAssassin/Conf/
lib/Mail/SpamAssassin/Plugin/ masses/ rules/ t/
Author: duncf
Date: Mon Mar 2 22:49:50 2009
New Revision: 749462
URL: http://svn.apache.org/viewvc?rev=749462&view=rev
Log:
Bug 6012: Improve reuse logic to better simulate rule hits. This moves
the reuse logic to a plugin and adds several plugin hooks.
Added:
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Reuse.pm
spamassassin/trunk/t/reuse.t
Modified:
spamassassin/trunk/MANIFEST
spamassassin/trunk/build/mkrules
spamassassin/trunk/build/parse-rules-for-masses
spamassassin/trunk/lib/Mail/SpamAssassin.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
spamassassin/trunk/masses/mass-check
spamassassin/trunk/rules/20_dnsbl_tests.cf
spamassassin/trunk/rules/20_net_tests.cf
spamassassin/trunk/rules/25_dcc.cf
spamassassin/trunk/rules/25_pyzor.cf
spamassassin/trunk/rules/25_razor2.cf
spamassassin/trunk/rules/25_spf.cf
spamassassin/trunk/rules/25_uribl.cf
Modified: spamassassin/trunk/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/trunk/MANIFEST?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/MANIFEST (original)
+++ spamassassin/trunk/MANIFEST Mon Mar 2 22:49:50 2009
@@ -95,6 +95,7 @@
lib/Mail/SpamAssassin/Plugin/RelayCountry.pm
lib/Mail/SpamAssassin/Plugin/RelayEval.pm
lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm
+lib/Mail/SpamAssassin/Plugin/Reuse.pm
lib/Mail/SpamAssassin/Plugin/Rule2XSBody.pm
lib/Mail/SpamAssassin/Plugin/SPF.pm
lib/Mail/SpamAssassin/Plugin/Shortcircuit.pm
@@ -371,6 +372,7 @@
t/report_safe.t
t/reportheader.t
t/reportheader_8bit.t
+t/reuse.t
t/rule_multiple.t
t/rule_names.t
t/rule_tests.t
Modified: spamassassin/trunk/build/mkrules
URL: http://svn.apache.org/viewvc/spamassassin/trunk/build/mkrules?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/build/mkrules (original)
+++ spamassassin/trunk/build/mkrules Mon Mar 2 22:49:50 2009
@@ -412,9 +412,6 @@
while (<IN>) {
my $orig = $_;
- s/^#reuse/reuse/; # TODO - dirty hack. we need to fix this to just be
- # a keyword which the engine ignores, this is absurd!
-
s/#.*$//g; s/^\s+//; s/\s+$//;
# drop comments/blank lines from output
@@ -673,9 +670,6 @@
while (<IN>) {
my $orig = $_;
- s/^#reuse/reuse/; # TODO - dirty hack. we need to fix this to just be
- # a keyword which the engine ignores, this is absurd!
-
s/#.*$//g; s/^\s+//; s/\s+$//;
# drop comments/blank lines from output
Modified: spamassassin/trunk/build/parse-rules-for-masses
URL: http://svn.apache.org/viewvc/spamassassin/trunk/build/parse-rules-for-masses?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/build/parse-rules-for-masses (original)
+++ spamassassin/trunk/build/parse-rules-for-masses Mon Mar 2 22:49:50 2009
@@ -56,7 +56,6 @@
$scoreset = 0 if ( !defined $scoreset );
my $rules = { };
-my $reuse = { };
$rules->{_scoreset} = $scoreset;
readrules(@rulesdirs);
@@ -94,9 +93,6 @@
$scores_mutable = 1;
}
- # oh, this is a dirty dirty hack, but we don't need this at runtime
- s/^#reuse/reuse/;
-
s/#.*$//g; s/^\s+//; s/\s+$//; next if /^$/;
# TODO: this could be overwriting stuff
@@ -105,11 +101,16 @@
$lang = $1;
}
- if (/^(header|rawbody|body|full|uri|meta|mimeheader)\s+(\S+)\s+(.*)$/) {
+ if (/^(header|rawbody|body|full|uri|meta|mimeheader|reuse)\s+(\S+)\s+(.*)$/) {
my $type = $1;
my $name = $2;
my $val = $3;
+ if (exists $rules->{$name}->{type} && $type eq 'reuse') {
+ # "reuse" should be skipped if we already have a rule
+ next;
+ }
+
$rules->{$name} ||= { };
$rules->{$name}->{type} = $type;
$rules->{$name}->{lang} = $lang;
@@ -143,16 +144,7 @@
$rules->{$name}->{score} = $score;
$rules->{$name}->{mutable} = $scores_mutable;
- } elsif (/^reuse\s+(.*)$/) {
- my ($new, @old) = split(' ', $1);
- push @old, $new;
- for my $old (@old) {
- $reuse->{$old} ||= { };
- $reuse->{$old}->{reuse} = $new;
- }
- $reuse->{$new} ||= { };
- $reuse->{$new}->{skip} = 1;
- }
+ }
}
close IN;
}
@@ -218,7 +210,7 @@
print OUT "# dumped at ".`date`."\n";
$Data::Dumper::Purity = 1;
- print OUT Data::Dumper->Dump ([$rules, $scores, $reuse], ['*rules', '*scores', '*reuse']);
+ print OUT Data::Dumper->Dump ([$rules, $scores], ['*rules', '*scores']);
print OUT "1;";
close OUT;
Modified: spamassassin/trunk/lib/Mail/SpamAssassin.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin.pm?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin.pm Mon Mar 2 22:49:50 2009
@@ -220,6 +220,11 @@
override the settings for C<rules_filename>, C<site_rules_filename>,
and C<userprefs_filename>.
+=item pre_config_text
+
+Similar to C<config_text>, this text is placed before config_text to allow an
+override of config files.
+
=item post_config_text
Similar to C<config_text>, this text is placed after config_text to allow an
@@ -1650,7 +1655,12 @@
}
}
- $self->{config_text} .= $self->{post_config_text} if ($self->{post_config_text});
+ if ($self->{pre_config_text}) {
+ $self->{config_text} = $self->{pre_config_text} . $self->{config_text};
+ }
+ if ($self->{post_config_text}) {
+ $self->{config_text} .= $self->{post_config_text};
+ }
if ($self->{config_text} !~ /\S/) {
my $m = "config: no configuration text or files found! do you need to run 'sa-update'?\n";
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Mon Mar 2 22:49:50 2009
@@ -102,7 +102,7 @@
$TYPE_HEAD_TESTS $TYPE_HEAD_EVALS
$TYPE_BODY_TESTS $TYPE_BODY_EVALS $TYPE_FULL_TESTS $TYPE_FULL_EVALS
$TYPE_RAWBODY_TESTS $TYPE_RAWBODY_EVALS $TYPE_URI_TESTS $TYPE_URI_EVALS
-$TYPE_META_TESTS $TYPE_RBL_EVALS
+$TYPE_META_TESTS $TYPE_RBL_EVALS $TYPE_EMPTY_TESTS
};
@ISA = qw();
@@ -121,6 +121,7 @@
$TYPE_URI_EVALS = 0x0011;
$TYPE_META_TESTS = 0x0012;
$TYPE_RBL_EVALS = 0x0013;
+$TYPE_EMPTY_TESTS = 0x0014;
my @rule_types = ("body_tests", "uri_tests", "uri_evals",
"head_tests", "head_evals", "body_evals", "full_tests",
@@ -2325,6 +2326,38 @@
}
});
+=item reuse SYMBOLIC_TEST_NAME [ OLD_SYMBOLIC_TEST_NAME_1 ... ]
+
+Defines the name of a test that should be "reused" during the scoring
+process. If a message has an X-Spam-Status header that shows a hit for
+this rule or any of the old rule names given, a hit will be added for
+this rule when B<mass-check --reuse> is used. Examples:
+
+C<reuse SPF_PASS>
+
+C<reuse MY_NET_RULE_V2 MY_NET_RULE_V1>
+
+The actual logic for reuse tests is done by
+B<Mail::SpamAssassin::Plugin::Reuse>.
+
+=cut
+
+ push (@cmds, {
+ setting => 'reuse',
+ is_priv => 1,
+ code => sub {
+ my ($self, $key, $value, $line) = @_;
+ if ($value !~ /\s*(\w+)(?:\s+(?:\w+(?:\s+\w+)*))?\s*$/) {
+ return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+ }
+ my $rule_name = $1;
+ # don't overwrite tests, just define them so scores, priorities work
+ if (!exists $self->{tests}->{$rule_name}) {
+ $self->{parser}->add_test($rule_name, undef, $TYPE_EMPTY_TESTS);
+ }
+ }
+ });
+
=item tflags SYMBOLIC_TEST_NAME [ {net|nice|learn|userconf|noautolearn|multiple} ]
Used to set flags on a test. These flags are used in the
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm Mon Mar 2 22:49:50 2009
@@ -699,6 +699,11 @@
# note: this function is called once for system-wide configuration
# with $isuserconf set to 0, then again for user conf with $isuserconf set to 1.
+ if (!$isuserconf) {
+ $conf->{main}->call_plugins("finish_parsing_start", { conf => $conf });
+ } else {
+ $conf->{main}->call_plugins("user_conf_parsing_start", { conf => $conf });
+ }
$self->trace_meta_dependencies();
$self->fix_priorities();
@@ -773,6 +778,8 @@
elsif ($type == $Mail::SpamAssassin::Conf::TYPE_FULL_TESTS) {
$conf->{full_tests}->{$priority}->{$name} = $text;
}
+ elsif ($type == $Mail::SpamAssassin::Conf::TYPE_EMPTY_TESTS) {
+ }
else {
$self->lint_warn("unknown type $type for $name: $text", $name);
}
@@ -782,7 +789,6 @@
$self->lint_trusted_networks();
if (!$isuserconf) {
- # named this way just in case we ever want a "finish_parsing_start"
$conf->{main}->call_plugins("finish_parsing_end", { conf => $conf });
} else {
$conf->{main}->call_plugins("user_conf_parsing_end", { conf => $conf });
@@ -880,7 +886,10 @@
my %dups;
while (my ($name, $text) = each %{$conf->{tests}}) {
my $type = $conf->{test_types}->{$name};
- next if ($type & 1); # skip eval tests
+
+ # skip eval and empty tests
+ next if ($type & 1) ||
+ ($type eq $Mail::SpamAssassin::Conf::TYPE_EMPTY_TESTS);
my $tf = ($conf->{tflags}->{$name}||''); $tf =~ s/\s+/ /gs;
# ensure similar, but differently-typed, rules are not marked as dups;
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm Mon Mar 2 22:49:50 2009
@@ -2177,6 +2177,12 @@
sub got_hit {
my ($self, $rule, $area, %params) = @_;
+ my $score = $params{score} || $self->{conf}->{scores}->{$rule};
+
+ # adding a hit does nothing if we don't have a score -- we probably
+ # shouldn't have run it in the first place
+ return unless $score;
+
# ensure that rule values always result in an *increase* of
# $self->{tests_already_hit}->{$rule}:
my $value = $params{value}; if (!$value || $value <= 0) { $value = 1; }
@@ -2194,7 +2200,7 @@
$params{ruletype} ||= 'unknown';
$self->_handle_hit($rule,
- $params{score} || $self->{conf}->{scores}->{$rule},
+ $score,
$area,
$params{ruletype},
$self->{conf}->get_description_for_rule($rule) || $rule);
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin.pm Mon Mar 2 22:49:50 2009
@@ -198,6 +198,30 @@
C<$options> hash reference above. By storing it on C<conf>, this allows
per-user and system-wide configuration precedence to be dealt with correctly.
+=item $plugin->finish_parsing_start ( { options ... } )
+
+Signals that the system-wide configuration has been completely read,
+but internal data structures are not yet created. It is possible to
+use this hook to dynamically change the configuration already read in
+or add new config options.
+
+C<options> is a reference to a hash containing these options:
+
+=over 4
+
+=item conf
+
+The C<Mail::SpamAssassin::Conf> object on which the configuration
+data should be stored.
+
+=back
+
+Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release. In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.
+
=item $plugin->finish_parsing_end ( { options ... } )
Signals that the system-wide configuration parsing has just finished, and
@@ -220,6 +244,32 @@
third-party plugin, all bets are off until such time that an API is
present for modifying that configuration data.
+=item $plugin->user_conf_parsing_start ( { options ... } )
+
+Signals that the per-user configuration has been completely read, but
+not converted to internal data structures. It is possible to use this
+hook to dynamically change the configuration already read in or add
+new config options.
+
+If C<allow_user_rules> is enabled in the configuration, it is possible
+that additional rules have been added since the C<finish_parsing_start>
+plugin hook invocation was called.
+
+=over 4
+
+=item conf
+
+The C<Mail::SpamAssassin::Conf> object on which the configuration
+data should be stored.
+
+=back
+
+Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release. In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.
+
=item $plugin->user_conf_parsing_end ( { options ... } )
Signals that the per-user configuration parsing has just finished, and
@@ -238,6 +288,12 @@
=back
+Note: there are no guarantees that the internal data structures of
+SpamAssassin will not change from release to release. In particular to
+this plugin hook, if you modify the rules data structures in a
+third-party plugin, all bets are off until such time that an API is
+present for modifying that configuration data.
+
=item $plugin->signal_user_changed ( { options ... } )
Signals that the current user has changed for a new one.
Added: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Reuse.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Reuse.pm?rev=749462&view=auto
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Reuse.pm (added)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Reuse.pm Mon Mar 2 22:49:50 2009
@@ -0,0 +1,241 @@
+=head1 NAME
+
+Mail::SpamAssassin::Plugin::Reuse - For reusing old rule hits during a mass-check
+
+=head1 SYNOPSIS
+
+ loadplugin Mail::SpamAssassin::Plugin::Reuse
+
+ ifplugin Mail::SpamAssassin::Plugin::Reuse
+
+ reuse NETWORK_RULE [ NETWORK_RULE_OLD_NAME ]
+
+ endif
+
+=head1 DESCRIPTION
+
+The purpose of this plugin is to work in conjunction with B<mass-check
+--reuse> to map rules hit in input messages to rule hits in the
+mass-check output.
+
+=cut
+
+package Mail::SpamAssassin::Plugin::Reuse;
+
+use bytes;
+use strict;
+use warnings;
+
+use Mail::SpamAssassin::Conf;
+use Mail::SpamAssassin::Logger;
+
+use vars qw(@ISA);
+@ISA = qw(Mail::SpamAssassin::Plugin);
+
+# constructor
+sub new {
+ my $invocant = shift;
+ my $samain = shift;
+
+ # some boilerplate...
+ my $class = ref($invocant) || $invocant;
+ my $self = $class->SUPER::new($samain);
+ bless ($self, $class);
+
+ $self->set_config($samain->{conf});
+ # make sure we run last (or close) of the finish_parsing_start since
+ # we need all other rules to be defined
+ $self->register_method_priority("finish_parsing_start", 100);
+ return $self;
+}
+
+sub set_config {
+ my ($self, $conf) = @_;
+ my @cmds = ();
+
+ # reuse CURRENT_NAME ADDITIONAL_NAMES_IN_INPUT ...
+ # e.g.
+ # reuse NET_TEST_V1 NET_TEST_V0
+
+ push (@cmds, { setting => 'reuse',
+ code => sub {
+ my ($conf, $key, $value, $line) = @_;
+
+ if ($value !~ /\s*(\w+)(?:\s+(\w+(?:\s+\w+)*))?\s*$/) {
+ return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+ }
+
+ my $new_name = $1;
+ my @old_names = ($new_name);
+ if ($2) {
+ push @old_names, split (' ', $2);
+ }
+
+ dbg("reuse: read rule, old: @old_names new: $new_name");
+
+ foreach my $old (@old_names) {
+ push @{$conf->{reuse_tests}->{$new_name}}, $old;
+ }
+
+ }});
+
+
+ $conf->{parser}->register_commands(\@cmds);
+}
+
+sub finish_parsing_start {
+ my ($self, $opts) = @_;
+
+ my $conf = $opts->{conf};
+
+ dbg("reuse: finish_parsing_start called");
+
+ return 0 if (!exists $conf->{reuse_tests});
+
+ foreach my $rule_name (keys %{$conf->{reuse_tests}}) {
+
+ # If the rule does not exist, add a new EMPTY test, set default score
+ if (!exists $conf->{tests}->{$rule_name}) {
+ dbg("reuse: $rule_name does not exist, adding empty test");
+ $conf->{parser}->add_test($rule_name, undef, $Mail::SpamAssassin::Conf::TYPE_EMPTY_TESTS);
+ }
+ if (!exists $conf->{scores}->{$rule_name}) {
+ my $set_score = ($rule_name =~/^T_/) ? 0.01 : 1.0;
+ $set_score = -$set_score if ( ($conf->{tflags}->{$rule_name}||'') =~ /\bnice\b/ );
+ foreach my $ss (0..3) {
+ $conf->{scoreset}->[$ss]->{$rule_name} = $set_score;
+ }
+ }
+
+ # Figure out when to add any hits -- grab priority and "stage"
+ my $priority = $conf->{priority}->{$rule_name} || 0;
+ my $stage = $self->_get_stage_from_rule($opts->{conf}, $rule_name);
+ $conf->{reuse_tests_order}->{$rule_name} = [ $priority, $stage ];
+
+ }
+}
+
+sub check_start {
+ my ($self, $opts) = @_;
+
+ my $pms = $opts->{permsgstatus};
+
+ # Can we reuse?
+ my $msg = $pms->get_message();
+
+ unless (exists $msg->{metadata}->{reuse_tests_hit}) {
+ dbg("reuse: no old test hits passed in");
+ return 0;
+ }
+ my $old_hash = $msg->{metadata}->{reuse_tests_hit};
+
+ # now go through the rules and priorities and figure out which ones
+ # need to be disabled
+ foreach my $rule (keys %{$pms->{conf}->{reuse_tests}}) {
+
+ dbg("reuse: looking at rule $rule");
+ my ($priority, $stage) = @{$pms->{conf}->{reuse_tests_order}->{$rule}};
+
+ # score set could change after check_start but before we add hits,
+ # so we need to disable the rule in all sets
+ foreach my $ss (0..3) {
+ if (exists $pms->{conf}->{scoreset}->[$ss]->{$rule}) {
+ dbg("reuse: disabling rule $rule in score set $ss");
+ $pms->{reuse_old_scores}->{$rule}->[$ss] =
+ $pms->{conf}->{scoreset}->[$ss]->{$rule};
+ $pms->{conf}->{scoreset}->[$ss]->{$rule} = 0;
+ }
+ }
+
+ # now, check for hits
+ OLD: foreach my $old_test (@{$pms->{conf}->{reuse_tests}->{$rule}}) {
+ dbg("reuse: looking for rule $old_test");
+ if ($old_hash->{$old_test}) {
+ push @{$pms->{reuse_hits_to_add}->{"$priority $stage"}}, $rule;
+ dbg("reuse: rule $rule hit, will add at priority $priority, stage " .
+ "$stage");
+ last OLD;
+ }
+ }
+ }
+}
+
+sub check_end {
+ my ($self, $opts) = @_;
+
+ my $pms = $opts->{permsgstatus};
+
+ foreach my $disabled_rule (keys %{$pms->{reuse_old_scores}}) {
+ foreach my $ss (0..3) {
+ next unless exists $pms->{conf}->{scoreset}->[$ss]->{$disabled_rule};
+ $pms->{conf}->{scoreset}->[$ss]->{$disabled_rule} =
+ $pms->{reuse_old_scores}->{$disabled_rule}->[$ss];
+ }
+ }
+
+ delete $pms->{reuse_old_scores};
+}
+
+sub start_rules {
+ my ($self, $opts) = @_;
+
+ return $self->_add_hits($opts->{permsgstatus}, $opts->{priority},
+ $opts->{ruletype});
+}
+
+sub _add_hits {
+ my ($self, $pms, $priority, $stage) = @_;
+
+ return unless exists $pms->{reuse_hits_to_add}->{"$priority $stage"};
+ foreach my $rule (@{$pms->{reuse_hits_to_add}->{"$priority $stage"}}) {
+ # Add hit even if rule was originally disabled
+ my $ss = $pms->{conf}->get_score_set();
+ $pms->{conf}->{scores}->{$rule} =
+ $pms->{reuse_old_scores}->{$rule}->[$ss] || 0.001;
+
+ dbg("reuse: registering hit for $rule: score: " .
+ $pms->{conf}->{scores}->{$rule});
+ $pms->got_hit($rule);
+
+ $pms->{conf}->{scores}->{$rule} = 0;
+ }
+}
+
+my %type_to_stage = (
+ $Mail::SpamAssassin::Conf::TYPE_HEAD_TESTS => "head",
+ $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS => "eval",
+ $Mail::SpamAssassin::Conf::TYPE_BODY_TESTS => "body",
+ $Mail::SpamAssassin::Conf::TYPE_BODY_EVALS => "eval",
+ $Mail::SpamAssassin::Conf::TYPE_FULL_TESTS => "full",
+ $Mail::SpamAssassin::Conf::TYPE_FULL_EVALS => "eval",
+ $Mail::SpamAssassin::Conf::TYPE_RAWBODY_TESTS => "rawbody",
+ $Mail::SpamAssassin::Conf::TYPE_RAWBODY_EVALS => "eval",
+ $Mail::SpamAssassin::Conf::TYPE_URI_TESTS => "uri",
+ $Mail::SpamAssassin::Conf::TYPE_URI_EVALS => "eval",
+ $Mail::SpamAssassin::Conf::TYPE_META_TESTS => "meta",
+ $Mail::SpamAssassin::Conf::TYPE_RBL_EVALS => "eval",
+ );
+
+sub _get_stage_from_rule {
+ my ($self, $conf, $rule) = @_;
+
+ my $type = $conf->{test_types}->{$rule};
+ if ($type && $type == $Mail::SpamAssassin::Conf::TYPE_EMPTY_TESTS) {
+ # this is a "fake" rule... see if the rule "text"/"definition" is
+ # the name of the "parent" rule"
+ my $parent = $conf->{tests}->{$rule};
+ if ($parent) {
+ $type = $conf->{test_types}->{$parent};
+ }
+ }
+ if ($type && exists $type_to_stage{$type}) {
+ return $type_to_stage{$type};
+ }
+ else {
+ # Run before the meta rules run so that they can use these hits as
+ # inputs.
+ return "meta";
+ }
+}
+
+
Modified: spamassassin/trunk/masses/mass-check
URL: http://svn.apache.org/viewvc/spamassassin/trunk/masses/mass-check?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/masses/mass-check (original)
+++ spamassassin/trunk/masses/mass-check Mon Mar 2 22:49:50 2009
@@ -44,6 +44,7 @@
(default = extract all SpamAssassin-encapsulated mails)
--lint check rules for syntax before running
--cf='config line' Additional line of configuration
+ --pre='config line' Additional line of ".pre" (prepended to configuration)
--run_post_scan='command' Run the named command after the 'scan' stage,
before starting the 'run' stage
@@ -158,8 +159,8 @@
$opt_cs_ssl $opt_run_post_scan $opt_cs_verbose %client_caches
%server_caches @cache_tmp_files %min_other_caches
%unique_cache_completed $opt_cs_schedule_cache $opt_cs_cache
- $opt_cs_cachedir $opt_cs_max_tries
- $tmpfd %rules %reuse %orig_conf %reuse_conf $reuse_rules_loaded_p);
+ $opt_cs_cachedir $opt_cs_max_tries $opt_pre
+ $tmpfd);
use FindBin;
@@ -200,8 +201,8 @@
$opt_hamlog = "ham.log";
$opt_spamlog = "spam.log";
$opt_learn = 0;
-$reuse_rules_loaded_p = 0;
$opt_cf = [];
+$opt_pre = [];
my $rcvd_bytes = 0;
my $sent_bytes = 0;
@@ -224,7 +225,8 @@
"cs_schedule_cache", "cs_cache", "cs_cachedir=s", "cs_max_tries=i",
"before=s" => \&deal_with_before_after,
"after=s" => \&deal_with_before_after,
- 'cf=s' => \@{$opt_cf},
+ "cf=s" => \@{$opt_cf},
+ "pre=s" => \@{$opt_pre},
"dir" => sub { $opt_format = "dir"; },
"file" => sub { $opt_format = "file"; },
"mbox" => sub { $opt_format = "mbox"; },
@@ -241,23 +243,6 @@
die "IO::Socket::SSL required for --cs_ssl!\n";
}
-# rules.pl is for the --reuse option, score set doesn't matter
-if ($opt_reuse) {
- my $rules_path = "$FindBin::Bin/tmp/rules$$.pl";
- # some people specify paths relatively, whereas this needs an absolute path,
- # so "do the right thing"(tm).
- my $abs_opt_c = File::Spec->rel2abs($opt_c);
- system("cd $FindBin::Bin; perl ../build/parse-rules-for-masses -d $abs_opt_c -o $rules_path");
-
- unless (-s $rules_path > 130) {
- die '--reuse configuration error detected; rules.pl file size is too small'.
- ' ('.(-s $rules_path)." bytes)\nrules.pl path: $rules_path\n";
- }
-
- require $rules_path;
- unlink $rules_path;
-}
-
if ($opt_noisy) {
$opt_progress = 1; # implies --progress
}
@@ -290,9 +275,6 @@
exit;
}
-# either --net or --reuse means we should use set1/set3
-my $use_net_rules = $opt_net || $opt_reuse;
-
# --lint
if ($opt_lint) {
# In theory we could probably use the same spamtest object as below,
@@ -325,23 +307,9 @@
# the wire at all, and in fact we may be running without a net connection
push @{$opt_cf}, "dns_available yes\n";
- # --reuse without --net means we need to just zero ALL net rules; skip net
- # lookups entirely except for the reused ones. Do this before constructing
- # the Mail::SpamAssassin object to ensure no network-rules stuff is compiled
- # in compile_now(). (This config is for the reuse=no case. We create a
- # reuse=yes config after compile_now().)
- if (!$opt_net) {
- my @zero = (sort grep {
- (ref($rules{$_}) eq 'HASH')
- && $rules{$_}->{tflags}
- && $rules{$_}->{tflags} =~ /\bnet\b/;
- } keys %rules);
-
- foreach my $r (@zero) {
- push @{$opt_cf}, "score $r 0\n";
- # warn "--reuse/!--net zeroed $r";
- }
- }
+ # need to load M:SA:Plugin:Reuse
+ push @{$opt_pre}, "loadplugin Mail::SpamAssassin::Plugin::Reuse\n";
+
}
my $user_prefs = "$opt_p/user_prefs";
@@ -355,9 +323,10 @@
'userstate_dir' => $opt_p,
'save_pattern_hits' => $opt_loghits,
'dont_copy_prefs' => 1,
- 'local_tests_only' => $use_net_rules ? 0 : 1,
+ 'local_tests_only' => $opt_net ? 0 : 1,
'only_these_rules' => $opt_rules,
'ignore_safety_expire_timeout' => 1,
+ 'pre_config_text' => join("\n", @{$opt_pre})."\n",
'post_config_text' => join("\n", @{$opt_cf})."\n",
PREFIX => '',
DEF_RULES_DIR => $opt_c,
@@ -370,35 +339,6 @@
$spamtest->read_scoreonly_config("$FindBin::Bin/mass-check.cf");
$spamtest->read_scoreonly_config($user_prefs);
-# generated user_prefs
-if ($opt_reuse) {
- # copy current prefs if it exists
- $spamtest->copy_config(undef, \%orig_conf);
-
- # zeroed scores to reuse_prefs
- my @zero = (sort grep {
- defined $reuse{$_}->{skip}
- } keys %reuse);
- zero_rule_scores(@zero);
-
- $spamtest->copy_config(undef, \%reuse_conf);
- $reuse_rules_loaded_p = 1;
-}
-
-sub zero_rule_scores {
- my @zero = @_;
-
- my $pfile = "$FindBin::Bin/tmp/reuse_prefs";
- open(PREFS, ">$pfile") or die "Unable to open $pfile: $!\n".
- "Needed for --reuse to work properly";
- for my $rule (@zero) {
- print PREFS "score $rule 0\n";
- }
- close PREFS or die "failed to write $pfile";
- $spamtest->read_scoreonly_config($pfile);
- unlink $pfile;
-}
-
my $who = `id -un 2>/dev/null`;
my $where = `uname -n 2>/dev/null`;
my $when = `date -u`;
@@ -727,34 +667,11 @@
# get X-Spam-Status: header for rule hit resue
my $x_spam_status;
+ my $reusing;
if ($opt_reuse) {
$x_spam_status = $ma->get_header("X-Spam-Status");
$x_spam_status and $x_spam_status =~ s/,\s+/,/gs;
}
- my @previous; # previous hits, only set if $opt_reuse
-
- if ($opt_reuse) {
- if ($x_spam_status
- && $x_spam_status =~ m/tests=(\S*)/
- && $x_spam_status !~ /\bshortcircuit=(?:ham|spam|default)\b/)
- {
- push @previous, split(/,/, $1);
-
- # we found previous tests, so move the reuse config into place
- unless ($reuse_rules_loaded_p) {
- $spamtest->copy_config(\%reuse_conf, undef);
- $reuse_rules_loaded_p = 1;
- dbg "mass-check: reusing hits";
- }
- }
- else {
- if ($reuse_rules_loaded_p) {
- $spamtest->copy_config(\%orig_conf, undef);
- $reuse_rules_loaded_p = 0;
- dbg "mass-check: not reusing hits";
- }
- }
- }
# remove SpamAssassin markup, if present and the mail was spam
my $header = $ma->get_header("Received");
@@ -766,6 +683,17 @@
}
}
+ if ($opt_reuse) {
+ if ($x_spam_status
+ && $x_spam_status =~ m/tests=(\S*)/
+ && $x_spam_status !~ /\bshortcircuit=(?:ham|spam|default)\b/)
+ {
+ my @previous = split(/,/, $1);
+ $ma->{metadata}->{reuse_tests_hit} = { map {$_ => 1} @previous };
+ $reusing = 1;
+ }
+ }
+
# plugin hook to cause us to skip messages
my $skip = $spamtest->call_plugins("mass_check_skip_message", {
class => $class,
@@ -859,17 +787,12 @@
}
}
- if ($reuse_rules_loaded_p) {
- push(@extra, "reuse=yes");
- } else {
- push(@extra, "reuse=no");
- }
+ push(@extra, "reuse=" . ($reusing ? "yes" : "no"));
# log the scoreset we're in
{
my $set = 0;
if ($opt_net) { $set |= 1; }
- if ($reuse_rules_loaded_p) { $set |= 1; }
if ($status && defined $status->{bayes_score}) { $set |= 2; }
push(@extra, "set=".$set);
}
@@ -896,15 +819,7 @@
my @tests;
push @tests, split(/,/, $status->get_names_of_tests_hit());
push @tests, split(/,/, $status->get_names_of_subtests_hit());
- # hit reuse; $opt_reuse
- if ($x_spam_status) {
- # generate mapping of hits to remove hits that are marked as skip
- @tests = grep { !$reuse{$_}->{skip} } @tests;
- # add hits from previous
- for (@previous) {
- push(@tests, $reuse{$_}->{reuse}) if $reuse{$_}->{reuse};
- }
- }
+
$tests = join(",", sort(@tests));
$extra = join(",", @extra);
}
Modified: spamassassin/trunk/rules/20_dnsbl_tests.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/20_dnsbl_tests.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/20_dnsbl_tests.cf (original)
+++ spamassassin/trunk/rules/20_dnsbl_tests.cf Mon Mar 2 22:49:50 2009
@@ -46,34 +46,34 @@
header __RCVD_IN_NJABL eval:check_rbl('njabl', 'combined.njabl.org.')
describe __RCVD_IN_NJABL Received via a relay in combined.njabl.org
tflags __RCVD_IN_NJABL net
-#reuse __RCVD_IN_NJABL
+reuse __RCVD_IN_NJABL
header RCVD_IN_NJABL_RELAY eval:check_rbl_sub('njabl', '127.0.0.2')
describe RCVD_IN_NJABL_RELAY NJABL: sender is confirmed open relay
tflags RCVD_IN_NJABL_RELAY net
-#reuse RCVD_IN_NJABL_RELAY
+reuse RCVD_IN_NJABL_RELAY
# NJABL DUL: obsoleted by PBL (bug 5187)
header RCVD_IN_NJABL_SPAM eval:check_rbl_sub('njabl', '127.0.0.4')
describe RCVD_IN_NJABL_SPAM NJABL: sender is confirmed spam source
tflags RCVD_IN_NJABL_SPAM net
-#reuse RCVD_IN_NJABL_SPAM
+reuse RCVD_IN_NJABL_SPAM
header RCVD_IN_NJABL_MULTI eval:check_rbl_sub('njabl', '127.0.0.5')
describe RCVD_IN_NJABL_MULTI NJABL: sent through multi-stage open relay
tflags RCVD_IN_NJABL_MULTI net
-#reuse RCVD_IN_NJABL_MULTI
+reuse RCVD_IN_NJABL_MULTI
header RCVD_IN_NJABL_CGI eval:check_rbl_sub('njabl', '127.0.0.8')
describe RCVD_IN_NJABL_CGI NJABL: sender is an open formmail
tflags RCVD_IN_NJABL_CGI net
-#reuse RCVD_IN_NJABL_CGI
+reuse RCVD_IN_NJABL_CGI
header RCVD_IN_NJABL_PROXY eval:check_rbl_sub('njabl', '127.0.0.9')
describe RCVD_IN_NJABL_PROXY NJABL: sender is an open proxy
tflags RCVD_IN_NJABL_PROXY net
-#reuse RCVD_IN_NJABL_PROXY
+reuse RCVD_IN_NJABL_PROXY
# ---------------------------------------------------------------------------
# SORBS
@@ -85,53 +85,53 @@
header __RCVD_IN_SORBS eval:check_rbl('sorbs', 'dnsbl.sorbs.net.')
describe __RCVD_IN_SORBS SORBS: sender is listed in SORBS
tflags __RCVD_IN_SORBS net
-#reuse __RCVD_IN_SORBS
+reuse __RCVD_IN_SORBS
header RCVD_IN_SORBS_HTTP eval:check_rbl_sub('sorbs', '127.0.0.2')
describe RCVD_IN_SORBS_HTTP SORBS: sender is open HTTP proxy server
tflags RCVD_IN_SORBS_HTTP net
-#reuse RCVD_IN_SORBS_HTTP
+reuse RCVD_IN_SORBS_HTTP
header RCVD_IN_SORBS_SOCKS eval:check_rbl_sub('sorbs', '127.0.0.3')
describe RCVD_IN_SORBS_SOCKS SORBS: sender is open SOCKS proxy server
tflags RCVD_IN_SORBS_SOCKS net
-#reuse RCVD_IN_SORBS_SOCKS
+reuse RCVD_IN_SORBS_SOCKS
header RCVD_IN_SORBS_MISC eval:check_rbl_sub('sorbs', '127.0.0.4')
describe RCVD_IN_SORBS_MISC SORBS: sender is open proxy server
tflags RCVD_IN_SORBS_MISC net
-#reuse RCVD_IN_SORBS_MISC
+reuse RCVD_IN_SORBS_MISC
header RCVD_IN_SORBS_SMTP eval:check_rbl_sub('sorbs', '127.0.0.5')
describe RCVD_IN_SORBS_SMTP SORBS: sender is open SMTP relay
tflags RCVD_IN_SORBS_SMTP net
-#reuse RCVD_IN_SORBS_SMTP
+reuse RCVD_IN_SORBS_SMTP
# delist: $50 fee
#header RCVD_IN_SORBS_SPAM eval:check_rbl_sub('sorbs', '127.0.0.6')
#describe RCVD_IN_SORBS_SPAM SORBS: sender is a spam source
#tflags RCVD_IN_SORBS_SPAM net
-#reuse RCVD_IN_SORBS_SPAM
+#reuse RCVD_IN_SORBS_SPAM RCVD_IN_SORBS_SPAM
header RCVD_IN_SORBS_WEB eval:check_rbl_sub('sorbs', '127.0.0.7')
describe RCVD_IN_SORBS_WEB SORBS: sender is a abuseable web server
tflags RCVD_IN_SORBS_WEB net
-#reuse RCVD_IN_SORBS_WEB
+reuse RCVD_IN_SORBS_WEB
header RCVD_IN_SORBS_BLOCK eval:check_rbl_sub('sorbs', '127.0.0.8')
describe RCVD_IN_SORBS_BLOCK SORBS: sender demands to never be tested
tflags RCVD_IN_SORBS_BLOCK net
-#reuse RCVD_IN_SORBS_BLOCK
+reuse RCVD_IN_SORBS_BLOCK
header RCVD_IN_SORBS_ZOMBIE eval:check_rbl_sub('sorbs', '127.0.0.9')
describe RCVD_IN_SORBS_ZOMBIE SORBS: sender is on a hijacked network
tflags RCVD_IN_SORBS_ZOMBIE net
-#reuse RCVD_IN_SORBS_ZOMBIE
+reuse RCVD_IN_SORBS_ZOMBIE
header RCVD_IN_SORBS_DUL eval:check_rbl('sorbs-lastexternal', 'dnsbl.sorbs.net.', '127.0.0.10')
describe RCVD_IN_SORBS_DUL SORBS: sent directly from dynamic IP address
tflags RCVD_IN_SORBS_DUL net
-#reuse RCVD_IN_SORBS_DUL
+reuse RCVD_IN_SORBS_DUL
# ---------------------------------------------------------------------------
# Spamhaus SBL+XBL, now called Zen
@@ -142,25 +142,25 @@
header __RCVD_IN_ZEN eval:check_rbl('zen', 'zen.spamhaus.org.')
describe __RCVD_IN_ZEN Received via a relay in Spamhaus Zen
tflags __RCVD_IN_ZEN net
-#reuse __RCVD_IN_ZEN
+reuse __RCVD_IN_ZEN
# SBL is the Spamhaus Block List: http://www.spamhaus.org/sbl/
header RCVD_IN_SBL eval:check_rbl_sub('zen', '127.0.0.2')
describe RCVD_IN_SBL Received via a relay in Spamhaus SBL
tflags RCVD_IN_SBL net
-#reuse RCVD_IN_SBL
+reuse RCVD_IN_SBL
# XBL is the Exploits Block List: http://www.spamhaus.org/xbl/
header RCVD_IN_XBL eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '127.0.0.[45678]')
describe RCVD_IN_XBL Received via a relay in Spamhaus XBL
tflags RCVD_IN_XBL net
-#reuse RCVD_IN_XBL
+reuse RCVD_IN_XBL
# PBL is the Policy Block List: http://www.spamhaus.org/pbl/
header RCVD_IN_PBL eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '127.0.0.1[01]')
describe RCVD_IN_PBL Received via a relay in Spamhaus PBL
tflags RCVD_IN_PBL net
-#reuse RCVD_IN_PBL T_RCVD_IN_PBL_WITH_NJABL_DUL RCVD_IN_NJABL_DUL
+reuse RCVD_IN_PBL RCVD_IN_PBL T_RCVD_IN_PBL_WITH_NJABL_DUL RCVD_IN_NJABL_DUL
# ---------------------------------------------------------------------------
# RFC-Ignorant blacklists (both name and IP based)
@@ -171,25 +171,25 @@
header DNS_FROM_RFC_DSN eval:check_rbl_sub('rfci_envfrom', '127.0.0.2')
describe DNS_FROM_RFC_DSN Envelope sender in dsn.rfc-ignorant.org
tflags DNS_FROM_RFC_DSN net
-#reuse DNS_FROM_RFC_DSN
+reuse DNS_FROM_RFC_DSN
header DNS_FROM_RFC_BOGUSMX eval:check_rbl_sub('rfci_envfrom', '127.0.0.8')
describe DNS_FROM_RFC_BOGUSMX Envelope sender in bogusmx.rfc-ignorant.org
tflags DNS_FROM_RFC_BOGUSMX net
-#reuse DNS_FROM_RFC_BOGUSMX
+reuse DNS_FROM_RFC_BOGUSMX
# bug 4628: these rules are too unreliable to assign scores to
header __DNS_FROM_RFC_POST eval:check_rbl_sub('rfci_envfrom', '127.0.0.3')
tflags __DNS_FROM_RFC_POST net
-#reuse __DNS_FROM_RFC_POST DNS_FROM_RFC_POST
+reuse __DNS_FROM_RFC_POST DNS_FROM_RFC_POST
header __DNS_FROM_RFC_ABUSE eval:check_rbl_sub('rfci_envfrom', '127.0.0.4')
tflags __DNS_FROM_RFC_ABUSE net
-#reuse __DNS_FROM_RFC_ABUSE DNS_FROM_RFC_ABUSE
+reuse __DNS_FROM_RFC_ABUSE DNS_FROM_RFC_ABUSE
header __DNS_FROM_RFC_WHOIS eval:check_rbl_sub('rfci_envfrom', '127.0.0.5')
tflags __DNS_FROM_RFC_WHOIS net
-#reuse __DNS_FROM_RFC_WHOIS DNS_FROM_RFC_WHOIS
+reuse __DNS_FROM_RFC_WHOIS DNS_FROM_RFC_WHOIS
# ---------------------------------------------------------------------------
# Now, single zone BLs follow:
@@ -198,7 +198,7 @@
header DNS_FROM_AHBL_RHSBL eval:check_rbl_envfrom('ahbl', 'rhsbl.ahbl.org.')
describe DNS_FROM_AHBL_RHSBL Envelope sender listed in dnsbl.ahbl.org
tflags DNS_FROM_AHBL_RHSBL net
-#reuse DNS_FROM_AHBL_RHSBL
+reuse DNS_FROM_AHBL_RHSBL
# ---------------------------------------------------------------------------
# NOTE: donation tests, see README file for details
@@ -206,7 +206,7 @@
header RCVD_IN_BL_SPAMCOP_NET eval:check_rbl_txt('spamcop', 'bl.spamcop.net.', '(?i:spamcop)')
describe RCVD_IN_BL_SPAMCOP_NET Received via a relay in bl.spamcop.net
tflags RCVD_IN_BL_SPAMCOP_NET net
-#reuse RCVD_IN_BL_SPAMCOP_NET
+reuse RCVD_IN_BL_SPAMCOP_NET
# ---------------------------------------------------------------------------
# NOTE: commercial tests, see README file for details
@@ -240,18 +240,18 @@
header RCVD_IN_BSP_TRUSTED eval:check_rbl_txt('bsp-firsttrusted', 'sa-trusted.bondedsender.org.', '(?i:bonded)')
describe RCVD_IN_BSP_TRUSTED Sender is in Sender Score Certified (trusted relay)
tflags RCVD_IN_BSP_TRUSTED net nice
-#reuse RCVD_IN_BSP_TRUSTED
+reuse RCVD_IN_BSP_TRUSTED
header RCVD_IN_BSP_OTHER eval:check_rbl_txt('bsp-untrusted', 'sa-other.bondedsender.org.', '(?i:bonded)')
describe RCVD_IN_BSP_OTHER Sender is in Sender Score Certified (other relay)
tflags RCVD_IN_BSP_OTHER net nice
-#reuse RCVD_IN_BSP_OTHER
+reuse RCVD_IN_BSP_OTHER
# confirmed-opt-in list; see bug 5476
header RCVD_IN_SSC_TRUSTED_COI eval:check_rbl('ssc-firsttrusted', 'plus.bondedsender.org.')
describe RCVD_IN_SSC_TRUSTED_COI Sender is in Sender Score Certified (confirmed opt-in)
tflags RCVD_IN_SSC_TRUSTED_COI net nice
-#reuse RCVD_IN_SSC_TRUSTED_COI
+reuse RCVD_IN_SSC_TRUSTED_COI
# ---------------------------------------------------------------------------
Modified: spamassassin/trunk/rules/20_net_tests.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/20_net_tests.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/20_net_tests.cf (original)
+++ spamassassin/trunk/rules/20_net_tests.cf Mon Mar 2 22:49:50 2009
@@ -36,14 +36,14 @@
meta DIGEST_MULTIPLE RAZOR2_CHECK + DCC_CHECK + PYZOR_CHECK > 1
describe DIGEST_MULTIPLE Message hits more than one network digest check
tflags DIGEST_MULTIPLE net
-#reuse DIGEST_MULTIPLE
+reuse DIGEST_MULTIPLE
ifplugin Mail::SpamAssassin::Plugin::DNSEval
header NO_DNS_FOR_FROM eval:check_dns_sender()
describe NO_DNS_FOR_FROM Envelope sender has no MX or A DNS records
tflags NO_DNS_FOR_FROM net
-#reuse NO_DNS_FOR_FROM
+reuse NO_DNS_FOR_FROM
endif
Modified: spamassassin/trunk/rules/25_dcc.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_dcc.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_dcc.cf (original)
+++ spamassassin/trunk/rules/25_dcc.cf Mon Mar 2 22:49:50 2009
@@ -28,6 +28,6 @@
full DCC_CHECK eval:check_dcc()
describe DCC_CHECK Listed in DCC (http://rhyolite.com/anti-spam/dcc/)
tflags DCC_CHECK net
-#reuse DCC_CHECK
+reuse DCC_CHECK
endif
Modified: spamassassin/trunk/rules/25_pyzor.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_pyzor.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_pyzor.cf (original)
+++ spamassassin/trunk/rules/25_pyzor.cf Mon Mar 2 22:49:50 2009
@@ -28,6 +28,6 @@
full PYZOR_CHECK eval:check_pyzor()
describe PYZOR_CHECK Listed in Pyzor (http://pyzor.sf.net/)
tflags PYZOR_CHECK net
-#reuse PYZOR_CHECK
+reuse PYZOR_CHECK
endif
Modified: spamassassin/trunk/rules/25_razor2.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_razor2.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_razor2.cf (original)
+++ spamassassin/trunk/rules/25_razor2.cf Mon Mar 2 22:49:50 2009
@@ -28,7 +28,7 @@
full RAZOR2_CHECK eval:check_razor2()
describe RAZOR2_CHECK Listed in Razor2 (http://razor.sf.net/)
tflags RAZOR2_CHECK net
-#reuse RAZOR2_CHECK
+reuse RAZOR2_CHECK
lang de describe RAZOR2_CHECK Gelistet im "Razor2"-System (http://razor.sf.net/)
lang nl describe RAZOR2_CHECK Gevonden in Razor2 (http://razor.sf.net/)
@@ -53,17 +53,17 @@
full RAZOR2_CF_RANGE_51_100 eval:check_razor2_range('','51','100')
tflags RAZOR2_CF_RANGE_51_100 net
-#reuse RAZOR2_CF_RANGE_51_100
+reuse RAZOR2_CF_RANGE_51_100
describe RAZOR2_CF_RANGE_51_100 Razor2 gives confidence level above 50%
full RAZOR2_CF_RANGE_E4_51_100 eval:check_razor2_range('4','51','100')
tflags RAZOR2_CF_RANGE_E4_51_100 net
-#reuse RAZOR2_CF_RANGE_E4_51_100
+reuse RAZOR2_CF_RANGE_E4_51_100
describe RAZOR2_CF_RANGE_E4_51_100 Razor2 gives engine 4 confidence level above 50%
full RAZOR2_CF_RANGE_E8_51_100 eval:check_razor2_range('8','51','100')
tflags RAZOR2_CF_RANGE_E8_51_100 net
-#reuse RAZOR2_CF_RANGE_E8_51_100
+reuse RAZOR2_CF_RANGE_E8_51_100
describe RAZOR2_CF_RANGE_E8_51_100 Razor2 gives engine 8 confidence level above 50%
lang de describe RAZOR2_CF_RANGE_51_100 Razor2 Spam-Bewertung liegt zwischen 51 und 100
Modified: spamassassin/trunk/rules/25_spf.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_spf.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_spf.cf (original)
+++ spamassassin/trunk/rules/25_spf.cf Mon Mar 2 22:49:50 2009
@@ -68,13 +68,13 @@
tflags SPF_HELO_SOFTFAIL net
# rules from earlier than current release that can be reused
-#reuse SPF_PASS
-#reuse SPF_FAIL
-#reuse SPF_SOFTFAIL
-#reuse SPF_HELO_PASS
-#reuse SPF_HELO_FAIL
-#reuse SPF_HELO_SOFTFAIL
-#reuse SPF_NEUTRAL
-#reuse SPF_HELO_NEUTRAL
+reuse SPF_PASS
+reuse SPF_FAIL
+reuse SPF_SOFTFAIL
+reuse SPF_HELO_PASS
+reuse SPF_HELO_FAIL
+reuse SPF_HELO_SOFTFAIL
+reuse SPF_NEUTRAL
+reuse SPF_HELO_NEUTRAL
endif # Mail::SpamAssassin::Plugin::SPF
Modified: spamassassin/trunk/rules/25_uribl.cf
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/25_uribl.cf?rev=749462&r1=749461&r2=749462&view=diff
==============================================================================
--- spamassassin/trunk/rules/25_uribl.cf (original)
+++ spamassassin/trunk/rules/25_uribl.cf Mon Mar 2 22:49:50 2009
@@ -37,7 +37,7 @@
body URIBL_SBL eval:check_uridnsbl('URIBL_SBL')
describe URIBL_SBL Contains an URL listed in the SBL blocklist
tflags URIBL_SBL net
-#reuse URIBL_SBL
+reuse URIBL_SBL
###########################################################################
## SURBL
@@ -46,37 +46,37 @@
body URIBL_SC_SURBL eval:check_uridnsbl('URIBL_SC_SURBL')
describe URIBL_SC_SURBL Contains an URL listed in the SC SURBL blocklist
tflags URIBL_SC_SURBL net
-#reuse URIBL_SC_SURBL
+reuse URIBL_SC_SURBL
urirhssub URIBL_WS_SURBL multi.surbl.org. A 4
body URIBL_WS_SURBL eval:check_uridnsbl('URIBL_WS_SURBL')
describe URIBL_WS_SURBL Contains an URL listed in the WS SURBL blocklist
tflags URIBL_WS_SURBL net
-#reuse URIBL_WS_SURBL
+reuse URIBL_WS_SURBL
urirhssub URIBL_PH_SURBL multi.surbl.org. A 8
body URIBL_PH_SURBL eval:check_uridnsbl('URIBL_PH_SURBL')
describe URIBL_PH_SURBL Contains an URL listed in the PH SURBL blocklist
tflags URIBL_PH_SURBL net
-#reuse URIBL_PH_SURBL
+reuse URIBL_PH_SURBL
urirhssub URIBL_OB_SURBL multi.surbl.org. A 16
body URIBL_OB_SURBL eval:check_uridnsbl('URIBL_OB_SURBL')
describe URIBL_OB_SURBL Contains an URL listed in the OB SURBL blocklist
tflags URIBL_OB_SURBL net
-#reuse URIBL_OB_SURBL
+reuse URIBL_OB_SURBL
urirhssub URIBL_AB_SURBL multi.surbl.org. A 32
body URIBL_AB_SURBL eval:check_uridnsbl('URIBL_AB_SURBL')
describe URIBL_AB_SURBL Contains an URL listed in the AB SURBL blocklist
tflags URIBL_AB_SURBL net
-#reuse URIBL_AB_SURBL
+reuse URIBL_AB_SURBL
urirhssub URIBL_JP_SURBL multi.surbl.org. A 64
body URIBL_JP_SURBL eval:check_uridnsbl('URIBL_JP_SURBL')
describe URIBL_JP_SURBL Contains an URL listed in the JP SURBL blocklist
tflags URIBL_JP_SURBL net
-#reuse URIBL_JP_SURBL
+reuse URIBL_JP_SURBL
###########################################################################
## URIBL
@@ -85,19 +85,19 @@
body URIBL_BLACK eval:check_uridnsbl('URIBL_BLACK')
describe URIBL_BLACK Contains an URL listed in the URIBL blacklist
tflags URIBL_BLACK net
-#reuse URIBL_BLACK
+reuse URIBL_BLACK
urirhssub URIBL_GREY multi.uribl.com. A 4
body URIBL_GREY eval:check_uridnsbl('URIBL_GREY')
describe URIBL_GREY Contains an URL listed in the URIBL greylist
tflags URIBL_GREY net
-#reuse URIBL_GREY
+reuse URIBL_GREY
urirhssub URIBL_RED multi.uribl.com. A 8
body URIBL_RED eval:check_uridnsbl('URIBL_RED')
describe URIBL_RED Contains an URL listed in the URIBL redlist
tflags URIBL_RED net
-#reuse URIBL_RED
+reuse URIBL_RED
###########################################################################
## DOMAINS TO SKIP (KNOWN GOOD)
Added: spamassassin/trunk/t/reuse.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/reuse.t?rev=749462&view=auto
==============================================================================
--- spamassassin/trunk/t/reuse.t (added)
+++ spamassassin/trunk/t/reuse.t Mon Mar 2 22:49:50 2009
@@ -0,0 +1,217 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if (-e 't/test_dir') { # if we are running "t/rule_tests.t", kluge around ...
+ chdir 't';
+ }
+
+ if (-e 'test_dir') { # running from test directory, not ..
+ unshift(@INC, '../blib/lib');
+ }
+}
+
+my $prefix = '.';
+if (-e 'test_dir') { # running from test directory, not ..
+ $prefix = '..';
+}
+
+use strict;
+use SATest; sa_t_init("reuse");
+use Test;
+
+use vars qw(%patterns %anti_patterns $perl_path &patterns_run_cb);
+
+use Mail::SpamAssassin;
+
+plan tests => 37;
+
+# Tests the following cases:
+# - No reuse: no change
+# - Reuse and no X-Spam-Status: no change
+# - Reuse on: metas work
+# - Reuse works with existing tests (disabled)
+# - Reuse works with non-existing tests (they get scores)
+# - Reuse handles multiple "old rule names"
+# - Reuse works in positive and negative cases
+# - Rules defined only by "reuse" can have arbitrary scores and priorities set
+
+tstlocalrules('
+
+# Check that order of reuse/body lines for BODY_RULE_* does not matter
+reuse BODY_RULE_1
+
+body BODY_RULE_1 /./
+score BODY_RULE_1 1.0
+
+body BODY_RULE_2 /\bfoobar\b/
+score BODY_RULE_2 1.0
+
+header HEADER_RULE_1 Subject =~ /\bmessage\b/
+
+meta META_RULE_1 BODY_RULE_1 || BODY_RULE_2
+
+reuse BODY_RULE_2
+priority BODY_RULE_2 -2
+score BODY_RULE_2 1.5
+
+reuse NEW_RULE OTHER_RULE
+priority NEW_RULE -3
+score NEW_RULE 0.5
+
+reuse OTHER_RULE
+priority OTHER_RULE -4
+
+reuse RENAMED_RULE OLD_RULE_1 OLD_RULE_2 OLD_RULE_3
+
+reuse SCORED_RULE OLD_RULE_2
+score SCORED_RULE 2.0
+priority SCORED_RULE -1
+
+');
+
+# reuse on, mail has no X-Spam-Status
+write_mail(0);
+ok_system("$perl_path -w ../masses/mass-check -c=log/localrules.tmp --reuse --file log/mail.txt > log/noxss.out");
+
+%patterns = (
+ 'BODY_RULE_1' => 'BODY_RULE_1',
+ 'HEADER_RULE_1' => 'HEADER_RULE_1',
+ 'META_RULE_1' => 'META_RULE_1'
+ );
+%anti_patterns = (
+ 'NEW_RULE' => 'NEW_RULE',
+ 'OTHER_RULE' => 'OTHER_RULE',
+ 'RENAMED_RULE' => 'RENAMED_RULE',
+ 'NONEXISTANT_RULE' => 'NONEXISTANT_RULE',
+ 'BODY_RULE_2' => 'BODY_RULE_2',
+ 'SCORED_RULE' => 'SCORED_RULE'
+ );
+
+checkfile("noxss.out", \&patterns_run_cb);
+ok_all_patterns();
+clear_pattern_counters();
+
+# write mail with X-Spam-Status
+write_mail(1);
+
+# test without reuse
+ok_system("$perl_path -w ../masses/mass-check -c=log/localrules.tmp --file log/mail.txt > log/noreuse.out");
+
+%patterns = (
+ 'BODY_RULE_1' => 'BODY_RULE_1',
+ 'HEADER_RULE_1' => 'HEADER_RULE_1',
+ 'META_RULE_1' => 'META_RULE_1'
+ );
+%anti_patterns = (
+ 'NEW_RULE' => 'NEW_RULE',
+ 'OTHER_RULE' => 'OTHER_RULE',
+ 'RENAMED_RULE' => 'RENAMED_RULE',
+ 'NONEXISTANT_RULE' => 'NONEXISTANT_RULE',
+ 'BODY_RULE_2' => 'BODY_RULE_2',
+ 'SCORED_RULE' => 'SCORED_RULE'
+ );
+checkfile("noreuse.out", \&patterns_run_cb);
+ok_all_patterns();
+clear_pattern_counters();
+
+# test with reuse
+ok_system("$perl_path -w ../masses/mass-check -c=log/localrules.tmp --reuse --file log/mail.txt > log/reuse.out");
+
+
+%patterns = (
+ 'HEADER_RULE_1' => 'HEADER_RULE_1',
+ 'BODY_RULE_2' => 'BODY_RULE_2',
+ 'META_RULE_1' => 'META_RULE_1',
+ 'NEW_RULE' => 'NEW_RULE',
+ 'OTHER_RULE' => 'OTHER_RULE',
+ 'RENAMED_RULE' => 'RENAMED_RULE',
+ 'SCORED_RULE' => 'SCORED_RULE',
+ 'Y 8' => 'score'
+ );
+%anti_patterns = (
+ 'BODY_RULE_1' => 'BODY_RULE_1',
+ 'NONEXISTANT_RULE' => 'NONEXISTANT_RULE'
+ );
+
+checkfile("reuse.out", \&patterns_run_cb);
+ok_all_patterns();
+clear_pattern_counters();
+
+tstlocalrules('
+
+meta META_RULE_1 RULE_A && !RULE_B
+
+body RULE_A /./
+reuse RULE_B OTHER_RULE
+
+body RULE_C / does not hit /
+
+meta META_RULE_2 (RULE_A && RULE_B) || RULE_C
+
+');
+
+write_mail(1);
+
+# test with reuse
+ok_system("$perl_path -w ../masses/mass-check -c=log/localrules.tmp --reuse --file log/mail.txt > log/metareuse.out");
+
+%patterns = (
+ 'META_RULE_2' => 'META_RULE_2',
+ 'RULE_A' => 'RULE_A',
+ 'RULE_B' => 'RULE_B',
+ );
+%anti_patterns = (
+ 'META_RULE_1' => 'META_RULE_1',
+ 'RULE_C' => 'RULE_C',
+ );
+checkfile("metareuse.out", \&patterns_run_cb);
+ok_all_patterns();
+clear_pattern_counters();
+
+
+sub write_mail {
+ my ($x_spam_status) = @_;
+
+ my $msg = <<EOF;
+Received: from internal.example.com [127.0.0.1] by localhost
+ for recipient\@example.com; Fri, 07 Oct 2002 09:02:00 +0000
+Received: from external.spammer.com (external.spammer.com
+ [150.51.53.1]) by internal.example.com for recipient\@example.com;
+ Fri, 07 Oct 2002 09:01:00 +0000
+Message-ID: <cl...@example.com>
+Date: Mon, 07 Oct 2002 09:00:00 +0000
+From: Sender <se...@this-spammer.com>
+MIME-Version: 1.0
+To: Recipient <re...@example.com>
+Subject: trivial message
+Content-Type: text/plain; charset=us-ascii; format=flowed
+Content-Transfer-Encoding: 7bit
+EOF
+
+ if ($x_spam_status) {
+ $msg .= <<END;
+X-Spam-Status: Yes, score=15.3 required=5.0 tests=BODY_RULE_2,
+ NONEXISTANT_RULE,OTHER_RULE,OLD_RULE_2,OLD_RULE_3
+END
+ }
+
+ $msg .= <<END;
+
+
+This is a test message.
+
+END
+
+ tstfile($msg);
+}
+
+sub ok_system {
+ my $cmd = shift;
+
+ print "\t$cmd\n";
+ system($cmd);
+ my $exit_code = ($?>>8);
+ ok ($exit_code == 0)
+
+}
+