Mailing List Archive

svn commit: r453586 [4/7] - in /spamassassin/branches/jm_re2c_hacks: ./ build/ build/automc/ build/buildbot/ contrib/ lib/Mail/ lib/Mail/SpamAssassin/ lib/Mail/SpamAssassin/Bayes/ lib/Mail/SpamAssassin/BayesStore/ lib/Mail/SpamAssassin/Conf/ lib/Mail/S...
Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PerMsgStatus.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -82,13 +83,14 @@
'subtest_names_hit' => [ ],
'spamd_result_log_items' => [ ],
'tests_already_hit' => { },
- 'hdr_cache' => { },
+ 'c' => { },
'rule_errors' => 0,
'disable_auto_learning' => 0,
'auto_learn_status' => undef,
'conf' => $main->{conf},
'async' => Mail::SpamAssassin::AsyncLoop->new($main)
};
+ #$self->{main}->{use_rule_subs} = 1;

if (defined $opts && $opts->{disable_auto_learning}) {
$self->{disable_auto_learning} = 1;
@@ -245,7 +247,7 @@

# now that we've finished checking the mail, clear out this cache
# to avoid unforeseen side-effects.
- $self->{hdr_cache} = { };
+ $self->{c} = { };

# Round the score to 3 decimal places to avoid rounding issues
# We assume required_score to be properly rounded already.
@@ -258,6 +260,7 @@
dbg("check: subtests=".$self->get_names_of_subtests_hit());
$self->{is_spam} = $self->is_spam();

+ $self->{main}->{resolver}->bgabort();
$self->{main}->call_plugins ("check_end", { permsgstatus => $self });

1;
@@ -780,7 +783,7 @@

foreach my $header (keys %{$self->{conf}->{headers_spam}}) {
my $data = $self->{conf}->{headers_spam}->{$header};
- my $line = $self->_process_header($header,$data) || "";
+ my $line = $self->_process_header($header,$data);
$line = $self->qp_encode_header($line);
$newmsg .= "X-Spam-$header: $line\n" # add even if empty
}
@@ -960,7 +963,7 @@
# use string appends to put this back together -- I finally benchmarked it.
# join() is 56% of the speed of just using string appends. ;)
while (my ($header, $data) = each %{$self->{conf}->{$addition}}) {
- my $line = $self->_process_header($header,$data) || "";
+ my $line = $self->_process_header($header,$data);
$line = $self->qp_encode_header($line);
$new_hdrs_pre .= "X-Spam-$header: $line\n";
}
@@ -1363,12 +1366,10 @@
permsgstatus => $self
});

- foreach(keys %{$self}) {
- # TODO: we should not be explicitly deleting every key here,
- # just the ones that need it. This is surprisingly slow
- # (in the top 10 measured with Devel::SmallProf)
- delete $self->{$_};
- }
+ # Delete out all of the members of $self. This will remove any direct
+ # circular references and let the memory get reclaimed while also being more
+ # efficient than a foreach() loop over the keys.
+ %{$self} = ();
}

sub finish_tests {
@@ -1800,10 +1801,13 @@
}

my $evalstr = $self->start_rules_plugin_code("header", $priority);
+ my $use_rule_subs = $self->{main}->{use_rule_subs};
+
my $evalstr2 = '';

# hash to hold the rules, "header\tdefault value" => rulename
my %ordered = ();
+ my %testcode = ();

while (my($rulename, $rule) = each %{$self->{conf}{head_tests}->{$priority}}) {
my $def = '';
@@ -1827,16 +1831,22 @@
next if (!$self->is_user_rule_sub ($rulename.'_head_test'));
}

- $evalstr2 .= '
- sub '.$rulename.'_head_test {
- my($self,$text) = @_;
- '.$self->hash_line_for_rule($rulename).'
- while ($text '.$testtype.'~ '.$pat.'g) {
- $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
- '. $self->hit_rule_plugin_code($rulename, "header", "last") . '
- }
- }';
-
+ if ($use_rule_subs) {
+ $evalstr2 .= '
+ sub '.$rulename.'_head_test {
+ my($self,$text) = @_;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($text '.$testtype.'~ '.$pat.'g) {
+ $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
+ '. $self->hit_rule_plugin_code($rulename, "header", "last") . '
+ }
+ }
+ ';
+ }
+ else {
+ # store for use below
+ $testcode{$rulename} = $testtype.'~ '.$pat.'g';
+ }
}

# setup the function to run the rules
@@ -1844,12 +1854,29 @@
my($hdrname, $def) = split(/\t/, $k, 2);
$evalstr .= ' $hval = $self->get(q#'.$hdrname.'#, q#'.$def.'#);';
foreach my $rulename (@{$v}) {
- $evalstr .= '
- if ($scoresptr->{q#'.$rulename.'#}) {
- '.$rulename.'_head_test($self, $hval); # no need for OO calling here (its faster this way)
- '.$self->ran_rule_plugin_code($rulename, "header").'
+ if ($use_rule_subs) {
+ $evalstr .= '
+ if ($scoresptr->{q#'.$rulename.'#}) {
+ '.$rulename.'_head_test($self, $hval);
+ '.$self->ran_rule_plugin_code($rulename, "header").'
+ }
+ ';
+ }
+ else {
+ my $testcode = $testcode{$rulename};
+
+ $evalstr .= '
+ if ($scoresptr->{q#'.$rulename.'#}) {
+ pos $hval = 0;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($hval '.$testcode.') {
+ $self->got_hit(q#'.$rulename.'#, "", ruletype => "header");
+ '.$self->hit_rule_plugin_code($rulename, "header", "last").'
+ }
+ '.$self->ran_rule_plugin_code($rulename, "header").'
+ }
+ ';
}
- ';
}
}

@@ -1914,10 +1941,15 @@
return;
}

+ # caller can set this member of the Mail::SpamAssassin object to
+ # override this; useful for profiling rule runtimes, although I think
+ # the HitFreqsRuleTiming.pm plugin is probably better nowadays anyway
+ my $use_rule_subs = $self->{main}->{use_rule_subs};
+
# build up the eval string...
my $evalstr = $self->start_rules_plugin_code("body", $priority);
my $evalstr2 = '';
-
+ my $loopid = 0;

$evalstr .= '

@@ -1928,45 +1960,89 @@

';

- while (my($rulename, $pat) = each %{$self->{conf}{body_tests}->{$priority}}) {
-
- if (!$self->{conf}{skip_body_rules}{$rulename}) {
+ while (my($rulename, $pat) = each %{$self->{conf}{body_tests}->{$priority}})
+ {
+ my $sub;
+ my $sub_one_line;

- $evalstr .= '
- if ($scoresptr->{q{'.$rulename.'}}) {
- '.$rulename.'_body_test($self,@_);
- '.$self->ran_rule_plugin_code($rulename, "body").'
+ if ($self->{conf}->{tflags}->{$rulename} =~ /\bmultiple\b/)
+ {
+ # support multiple matches
+ $loopid++;
+ $sub = '
+ body_'.$loopid.': foreach my $l (@_) {
+ pos $l = 0;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($l =~ '.$pat.'g) {
+ $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+ '. $self->hit_rule_plugin_code($rulename, "body",
+ "last body_".$loopid) . '
+ }
+ }
+ ';
+ $sub_one_line = '
+ pos $_[1] = 0;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($_[1] =~ '.$pat.'g) {
+ my $self = $_[0];
+ $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+ '. $self->hit_rule_plugin_code($rulename, "body", "return") . '
}
';
+ }
+ else {
+ # omitting the "pos" call, "body_loopid" label, use of while()
+ # instead of if() etc., shaves off 8 perl OPs.
+ $sub = '
+ foreach my $l (@_) {
+ '.$self->hash_line_for_rule($rulename).'
+ if ($l =~ '.$pat.') {
+ $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+ '. $self->hit_rule_plugin_code($rulename, "body", "last") .'
+ }
+ }
+ ';
+ $sub_one_line = '
+ '.$self->hash_line_for_rule($rulename).'
+ if ($_[1] =~ '.$pat.') {
+ my $self = $_[0];
+ $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
+ '. $self->hit_rule_plugin_code($rulename, "body", "return") . '
+ }
+ ';
+ }

+ if (!$self->{conf}{skip_body_rules}{$rulename}) {
+ if ($use_rule_subs) {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$rulename.'_body_test($self,@_);
+ '.$self->ran_rule_plugin_code($rulename, "body").'
+ }
+ ';
+ }
+ else {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$sub.'
+ '.$self->ran_rule_plugin_code($rulename, "body").'
+ }
+ ';
+ }
}

if ($doing_user_rules) {
next if (!$self->is_user_rule_sub ($rulename.'_body_test'));
}

- $evalstr2 .= '
- sub '.$rulename.'_body_test {
- my $self = shift;
- foreach (@_) {
- pos = 0;
- '.$self->hash_line_for_rule($rulename).'
- while ('.$pat.'g) {
- $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
- '. $self->hit_rule_plugin_code($rulename, "body", "return") . '
- }
- }
- }
-
- sub '.$rulename.'_one_line_body_test {
- pos $_[1] = 0;
- '.$self->hash_line_for_rule($rulename).'
- while ($_[1] =~ '.$pat.'g) {
- my $self = $_[0];
- $self->got_hit(q{'.$rulename.'}, "BODY: ", ruletype => "body");
- '.$self->hit_rule_plugin_code($rulename,"one-line-body","return").'
- }
+ if ($use_rule_subs) {
+ $evalstr2 .= '
+ sub '.$rulename.'_body_test { my $self = shift; '.$sub.' }
+ ';
}
+
+ $evalstr2 .= '
+ sub '.$rulename.'_one_line_body_test { '.$sub_one_line.' }
';
}

@@ -2201,7 +2277,7 @@
}
}

- if (would_log('dbg', 'uri')) {
+ if (would_log('dbg', 'uri') == 2) {
dbg("uri: html uri found, $uri");
foreach my $nuri (@tmp) {
dbg("uri: cleaned html uri, $nuri");
@@ -2234,7 +2310,7 @@
}
}

- if (would_log('dbg', 'uri')) {
+ if (would_log('dbg', 'uri') == 2) {
dbg("uri: parsed uri found, $uri");
foreach my $nuri (@uris) {
dbg("uri: cleaned parsed uri, $nuri");
@@ -2352,35 +2428,67 @@
return;
}

+ my $use_rule_subs = $self->{main}->{use_rule_subs};
+
# otherwise build up the eval string...
my $evalstr = $self->start_rules_plugin_code("uri", $priority);
my $evalstr2 = '';
+ my $loopid = 0;

while (my($rulename, $pat) = each %{$self->{conf}{uri_tests}->{$priority}}) {
- $evalstr .= '
- if ($scoresptr->{q{'.$rulename.'}}) {
- '.$rulename.'_uri_test($self, @_);
- '.$self->ran_rule_plugin_code($rulename, "uri").'
+ my $sub;
+ if ($self->{conf}->{tflags}->{$rulename} =~ /\bmultiple\b/)
+ {
+ $loopid++;
+ $sub = '
+ uri_'.$loopid.': foreach my $l (@_) {
+ pos $l = 0;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($l =~ '.$pat.'g) {
+ $self->got_hit(q{'.$rulename.'}, "URI: ", ruletype => "uri");
+ '. $self->hit_rule_plugin_code($rulename, "uri",
+ "last uri_".$loopid) . '
+ }
}
- ';
+ ';
+ } else {
+ $sub = '
+ foreach my $l (@_) {
+ '.$self->hash_line_for_rule($rulename).'
+ if ($l =~ '.$pat.') {
+ $self->got_hit(q{'.$rulename.'}, "URI: ", ruletype => "uri");
+ '. $self->hit_rule_plugin_code($rulename, "uri", "last") .'
+ }
+ }
+ ';
+ }
+
+ if ($use_rule_subs) {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$rulename.'_uri_test($self, @_);
+ '.$self->ran_rule_plugin_code($rulename, "uri").'
+ }
+ ';
+ }
+ else {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$sub.'
+ '.$self->ran_rule_plugin_code($rulename, "uri").'
+ }
+ ';
+ }

if ($doing_user_rules) {
next if (!$self->is_user_rule_sub ($rulename.'_uri_test'));
}

- $evalstr2 .= '
- sub '.$rulename.'_uri_test {
- my $self = shift;
- foreach (@_) {
- pos = 0;
- '.$self->hash_line_for_rule($rulename).'
- while ('.$pat.'g) {
- $self->got_hit(q{'.$rulename.'}, "URI: ", ruletype => "uri");
- '. $self->hit_rule_plugin_code($rulename, "uri", "return") .'
- }
- }
+ if ($use_rule_subs) {
+ $evalstr2 .= '
+ sub '.$rulename.'_uri_test { my $self = shift; '.$sub.' }
+ ';
}
- ';
}

# clear out a previous version of this fn, if already defined
@@ -2443,35 +2551,69 @@
return;
}

+ my $use_rule_subs = $self->{main}->{use_rule_subs};
+
# build up the eval string...
my $evalstr = $self->start_rules_plugin_code("rawbody", $priority);
my $evalstr2 = '';
+ my $loopid = 0;

while (my($rulename, $pat) = each %{$self->{conf}{rawbody_tests}->{$priority}}) {
- $evalstr .= '
- if ($scoresptr->{q{'.$rulename.'}}) {
- '.$rulename.'_rawbody_test($self, @_);
- '.$self->ran_rule_plugin_code($rulename, "rawbody").'
+ my $sub;
+ if ($self->{conf}->{tflags}->{$rulename} =~ /\bmultiple\b/)
+ {
+ # support multiple matches
+ $loopid++;
+ $sub = '
+ rawbody_'.$loopid.': foreach my $l (@_) {
+ pos $l = 0;
+ '.$self->hash_line_for_rule($rulename).'
+ while ($l =~ '.$pat.'g) {
+ $self->got_hit(q{'.$rulename.'}, "RAW: ", ruletype => "rawbody");
+ '. $self->hit_rule_plugin_code($rulename, "rawbody",
+ "last rawbody_".$loopid) . '
+ }
}
- ';
+ ';
+ }
+ else {
+ $sub = '
+ foreach my $l (@_) {
+ '.$self->hash_line_for_rule($rulename).'
+ if ($l =~ '.$pat.') {
+ $self->got_hit(q{'.$rulename.'}, "RAW: ", ruletype => "rawbody");
+ '. $self->hit_rule_plugin_code($rulename, "rawbody", "last") . '
+ }
+ }
+ ';
+ }
+
+ if ($use_rule_subs) {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$rulename.'_rawbody_test($self, @_);
+ '.$self->ran_rule_plugin_code($rulename, "rawbody").'
+ }
+ ';
+ }
+ else {
+ $evalstr .= '
+ if ($scoresptr->{q{'.$rulename.'}}) {
+ '.$sub.'
+ '.$self->ran_rule_plugin_code($rulename, "rawbody").'
+ }
+ ';
+ }

if ($doing_user_rules) {
next if (!$self->is_user_rule_sub ($rulename.'_rawbody_test'));
}

- $evalstr2 .= '
- sub '.$rulename.'_rawbody_test {
- my $self = shift;
- foreach (@_) {
- pos = 0;
- '.$self->hash_line_for_rule($rulename).'
- while ('.$pat.'g) {
- $self->got_hit(q{'.$rulename.'}, "RAW: ", ruletype => "rawbody");
- '. $self->hit_rule_plugin_code($rulename, "rawbody", "return") . '
- }
- }
+ if ($use_rule_subs) {
+ $evalstr2 .= '
+ sub '.$rulename.'_rawbody_test { my $self = shift; '.$sub.' }
+ ';
}
- ';
}

# clear out a previous version of this fn, if already defined
@@ -2684,7 +2826,18 @@
info("rules: meta test $rulename has undefined dependency '$token'");
}
elsif ($conf->{scores}->{$token} == 0) {
- info("rules: meta test $rulename has dependency '$token' with a zero score");
+ my $dowarn = 1;
+
+ # there are some cases where this is expected; don't warn
+ # in those cases.
+ if ((($self->{conf}->get_score_set()) & 1) == 0 &&
+ $conf->{tflags}->{$token} &&
+ $conf->{tflags}->{$token} =~ /\bnet\b/)
+ {
+ $dowarn = 0; # bug 5040: net rules in a non-net scoreset
+ }
+
+ $dowarn and info("rules: meta test $rulename has dependency '$token' with a zero score");
}

# If the token is another meta rule, add it as a dependency
@@ -2874,6 +3027,10 @@
}

my ($function, @args) = @{$test};
+ if (!$function) {
+ warn "rules: error: no function defined for $rulename";
+ next;
+ }

$evalstr .= '
$rulename = q#'.$rulename.'#;
@@ -2973,6 +3130,11 @@

sub register_plugin_eval_glue {
my ($self, $function) = @_;
+
+ if (!$function) {
+ warn "rules: empty function name";
+ return;
+ }

# return if it's not an eval_plugin function
return if (!exists $self->{conf}->{eval_plugins}->{$function});

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PersistentAddrList.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PersistentAddrList.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PersistentAddrList.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/PersistentAddrList.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -755,7 +756,7 @@

sub finish {
my ($self) = @_;
- delete $self->{main};
+ %{$self} = ();
}

=head1 HELPER APIS
@@ -835,13 +836,13 @@

=over 4

-=item The plugin object itself
+=item - The plugin object itself

-=item The C<Mail::SpamAssassin::PerMsgStatus> object calling the rule
+=item - The C<Mail::SpamAssassin::PerMsgStatus> object calling the rule

-=item standard arguments for the rule type in use
+=item - standard arguments for the rule type in use

-=item any and all arguments as specified in the configuration file
+=item - any and all arguments as specified in the configuration file

=back

@@ -872,13 +873,13 @@

=over 4

-=item header tests, no extra arguments
+=item - header tests: no extra arguments

-=item body tests, fully rendered message as array reference
+=item - body tests: fully rendered message as array reference

-=item rawbody tests, fully decoded message as array reference
+=item - rawbody tests: fully decoded message as array reference

-=item full tests, pristine message as scalar reference
+=item - full tests: pristine message as scalar reference

=back


Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AWL.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AWL.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AWL.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AWL.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AccessDB.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AccessDB.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AccessDB.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AccessDB.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AntiVirus.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AntiVirus.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AntiVirus.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AntiVirus.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -106,7 +107,7 @@
# file extension indicates an executable
$pms->{antivirus_microsoft_exe} = 1;
}
- elsif ($cte =~ /base64/ &&
+ elsif ($cte =~ /base64/ && defined $p->raw()->[0] &&
$p->raw()->[0] =~ /^TV[opqr].A..[AB].[AQgw][A-H].A/)
{
# base64-encoded executable

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AutoLearnThreshold.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AutoLearnThreshold.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AutoLearnThreshold.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/AutoLearnThreshold.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Bayes.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Bayes.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Bayes.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Bayes.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/BodyEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/BodyEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/BodyEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/BodyEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -132,6 +133,7 @@
foreach my $text (@txt) {
# we only care about the rendered version of the part
my ($type, $rnd) = $text->rendered();
+ next unless defined $type;

# parse the rendered text into tokens. assume they are whitespace
# separated, and ignore anything that doesn't have a word-character

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DCC.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DCC.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DCC.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DCC.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -636,7 +637,7 @@
sub plugin_report {
my ($self, $options) = @_;

- return if $self->{options}->{dont_report_to_dcc};
+ return if $options->{report}->{options}->{dont_report_to_dcc};
$self->get_dcc_interface();
return if $self->{dcc_disabled};


Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DKIM.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DNSEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DNSEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DNSEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DNSEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -60,6 +61,8 @@
$self->register_eval_rule ("check_domainkeys_signsome");
$self->register_eval_rule ("check_domainkeys_testing");
$self->register_eval_rule ("check_domainkeys_signall");
+ $self->register_eval_rule ("check_for_dk_whitelist_from");
+ $self->register_eval_rule ("check_for_def_dk_whitelist_from");

$self->set_config($mailsaobject->{conf});

@@ -89,6 +92,86 @@
type => $Mail::SpamAssassin::Conf::CONF_TYPE_NUMERIC
});

+=item whitelist_from_dk add@ress.com [signing domain name]
+
+Use this to supplement the whitelist_from addresses with a check to make sure
+the message has been signed by a DomainKeys signature that can be verified
+against the From: domain's DomainKeys public key.
+
+In order to support signing domain names that differ from the address domain
+name, only one whitelist entry is allowed per line, exactly like
+C<whitelist_from_rcvd>. Multiple C<whitelist_from_dk> lines are allowed.
+File-glob style meta characters are allowed for the From: address, just like
+with C<whitelist_from_rcvd>. The optional signing domain name parameter must
+match from the right-most side, also like in C<whitelist_from_rcvd>.
+
+If no signing domain name parameter is specified the domain of the address
+parameter specified will be used instead.
+
+The From: address is obtained from a signed part of the message (ie. the
+"From:" header), not from envelope data that is possible to forge.
+
+Since this whitelist requires a DomainKeys check to be made, network tests must
+be enabled.
+
+Examples:
+
+ whitelist_from_dk joe@example.com
+ whitelist_from_dk *@corp.example.com
+
+ whitelist_from_dk bob@it.example.net example.net
+ whitelist_from_dk *@eng.example.net example.net
+
+=item def_whitelist_from_dk add@ress.com [signing domain name]
+
+Same as C<whitelist_from_dk>, but used for the default whitelist entries
+in the SpamAssassin distribution. The whitelist score is lower, because
+these are often targets for spammer spoofing.
+
+=cut
+
+ push (@cmds, {
+ setting => 'whitelist_from_dk',
+ code => sub {
+ my ($self, $key, $value, $line) = @_;
+ unless (defined $value && $value !~ /^$/) {
+ return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
+ }
+ unless ($value =~ /^(\S+)(?:\s+(\S+))?$/) {
+ return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+ }
+ my $address = $1;
+ my $signer = (defined $2 ? $2 : $1);
+
+ unless (defined $2) {
+ $signer =~ s/^.*@(.*)$/$1/;
+ }
+ $self->{parser}->add_to_addrlist_rcvd ('whitelist_from_dk',
+ $address, $signer);
+ }
+ });
+
+ push (@cmds, {
+ setting => 'def_whitelist_from_dk',,
+ code => sub {
+ my ($self, $key, $value, $line) = @_;
+ unless (defined $value && $value !~ /^$/) {
+ return $Mail::SpamAssassin::Conf::MISSING_REQUIRED_VALUE;
+ }
+ unless ($value =~ /^(\S+)(?:\s+(\S+))?$/) {
+ return $Mail::SpamAssassin::Conf::INVALID_VALUE;
+ }
+ my $address = $1;
+ my $signer = (defined $2 ? $2 : $1);
+
+ unless (defined $2) {
+ $signer =~ s/^.*@(.*)$/$1/;
+ }
+ $self->{parser}->add_to_addrlist_rcvd ('def_whitelist_from_dk',
+ $address, $signer);
+ }
+ });
+
$conf->{parser}->register_commands(\@cmds);
}

@@ -132,7 +215,19 @@
return $scan->{domainkeys_signall};
}

+sub check_for_dk_whitelist_from {
+ my ($self, $scan) = @_;
+ $self->_check_dk_whitelist($scan, 0) unless $scan->{dk_whitelist_from_checked};
+ $scan->{dk_whitelist_from};
+}

+sub check_for_def_dk_whitelist_from {
+ my ($self, $scan) = @_;
+ $self->_check_dk_whitelist($scan, 1) unless $scan->{def_dk_whitelist_from_checked};
+ $scan->{def_dk_whitelist_from};
+}
+
+# ---------------------------------------------------------------------------

sub _check_domainkeys {
my ($self, $scan) = @_;
@@ -166,6 +261,22 @@
return;
}

+ # get the sender address for whitelist checks
+ if (defined $message->sender()) {
+ $scan->{dk_address} = @{$message->sender()}[1];
+ dbg("dk: sender: $scan->{dk_address}");
+ } elsif (defined $message->from()) {
+ $scan->{dk_address} ||= @{$message->from()}[1];
+ dbg("dk: from: $scan->{dk_address}");
+ } else {
+ dbg("dk: could not determine sender: or from: identity");
+ }
+
+ # get the signing domain name for whitelist checks
+ $scan->{dk_signing_domain} = $self->_dkmsg_signing_domain($scan, $message);
+ dbg("dk: signing domain name: ".
+ ($scan->{dk_signing_domain} ? $scan->{dk_signing_domain} : "not found"));
+
my $timeout = $scan->{conf}->{domainkeys_timeout};

my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
@@ -244,6 +355,24 @@
}
}

+# get the DK signing domain name from the Mail::DomainKeys::Message object
+sub _dkmsg_signing_domain {
+ my ($self, $scan, $message) = @_;
+ # try to use the signature() API if it exists (post-0.80)
+ if ($message->can("signature")) {
+ if (!$message->signed) {
+ return undef;
+ }
+ return $message->signature->domain;
+ } else {
+ # otherwise parse it ourself
+ if ($scan->{msg}->get_header("DomainKey-Signature") =~ /d=(\S+);/) {
+ return $1;
+ }
+ return undef;
+ }
+}
+
sub sanitize_header_for_dk {
my ($self, $ref) = @_;

@@ -309,6 +438,102 @@
# $$ref =~ s/^\n//gs; $$ref =~ s/\n$//gs;
$$ref =~ s/!nl;/\n/gs;
$$ref =~ s/!ex;/!/gs;
+}
+
+sub _check_dk_whitelist {
+ my ($self, $scan, $default) = @_;
+
+ return unless $scan->is_dns_available();
+
+ # trigger a DK check so we can get address/signer info
+ # if verification failed only continue if we want the debug info
+ unless ($self->check_domainkeys_verified($scan)) {
+ unless (would_log("dbg", "dk")) {
+ return;
+ }
+ }
+
+ unless ($scan->{dk_address}) {
+ dbg("dk: ". ($default ? "def_" : "") ."whitelist_from_dk: could not find sender or from address");
+ return;
+ }
+ unless ($scan->{dk_signing_domain}) {
+ dbg("dk: ". ($default ? "def_" : "") ."whitelist_from_dk: could not find signing domain name");
+ return;
+ }
+
+ if ($default) {
+ $scan->{def_dk_whitelist_from_checked} = 1;
+ $scan->{def_dk_whitelist_from} = 0;
+
+ # copied and butchered from the code for whitelist_from_rcvd in Evaltests.pm
+ ONE: foreach my $white_addr (keys %{$scan->{conf}->{def_whitelist_from_dk}}) {
+ my $regexp = qr/$scan->{conf}->{def_whitelist_from_dk}->{$white_addr}{re}/i;
+ foreach my $domain (@{$scan->{conf}->{def_whitelist_from_dk}->{$white_addr}{domain}}) {
+ if ($scan->{dk_address} =~ $regexp) {
+ if ($scan->{dk_signing_domain} =~ /(?:^|\.)\Q${domain}\E$/i) {
+ dbg("dk: address: $scan->{dk_address} matches def_whitelist_from_dk ".
+ "$scan->{conf}->{def_whitelist_from_dk}->{$white_addr}{re} ${domain}");
+ $scan->{def_dk_whitelist_from} = 1;
+ last ONE;
+ }
+ }
+ }
+ }
+ } else {
+ $scan->{dk_whitelist_from_checked} = 1;
+ $scan->{dk_whitelist_from} = 0;
+
+ # copied and butchered from the code for whitelist_from_rcvd in Evaltests.pm
+ ONE: foreach my $white_addr (keys %{$scan->{conf}->{whitelist_from_dk}}) {
+ my $regexp = qr/$scan->{conf}->{whitelist_from_dk}->{$white_addr}{re}/i;
+ foreach my $domain (@{$scan->{conf}->{whitelist_from_dk}->{$white_addr}{domain}}) {
+ if ($scan->{dk_address} =~ $regexp) {
+ if ($scan->{dk_signing_domain} =~ /(?:^|\.)\Q${domain}\E$/i) {
+ dbg("dk: address: $scan->{dk_address} matches whitelist_from_dk ".
+ "$scan->{conf}->{whitelist_from_dk}->{$white_addr}{re} ${domain}");
+ $scan->{dk_whitelist_from} = 1;
+ last ONE;
+ }
+ }
+ }
+ }
+ }
+
+ # if the message doesn't pass DK validation, it can't pass a DK whitelist
+ if ($default) {
+ if ($scan->{def_dk_whitelist_from}) {
+ if ($self->check_domainkeys_verified($scan)) {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is in user's DEF_WHITELIST_FROM_DK and ".
+ "passed DK verification");
+ } else {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is in user's DEF_WHITELIST_FROM_DK but ".
+ "failed DK verification");
+ $scan->{def_dk_whitelist_from} = 0;
+ }
+ } else {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is not in user's DEF_WHITELIST_FROM_DK");
+ }
+ } else {
+ if ($scan->{dk_whitelist_from}) {
+ if ($self->check_domainkeys_verified($scan)) {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is in user's WHITELIST_FROM_DK and ".
+ "passed DK verification");
+ } else {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is in user's WHITELIST_FROM_DK but ".
+ "failed DK verification");
+ $scan->{dk_whitelist_from} = 0;
+ }
+ } else {
+ dbg("dk: address: $scan->{dk_address} signing domain name: ".
+ "$scan->{dk_signing_domain} is not in user's WHITELIST_FROM_DK");
+ }
+ }
}

1;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTMLEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTMLEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTMLEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTMLEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTTPSMismatch.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTTPSMismatch.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTTPSMismatch.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HTTPSMismatch.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Hashcash.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Hashcash.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Hashcash.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Hashcash.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HeaderEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HeaderEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HeaderEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/HeaderEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -548,9 +549,14 @@
&& $rcvd !~ / cookie\.(?:juno|untd)\.com /) { return 1; }
if($xmailer !~ /Juno /) { return 1; }
} else {
- if($rcvd !~ /from.*\bmail\.com.*\[$IP_ADDRESS\].*by/) { return 1; }
+ if($rcvd =~ /from.*\bmail\.com.*\[$IP_ADDRESS\].*by/) {
+ if($xmailer !~ /\bmail\.com/) { return 1; }
+ } elsif($rcvd =~ /from (webmail\S+\.untd\.com) \(\1 \[$IP_ADDRESS\]\) by/) {
+ if($xmailer !~ /^Webmail Version \d/) { return 1; }
+ } else {
+ return 1;
+ }
if($xorig !~ /$IP_ADDRESS/) { return 1; }
- if($xmailer !~ /\bmail\.com/) { return 1; }
}

return 0;
@@ -789,13 +795,15 @@

my $time;
# a Resent-Date: header takes precedence over any Date: header
- for my $header ('Resent-Date', 'Date') {
- my $date = $pms->get($header);
- if (defined($date) && length($date)) {
- chomp($date);
- $time = Mail::SpamAssassin::Util::parse_rfc822_date($date);
+ DATE: for my $header ('Resent-Date', 'Date') {
+ my @dates = $pms->{msg}->get_header($header);
+ for my $date (@dates) {
+ if (defined($date) && length($date)) {
+ chomp($date);
+ $time = Mail::SpamAssassin::Util::parse_rfc822_date($date);
+ }
+ last DATE if defined($time);
}
- last if defined($time);
}
if (defined($time)) {
$pms->{date_header_time} = $time;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -18,7 +19,7 @@

use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Locales;
-use Mail::SpamAssassin::Constants qw(:sa);
+use Mail::SpamAssassin::Constants qw(:sa CHARSETS_LIKELY_TO_FP_AS_CAPS);
use strict;
use warnings;
use bytes;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/MIMEHeader.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/NetCache.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/NetCache.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/NetCache.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/NetCache.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Pyzor.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Pyzor.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Pyzor.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Pyzor.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -334,7 +335,7 @@
return unless $self->{pyzor_available};
return unless $self->{main}->{conf}->{use_pyzor};

- if (!$self->{options}->{dont_report_to_pyzor} && $self->is_pyzor_available())
+ if (!$options->{report}->{options}->{dont_report_to_pyzor} && $self->is_pyzor_available())
{
# use temporary file: open2() is unreliable due to buffering under spamd
my $tmpf = $options->{report}->create_fulltext_tmpfile($options->{text});

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Razor2.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Razor2.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Razor2.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Razor2.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayCountry.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/RelayEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -101,12 +102,10 @@
foreach my $rcvd ( @{$pms->{relays_untrusted}} ) {
# (note this might miss some hits if the Received.pm skips any invalid IPs)
foreach my $check ( $rcvd->{ip}, $rcvd->{by} ) {
- return 1 if ($check =~ /^(?:
- (?:[01257]|22[3-9]|23[0-9]|24[0-9]|25[0-5])\.\d+\.\d+\.\d+|
- 127\.[1-9]\.\d+\.\d+|
- 127\.0\.[1-9]\.\d+|
- 127\.0\.0\.(?:\d\d+|[2-9])
- )$/x);
+ next if ($check eq '127.0.0.1');
+ return 1 if ($check =~ /^
+ (?:[01257]|127|22[3-9]|23[0-9]|24[0-9]|25[0-5])\.\d+\.\d+\.\d+
+ $/x);
}
}
return 0;

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/ReplaceTags.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SPF.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SPF.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SPF.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SPF.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -315,7 +316,7 @@
return 0;
}

- $result ||= 'softfail';
+ $result ||= 'timeout'; # bug 5077
$comment ||= '';
$comment =~ s/\s+/ /gs; # no newlines please


Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Shortcircuit.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Shortcircuit.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Shortcircuit.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Shortcircuit.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SpamCop.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SpamCop.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SpamCop.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/SpamCop.pm Fri Oct 6 05:46:56 2006
@@ -1,12 +1,13 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -160,7 +161,7 @@

return unless $self->{spamcop_available};

- if (!$self->{options}->{dont_report_to_spamcop}) {
+ if (!$options->{report}->{options}->{dont_report_to_spamcop}) {
if ($self->spamcop_report($options)) {
$options->{report}->{report_available} = 1;
info("reporter: spam reported to SpamCop");

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Test.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Test.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Test.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/Test.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/TextCat.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/TextCat.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/TextCat.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/TextCat.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDNSBL.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
@@ -75,10 +76,9 @@
in, and C<lookuptype> is the type of lookup (B<TXT> or B<A>).

C<subtest> is the sub-test to run against the returned data. The sub-test may
-either be an IPv4 dotted address for RHSBLs that return multiple A records, a
+either be an IPv4 dotted address for RHSBLs that return multiple A records or a
non-negative decimal number to specify a bitmask for RHSBLs that return a
-single A record containing a bitmask of results, or (if none of the preceding
-options seem to fit) a regular expression.
+single A record containing a bitmask of results.

Note that, as with C<urirhsbl>, you must also define a body-eval rule calling
C<check_uridnsbl()> to use this.
@@ -161,31 +161,25 @@
return;
}

- $self->{scanner} = $scanner;
- my $scanstate = $scanner->{uribl_scanstate} = {
- self => $self,
- scanner => $scanner,
- activerules => { },
- hits => { }
- };
+ $scanner->{'uridnsbl_activerules'} = { };
+ $scanner->{'uridnsbl_hits'} = { };
+ $scanner->{'uridnsbl_seen_domain'} = { };

# only hit DNSBLs for active rules (defined and score != 0)
- $scanstate->{active_rules_rhsbl} = { };
- $scanstate->{active_rules_revipbl} = { };
+ $scanner->{'uridnsbl_active_rules_rhsbl'} = { };
+ $scanner->{'uridnsbl_active_rules_revipbl'} = { };
+
foreach my $rulename (keys %{$scanner->{conf}->{uridnsbls}}) {
next unless ($scanner->{conf}->is_rule_active('body_evals',$rulename));

- my $rulecf = $scanstate->{scanner}->{conf}->{uridnsbls}->{$rulename};
+ my $rulecf = $scanner->{conf}->{uridnsbls}->{$rulename};
if ($rulecf->{is_rhsbl}) {
- $scanstate->{active_rules_rhsbl}->{$rulename} = 1;
+ $scanner->{uridnsbl_active_rules_rhsbl}->{$rulename} = 1;
} else {
- $scanstate->{active_rules_revipbl}->{$rulename} = 1;
+ $scanner->{uridnsbl_active_rules_revipbl}->{$rulename} = 1;
}
}

- $self->setup ($scanstate);
-
-
# get all domains in message

# don't keep dereferencing this
@@ -247,7 +241,8 @@
# at this point, @uri_ordered is an ordered array of uri hashes

my %domlist = ();
- while (keys %domlist < $scanner->{main}->{conf}->{uridnsbl_max_domains} && @uri_ordered) {
+ my $umd = $scanner->{main}->{conf}->{uridnsbl_max_domains};
+ while (keys %domlist < $umd && @uri_ordered) {
my $array = shift @uri_ordered;
next unless $array;

@@ -256,7 +251,7 @@
next unless @domains;

# the new domains are all useful, just add them in
- if (keys(%domlist) + @domains <= $scanner->{main}->{conf}->{uridnsbl_max_domains}) {
+ if (keys(%domlist) + @domains <= $umd) {
foreach (@domains) {
$domlist{$_} = 1;
}
@@ -264,7 +259,7 @@
else {
# trim down to a limited number - pick randomly
my $i;
- while (@domains && keys %domlist < $scanner->{main}->{conf}->{uridnsbl_max_domains}) {
+ while (@domains && keys %domlist < $umd) {
my $r = int rand (scalar @domains);
$domlist{splice (@domains, $r, 1)} = 1;
}
@@ -274,7 +269,7 @@
# and query
dbg("uridnsbl: domains to query: ".join(' ',keys %domlist));
foreach my $dom (keys %domlist) {
- $self->query_domain ($scanstate, $dom);
+ $self->query_domain ($scanner, $dom);
}

return 1;
@@ -344,7 +339,7 @@
setting => 'urirhssub',
code => sub {
my ($self, $key, $value, $line) = @_;
- if ($value =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/) {
+ if ($value =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\d{1,10}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/) {
my $rulename = $1;
my $zone = $2;
my $type = $3;
@@ -386,22 +381,15 @@

# ---------------------------------------------------------------------------

-sub setup {
- my ($self, $scanstate) = @_;
- $scanstate->{seen_domain} = { };
-}
-
-# ---------------------------------------------------------------------------
-
sub query_domain {
- my ($self, $scanstate, $dom) = @_;
+ my ($self, $scanner, $dom) = @_;

#warn "uridnsbl: domain $dom\n";
#return;

$dom = lc $dom;
- return if $scanstate->{seen_domain}->{$dom};
- $scanstate->{seen_domain}->{$dom} = 1;
+ return if $scanner->{uridnsbl_seen_domain}->{$dom};
+ $scanner->{uridnsbl_seen_domain}->{$dom} = 1;
$self->log_dns_result("querying domain $dom");

my $obj = {
@@ -415,7 +403,7 @@
my $IP_PRIVATE = IP_PRIVATE;
# only look up the IP if it is public and valid
if ($dom =~ /^$IPV4_ADDRESS$/ && $dom !~ /^$IP_PRIVATE$/) {
- $self->lookup_dnsbl_for_ip($scanstate, $obj, $dom);
+ $self->lookup_dnsbl_for_ip($scanner, $obj, $dom);
# and check the IP in RHSBLs too
if ($dom =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
$dom = "$4.$3.$2.$1";
@@ -429,46 +417,46 @@

if ($single_dnsbl) {
# look up the domain in the RHSBL subset
- my $cf = $scanstate->{active_rules_rhsbl};
+ my $cf = $scanner->{uridnsbl_active_rules_rhsbl};
foreach my $rulename (keys %{$cf}) {
- my $rulecf = $scanstate->{scanner}->{conf}->{uridnsbls}->{$rulename};
- $self->lookup_single_dnsbl($scanstate, $obj, $rulename,
+ my $rulecf = $scanner->{conf}->{uridnsbls}->{$rulename};
+ $self->lookup_single_dnsbl($scanner, $obj, $rulename,
$dom, $rulecf->{zone}, $rulecf->{type});

# see comment below
- $scanstate->{scanner}->register_async_rule_start($rulename);
+ $scanner->register_async_rule_start($rulename);
}

# perform NS, A lookups to look up the domain in the non-RHSBL subset
if ($dom !~ /^\d+\.\d+\.\d+\.\d+$/) {
- $self->lookup_domain_ns($scanstate, $obj, $dom);
+ $self->lookup_domain_ns($scanner, $obj, $dom);
}
}

# note that these rules are now underway. important: unless the
# rule hits, in the current design, these will not be considered
# "finished" until harvest_dnsbl_queries() completes
- my $cf = $scanstate->{active_rules_revipbl};
+ my $cf = $scanner->{uridnsbl_active_rules_revipbl};
foreach my $rulename (keys %{$cf}) {
- $scanstate->{scanner}->register_async_rule_start($rulename);
+ $scanner->register_async_rule_start($rulename);
}
}

# ---------------------------------------------------------------------------

sub lookup_domain_ns {
- my ($self, $scanstate, $obj, $dom) = @_;
+ my ($self, $scanner, $obj, $dom) = @_;

my $key = "NS:".$dom;
- return if $scanstate->{scanner}->{async}->get_lookup($key);
+ return if $scanner->{async}->get_lookup($key);

# dig $dom ns
- my $ent = $self->start_lookup ($scanstate, 'NS', $self->res_bgsend($scanstate, $dom, 'NS'), $key);
+ my $ent = $self->start_lookup ($scanner, 'NS', $self->res_bgsend($scanner, $dom, 'NS'), $key);
$ent->{obj} = $obj;
}

sub complete_ns_lookup {
- my ($self, $scanstate, $ent, $dom) = @_;
+ my ($self, $scanner, $ent, $dom) = @_;

my $packet = $ent->{response_packet};
my @answer = $packet->answer;
@@ -488,11 +476,11 @@
$nsmatch =~ s/\.$//;
# only look up the IP if it is public and valid
if ($nsmatch =~ /^$IPV4_ADDRESS$/ && $nsmatch !~ /^$IP_PRIVATE$/) {
- $self->lookup_dnsbl_for_ip($scanstate, $ent->{obj}, $nsmatch);
+ $self->lookup_dnsbl_for_ip($scanner, $ent->{obj}, $nsmatch);
}
}
else {
- $self->lookup_a_record($scanstate, $ent->{obj}, $nsmatch);
+ $self->lookup_a_record($scanner, $ent->{obj}, $nsmatch);
}
}
}
@@ -501,25 +489,25 @@
# ---------------------------------------------------------------------------

sub lookup_a_record {
- my ($self, $scanstate, $obj, $hname) = @_;
+ my ($self, $scanner, $obj, $hname) = @_;

my $key = "A:".$hname;
- return if $scanstate->{scanner}->{async}->get_lookup($key);
+ return if $scanner->{async}->get_lookup($key);

# dig $hname a
- my $ent = $self->start_lookup ($scanstate, 'A', $self->res_bgsend($scanstate, $hname, 'A'), $key);
+ my $ent = $self->start_lookup ($scanner, 'A', $self->res_bgsend($scanner, $hname, 'A'), $key);
$ent->{obj} = $obj;
}

sub complete_a_lookup {
- my ($self, $scanstate, $ent, $hname) = @_;
+ my ($self, $scanner, $ent, $hname) = @_;

foreach my $rr ($ent->{response_packet}->answer) {
my $str = $rr->string;
$self->log_dns_result ("A for NS $hname: $str");

if ($str =~ /IN\s+A\s+(\S+)/) {
- $self->lookup_dnsbl_for_ip($scanstate, $ent->{obj}, $1);
+ $self->lookup_dnsbl_for_ip($scanner, $ent->{obj}, $1);
}
}
}
@@ -527,39 +515,38 @@
# ---------------------------------------------------------------------------

sub lookup_dnsbl_for_ip {
- my ($self, $scanstate, $obj, $ip) = @_;
+ my ($self, $scanner, $obj, $ip) = @_;

$ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
my $revip = "$4.$3.$2.$1";

- my $cf = $scanstate->{active_rules_revipbl};
+ my $cf = $scanner->{uridnsbl_active_rules_revipbl};
foreach my $rulename (keys %{$cf}) {
- my $rulecf = $scanstate->{scanner}->{conf}->{uridnsbls}->{$rulename};
- $self->lookup_single_dnsbl($scanstate, $obj, $rulename,
+ my $rulecf = $scanner->{conf}->{uridnsbls}->{$rulename};
+ $self->lookup_single_dnsbl($scanner, $obj, $rulename,
$revip, $rulecf->{zone}, $rulecf->{type});
}
}

sub lookup_single_dnsbl {
- my ($self, $scanstate, $obj, $rulename, $lookupstr, $dnsbl, $qtype) = @_;
+ my ($self, $scanner, $obj, $rulename, $lookupstr, $dnsbl, $qtype) = @_;

my $key = "DNSBL:".$dnsbl.":".$lookupstr;
- return if $scanstate->{scanner}->{async}->get_lookup($key);
+ return if $scanner->{async}->get_lookup($key);
my $item = $lookupstr.".".$dnsbl;

# dig $ip txt
- my $ent = $self->start_lookup ($scanstate, 'DNSBL',
- $self->res_bgsend($scanstate, $item, $qtype), $key);
+ my $ent = $self->start_lookup ($scanner, 'DNSBL',
+ $self->res_bgsend($scanner, $item, $qtype), $key);
$ent->{obj} = $obj;
$ent->{rulename} = $rulename;
$ent->{zone} = $dnsbl;
}

sub complete_dnsbl_lookup {
- my ($self, $scanstate, $ent, $dnsblip) = @_;
+ my ($self, $scanner, $ent, $dnsblip) = @_;

- my $scan = $scanstate->{scanner};
- my $conf = $scan->{conf};
+ my $conf = $scanner->{conf};
my @subtests = ();
my $rulename = $ent->{rulename};
my $rulecf = $conf->{uridnsbls}->{$rulename};
@@ -583,7 +570,7 @@
$packet->header->id." rr=".$rr->string);
next;
}
- $self->got_dnsbl_hit($scanstate, $ent, $rdatastr, $dom, $rulename);
+ $self->got_dnsbl_hit($scanner, $ent, $rdatastr, $dom, $rulename);
}
else {
foreach my $subtest (keys (%{$uridnsbl_subs}))
@@ -591,20 +578,14 @@
my $subrulename = $uridnsbl_subs->{$subtest}->{rulename};

if ($subtest eq $rdatastr) {
- $self->got_dnsbl_hit($scanstate, $ent, $rdatastr, $dom, $subrulename);
+ $self->got_dnsbl_hit($scanner, $ent, $rdatastr, $dom, $subrulename);
}
# bitmask
elsif ($subtest =~ /^\d+$/) {
- if ($rdatastr =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ &&
- Mail::SpamAssassin::Util::my_inet_aton($rdatastr) & $subtest)
+ if ($rdatastr =~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ &&
+ Mail::SpamAssassin::Util::my_inet_aton($rdatastr) & $subtest)
{
- $self->got_dnsbl_hit($scanstate, $ent, $rdatastr, $dom, $subrulename);
- }
- }
- # regular expression
- else {
- if ($rdatastr =~ /${subtest}/) {
- $self->got_dnsbl_hit($scanstate, $ent, $rdatastr, $dom, $subrulename);
+ $self->got_dnsbl_hit($scanner, $ent, $rdatastr, $dom, $subrulename);
}
}
}
@@ -613,35 +594,34 @@
}

sub got_dnsbl_hit {
- my ($self, $scanstate, $ent, $str, $dom, $rulename) = @_;
+ my ($self, $scanner, $ent, $str, $dom, $rulename) = @_;

$str =~ s/\s+/ /gs; # long whitespace => short
dbg("uridnsbl: domain \"$dom\" listed ($rulename): $str");

- if (!defined $scanstate->{hits}->{$rulename}) {
- $scanstate->{hits}->{$rulename} = { };
+ if (!defined $scanner->{uridnsbl_hits}->{$rulename}) {
+ $scanner->{uridnsbl_hits}->{$rulename} = { };
};
- $scanstate->{hits}->{$rulename}->{$dom} = 1;
+ $scanner->{uridnsbl_hits}->{$rulename}->{$dom} = 1;

- my $scan = $scanstate->{scanner};
- if ($scanstate->{active_rules_revipbl}->{$rulename}
- || $scanstate->{active_rules_rhsbl}->{$rulename})
+ if ($scanner->{uridnsbl_active_rules_revipbl}->{$rulename}
+ || $scanner->{uridnsbl_active_rules_rhsbl}->{$rulename})
{
# TODO: this needs to handle multiple domain hits per rule
- $scan->clear_test_state();
- my $uris = join (' ', keys %{$scanstate->{hits}->{$rulename}});
- $scan->test_log ("URIs: $uris");
- $scan->got_hit ($rulename, "");
+ $scanner->clear_test_state();
+ my $uris = join (' ', keys %{$scanner->{uridnsbl_hits}->{$rulename}});
+ $scanner->test_log ("URIs: $uris");
+ $scanner->got_hit ($rulename, "");

# note that this rule has completed (since it got at least 1 hit)
- $scanstate->{scanner}->register_async_rule_finish($rulename);
+ $scanner->register_async_rule_finish($rulename);
}
}

# ---------------------------------------------------------------------------

sub start_lookup {
- my ($self, $scanstate, $type, $id, $key) = @_;
+ my ($self, $scanner, $type, $id, $key) = @_;

my $ent = {
key => $key,
@@ -649,27 +629,27 @@
id => $id,
completed_callback => sub {
my $ent = shift;
- $self->completed_lookup_callback ($scanstate, $ent);
+ $self->completed_lookup_callback ($scanner, $ent);
}
};
- $scanstate->{scanner}->{async}->start_lookup($ent);
+ $scanner->{async}->start_lookup($ent);
return $ent;
}

sub completed_lookup_callback {
- my ($self, $scanstate, $ent) = @_;
+ my ($self, $scanner, $ent) = @_;
my $type = $ent->{type};
my $key = $ent->{key};
$key =~ /:(\S+?)$/; my $val = $1;

if ($type eq 'URI-NS') {
- $self->complete_ns_lookup ($scanstate, $ent, $val);
+ $self->complete_ns_lookup ($scanner, $ent, $val);
}
elsif ($type eq 'URI-A') {
- $self->complete_a_lookup ($scanstate, $ent, $val);
+ $self->complete_a_lookup ($scanner, $ent, $val);
}
elsif ($type eq 'URI-DNSBL') {
- $self->complete_dnsbl_lookup ($scanstate, $ent, $val);
+ $self->complete_dnsbl_lookup ($scanner, $ent, $val);
my $totalsecs = (time - $ent->{obj}->{querystart});
dbg("uridnsbl: query for ".$ent->{obj}->{dom}." took ".
$totalsecs." seconds to look up ($val)");
@@ -679,12 +659,12 @@
# ---------------------------------------------------------------------------

sub res_bgsend {
- my ($self, $scanstate, $host, $type) = @_;
+ my ($self, $scanner, $host, $type) = @_;

return $self->{main}->{resolver}->bgsend($host, $type, undef, sub {
my $pkt = shift;
my $id = shift;
- $scanstate->{scanner}->{async}->set_response_packet($id, $pkt);
+ $scanner->{async}->set_response_packet($id, $pkt);
});
}


Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDetail.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDetail.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDetail.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIDetail.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/URIEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#

Modified: spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/WLBLEval.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/WLBLEval.pm?view=diff&rev=453586&r1=453585&r2=453586
==============================================================================
--- spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/WLBLEval.pm (original)
+++ spamassassin/branches/jm_re2c_hacks/lib/Mail/SpamAssassin/Plugin/WLBLEval.pm Fri Oct 6 05:46:56 2006
@@ -1,9 +1,10 @@
# <@LICENSE>
-# Copyright 2004 Apache Software Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#