You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2019/08/31 11:58:50 UTC
svn commit: r1866204 -
/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm
Author: hege
Date: Sat Aug 31 11:58:50 2019
New Revision: 1866204
URL: http://svn.apache.org/viewvc?rev=1866204&view=rev
Log:
Use check_dnsbl instead of priority hacks to launch async
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm?rev=1866204&r1=1866203&r2=1866204&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DCC.pm Sat Aug 31 11:58:50 2019
@@ -115,9 +115,6 @@ sub new {
$self->{dcc_disabled} = 1;
dbg("dcc: local tests only, disabling DCC");
}
- else {
- dbg("dcc: network tests on, registering DCC");
- }
$self->register_eval_rule("check_dcc");
$self->register_eval_rule("check_dcc_reputation_range");
@@ -656,7 +653,7 @@ sub check_cleanup {
my $pms = $opts->{permsgstatus};
# Finish callbacks
- if ($pms->{dcc_x_result} && $pms->{dcc_range_callbacks}) {
+ if ($pms->{dcc_range_callbacks}) {
foreach (@{$pms->{dcc_range_callbacks}}) {
$self->check_dcc_reputation_range($pms, @$_);
}
@@ -671,7 +668,8 @@ sub _check_async {
my $timer = $self->{main}->time_method("check_dcc");
- $pms->{dcc_abort} = $pms->{deadline_exceeded} || $pms->{shortcircuited};
+ $pms->{dcc_abort} =
+ $pms->{dcc_abort} || $pms->{deadline_exceeded} || $pms->{shortcircuited};
if ($pms->{dcc_abort}) {
$timeout = 0;
@@ -694,7 +692,6 @@ sub _check_async {
@resp = $pms->{dcc_sock}->getlines();
});
delete $pms->{dcc_sock};
- $pms->{dcc_result} = 0;
if ($timer->timed_out()) {
info("dcc: dccifd read failed");
} elsif ($err) {
@@ -708,9 +705,12 @@ sub _check_async {
$self->parse_dcc_response(\@resp, 'dccifd');
if ($pms->{dcc_x_result}) {
dbg("dcc: dccifd parsed response: $pms->{dcc_x_result}");
- $pms->{dcc_result} = $self->check_dcc_result($pms, $pms->{dcc_x_result});
+ ($pms->{dcc_result}, $pms->{dcc_rep}) =
+ $self->check_dcc_result($pms, $pms->{dcc_x_result});
if ($pms->{dcc_result}) {
- $pms->got_hit($pms->{dcc_rulename}, "", ruletype => 'eval');
+ foreach (@{$pms->{conf}->{eval_to_rule}->{check_dcc}}) {
+ $pms->got_hit($_, "", ruletype => 'eval');
+ }
}
}
} else {
@@ -730,34 +730,29 @@ sub _check_async {
}
}
-sub finish_parsing_start {
- my ($self, $opts) = @_;
+sub check_dnsbl {
+ my($self, $opts) = @_;
+
+ return 0 if $self->{dcc_disabled};
+ return 0 if !$self->{main}->{conf}->{use_dcc};
+
+ my $pms = $opts->{permsgstatus};
- # If using dccifd, hard adjust priority -100 to launch early async
+ # Check that rules are active
+ return 0 if !grep {$pms->{conf}->{scores}->{$_}}
+ @{$pms->{conf}->{eval_to_rule}->{check_dcc}};
+
+ # Launch async only if dccifd found
$self->find_dcc_home();
if ($self->is_dccifd_available()) {
- foreach (@{$opts->{conf}->{eval_to_rule}->{check_dcc}}) {
- dbg("dcc: adjusting rule $_ priority to -100");
- $opts->{conf}->{priority}->{$_} = -100;
- }
- if ($opts->{conf}->{use_dcc_rep}) {
- foreach (@{$opts->{conf}->{eval_to_rule}->{check_dcc_reputation_range}}) {
- dbg("dcc: adjusting rule $_ priority to -100");
- $opts->{conf}->{priority}->{$_} = -100;
- }
- }
+ $self->_launch_dcc($pms);
}
}
-sub check_dcc {
- my ($self, $pms, $fulltext, $rulename) = @_;
-
- return 0 if $self->{dcc_disabled};
- return 0 if !$self->{main}->{conf}->{use_dcc};
+sub _launch_dcc {
+ my ($self, $pms) = @_;
- return $pms->{dcc_result} if defined $pms->{dcc_result};
-
- return 0 if $pms->{dcc_running};
+ return if $pms->{dcc_running};
$pms->{dcc_running} = 1;
my $timer = $self->{main}->time_method("check_dcc");
@@ -767,9 +762,18 @@ sub check_dcc {
$pms->{tag_data}->{DCCR} = '';
$pms->{tag_data}->{DCCREP} = '';
- if ($$fulltext eq '') {
+ my $fulltext = $pms->{msg}->get_pristine();
+ if ($fulltext eq '') {
dbg("dcc: empty message; skipping dcc check");
- return 0;
+ $pms->{dcc_result} = 0;
+ $pms->{dcc_abort} = 1;
+ return;
+ }
+
+ if (!$self->get_dcc_interface()) {
+ $pms->{dcc_result} = 0;
+ $pms->{dcc_abort} = 1;
+ return;
}
if ($pms->get('ALL-TRUSTED') =~ /^(X-DCC-[^:]*?-Metrics: .*)$/m) {
@@ -782,85 +786,95 @@ sub check_dcc {
#}
}
- $pms->{dcc_rulename} = $pms->get_current_eval_rule_name();
-
- return 0 if !$self->get_dcc_interface();
-
my $envelope = $pms->{relays_external}->[0];
+
($pms->{dcc_x_result}, $pms->{dcc_cksums}) =
- $self->ask_dcc('dcc:', $pms, $fulltext, $envelope);
+ $self->ask_dcc('dcc:', $pms, \$fulltext, $envelope);
+
+ return;
+}
+
+sub check_dcc {
+ my ($self, $pms) = @_;
+
+ return 0 if $self->{dcc_disabled};
+ return 0 if !$pms->{conf}->{use_dcc};
+ return 0 if $pms->{dcc_abort};
+ return 0 if $pms->{dcc_async_start}; # async already handling?
+
+ return $pms->{dcc_result} if defined $pms->{dcc_result};
+
+ $self->_launch_dcc($pms);
+
if (!defined $pms->{dcc_x_result}) {
- $pms->{dcc_result} = 0;
- } elsif ($pms->{dcc_x_result} eq 'async') {
- return 0; # read result later
- } else {
- $pms->{dcc_result} =
- $self->check_dcc_result($pms, $pms->{dcc_x_result});
+ $pms->{dcc_abort} = 1;
+ return 0;
}
+ ($pms->{dcc_result}, $pms->{dcc_rep}) =
+ $self->check_dcc_result($pms, $pms->{dcc_x_result});
+
return $pms->{dcc_result};
}
sub check_dcc_reputation_range {
- my ($self, $pms, $fulltext, $min, $max, $rulename) = @_;
+ my ($self, $pms, undef, $min, $max, $cb_rulename) = @_;
return 0 if $self->{dcc_disabled};
- return 0 if !$self->{main}->{conf}->{use_dcc};
- return 0 if !$self->{main}->{conf}->{use_dcc_rep};
+ return 0 if !$pms->{conf}->{use_dcc};
+ return 0 if !$pms->{conf}->{use_dcc_rep};
return 0 if $pms->{dcc_abort};
- # Check if callback (overrides rulename)
- my $cb = defined $rulename;
- if (!$cb) {
- $rulename = $pms->get_current_eval_rule_name();
- dbg("dcc: delaying check_dcc_reputation_range call for $rulename");
- # array matches check_dcc_reputation_range() argument order
- push @{$pms->{dcc_range_callbacks}}, [$fulltext, $min, $max, $rulename];
- return 0;
- }
+ my $timer = $self->{main}->time_method("check_dcc");
- return 0 if !defined $pms->{dcc_x_result};
+ if (exists $pms->{dcc_rep}) {
+ my $result;
- # this is called several times per message, so parse the X-DCC header once
- if (!defined $pms->{dcc_rep}) {
- my $dcc_rep;
- if ($pms->{dcc_x_result} =~ /\brep=(\d+)/) {
- $dcc_rep = $1+0;
- $pms->set_tag('DCCREP', $dcc_rep);
+ # Process result
+ if ($pms->{dcc_rep} < 0) {
+ # Not used or missing reputation
+ $result = 0;
} else {
- $dcc_rep = -1;
+ # cover the entire range of reputations if not told otherwise
+ $min = 0 if !defined $min;
+ $max = 100 if !defined $max;
+ $result = $pms->{dcc_rep} >= $min && $pms->{dcc_rep} <= $max ? 1 : 0;
+ dbg("dcc: dcc_rep %s, min %s, max %s => result=%s",
+ $pms->{dcc_rep}, $min, $max, $result ? 'YES' : 'no');
}
- $pms->{dcc_rep} = $dcc_rep;
- }
-
- # no X-DCC header or no reputation in the X-DCC header, perhaps for lack
- # of data in the DCC Reputation server
- return 0 if $pms->{dcc_rep} < 0;
-
- # cover the entire range of reputations if not told otherwise
- $min = 0 if !defined $min;
- $max = 100 if !defined $max;
- my $result = $pms->{dcc_rep} >= $min && $pms->{dcc_rep} <= $max ? 1 : 0;
- dbg("dcc: dcc_rep %s, min %s, max %s => result=%s",
- $pms->{dcc_rep}, $min, $max, $result ? 'YES' : 'no');
-
- if ($cb) {
- # Callback needs to got_hit()
- if ($result) {
- $pms->got_hit($rulename, "", ruletype => 'eval');
+ if (defined $cb_rulename) {
+ # If callback, use got_hit()
+ if ($result) {
+ $pms->got_hit($cb_rulename, "", ruletype => 'eval');
+ }
+ return 0;
+ } else {
+ return $result;
}
} else {
- return $result;
+ # Install callback if waiting for async result
+ if (!defined $cb_rulename) {
+ my $rulename = $pms->get_current_eval_rule_name();
+ # array matches check_dcc_reputation_range() argument order
+ push @{$pms->{dcc_range_callbacks}}, [undef, $min, $max, $rulename];
+ }
}
+
+ return 0;
}
sub check_dcc_result {
my ($self, $pms, $x_dcc) = @_;
- return 0 if !defined $x_dcc || $x_dcc eq '';
+ my $dcc_result = 0;
+ my $dcc_rep = -1;
+
+ if (!defined $x_dcc || $x_dcc eq '') {
+ return ($dcc_result, $dcc_rep);
+ }
- my $conf = $pms->{main}->{conf};
+ my $conf = $pms->{conf};
if ($x_dcc =~ /^X-DCC-([^:]*?)-Metrics: (.*)$/) {
$pms->set_tag('DCCB', $1);
@@ -879,8 +893,10 @@ sub check_dcc_result {
if ($x_dcc =~ /\bFuz2=(\d+)/) {
$count{fuz2} = $1+0;
}
- if ($x_dcc =~ /\brep=(\d+)/) {
+ if ($pms->{conf}->{use_dcc_rep} && $x_dcc =~ /\brep=(\d+)/) {
$count{rep} = $1+0;
+ $dcc_rep = $count{rep};
+ $pms->set_tag('DCCREP', $dcc_rep);
}
if ($count{body} >= $conf->{dcc_body_max} ||
$count{fuz1} >= $conf->{dcc_fuz1_max} ||
@@ -894,9 +910,10 @@ sub check_dcc_result {
$count{fuz2}, $conf->{dcc_fuz2_max},
$count{rep}, $conf->{dcc_rep_percent})
));
- return 1;
+ $dcc_result = 1;
}
- return 0;
+
+ return ($dcc_result, $dcc_rep);
}
# get the X-DCC header line and save the checksums from dccifd or dccproc
@@ -930,7 +947,7 @@ sub parse_dcc_response {
sub ask_dcc {
my ($self, $tag, $pms, $fulltext, $envelope) = @_;
- my $conf = $self->{main}->{conf};
+ my $conf = $pms->{conf};
my $timeout = $conf->{dcc_timeout};
if ($self->is_dccifd_available()) {