Fix CVE-2016-1531
[exim.git] / test / runtest
index 421e0b3805d3c7db1208eac502f56e0b75541b13..a05bc48edefbba672f60d34a3079d4fc42cbce8f 100755 (executable)
@@ -339,7 +339,7 @@ $spid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
 # that are specific to certain file types, though there are also some of those
 # inline too.
 
-while(<IN>)
+LINE: while(<IN>)
   {
 RESET_AFTER_EXTRA_LINE_READ:
   # Custom munges
@@ -485,12 +485,15 @@ RESET_AFTER_EXTRA_LINE_READ:
   s/\d\d-[A-Z][a-z]{2}-\d{4}\s\d\d:\d\d:\d\d/07-Mar-2000 12:21:52/g;
 
   # Time on queue tolerance
-  s/QT=1s/QT=0s/;
+  s/(QT|D)=1s/$1=0s/;
 
   # Eximstats heading
   s/Exim\sstatistics\sfrom\s\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d\sto\s
     \d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d/Exim statistics from <time> to <time>/x;
 
+  # Treat ECONNRESET the same as ECONNREFUSED.  At least some systems give
+  # us the former on a new connection.
+  s/(could not connect to .*: Connection) reset by peer$/$1 refused/;
 
   # ======== TLS certificate algorithms ========
   # Test machines might have various different TLS library versions supporting
@@ -550,6 +553,25 @@ RESET_AFTER_EXTRA_LINE_READ:
   # signature algorithm names
   s/RSA-SHA1/RSA-SHA/;
 
+  # -d produces a list of environement variables as they are checked if they exist in the
+  # in the environment. Unfortunately this list isn't always in the same order. For now we
+  # just remove this list
+  #
+  if (/^\w+ in keep_environment/)
+    {
+    my @lines = $_;
+    while (<IN>)
+      {
+      if (/^\w+ in keep_environment/)
+        {
+        push @lines, $_;
+        next;
+        }
+      print MUNGED sort grep { !/^(SHLVL|_) / } @lines;
+      redo LINE;
+      }
+    }
+
 
   # ======== Caller's login, uid, gid, home, gecos ========
 
@@ -896,7 +918,7 @@ RESET_AFTER_EXTRA_LINE_READ:
     # As of Exim 4.74, we log when a setgid fails; because we invoke Exim
     # with -be, privileges will have been dropped, so this will always
     # be the case
-    next if /^changing group to \d+ failed: Operation not permitted/;
+    next if /^changing group to \d+ failed: (Operation not permitted|Not owner)/;
 
     # We might not keep this check; rather than change all the tests, just
     # ignore it as long as it succeeds; then we only need to change the
@@ -1029,6 +1051,14 @@ RESET_AFTER_EXTRA_LINE_READ:
     next;
     }
 
+  # ======== log ========
+
+  elsif ($is_log)
+    {
+    # Berkeley DB version differences
+    next if / Berkeley DB error: /;
+    }
+
   # ======== All files other than stderr ========
 
   print MUNGED;
@@ -1290,19 +1320,29 @@ return 1;
 #  paniclog, rejectlog, mainlog, stdout, stderr, msglog, mail
 # Search strings starting with 's' do substitutions;
 # with '/' do line-skips.
+# Triggered by a scriptfile line "munge <name>"
 ##################################################
 $munges =
   { 'dnssec' =>
-    { 'stderr' => '/^Reverse DNS security status: unverified\n/', },
+    { 'stderr' => '/^Reverse DNS security status: unverified\n/' },
 
     'gnutls_unexpected' =>
-    { 'mainlog' => '/\(recv\): A TLS packet with unexpected length was received./', },
+    { 'mainlog' => '/\(recv\): A TLS packet with unexpected length was received./' },
 
     'gnutls_handshake' =>
-    { 'mainlog' => 's/\(gnutls_handshake\): Error in the push function/\(gnutls_handshake\): A TLS packet with unexpected length was received/', },
+    { 'mainlog' => 's/\(gnutls_handshake\): Error in the push function/\(gnutls_handshake\): A TLS packet with unexpected length was received/' },
 
-    'tpda' =>
-    { 'stdout' => '/tpda_event_action =/', },
+    'optional_events' =>
+    { 'stdout' => '/event_action =/' },
+
+    'optional_ocsp' =>
+    { 'stderr' => '/127.0.0.1 in hosts_requ(ire|est)_ocsp/' },
+
+    'no_tpt_filter_epipe' =>
+    { 'stderr' => '/^writing error 32: Broken pipe$/' },
+
+    'optional_cert_hostnames' =>
+    { 'stderr' => '/in tls_verify_cert_hostnames\? no/' },
 
   };
 
@@ -1579,6 +1619,8 @@ my($commandnameref) = $_[3];
 my($aux_info) = $_[4];
 my($yield) = 1;
 
+our %ENV = map { $_ => $ENV{$_} } grep { /^(?:USER|SHELL|PATH|TERM|EXIM_TEST_.*)$/ } keys %ENV;
+
 if (/^(\d+)\s*$/)                # Handle unusual return code
   {
   my($r) = $_[2];
@@ -1648,19 +1690,42 @@ if (/^dump\s+(\S+)/)
   my(@temp);
   print ">> ./eximdir/exim_dumpdb $parm_cwd/spool $which\n" if $debug;
   open(IN, "./eximdir/exim_dumpdb $parm_cwd/spool $which |");
-  @temp = <IN>;
-  close(IN);
-  if ($which eq "callout")
+  open(OUT, ">>test-stdout");
+  print OUT "+++++++++++++++++++++++++++\n";
+
+  if ($which eq "retry")
     {
+    $/ = "\n  ";
+    @temp = <IN>;
+    $/ = "\n";
+
     @temp = sort {
-                 my($aa) = substr $a, 21;
-                 my($bb) = substr $b, 21;
-                 return $aa cmp $bb;
+                   my($aa) = split(' ', $a);
+                   my($bb) = split(' ', $b);
+                   return $aa cmp $bb;
                  } @temp;
+
+    foreach $item (@temp)
+      {
+      $item =~ s/^\s*(.*)\n(.*)\n?\s*$/$1\n$2/m;
+      print OUT "  $item\n";
+      }
     }
-  open(OUT, ">>test-stdout");
-  print OUT "+++++++++++++++++++++++++++\n";
-  print OUT @temp;
+  else
+    {
+    @temp = <IN>;
+    if ($which eq "callout")
+      {
+      @temp = sort {
+                   my($aa) = substr $a, 21;
+                   my($bb) = substr $b, 21;
+                   return $aa cmp $bb;
+                   } @temp;
+      }
+    print OUT @temp;
+    }
+
+  close(IN);
   close(OUT);
   return 1;
   }
@@ -1959,12 +2024,12 @@ if (/^client/ || /^(sudo\s+)?perl\b/)
 # not drop privilege when -C and -D options are present. To run the exim
 # command as root, we use sudo.
 
-elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo\s+)?exim(_\S+)?\s+(.*)$/)
+elsif (/^((?i:[A-Z\d_]+=\S+\s+)+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+)?\s+(.*)$/)
   {
-  $args = $5;
+  $args = $6;
   my($envset) = (defined $1)? $1      : "";
-  my($sudo)   = (defined $3)? "sudo " : "";
-  my($special)= (defined $4)? $4      : "";
+  my($sudo)   = (defined $3)? "sudo " . (defined $4 ? "-u $4 ":"")  : "";
+  my($special)= (defined $5)? $5      : "";
   $wait_time  = (defined $2)? $2      : 0;
 
   # Return 2 rather than 1 afterwards
@@ -2010,7 +2075,8 @@ elsif (/^([A-Z_]+=\S+\s+)?(\d+)?\s*(sudo\s+)?exim(_\S+)?\s+(.*)$/)
     for ($i = @msglist; $i > 0; $i--) { $args =~ s/\$msg$i/$msglist[$i-1]/g; }
     if ( $args =~ /\$msg\d/ )
       {
-      tests_exit(-1, "Not enough messages in spool, for test $testno line $lineno\n");
+      tests_exit(-1, "Not enough messages in spool, for test $testno line $lineno\n")
+        unless $force_continue;
       }
     }
 
@@ -2723,7 +2789,7 @@ $pwcomm = $pwcomm;
 
 $parm_caller_group = getgrgid($parm_caller_gid);
 
-print "Program caller is $parm_caller, whose group is $parm_caller_group\n";
+print "Program caller is $parm_caller ($parm_caller_uid), whose group is $parm_caller_group ($parm_caller_gid)\n";
 print "Home directory is $parm_caller_home\n";
 
 unless (defined $parm_eximgroup)