Testsuite: GnuTLS version variances
[exim.git] / test / runtest
index a35796c2cae79caff3bbefd5daf3dc350eb056e1..62b24290376f3964a189ebf973841bd77fe7a822 100755 (executable)
@@ -460,7 +460,9 @@ RESET_AFTER_EXTRA_LINE_READ:
     {
     my($date1,$date2,$date3,$expired) = ($1,$2,$3,$4);
     $expired = '' if !defined $expired;
-    my($increment) = date_seconds($date3) - date_seconds($date2);
+
+    # Round the time-difference up to nearest even value
+    my($increment) = ((date_seconds($date3) - date_seconds($date2) + 1) >> 1) << 1;
 
     # We used to use globally unique replacement values, but timing
     # differences make this impossible. Just show the increment on the
@@ -474,6 +476,13 @@ RESET_AFTER_EXTRA_LINE_READ:
   # more_errno values in exim_dumpdb output which are times
   s/T:(\S+)\s-22\s(\S+)\s/T:$1 -22 xxxx /;
 
+  # port numbers in dumpdb output
+  s/T:([a-z.]+(:[0-9.]+)?):$parm_port_n /T:$1:PORT_N /;
+
+  # port numbers in stderr
+  s/^set_process_info: .*\]:\K$parm_port_d /PORT_D /;
+  s/^set_process_info: .*\]:\K$parm_port_s /PORT_S /;
+
 
   # ======== Dates and times ========
 
@@ -485,6 +494,9 @@ RESET_AFTER_EXTRA_LINE_READ:
   # Date/time in header lines and SMTP responses
   s/[A-Z][a-z]{2},\s\d\d?\s[A-Z][a-z]{2}\s\d\d\d\d\s\d\d\:\d\d:\d\d\s[-+]\d{4}
     /Tue, 2 Mar 1999 09:44:33 +0000/gx;
+  # and in a French locale
+  s/\S{4},\s\d\d?\s[^,]+\s\d\d\d\d\s\d\d\:\d\d:\d\d\s[-+]\d{4}
+    /dim., 10 f\xE9vr 2019 20:05:49 +0000/gx;
 
   # Date/time in logs and in one instance of a filter test
   s/^\d{4}-\d\d-\d\d\s\d\d:\d\d:\d\d(\s[+-]\d\d\d\d)?\s/1999-03-02 09:44:33 /gx;
@@ -515,7 +527,7 @@ RESET_AFTER_EXTRA_LINE_READ:
     my($next) = $3 - $2;
     $_ = "  first failed=dddd last try=dddd next try=+$next $4\n";
     }
-  s/^(\s*)now=\d+ first_failed=\d+ next_try=\d+ expired=(\d)/$1now=tttt first_failed=tttt next_try=tttt expired=$2/;
+  s/^(\s*)now=\d+ first_failed=\d+ next_try=\d+ expired=(\w)/$1now=tttt first_failed=tttt next_try=tttt expired=$2/;
   s/^(\s*)received_time=\d+ diff=\d+ timeout=(\d+)/$1received_time=tttt diff=tttt timeout=$2/;
 
   # Time to retry may vary
@@ -538,6 +550,9 @@ RESET_AFTER_EXTRA_LINE_READ:
   # Test machines might have various different TLS library versions supporting
   # different protocols; can't rely upon TLS 1.2's AES256-GCM-SHA384, so we
   # treat the standard algorithms the same.
+  #
+  # TLSversion : KeyExchange? - Authentication/Signature - C_iph_er - MAC : ???
+  #
   # So far, have seen:
   #   TLSv1:AES128-GCM-SHA256:128
   #   TLSv1:AES256-SHA:256
@@ -554,13 +569,18 @@ RESET_AFTER_EXTRA_LINE_READ:
   #
   # Retain the authentication algorith field as we want to test that.
 
-  s/( (?: (?:\b|\s) [\(=] ) | \s )TLSv1\.[123]:/$1TLSv1:/xg;
-  s/((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA)(?!:)/ke-$3-AES256-SHA/g;
-  s/((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA):(128|256)/ke-$3-AES256-SHA:xxx/g;
+  s/( (?: (?:\b|\s) [\(=] ) | \s )TLSv1(\.[123])?:/$1TLS1.x:/xg;
+  s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA)(?!:)/ke-$3-AES256-SHAnnn/g;
+  s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-AES(128|256)-(GCM-SHA(256|384)|SHA):(128|256)/ke-$3-AES256-SHAnnn:xxx/g;
 
   # OpenSSL TLSv1.3 - unsure what to do about the authentication-variant testcases now,
-  # as it seems the protocol no longer supports a user choice.
-  s/TLS_AES(_256)_GCM_SHA384:256/TLS-AES256-SHA:xxx/g;
+  # as it seems the protocol no longer supports a user choice.  Replace the "TLS" field with "RSA".
+  # Also insert a key-exchange field for back-compat, even though 1.3 doesn't do that.
+  #
+  # TLSversion : "TLS" - C_iph_er - MAC : ???
+  #
+  s/TLS_AES(_256)?_GCM_SHA384(?!:)/ke-RSA-AES256-SHAnnn/g;
+  s/:TLS_AES(_256)?_GCM_SHA384:256/:ke-RSA-AES256-SHAnnn:xxx/g;
 
   # LibreSSL
   # TLSv1:AES256-GCM-SHA384:256
@@ -570,14 +590,24 @@ RESET_AFTER_EXTRA_LINE_READ:
   # AES256-GCM-SHA384
 
   s/(?<!-)(AES256-GCM-SHA384)/RSA-$1/;
-  s/((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305)(?!:)/ke-$3-AES256-SHA/g;
-  s/((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305):256/ke-$3-AES256-SHA:xxx/g;
+  s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305)(?!:)/ke-$3-AES256-SHAnnn/g;
+  s/(?<!ke-)((EC)?DHE-)?(RSA|ECDSA)-(AES256|CHACHA20)-(GCM-SHA384|POLY1305):256/ke-$3-AES256-SHAnnn:xxx/g;
 
   # GnuTLS have seen:
+  #   TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256
+  #   TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM__AEAD:256
+  #   TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256
+  #   TLS1.3:ECDHE_PSK_SECP256R1__AES_256_GCM__AEAD:256
+  #
   #   TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256
   #   TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128
   #   TLS1.2:RSA_AES_256_CBC_SHA1:256 (canonical)
   #   TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128
+  #   TLS1.2:ECDHE_SECP256R1__RSA_SHA256__AES_256_GCM:256
+  #   TLS1.2:ECDHE_SECP256R1__RSA_SHA256__AES_128_CBC__SHA256:128
+  #   TLS1.2:ECDHE_SECP256R1__ECDSA_SHA512__AES_256_GCM:256
+  #   TLS1.2:ECDHE_RSA_SECP256R1__AES_256_GCM:256 (! 3.5.18 !)
+  #   TLS1.2:RSA__CAMELLIA_256_GCM:256 (leave the cipher name)
   #
   #   X=TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256
   #   X=TLS1.2:RSA_AES_256_CBC_SHA1:256
@@ -588,14 +618,25 @@ RESET_AFTER_EXTRA_LINE_READ:
   #   DHE-RSA-AES256-SHA256
   #   DHE-RSA-AES256-SHA
   # picking latter as canonical simply because regex easier that way.
-  s/\bDHE_RSA_AES_128_CBC_SHA1:128/RSA_AES_256_CBC_SHA1:256/g;
-  s/TLS1.[012]:((EC)?DHE_)?(RSA|ECDSA)_AES_(256|128)_(CBC|GCM)_SHA(1|256|384):(256|128)/TLS1.x:ke_$3_AES_256_CBC_SHAnnn:256/g;
-  s/\b(ECDHE-(RSA|ECDSA)-AES256-SHA|DHE-RSA-AES256-SHA256)\b/ke-$2-AES256-SHAxx/g;
+  s/\bDHE_RSA_AES_128_CBC_SHA1:128/RSA-AES256-SHA1:256/g;
+  s/TLS1.[0123]:                                                               # TLS version
+    ((EC)?DHE(_((?<psk>PSK)_)?((?<auth>RSA|ECDSA)_)?(SECP256R1|X25519))?__?)?  # key-exchange
+    ((?<auth>RSA|ECDSA)((_PSS_RSAE)?_SHA(512|256))?__?)?                       # authentication
+    AES_(256|128)_(CBC|GCM)                                                    # cipher
+    (__?SHA(1|256|384))?:                                                      # PRF
+    (256|128)                                                                  # cipher strength
+    /"TLS1.x:ke-"
+       . (defined($+{psk}) ? $+{psk} : "")
+       . (defined($+{auth}) ? $+{auth} : "")
+       . "-AES256-SHAnnn:xxx"/gex;
+  s/TLS1.2:RSA__CAMELLIA_256_GCM(_SHA384)?:256/TLS1.2:RSA_CAMELLIA_256_GCM-SHAnnn:256/g;
+  s/\b(ECDHE-(RSA|ECDSA)-AES256-SHA|DHE-RSA-AES256-SHA256)\b/ke-$2-AES256-SHAnnn/g;
 
   # GnuTLS library error message changes
-  s/No certificate was found/The peer did not send any certificate/g;
+  s/(No certificate was found|Certificate is required)/The peer did not send any certificate/g;
 #(dodgy test?)  s/\(certificate verification failed\): invalid/\(gnutls_handshake\): The peer did not send any certificate./g;
   s/\(gnutls_priority_set\): No or insufficient priorities were set/\(gnutls_handshake\): Could not negotiate a supported cipher suite/g;
+  s/\(gnutls_handshake\): \KNo supported cipher suites have been found.$/Could not negotiate a supported cipher suite./;
 
   # (this new one is a generic channel-read error, but the testsuite
   # only hits it in one place)
@@ -926,6 +967,7 @@ RESET_AFTER_EXTRA_LINE_READ:
     s/SSL3_READ_BYTES/ssl3_read_bytes/i;
     s/CONNECT_CR_FINISHED/ssl3_read_bytes/i;
     s/^\d+:error:\d+(?:E\d+)?(:SSL routines:ssl3_read_bytes:[^:]+:).*(:SSL alert number \d\d)$/pppp:error:dddddddd$1\[...\]$2/;
+    s/^error:[^:]*:(SSL routines:ssl3_read_bytes:(tls|ssl)v\d+ alert)/error:dddddddd:$1/;
 
     # gnutls version variances
     next if /^Error in the pull function./;
@@ -1066,12 +1108,14 @@ RESET_AFTER_EXTRA_LINE_READ:
     # Some DBM libraries seem to make DBM files on opening with O_RDWR without
     # O_CREAT; other's don't. In the latter case there is some debugging output
     # which is not present in the former. Skip the relevant lines (there are
-    # two of them).
+    # three of them).
 
-    if (/TESTSUITE\/spool\/db\/\S+ appears not to exist: trying to create/)
+    if (/returned from EXIM_DBOPEN: \(nil\)/)
       {
-      $_ = <IN>;
-      next;
+      $_ .= <IN>;
+      s?\Q$parm_cwd\E?TESTSUITE?g;
+      if (/TESTSUITE\/spool\/db\/\S+ appears not to exist: trying to create/)
+       { $_ = <IN>; next; }
       }
 
     # Some tests turn on +expand debugging to check on expansions.
@@ -1092,15 +1136,26 @@ RESET_AFTER_EXTRA_LINE_READ:
 
     # Skip hosts_require_dane checks when the options
     # are unset, because dane ain't always there.
-
     next if /in\shosts_require_dane\?\sno\s\(option\sunset\)/x;
 
+    # DISABLE_OCSP 
+    next if /in hosts_requ(est|ire)_ocsp\? (no|yes)/;
+
     # SUPPORT_PROXY
     next if /host in hosts_proxy\?/;
 
     # Experimental_International
     next if / in smtputf8_advertise_hosts\? no \(option unset\)/;
 
+    # Experimental_REQUIRETLS
+    next if / in tls_advertise_requiretls?\? no \(end of list\)/;
+
+    # TCP Fast Open
+    next if /^(ppppp )?setsockopt FASTOPEN: Network Error/;
+
+    # Experimental_PIPE_CONNECT
+    next if / in (pipelining_connect_advertise_hosts|hosts_pipe_connect)?\? no /;
+
     # Environment cleaning
     next if /\w+ in keep_environment\? (yes|no)/;
 
@@ -1140,12 +1195,12 @@ RESET_AFTER_EXTRA_LINE_READ:
       s/Address family not supported by protocol family/Network Error/;
       s/Network is unreachable/Network Error/;
       }
-
     next if /^(ppppp )?setsockopt FASTOPEN: Protocol not available$/;
+    s/^(Connecting to .* \.\.\. sending) \d+ (nonTFO early-data)$/$1 dd $2/;
 
     # Specific pointer values reported for DB operations change from run to run
-    s/^(returned from EXIM_DBOPEN: )(0x)?[0-9a-f]+/${1}0xAAAAAAAA/;
-    s/^(EXIM_DBCLOSE.)(0x)?[0-9a-f]+/${1}0xAAAAAAAA/;
+    s/^(\s*returned from EXIM_DBOPEN: )(0x)?[0-9a-f]+/${1}0xAAAAAAAA/;
+    s/^(\s*EXIM_DBCLOSE.)(0x)?[0-9a-f]+/${1}0xAAAAAAAA/;
 
     # Platform-dependent output during MySQL startup
     next if /PerconaFT file system space/;
@@ -1216,17 +1271,37 @@ RESET_AFTER_EXTRA_LINE_READ:
     s/(DANE attempt failed.*error:)[0-9A-F]{8}(:SSL routines:)(ssl3_get_server_certificate|tls_process_server_certificate|CONNECT_CR_CERT)(?=:certificate verify failed$)/$1xxxxxxxx$2ssl3_get_server_certificate/;
     s/(DKIM: validation error: )error:[0-9A-F]{8}:rsa routines:(?:(?i)int_rsa_verify|CRYPTO_internal):(?:bad signature|algorithm mismatch)$/$1Public key signature verification has failed./;
 
+    # gnutls version variances
+    if (/TLS error on connection \(recv\): .* (Decode error|peer did not send any certificate)/)
+      {
+      my $prev = $_;
+      $_ = <IN>;
+      if (/error on first read/)
+       {
+       s/TLS session: \Kerror on first read:/(gnutls_handshake): A TLS fatal alert has been received.:/;
+       goto RESET_AFTER_EXTRA_LINE_READ;
+       }
+      else
+       { $_ = $prev; }
+      }
+
     # DKIM timestamps
-    s/(DKIM: d=.*) t=([0-9]*) x=([0-9]*)(?{ return $3 - $2; }) /$1 t=T x=T+$^R /;
+    if ( /(DKIM: d=.*) t=([0-9]*) x=([0-9]*) / )
+      {
+      my ($prefix, $t_diff) = ($1, $3 - $2);
+      s/DKIM: d=.* t=[0-9]* x=[0-9]* /${prefix} t=T x=T+${t_diff} /;
+      }
     }
 
   # ======== mail ========
 
   elsif ($is_mail)
     {
-    # DKIM timestamps
-    if ( /^\s+t=[0-9]*; x=[0-9]*; b=[A-Za-z0-9+\/]+$/ ) {
-      s/^(\s+)t=([0-9]*); x=([0-9]*);(?{ return $3 - $2; }) b=[A-Za-z0-9+\/]+$/$1t=T; x=T+$^R; b=bbbb;/;
+    # DKIM timestamps, and signatures depending thereon
+    if ( /^(\s+)t=([0-9]*); x=([0-9]*); b=[A-Za-z0-9+\/]+$/ )
+      {
+      my ($indent, $t_diff) = ($1, $3 - $2);
+      s/.*/${indent}t=T; x=T+${t_diff}; b=bbbb;/;
       <IN>;
       <IN>;
       }
@@ -1559,6 +1634,11 @@ $munges =
     'gnutls_handshake' =>
     { 'mainlog' => 's/\(gnutls_handshake\): Error in the push function/\(gnutls_handshake\): A TLS packet with unexpected length was received/' },
 
+    'gnutls_bad_clientcert' =>
+    { 'mainlog' => 's/\(certificate verification failed\): certificate invalid/\(gnutls_handshake\): The peer did not send any certificate./',
+      'stdout'  => 's/Succeeded in starting TLS/A TLS fatal alert has been received.\nFailed to start TLS'
+    },
+
     'optional_events' =>
     { 'stdout' => '/event_action =/' },
 
@@ -1578,7 +1658,15 @@ $munges =
     { 'stderr' => 's/(1[5-9]|23\d)\d\d msec/ssss msec/' },
 
     'tls_anycipher' =>
-    { 'mainlog' => 's/ X=TLS\S+ / X=TLS_proto_and_cipher /' },
+    { 'mainlog'   => 's! X=TLS\S+ ! X=TLS_proto_and_cipher !;
+                     s! DN="C=! DN="/C=!;
+                     s! DN="[^,"]*\K,!/!;
+                     s! DN="[^,"]*\K,!/!;
+                     s! DN="[^,"]*\K,!/!;
+                    ',
+      'rejectlog' => 's/ X=TLS\S+ / X=TLS_proto_and_cipher /',
+      'mail'      => 's/ \(TLS[^)]*\)/ (TLS_proto_and_cipher)/',
+    },
 
     'debug_pid' =>
     { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d{1,5}/ppppp/g' },
@@ -1591,11 +1679,14 @@ $munges =
     { 'stdout' => '/^(
                   dkim_(canon|domain|private_key|selector|sign_headers|strict|hash|identity|timestamps)
                   |gnutls_require_(kx|mac|protocols)
+                 |hosts_pipe_connect
                   |hosts_(requ(est|ire)|try)_(dane|ocsp)
                  |dane_require_tls_ciphers
                   |hosts_(avoid|nopass|noproxy|require|verify_avoid)_tls
+                  |pipelining_connect_advertise_hosts
                   |socks_proxy
                   |tls_[^ ]*
+                 |utf8_downconvert
                   )($|[ ]=)/x'
     },
 
@@ -2145,7 +2236,7 @@ elsif (/^millisleep\s+(.*)$/)
 
 
 # The "munge" command selects one of a hardwired set of test-result modifications
-# to be made before result compares are run agains the golden set.  This lets
+# to be made before result compares are run against the golden set.  This lets
 # us account for test-system dependent things which only affect a few, but known,
 # test-cases.
 # Currently only the last munge takes effect.
@@ -2618,7 +2709,7 @@ GetOptions(
     'valgrind' => \$valgrind,
     'range=s{2}'       => \my @range_wanted,
     'test=i@'          => \my @tests_wanted,
-    'flavor|flavour=s' => $flavour,
+    'flavor|flavour=s' => \$flavour,
     'help'             => sub { pod2usage(-exit => 0) },
     'man'              => sub {
         pod2usage(
@@ -3342,6 +3433,12 @@ if ($parm_hostname =~ /[[:upper:]]/)
   print "\n*** Host name has upper case characters: this may cause problems ***\n\n";
   }
 
+if ($parm_hostname =~ /\.example\.com$/)
+  {
+  die "\n*** Host name ends in .example.com; this conflicts with the testsuite use of that domain.\n"
+       . "    Please change the host's name (or comment out this check, and fail several testcases)\n";
+  }
+
 
 
 ##################################################