SPF: arrage flow so if a pass result is possible,
we will get it and set the note for DMARC plugin
This commit is contained in:
parent
effb4e2269
commit
c0210a7877
@ -296,9 +296,16 @@ sub get_organizational_domain {
|
|||||||
|
|
||||||
# $self->log( LOGINFO, "i: $i, $tld" );
|
# $self->log( LOGINFO, "i: $i, $tld" );
|
||||||
#warn "i: $i - tld: $tld\n";
|
#warn "i: $i - tld: $tld\n";
|
||||||
if (grep /$tld/, $self->qp->config('public_suffix_list')) {
|
if (grep /^$tld/, $self->qp->config('public_suffix_list')) {
|
||||||
$greatest = $i + 1;
|
$greatest = $i + 1;
|
||||||
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# check for wildcards (ex: *.uk should match co.uk)
|
||||||
|
$tld = join '.', '\*', reverse((@labels)[0 .. $i-1]);
|
||||||
|
if (grep /^$tld/, $self->qp->config('public_suffix_list')) {
|
||||||
|
$greatest = $i + 1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $from_host if $greatest == scalar @labels; # same
|
return $from_host if $greatest == scalar @labels; # same
|
||||||
@ -327,7 +334,16 @@ sub exists_in_dns {
|
|||||||
# Since this search gets repeated for the Organizational Name, if it
|
# Since this search gets repeated for the Organizational Name, if it
|
||||||
# fails for the O.N., there's no delegation from the TLD.
|
# fails for the O.N., there's no delegation from the TLD.
|
||||||
my $res = $self->init_resolver(8);
|
my $res = $self->init_resolver(8);
|
||||||
my $query = $res->query($domain, 'NS') or do {
|
return 1 if $self->host_has_rr('NS', $res, $domain);
|
||||||
|
return 1 if $self->host_has_rr('MX', $res, $domain);
|
||||||
|
return 1 if $self->host_has_rr('A', $res, $domain);
|
||||||
|
return 1 if $self->host_has_rr('AAAA', $res, $domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub host_has_rr {
|
||||||
|
my ($self, $type, $res, $domain) = @_;
|
||||||
|
|
||||||
|
my $query = $res->query($domain, $type) or do {
|
||||||
if ($res->errorstring eq 'NXDOMAIN') {
|
if ($res->errorstring eq 'NXDOMAIN') {
|
||||||
$self->log(LOGDEBUG, "fail, non-existent domain: $domain");
|
$self->log(LOGDEBUG, "fail, non-existent domain: $domain");
|
||||||
return;
|
return;
|
||||||
@ -337,14 +353,14 @@ sub exists_in_dns {
|
|||||||
};
|
};
|
||||||
my $matches = 0;
|
my $matches = 0;
|
||||||
for my $rr ($query->answer) {
|
for my $rr ($query->answer) {
|
||||||
next if $rr->type !~ /(?:NS|MX|A|AAAA)/;
|
next if $rr->type ne $type;
|
||||||
$matches++;
|
$matches++;
|
||||||
}
|
}
|
||||||
if (0 == $matches) {
|
if (0 == $matches) {
|
||||||
$self->log(LOGDEBUG, "fail, no records for $domain");
|
$self->log(LOGDEBUG, "no $type records for $domain");
|
||||||
}
|
}
|
||||||
return $matches;
|
return $matches;
|
||||||
}
|
};
|
||||||
|
|
||||||
sub fetch_dmarc_record {
|
sub fetch_dmarc_record {
|
||||||
my ($self, $zone) = @_;
|
my ($self, $zone) = @_;
|
||||||
|
@ -96,28 +96,17 @@ sub mail_handler {
|
|||||||
return (DECLINED, "SPF - null sender");
|
return (DECLINED, "SPF - null sender");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($self->qp->connection->relay_client) {
|
|
||||||
$self->log(LOGINFO, "skip, relay_client");
|
|
||||||
return (DECLINED, "SPF - relaying permitted");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$self->{_args}{reject}) {
|
|
||||||
$self->log(LOGINFO, "skip, reject disabled");
|
|
||||||
return (DECLINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
my $client_ip = $self->qp->connection->remote_ip;
|
|
||||||
my $from = $sender->user . '@' . lc($sender->host);
|
my $from = $sender->user . '@' . lc($sender->host);
|
||||||
my $helo = $self->qp->connection->hello_host;
|
my $helo = $self->qp->connection->hello_host;
|
||||||
my $scope = $from ? 'mfrom' : 'helo';
|
my $scope = $from ? 'mfrom' : 'helo';
|
||||||
my %req_params = (
|
my %req_params = (
|
||||||
versions => [1, 2], # optional
|
versions => [1, 2], # optional
|
||||||
scope => $scope,
|
scope => $scope,
|
||||||
ip_address => $client_ip,
|
ip_address => $self->qp->connection->remote_ip,
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($scope =~ /^mfrom|pra$/) {
|
if ($scope =~ /^mfrom|pra$/) {
|
||||||
$req_params{identity} = $from;
|
$req_params{identity} = $from;
|
||||||
$req_params{helo_identity} = $helo if $helo;
|
$req_params{helo_identity} = $helo if $helo;
|
||||||
}
|
}
|
||||||
elsif ($scope eq 'helo') {
|
elsif ($scope eq 'helo') {
|
||||||
@ -144,28 +133,24 @@ sub mail_handler {
|
|||||||
return (DECLINED, "SPF - no response");
|
return (DECLINED, "SPF - no response");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$reject) {
|
if ($code eq 'pass') {
|
||||||
$self->log(LOGINFO, "fail, no reject policy ($code: $why)");
|
|
||||||
return (DECLINED, "SPF - $code: $why");
|
|
||||||
}
|
|
||||||
|
|
||||||
# SPF result codes: pass fail softfail neutral none error permerror temperror
|
|
||||||
return $self->handle_code_none($reject, $why) if $code eq 'none';
|
|
||||||
if ($code eq 'fail') {
|
|
||||||
$self->adjust_karma(-1);
|
|
||||||
return $self->handle_code_fail($reject, $why);
|
|
||||||
}
|
|
||||||
elsif ($code eq 'softfail') {
|
|
||||||
$self->adjust_karma(-1);
|
|
||||||
return $self->handle_code_softfail($reject, $why);
|
|
||||||
}
|
|
||||||
elsif ($code eq 'pass') {
|
|
||||||
$self->adjust_karma(1);
|
$self->adjust_karma(1);
|
||||||
$transaction->notes('spf_pass_host', lc $sender->host);
|
$transaction->notes('spf_pass_host', lc $sender->host);
|
||||||
$self->log(LOGINFO, "pass, $code: $why");
|
$self->log(LOGINFO, "pass, $code: $why");
|
||||||
return (DECLINED);
|
return (DECLINED);
|
||||||
}
|
}
|
||||||
elsif ($code eq 'neutral') {
|
|
||||||
|
if (!$reject) {
|
||||||
|
$self->log(LOGINFO, "skip, tolerated ($code: $why)");
|
||||||
|
return (DECLINED, "SPF - $code: $why");
|
||||||
|
}
|
||||||
|
|
||||||
|
# SPF result codes: pass fail softfail neutral none error permerror temperror
|
||||||
|
return $self->handle_code_none($reject, $why) if $code eq 'none';
|
||||||
|
return $self->handle_code_fail($reject, $why) if $code eq 'fail';
|
||||||
|
return $self->handle_code_softfail($reject, $why) if $code eq 'softfail';
|
||||||
|
|
||||||
|
if ($code eq 'neutral') {
|
||||||
$self->log(LOGINFO, "fail, $code, $why");
|
$self->log(LOGINFO, "fail, $code, $why");
|
||||||
return (DENY, "SPF - $code: $why") if $reject >= 5;
|
return (DENY, "SPF - $code: $why") if $reject >= 5;
|
||||||
}
|
}
|
||||||
@ -196,33 +181,37 @@ sub handle_code_none {
|
|||||||
return (DENY, "SPF - none: $why");
|
return (DENY, "SPF - none: $why");
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->log(LOGINFO, "pass, none, $why");
|
$self->log(LOGINFO, "skip, tolerated, none, $why");
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub handle_code_fail {
|
sub handle_code_fail {
|
||||||
my ($self, $reject, $why) = @_;
|
my ($self, $reject, $why) = @_;
|
||||||
|
|
||||||
|
$self->adjust_karma(-1);
|
||||||
|
|
||||||
if ($reject >= 2) {
|
if ($reject >= 2) {
|
||||||
$self->log(LOGINFO, "fail, $why");
|
$self->log(LOGINFO, "fail, $why");
|
||||||
return (DENY, "SPF - forgery: $why") if $reject >= 3;
|
return (DENY, "SPF - forgery: $why") if $reject >= 3;
|
||||||
return (DENYSOFT, "SPF - fail: $why");
|
return (DENYSOFT, "SPF - fail: $why");
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->log(LOGINFO, "pass, fail tolerated, $why");
|
$self->log(LOGINFO, "fail, tolerated, $why");
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub handle_code_softfail {
|
sub handle_code_softfail {
|
||||||
my ($self, $reject, $why) = @_;
|
my ($self, $reject, $why) = @_;
|
||||||
|
|
||||||
|
$self->adjust_karma(-1);
|
||||||
|
|
||||||
if ($reject >= 3) {
|
if ($reject >= 3) {
|
||||||
$self->log(LOGINFO, "fail, soft, $why");
|
$self->log(LOGINFO, "fail, soft, $why");
|
||||||
return (DENY, "SPF - fail: $why") if $reject >= 4;
|
return (DENY, "SPF - fail: $why") if $reject >= 4;
|
||||||
return (DENYSOFT, "SPF - fail: $why") if $reject >= 3;
|
return (DENYSOFT, "SPF - fail: $why") if $reject >= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->log(LOGINFO, "pass, softfail tolerated, $why");
|
$self->log(LOGINFO, "fail, soft, tolerated, $why");
|
||||||
return DECLINED;
|
return DECLINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user