in lib/Mail/SpamAssassin/Plugin/HashBL.pm [529:637]
sub check_hashbl_emails {
my ($self, $pms, $list, $opts, $from, $subtest, $acl) = @_;
return 0 if !$self->{hashbl_available};
return 0 if !$pms->is_dns_available();
my $conf = $pms->{conf};
my $rulename = $pms->get_current_eval_rule_name();
if (!defined $list) {
warn "HashBL: $rulename blocklist argument missing\n";
return 0;
}
if (defined $acl && $acl ne 'all' && !exists $self->{hashbl_acl}{$acl}) {
warn "HashBL: $rulename acl '$acl' not defined\n";
return 0;
}
if ($subtest) {
my ($rec, $err) = compile_regexp($subtest, 0);
if (!$rec) {
warn "HashBL: $rulename invalid subtest regex: $@\n";
return 0;
}
$subtest = $rec;
}
# Parse opts, defaults
$opts = _parse_opts($opts || 'sha1/notag/noquote/max=10/shuffle');
$from = 'ALLFROM/Reply-To/body' if !$from;
# Find all emails
my $emails = $self->_get_emails($pms, $opts, $from, $acl);
if (!@$emails) {
if (defined $acl) {
dbg("$rulename: no emails found ($from) on acl $acl");
} else {
dbg("$rulename: no emails found ($from)");
}
return 0;
} else {
dbg("$rulename: raw emails found: ".join(', ', @$emails));
}
# Filter list
my @filtered_emails; # keep order
my %seen;
foreach my $email (@$emails) {
next if $seen{$email}++;
if (exists $pms->{hashbl_welcomelist}{$email} ||
$email =~ $conf->{hashbl_email_welcomelist})
{
dbg("query skipped, address welcomelisted: $email");
next;
}
my ($username, $domain) = ($email =~ /(.*)\@(.*)/);
if(not defined $opts->{alldomains}) {
if (exists $conf->{uridnsbl_skip_domains}->{lc $domain}) {
dbg("query skipped, uridnsbl_skip_domains: $email");
next;
}
my $dom = $pms->{main}->{registryboundaries}->trim_domain($domain);
if (exists $conf->{uridnsbl_skip_domains}->{lc $dom}) {
dbg("query skipped, uridnsbl_skip_domains: $email");
next;
}
}
$username =~ tr/.//d if $opts->{nodot};
$username =~ s/\+.*// if $opts->{notag};
# Final query assembly
my $qmail;
if ($opts->{host} || $opts->{domain}) {
if ($opts->{domain}) {
$domain = $pms->{main}->{registryboundaries}->trim_domain($domain);
}
$qmail = $domain;
} elsif ($opts->{user}) {
$qmail = $username;
} else {
$qmail = $username.'@'.$domain;
}
$qmail = lc $qmail if !$opts->{case};
push @filtered_emails, $qmail;
}
return 0 unless @filtered_emails;
# Unique
@filtered_emails = do { my %seen; grep { !$seen{$_}++ } @filtered_emails; };
# Randomize order
if ($opts->{shuffle}) {
Mail::SpamAssassin::Util::fisher_yates_shuffle(\@filtered_emails);
}
# Truncate list
my $max = $opts->{max} || 10;
$#filtered_emails = $max-1 if scalar @filtered_emails > $max;
my $queries;
foreach my $email (@filtered_emails) {
my $ret = $self->_submit_query($pms, $rulename, $email, $list, $opts, $subtest);
$queries++ if defined $ret;
}
return 0 if !$queries; # no query started
return; # return undef for async status
}