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 2018/09/27 14:38:33 UTC
svn commit: r1842098 - in /spamassassin/trunk/lib/Mail/SpamAssassin:
AsyncLoop.pm Conf.pm PerMsgStatus.pm
Author: hege
Date: Thu Sep 27 14:38:33 2018
New Revision: 1842098
URL: http://svn.apache.org/viewvc?rev=1842098&view=rev
Log:
Bug 6728 - DNSBLs need a way to turn off queries based on BLOCKED rules triggering
Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm?rev=1842098&r1=1842097&r2=1842098&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/AsyncLoop.pm Thu Sep 27 14:38:33 2018
@@ -322,17 +322,39 @@ sub bgsend_and_start_lookup {
else { # no existing query, open a new DNS query
$dns_query_info = $self->{all_lookups}{$dnskey} = {}; # new query needed
- my($id, $blocked);
+ my($id, $blocked, $check_dbrdom);
+ # dns_query_restriction
+ my $blocked_by = 'dns_query_restriction';
my $dns_query_blockages = $self->{main}->{conf}->{dns_query_blocked};
- if ($dns_query_blockages) {
+ # dns_block_rule
+ my $dns_block_domains = $self->{main}->{conf}->{dns_block_rule_domains};
+ if ($dns_query_blockages || $dns_block_domains) {
my $search_list = domain_to_search_list($domain);
foreach my $parent_domain (@$search_list) {
- $blocked = $dns_query_blockages->{$parent_domain};
- last if defined $blocked; # stop at first defined, can be true or false
+ if ($dns_query_blockages) {
+ $blocked = $dns_query_blockages->{$parent_domain};
+ last if defined $blocked; # stop at first defined, can be true or false
+ } elsif ($dns_block_domains->{$parent_domain}) {
+ # save for later check.. ps. untainted already
+ $check_dbrdom = $dns_block_domains->{$parent_domain};
+ }
+ }
+ }
+ if (!$blocked && $check_dbrdom) {
+ my $blockfile =
+ $self->{main}->sed_path("__userstate__/dnsblock_${check_dbrdom}");
+ if (my $mtime = (stat($blockfile))[9]) {
+ if (time - $mtime <= $self->{main}->{conf}->{dns_block_time}) {
+ $blocked = 1;
+ $blocked_by = 'dns_block_rule';
+ } else {
+ dbg("async: dns_block_rule removing expired $blockfile");
+ unlink($blockfile);
+ }
}
}
if ($blocked) {
- dbg("async: blocked by dns_query_restriction: %s", $dnskey);
+ dbg("async: blocked by %s: %s", $blocked_by, $dnskey);
} else {
dbg("async: launching %s for %s", $dnskey, $key);
$id = $self->{main}->{resolver}->bgsend($domain, $type, $class, sub {
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm?rev=1842098&r1=1842097&r2=1842098&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf.pm Thu Sep 27 14:38:33 2018
@@ -1965,6 +1965,55 @@ options, leaving the list empty, i.e. al
}
});
+=item dns_block_rule RULE domain
+
+If rule named RULE is hit, DNS queries to specified domain are
+I<temporarily> blocked. Intended to be used with rules that check
+RBL return codes for specific blocked status. For example:
+
+ urirhssub URIBL_BLOCKED multi.uribl.com. A 1
+ dns_block_rule URIBL_BLOCKED multi.uribl.com
+
+Block status is maintained across all processes by empty statefile in
+userstate directory (~/.spamassassin/dnsblock_multi.uribl.com).
+
+=cut
+
+ push (@cmds, {
+ setting => 'dns_block_rule',
+ type => $CONF_TYPE_STRING,
+ code => sub {
+ my ($self, $key, $value, $line) = @_;
+ defined $value && $value =~ /^(\S+)\s+(.+)$/
+ or return $INVALID_VALUE;
+ my $rule = $1;
+ foreach my $domain (split(/\s+/, lc($2))) {
+ $domain =~ s/^\.//; $domain =~ s/\.\z//; # strip dots
+ if ($domain !~ /^[a-z0-9.-]+$/) {
+ return $INVALID_VALUE;
+ }
+ $domain = untaint_var($domain); # will be in filename!
+ # got_hit() uses this
+ $self->{dns_block_rule}{$rule}{$domain} = 1;
+ # bgsend_and_start_lookup() uses this
+ $self->{dns_block_rule_domains}{$domain} = $domain;
+ }
+ }
+ });
+
+=item dns_block_time (default: 300)
+
+dns_block_rule query blockage will last this many seconds.
+
+=cut
+
+ push (@cmds, {
+ setting => 'dns_block_time',
+ is_admin => 1,
+ default => 60,
+ type => $CONF_TYPE_NUMERIC,
+ });
+
=back
=head2 LEARNING OPTIONS
@@ -5422,6 +5471,7 @@ sub feature_edns { 1 } # supports 'dns_
sub feature_dns_query_restriction { 1 } # supported config option
sub feature_registryboundaries { 1 } # replaces deprecated registrarboundaries
sub feature_geodb { 1 } # if needed for some reason
+sub feature_dns_block_rule { 1 } # supports 'dns_block_rule' config option
sub perl_min_version_5010000 { return $] >= 5.010000 } # perl version check ("perl_version" not neatly backwards-compatible)
###########################################################################
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm?rev=1842098&r1=1842097&r2=1842098&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/PerMsgStatus.pm Thu Sep 27 14:38:33 2018
@@ -2773,6 +2773,17 @@ sub got_hit {
}
}
+ # dns_block_rule
+ if (defined $conf_ref->{dns_block_rule}{$rule}) {
+ foreach my $domain (keys %{$conf_ref->{dns_block_rule}{$rule}}) {
+ my $blockfile =
+ $self->{main}->sed_path("__userstate__/dnsblock_$domain");
+ next if -f $blockfile; # no need to warn and create again..
+ warn("check: dns_block_rule $rule hit, creating $blockfile\n");
+ Mail::SpamAssassin::Util::touch_file($blockfile, { create_exclusive => 1 });
+ }
+ }
+
%{$self->{test_log_msgs}} = (); # clear test logs
return 1;
}