You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by gb...@apache.org on 2023/03/29 14:17:43 UTC

svn commit: r1908779 - in /spamassassin/trunk: MANIFEST lib/Mail/SpamAssassin/Plugin/DMARC.pm rules/v401.pre

Author: gbechis
Date: Wed Mar 29 14:17:43 2023
New Revision: 1908779

URL: http://svn.apache.org/viewvc?rev=1908779&view=rev
Log:
If Mail::SpamAssassin::Plugin::AuthRes is available and DMARC fails, re-evaluate DMARC policies
accordingly

Added:
    spamassassin/trunk/rules/v401.pre
Modified:
    spamassassin/trunk/MANIFEST
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm

Modified: spamassassin/trunk/MANIFEST
URL: http://svn.apache.org/viewvc/spamassassin/trunk/MANIFEST?rev=1908779&r1=1908778&r2=1908779&view=diff
==============================================================================
--- spamassassin/trunk/MANIFEST (original)
+++ spamassassin/trunk/MANIFEST Wed Mar 29 14:17:43 2023
@@ -152,6 +152,7 @@ rules/v341.pre
 rules/v342.pre
 rules/v343.pre
 rules/v400.pre
+rules/v401.pre
 rules/20_aux_tlds.cf
 rules-extras/README.txt
 rules-extras/10_uridnsbl_skip_financial.cf

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm?rev=1908779&r1=1908778&r2=1908779&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/DMARC.pm Wed Mar 29 14:17:43 2023
@@ -326,6 +326,71 @@ sub _check_dmarc {
     return;
   }
 
+  my $dmarc_arc_verified = 0;
+  if (($result->result ne 'pass') and (ref($pms->{arc_verifier}) and ($pms->{arc_verifier}->result))) {
+    undef $result;
+    $dmarc_arc_verified = 1;
+    # if DMARC fails retry by reading data from AAR headers
+    # use Mail::SpamAssassin::Plugin::AuthRes if available to read ARC signature details
+    my @spf_parsed = sort { ( $a->{authres_parsed}{spf}{arc_index} // 0 ) <=> ( $b->{authres_parsed}{spf}{arc_index} // 0 ) } @{$pms->{authres_parsed}{spf}};
+    my $old_arc_index = 0;
+    foreach my $spf_parse ( @spf_parsed ) {
+      last if not defined $spf_parse->{arc_index};
+      last if $old_arc_index > $spf_parse->{arc_index};
+      dbg("Evaluate DMARC using AAR spf information for index $spf_parse->{arc_index}");
+      if(exists $spf_parse->{properties}{smtp}{mailfrom}) {
+        my $mfrom_dom = $spf_parse->{properties}{smtp}{mailfrom};
+        if($mfrom_dom =~ /\@(.*)/) {
+          $mfrom_dom = $1;
+        }
+        $dmarc->spf([
+          {
+            scope  => 'mfrom',
+            domain => $mfrom_dom,
+            result => $spf_parse->{result},
+          }
+        ]);
+      }
+      if(exists $spf_parse->{properties}{smtp}{helo}) {
+        $dmarc->spf([
+          {
+            scope  => 'helo',
+            domain => $spf_parse->{properties}{smtp}{helo},
+            result => $spf_parse->{result},
+          }
+        ]);
+      }
+      $old_arc_index = $spf_parse->{arc_index};
+    }
+
+    my @arc_seals = sort { ( $a->{arc_verifier}{seals}{tags_by_name}{i}{value} // 0 ) <=> ( $b->{arc_verifier}{seals}{tags_by_name}{i}{value} // 0 ) } @{$pms->{arc_verifier}{seals}};
+    foreach my $seals ( @arc_seals ) {
+      if(exists($seals->{tags_by_name}{d}) and exists($pms->{arc_author_domains}->{$mfrom_domain})) {
+        dbg("Evaluate DMARC using AAR dkim information for index $seals->{tags_by_name}{i}{value}");
+        $dmarc->dkim(domain => $mfrom_domain, selector => $seals->{tags_by_name}{s}{value}, result => $seals->{verify_result});
+        last;
+      }
+    }
+
+    eval { $result = $dmarc->validate(); };
+  }
+
+  # Report that DMARC failed but it has been overridden because of AAR headers
+  if(ref($pms->{arc_verifier}) and ($pms->{arc_verifier}->result) and ($dmarc_arc_verified)) {
+    $result->reason->[0]{type} = 'local_policy';
+    $result->reason->[0]{comment} = "arc=" . $pms->{arc_verifier}->result;
+    my $cnt = 1;
+    foreach my $seals ( @{$pms->{arc_verifier}{seals}} ) {
+      if(exists($seals->{tags_by_name}{d}) and exists($seals->{tags_by_name}{s})) {
+        $result->reason->[0]{comment} .= " as[$cnt].d=$seals->{tags_by_name}{d}{value} as[$cnt].s=$seals->{tags_by_name}{s}{value}";
+        $cnt++;
+      }
+    }
+    if($cnt gt 1) {
+      $result->reason->[0]{comment} .= " remote-ip[1]=$lasthop->{ip}";
+    }
+  }
+
   if (defined($pms->{dmarc_result} = $result->result)) {
     if ($pms->{conf}->{dmarc_save_reports}) {
       my $rua = eval { $result->published()->rua(); };

Added: spamassassin/trunk/rules/v401.pre
URL: http://svn.apache.org/viewvc/spamassassin/trunk/rules/v401.pre?rev=1908779&view=auto
==============================================================================
--- spamassassin/trunk/rules/v401.pre (added)
+++ spamassassin/trunk/rules/v401.pre Wed Mar 29 14:17:43 2023
@@ -0,0 +1,24 @@
+# This is the right place to customize your installation of SpamAssassin.
+#
+# See 'perldoc Mail::SpamAssassin::Conf' for details of what can be
+# tweaked.
+#
+# This file was installed during the installation of SpamAssassin 4.0.0,
+# and contains plugin loading commands for the new plugins added in that
+# release.  It will not be overwritten during future SpamAssassin installs,
+# so you can modify it to enable some disabled-by-default plugins below,
+# if you so wish.
+#
+# There are now multiple files read to enable plugins in the
+# /etc/mail/spamassassin directory; previously only one, "init.pre" was
+# read.  Now both "init.pre", "v310.pre", and any other files ending in
+# ".pre" will be read.  As future releases are made, new plugins will be
+# added to new files, named according to the release they're added in.
+###########################################################################
+
+# AuthRes - use Authentication-Results header fields
+#
+# This plugin parses Authentication-Results header fields and can supply
+# the results obtained to other plugins.
+#
+# loadplugin Mail::SpamAssassin::Plugin::AuthRes