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/10/19 10:20:18 UTC

svn commit: r1844324 - in /spamassassin/trunk: INSTALL UPGRADE lib/Mail/SpamAssassin/Plugin/SPF.pm t/spf.t

Author: hege
Date: Fri Oct 19 10:20:17 2018
New Revision: 1844324

URL: http://svn.apache.org/viewvc?rev=1844324&view=rev
Log:
Bug 7261 - deprecate Mail::SPF::Query use

Modified:
    spamassassin/trunk/INSTALL
    spamassassin/trunk/UPGRADE
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm
    spamassassin/trunk/t/spf.t

Modified: spamassassin/trunk/INSTALL
URL: http://svn.apache.org/viewvc/spamassassin/trunk/INSTALL?rev=1844324&r1=1844323&r2=1844324&view=diff
==============================================================================
--- spamassassin/trunk/INSTALL (original)
+++ spamassassin/trunk/INSTALL Fri Oct 19 10:20:17 2018
@@ -357,8 +357,7 @@ version is too low for them to be used.
   - Mail::SPF (from CPAN)
 
     Used to check DNS Sender Policy Framework (SPF) records to fight email
-    address forgery and make it easier to identify spams.  This module
-    makes Mail::SPF::Query obsolete.
+    address forgery and make it easier to identify spams.
 
     Net::DNS version 0.58 or higher is required.
 

Modified: spamassassin/trunk/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/trunk/UPGRADE?rev=1844324&r1=1844323&r2=1844324&view=diff
==============================================================================
--- spamassassin/trunk/UPGRADE (original)
+++ spamassassin/trunk/UPGRADE Fri Oct 19 10:20:17 2018
@@ -62,6 +62,12 @@ Note for Users Upgrading to SpamAssassin
   bgsend_and_start_lookup should always contain $ent->{rulename} for correct
   meta dependency handling.
 
+- SPF: Mail::SPF is now only supported.  Mail::SPF::Query use is deprecated,
+  along with settings do_not_use_mail_spf, do_not_use_mail_spf_query.  SPF
+  lookups are not done asyncronously, for best throughput one should use MTA
+  filter (pypolicyd-spf / spf-engine etc), from which generated Received-SPF
+  header can be parsed by SpamAssassin.
+
 Note for Users Upgrading to SpamAssassin 3.4.2
 ----------------------------------------------
 

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm?rev=1844324&r1=1844323&r2=1844324&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/SPF.pm Fri Oct 19 10:20:17 2018
@@ -29,6 +29,11 @@ This plugin checks a message against Sen
 records published by the domain owners in DNS to fight email address
 forgery and make it easier to identify spams.
 
+It's recommended to use MTA filter (pypolicyd-spf / spf-engine etc), so this
+plugin can reuse the Received-SPF header results as is.  Otherwise
+throughput could suffer, DNS lookups done by this plugin are not
+asynchronous.
+
 =cut
 
 package Mail::SpamAssassin::Plugin::SPF;
@@ -147,38 +152,6 @@ days, weeks).
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_DURATION
   });
 
-=item do_not_use_mail_spf (0|1)		(default: 0)
-
-By default the plugin will try to use the Mail::SPF module for SPF checks if
-it can be loaded.  If Mail::SPF cannot be used the plugin will fall back to
-using the legacy Mail::SPF::Query module if it can be loaded.
-
-Use this option to stop the plugin from using Mail::SPF and cause it to try to
-use Mail::SPF::Query instead.
-
-=cut
-
-  push(@cmds, {
-    setting => 'do_not_use_mail_spf',
-    is_admin => 1,
-    default => 0,
-    type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
-  });
-
-=item do_not_use_mail_spf_query (0|1)	(default: 0)
-
-As above, but instead stop the plugin from trying to use Mail::SPF::Query and
-cause it to only try to use Mail::SPF.
-
-=cut
-
-  push(@cmds, {
-    setting => 'do_not_use_mail_spf_query',
-    is_admin => 1,
-    default => 0,
-    type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
-  });
-
 =item ignore_received_spf_header (0|1)	(default: 0)
 
 By default, to avoid unnecessary DNS lookups, the plugin will try to use the
@@ -224,10 +197,23 @@ working downwards until results are succ
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
   });
 
+  # Deprecated since 4.0.0, leave for backwards compatibility
+  push(@cmds, {
+    setting => 'do_not_use_mail_spf',
+    is_admin => 1,
+    default => 0,
+    type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
+  });
+  push(@cmds, {
+    setting => 'do_not_use_mail_spf_query',
+    is_admin => 1,
+    default => 1,
+    type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
+  });
+
   $conf->{parser}->register_commands(\@cmds);
 }
 
-
 =item has_check_for_spf_errors
 
 Adds capability check for "if can()" for check_for_spf_permerror, check_for_spf_temperror, check_for_spf_helo_permerror and check_for_spf_helo_permerror
@@ -498,8 +484,6 @@ sub _check_spf {
   unless (defined $self->{has_mail_spf}) {
     my $eval_stat;
     eval {
-      die("Mail::SPF disabled by admin setting\n") if $scanner->{conf}->{do_not_use_mail_spf};
-
       require Mail::SPF;
       if (!defined $Mail::SPF::VERSION || $Mail::SPF::VERSION < 2.001) {
 	die "Mail::SPF 2.001 or later required, this is ".
@@ -521,39 +505,13 @@ sub _check_spf {
       dbg("spf: using Mail::SPF for SPF checks");
       $self->{has_mail_spf} = 1;
     } else {
-      # strip the @INC paths... users are going to see it and think there's a problem even though
-      # we're going to fall back to Mail::SPF::Query (which will display the same paths if it fails)
-      $eval_stat =~ s#^Can't locate Mail/SPFd.pm in \@INC .*#Can't locate Mail/SPFd.pm#;
-      dbg("spf: cannot load Mail::SPF module or create Mail::SPF::Server object: $eval_stat");
-      dbg("spf: attempting to use legacy Mail::SPF::Query module instead");
-
-      undef $eval_stat;
-      eval {
-	die("Mail::SPF::Query disabled by admin setting\n") if $scanner->{conf}->{do_not_use_mail_spf_query};
-
-	require Mail::SPF::Query;
-	if (!defined $Mail::SPF::Query::VERSION || $Mail::SPF::Query::VERSION < 1.996) {
-	  die "Mail::SPF::Query 1.996 or later required, this is ".
-	    (defined $Mail::SPF::Query::VERSION ? $Mail::SPF::Query::VERSION : 'unknown')."\n";
-	}
-        1;
-      } or do {
-        $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
-      };
-
-      if (!defined($eval_stat)) {
-	dbg("spf: using Mail::SPF::Query for SPF checks");
-	$self->{has_mail_spf} = 0;
-      } else {
-	dbg("spf: cannot load Mail::SPF::Query module: $eval_stat");
-	dbg("spf: one of Mail::SPF or Mail::SPF::Query is required for SPF checks, SPF checks disabled");
-	$self->{no_spf_module} = 1;
-	return;
-      }
+      dbg("spf: cannot load Mail::SPF: module: $eval_stat");
+      dbg("spf: Mail::SPF is required for SPF checks, SPF checks disabled");
+      $self->{no_spf_module} = 1;
+      return;
     }
   }
 
-
   # skip SPF checks if the A/MX records are nonexistent for the From
   # domain, anyway, to avoid crappy messages from slowing us down
   # (bug 3016)
@@ -632,81 +590,39 @@ sub _check_spf {
 
   my ($result, $comment, $text, $err);
 
-  # use Mail::SPF if it was available, otherwise use the legacy Mail::SPF::Query
-  if ($self->{has_mail_spf}) {
-
-    # TODO: currently we won't get to here for a mfrom check with a null sender
-    my $identity = $ishelo ? $helo : ($scanner->{sender}); # || $helo);
-
-    unless ($identity) {
-      dbg("spf: cannot determine %s identity, skipping %s SPF check",
-          ($ishelo ? 'helo' : 'mfrom'),  ($ishelo ? 'helo' : 'mfrom') );
-      return;
-    }
-    $helo ||= 'unknown';  # only used for macro expansion in the mfrom explanation
-
-    my $request;
-    eval {
-      $request = Mail::SPF::Request->new( scope         => $ishelo ? 'helo' : 'mfrom',
-					  identity      => $identity,
-					  ip_address    => $ip,
-					  helo_identity => $helo );
-      1;
-    } or do {
-      my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
-      dbg("spf: cannot create Mail::SPF::Request object: $eval_stat");
-      return;
-    };
-
-    my $timeout = $scanner->{conf}->{spf_timeout};
-
-    my $timer = Mail::SpamAssassin::Timeout->new(
-                { secs => $timeout, deadline => $scanner->{master_deadline} });
-    $err = $timer->run_and_catch(sub {
-
-      my $query = $self->{spf_server}->process($request);
-
-      $result = $query->code;
-      $comment = $query->authority_explanation if $query->can("authority_explanation");
-      $text = $query->text;
-
-    });
+  # TODO: currently we won't get to here for a mfrom check with a null sender
+  my $identity = $ishelo ? $helo : ($scanner->{sender}); # || $helo);
 
+  unless ($identity) {
+    dbg("spf: cannot determine %s identity, skipping %s SPF check",
+        ($ishelo ? 'helo' : 'mfrom'),  ($ishelo ? 'helo' : 'mfrom') );
+    return;
+  }
+  $helo ||= 'unknown';  # only used for macro expansion in the mfrom explanation
 
-  } else {
-
-    if (!$helo) {
-      dbg("spf: cannot get HELO, cannot use Mail::SPF::Query, consider installing Mail::SPF");
-      return;
-    }
-
-    # TODO: if we start doing checks on the null sender using the helo domain
-    # be sure to fix this so that it uses the correct sender identity
-    my $query;
-    eval {
-      $query = Mail::SPF::Query->new (ip => $ip,
-				    sender => $scanner->{sender},
-				    helo => $helo,
-				    debug => 0,
-				    trusted => 0);
-      1;
-    } or do {
-      my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
-      dbg("spf: cannot create Mail::SPF::Query object: $eval_stat");
-      return;
-    };
-
-    my $timeout = $scanner->{conf}->{spf_timeout};
-
-    my $timer = Mail::SpamAssassin::Timeout->new(
-                { secs => $timeout, deadline => $scanner->{master_deadline} });
-    $err = $timer->run_and_catch(sub {
-
-      ($result, $comment) = $query->result();
+  my $request;
+  eval {
+    $request = Mail::SPF::Request->new( scope         => $ishelo ? 'helo' : 'mfrom',
+			  identity      => $identity,
+			  ip_address    => $ip,
+			  helo_identity => $helo );
+    1;
+  } or do {
+    my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
+    dbg("spf: cannot create Mail::SPF::Request object: $eval_stat");
+    return;
+  };
 
-    });
+  my $timeout = $scanner->{conf}->{spf_timeout};
 
-  } # end of differences between Mail::SPF and Mail::SPF::Query
+  my $timer_spf = Mail::SpamAssassin::Timeout->new(
+              { secs => $timeout, deadline => $scanner->{master_deadline} });
+  $err = $timer_spf->run_and_catch(sub {
+    my $query = $self->{spf_server}->process($request);
+    $result = $query->code;
+    $comment = $query->authority_explanation if $query->can("authority_explanation");
+    $text = $query->text;
+  });
 
   if ($err) {
     chomp $err;
@@ -714,7 +630,6 @@ sub _check_spf {
     return 0;
   }
 
-
   $result ||= 'timeout';	# bug 5077
   $comment ||= '';
   $comment =~ s/\s+/ /gs;	# no newlines please

Modified: spamassassin/trunk/t/spf.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/spf.t?rev=1844324&r1=1844323&r2=1844324&view=diff
==============================================================================
--- spamassassin/trunk/t/spf.t (original)
+++ spamassassin/trunk/t/spf.t Fri Oct 19 10:20:17 2018
@@ -4,34 +4,14 @@ use lib '.'; use lib 't';
 use SATest; sa_t_init("spf");
 use Test::More;
 
-use constant HAS_SPFQUERY => eval { require Mail::SPF::Query; };
 use constant HAS_MAILSPF => eval { require Mail::SPF; };
 
-# bug 3806:
-# Do not run this test with version of Sys::Hostname::Long older than 1.4
-# on non-Linux unices as root, due to a bug in Sys::Hostname::Long
-# (it is used by Mail::SPF::Query, which is now obsoleted by Mail::SPF)
-use constant IS_LINUX   => $^O eq 'linux';
-use constant IS_OPENBSD => $^O eq 'openbsd';
-use constant IS_WINDOWS => ($^O =~ /^(mswin|dos|os2)/i);
-use constant AM_ROOT    => $< == 0;
-
-use constant HAS_UNSAFE_HOSTNAME =>  # Bug 3806 - module exists and is old
-  eval { require Sys::Hostname::Long && Sys::Hostname::Long->VERSION < 1.4 };
-
 plan skip_all => "Long running tests disabled" unless conf_bool('run_long_tests');
 plan skip_all => "Net tests disabled" unless conf_bool('run_net_tests');
-plan skip_all => "Need Mail::SPF or Mail::SPF::Query" unless (HAS_SPFQUERY || HAS_MAILSPF);
-plan skip_all => "root required" unless AM_ROOT;
-plan skip_all => "Sys::Hostname::Long > 1.4 required." if HAS_UNSAFE_HOSTNAME;
-plan skip_all => "Test only designed for Windows, Linux or OpenBSD" unless (IS_LINUX || IS_OPENBSD || IS_WINDOWS);
+plan skip_all => "Need Mail::SPF" unless HAS_MAILSPF;
+plan skip_all => "Can't use Net::DNS Safely" unless can_use_net_dns_safely();
 
-if(HAS_SPFQUERY && HAS_MAILSPF) {
-  plan tests => 106;
-}
-else {
-  plan tests => 58; # TODO: These should be skips down in the code, not changing the test count.
-}
+plan tests => 56;
 
 # ---------------------------------------------------------------------------
 
@@ -49,369 +29,329 @@ tstlocalrules ("
   score USER_IN_SPF_WHITELIST -0.001
 ");
 
-# test both of the SPF modules we support
-for $disable_an_spf_module ('do_not_use_mail_spf 1', 'do_not_use_mail_spf_query 1') {
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
-  # only do the tests if the module that wasn't disabled is available
-  next if ($disable_an_spf_module eq 'do_not_use_mail_spf 1' && !HAS_SPFQUERY);
-  next if ($disable_an_spf_module eq 'do_not_use_mail_spf_query 1' && !HAS_MAILSPF);
-
-  tstprefs("
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
+sarun ("-t < data/nice/spf1", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/nice/spf1", \&patterns_run_cb);
-  ok_all_patterns();
+%patterns = (
+  q{ SPF_NEUTRAL }, 'neutral',
+  q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
+);
 
-  %patterns = (
-    q{ SPF_NEUTRAL }, 'neutral',
-    q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
-  );
+sarun ("-t < data/spam/spf1", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/spam/spf1", \&patterns_run_cb);
-  ok_all_patterns();
+%patterns = (
+  q{ SPF_SOFTFAIL }, 'softfail',
+  q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
+);
 
-  %patterns = (
-    q{ SPF_SOFTFAIL }, 'softfail',
-    q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
-  );
+sarun ("-t < data/spam/spf2", \&patterns_run_cb);
+ok_all_patterns();
+%patterns = (
+  q{ SPF_FAIL }, 'fail',
+  q{ SPF_HELO_FAIL }, 'helo_fail',
+);
 
-  sarun ("-t < data/spam/spf2", \&patterns_run_cb);
-  ok_all_patterns();
-  %patterns = (
-    q{ SPF_FAIL }, 'fail',
-    q{ SPF_HELO_FAIL }, 'helo_fail',
-  );
+sarun ("-t < data/spam/spf3", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/spam/spf3", \&patterns_run_cb);
-  ok_all_patterns();
 
+# Test using an assortment of trusted and internal network definitions
 
-  # Test using an assortment of trusted and internal network definitions
+# 9-10: Trusted networks contain first header.
 
-  # 9-10: Trusted networks contain first header.
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.157
+  always_trust_envelope_sender 1
+");
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.157
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
+
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-  ok_all_patterns();
 
+# 11-12: Internal networks contain first header.
+#	   Trusted networks not defined.
 
-  # 11-12: Internal networks contain first header.
-  #	   Trusted networks not defined.
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  internal_networks 65.214.43.157
+  always_trust_envelope_sender 1
+");
+
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    internal_networks 65.214.43.157
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-  ok_all_patterns();
 
+# 13-14: Internal networks contain first header.
+#	   Trusted networks contain some other IP.
+#        jm: commented; this is now an error condition.
+
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 1.2.3.4
+  internal_networks 65.214.43.157
+  always_trust_envelope_sender 1
+");
 
-  # 13-14: Internal networks contain first header.
-  #	   Trusted networks contain some other IP.
-  #        jm: commented; this is now an error condition.
-
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 1.2.3.4
-    internal_networks 65.214.43.157
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
-    q{ SPF_NEUTRAL }, 'neutral',
-  );
-
-  if (0) {
-    sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-    ok_all_patterns();
-  } else {
-    ok(1);        # skip the tests
-    ok(1);
-  }
-
-
-  # 15-16: Trusted+Internal networks contain first header.
-
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.157
-    internal_networks 65.214.43.157
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
+%patterns = (
+  q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
+  q{ SPF_NEUTRAL }, 'neutral',
+);
 
+if (0) {
   sarun ("-t < data/nice/spf2", \&patterns_run_cb);
   ok_all_patterns();
+} else {
+  ok(1);        # skip the tests
+  ok(1);
+}
 
 
-  # 17-18: Trusted networks contain first and second header.
-  #	   Internal networks contain first header.
+# 15-16: Trusted+Internal networks contain first header.
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.157 64.142.3.173
-    internal_networks 65.214.43.157
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.157
+  internal_networks 65.214.43.157
+  always_trust_envelope_sender 1
+");
 
-  sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-  ok_all_patterns();
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  # 19-26: Trusted networks contain first and second header.
-  #	   Internal networks contain first and second header.
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.157 64.142.3.173
-    internal_networks 65.214.43.157 64.142.3.173
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_HELO_FAIL }, 'helo_fail',
-    q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
-    q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
-    q{ SPF_PASS }, 'pass',
-    q{ SPF_FAIL }, 'fail',
-    q{ SPF_SOFTFAIL }, 'softfail',
-    q{ SPF_NEUTRAL }, 'neutral',
-  );
-  %patterns = ();
+# 17-18: Trusted networks contain first and second header.
+#	   Internal networks contain first header.
 
-  sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-  ok_all_patterns();
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.157 64.142.3.173
+  internal_networks 65.214.43.157
+  always_trust_envelope_sender 1
+");
 
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
-  # 27-28: Trusted networks contain first header.
-  #	   Internal networks contain first and second header.
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.157
-    internal_networks 65.214.43.157 64.142.3.173
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = ();
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
 
-  sarun ("-t < data/nice/spf2", \&patterns_run_cb);
-  ok_all_patterns();
+# 19-26: Trusted networks contain first and second header.
+#	   Internal networks contain first and second header.
+
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.157 64.142.3.173
+  internal_networks 65.214.43.157 64.142.3.173
+  always_trust_envelope_sender 1
+");
 
+%anti_patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_HELO_FAIL }, 'helo_fail',
+  q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
+  q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
+  q{ SPF_PASS }, 'pass',
+  q{ SPF_FAIL }, 'fail',
+  q{ SPF_SOFTFAIL }, 'softfail',
+  q{ SPF_NEUTRAL }, 'neutral',
+);
+%patterns = ();
 
-  # 29-30: Trusted networks contain top 5 headers.
-  #	   Internal networks contain first header.
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
-    internal_networks 65.214.43.158
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = ();
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
 
-  sarun ("-t < data/nice/spf3", \&patterns_run_cb);
-  ok_all_patterns();
+# 27-28: Trusted networks contain first header.
+#	   Internal networks contain first and second header.
 
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.157
+  internal_networks 65.214.43.157 64.142.3.173
+  always_trust_envelope_sender 1
+");
 
-  # 31-32: Trusted networks contain top 5 headers.
-  #	   Internal networks contain top 2 headers.
+%anti_patterns = ();
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
-    internal_networks 65.214.43.158 64.142.3.173
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = ();
-  %patterns = (
-    q{ SPF_HELO_FAIL }, 'helo_fail',
-    q{ SPF_FAIL }, 'fail',
-  );
+sarun ("-t < data/nice/spf2", \&patterns_run_cb);
+ok_all_patterns();
 
-  sarun ("-t < data/nice/spf3", \&patterns_run_cb);
-  ok_all_patterns();
 
+# 29-30: Trusted networks contain top 5 headers.
+#	   Internal networks contain first header.
 
-  # 33-34: Trusted networks contain top 5 headers.
-  #	   Internal networks contain top 3 headers.
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
+  internal_networks 65.214.43.158
+  always_trust_envelope_sender 1
+");
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
-    internal_networks 65.214.43.158 64.142.3.173 65.214.43.155
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = ();
-  %patterns = (
-    q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
-    q{ SPF_SOFTFAIL }, 'softfail',
-  );
+%anti_patterns = ();
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
 
-  sarun ("-t < data/nice/spf3", \&patterns_run_cb);
-  ok_all_patterns();
+sarun ("-t < data/nice/spf3", \&patterns_run_cb);
+ok_all_patterns();
 
 
-  # 35-36: Trusted networks contain top 5 headers.
-  #	   Internal networks contain top 4 headers.	
+# 31-32: Trusted networks contain top 5 headers.
+#	   Internal networks contain top 2 headers.
 
-  tstprefs("
-    clear_trusted_networks
-    clear_internal_networks
-    trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
-    internal_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156
-    always_trust_envelope_sender 1
-    $disable_an_spf_module
-  ");
-
-  %anti_patterns = ();
-  %patterns = (
-    q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
-    q{ SPF_NEUTRAL }, 'neutral',
-  );
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
+  internal_networks 65.214.43.158 64.142.3.173
+  always_trust_envelope_sender 1
+");
 
-  sarun ("-t < data/nice/spf3", \&patterns_run_cb);
-  ok_all_patterns();
+%anti_patterns = ();
+%patterns = (
+  q{ SPF_HELO_FAIL }, 'helo_fail',
+  q{ SPF_FAIL }, 'fail',
+);
 
+sarun ("-t < data/nice/spf3", \&patterns_run_cb);
+ok_all_patterns();
 
-  # 37-40: same as test 1-2 with some spf whitelisting added
 
-  tstprefs("
-    whitelist_from_spf newsalerts-noreply\@dnsbltest.spamassassin.org
-    def_whitelist_from_spf *\@dnsbltest.spamassassin.org
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-    q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
-    q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
-  );
+# 33-34: Trusted networks contain top 5 headers.
+#	   Internal networks contain top 3 headers.
 
-  sarun ("-t < data/nice/spf1", \&patterns_run_cb);
-  ok_all_patterns();
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
+  internal_networks 65.214.43.158 64.142.3.173 65.214.43.155
+  always_trust_envelope_sender 1
+");
 
+%anti_patterns = ();
+%patterns = (
+  q{ SPF_HELO_SOFTFAIL }, 'helo_softfail',
+  q{ SPF_SOFTFAIL }, 'softfail',
+);
 
-  # 41-44: same as test 1-2 with some spf whitelist entires that don't match
+sarun ("-t < data/nice/spf3", \&patterns_run_cb);
+ok_all_patterns();
 
-  tstprefs("
-    whitelist_from_spf *\@example.com
-    def_whitelist_from_spf nothere\@dnsbltest.spamassassin.org
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-  );
-
-  %anti_patterns = (
-    q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
-    q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
-  );
 
-  sarun ("-t < data/nice/spf1", \&patterns_run_cb);
-  ok_all_patterns();
+# 35-36: Trusted networks contain top 5 headers.
+#	   Internal networks contain top 4 headers.	
 
-  # clear these out before we loop
-  %anti_patterns = ();
-  %patterns = ();
-
-
-  # 45-48: same as test 37-40 with whitelist_auth added
-
-  tstprefs("
-    whitelist_auth newsalerts-noreply\@dnsbltest.spamassassin.org
-    def_whitelist_auth *\@dnsbltest.spamassassin.org
-    $disable_an_spf_module
-  ");
-
-  %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
-    q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
-    q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
-  );
+tstprefs("
+  clear_trusted_networks
+  clear_internal_networks
+  trusted_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156 65.214.43.157
+  internal_networks 65.214.43.158 64.142.3.173 65.214.43.155 65.214.43.156
+  always_trust_envelope_sender 1
+");
 
-  sarun ("-t < data/nice/spf1", \&patterns_run_cb);
-  ok_all_patterns();
+%anti_patterns = ();
+%patterns = (
+  q{ SPF_HELO_NEUTRAL }, 'helo_neutral',
+  q{ SPF_NEUTRAL }, 'neutral',
+);
+
+sarun ("-t < data/nice/spf3", \&patterns_run_cb);
+ok_all_patterns();
+
+
+# 37-40: same as test 1-2 with some spf whitelisting added
+
+tstprefs("
+  whitelist_from_spf newsalerts-noreply\@dnsbltest.spamassassin.org
+  def_whitelist_from_spf *\@dnsbltest.spamassassin.org
+");
+
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+  q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
+  q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
+);
+
+sarun ("-t < data/nice/spf1", \&patterns_run_cb);
+ok_all_patterns();
 
-} # for each SPF module
 
+# 41-44: same as test 1-2 with some spf whitelist entires that don't match
 
-# test to see if the plugin will select an SPF module on its own
+tstprefs("
+  whitelist_from_spf *\@example.com
+  def_whitelist_from_spf nothere\@dnsbltest.spamassassin.org
+");
 
-tstprefs("");
+%patterns = (
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+);
+
+%anti_patterns = (
+  q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
+  q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
+);
+
+sarun ("-t < data/nice/spf1", \&patterns_run_cb);
+ok_all_patterns();
+
+# clear these out before we loop
+%anti_patterns = ();
+%patterns = ();
+
+
+# 45-48: same as test 37-40 with whitelist_auth added
+
+tstprefs("
+  whitelist_auth newsalerts-noreply\@dnsbltest.spamassassin.org
+  def_whitelist_auth *\@dnsbltest.spamassassin.org
+");
 
 %patterns = (
-    q{ SPF_HELO_PASS }, 'helo_pass',
-    q{ SPF_PASS }, 'pass',
+  q{ SPF_HELO_PASS }, 'helo_pass',
+  q{ SPF_PASS }, 'pass',
+  q{ USER_IN_SPF_WHITELIST }, 'spf_whitelist',
+  q{ USER_IN_DEF_SPF_WL }, 'default_spf_whitelist',
 );
 
 sarun ("-t < data/nice/spf1", \&patterns_run_cb);