Merge branch '4.next'
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 8 Dec 2019 23:36:01 +0000 (23:36 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 8 Dec 2019 23:36:01 +0000 (23:36 +0000)
136 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
doc/doc-txt/experimental-spec.txt
release-process/scripts/mk_exim_release
src/OS/Makefile-FreeBSD
src/README.UPDATING
src/src/EDITME
src/src/acl.c
src/src/arc.c
src/src/configure.default
src/src/dane-openssl.c
src/src/dcc.c
src/src/deliver.c
src/src/dns.c
src/src/environment.c
src/src/exim.c
src/src/exipick.src
src/src/functions.h
src/src/globals.c
src/src/globals.h
src/src/host.c
src/src/local_scan.h
src/src/lookups/dnsdb.c
src/src/macros.h
src/src/pdkim/pdkim.c
src/src/queue.c
src/src/readconf.c
src/src/smtp_in.c
src/src/spf.c
src/src/spool_in.c
src/src/spool_out.c
src/src/string.c
src/src/tls-gnu.c
src/src/tls-openssl.c
src/src/tls.c
src/src/tod.c
src/src/transports/smtp.c
src/src/verify.c
test/aux-fixed/exim-ca/example.com/server1.example.com/fullchain.ocsp.resp.pem [new file with mode: 0644]
test/aux-fixed/exim-ca/genall
test/aux-var-src/tls_conf_prefix
test/confs/0206
test/confs/0618
test/confs/1023 [new symlink]
test/confs/5602 [deleted symlink]
test/confs/5612 [new symlink]
test/confs/5615 [new symlink]
test/confs/5652 [deleted file]
test/confs/5655 [deleted file]
test/confs/5665 [new file with mode: 0644]
test/confs/5670 [new file with mode: 0644]
test/dnszones-src/db.kitterman.org [new file with mode: 0644]
test/log/0576
test/log/0618
test/log/0904
test/log/1003
test/log/1023 [new file with mode: 0644]
test/log/2102
test/log/4600
test/log/5601
test/log/5602 [deleted file]
test/log/5611
test/log/5612 [new file with mode: 0644]
test/log/5615 [new file with mode: 0644]
test/log/5651
test/log/5652 [deleted file]
test/log/5655 [deleted file]
test/log/5665 [new file with mode: 0644]
test/log/5670 [new file with mode: 0644]
test/log/5740
test/log/5821
test/rejectlog/0618
test/runtest
test/scripts/0000-Basic/0206
test/scripts/0000-Basic/0576
test/scripts/0000-Basic/0618
test/scripts/0000-Basic/0904
test/scripts/1000-Basic-ipv6/1003
test/scripts/1020-Linklocal-ipv6/1023 [new file with mode: 0644]
test/scripts/1020-Linklocal-ipv6/REQUIRES [new file with mode: 0644]
test/scripts/4540-DKIM-Ed25519/4540
test/scripts/5600-OCSP-OpenSSL/5602 [deleted file]
test/scripts/5612-OCSP-OpenSSL-multileaf/5612 [new file with mode: 0644]
test/scripts/5612-OCSP-OpenSSL-multileaf/REQUIRES [new file with mode: 0644]
test/scripts/5615-OCSP-OpenSSL-1.3/5615 [new file with mode: 0644]
test/scripts/5615-OCSP-OpenSSL-1.3/REQUIRES [new file with mode: 0644]
test/scripts/5650-OCSP-GnuTLS/5652 [deleted file]
test/scripts/5655-OCSP-GnuTLS-1.3/5655 [deleted file]
test/scripts/5655-OCSP-GnuTLS-1.3/REQUIRES [deleted file]
test/scripts/5665-OCSP-GnuTLS-multileaf/5665 [new file with mode: 0644]
test/scripts/5665-OCSP-GnuTLS-multileaf/REQUIRES [new file with mode: 0644]
test/scripts/5670-OCSP-GnuTLS-1.3/5670 [new file with mode: 0644]
test/scripts/5670-OCSP-GnuTLS-1.3/REQUIRES [new file with mode: 0644]
test/src/fakens.c
test/src/server.c
test/stderr/0044
test/stderr/0078
test/stderr/0092
test/stderr/0117
test/stderr/0145
test/stderr/0161
test/stderr/0175
test/stderr/0183
test/stderr/0278
test/stderr/0342
test/stderr/0361
test/stderr/0402
test/stderr/0419
test/stderr/0426
test/stderr/0443
test/stderr/0463
test/stderr/0469
test/stderr/0476
test/stderr/0513
test/stderr/0544
test/stderr/0545
test/stderr/0606
test/stderr/1006
test/stderr/2201
test/stderr/3000
test/stderr/3211
test/stderr/5410
test/stderr/5420
test/stdout/0147
test/stdout/0190
test/stdout/0350
test/stdout/0430
test/stdout/0442
test/stdout/0572
test/stdout/0576
test/stdout/0577
test/stdout/0904
test/stdout/1006
test/stdout/1009
test/stdout/4950

index 0e7d7655cafa69561d0af16371eb960b617a01ab..2946d70131621203ab938248b16f3617b65f034e 100644 (file)
 . Update the Copyright year (only) when changing content.
 . /////////////////////////////////////////////////////////////////////////////
 
-.set previousversion "4.92"
+.set previousversion "4.93"
 .include ./local_params
 
 .set ACL "access control lists (ACLs)"
 .set I   "&nbsp;&nbsp;&nbsp;&nbsp;"
 
 .macro copyyear
-2018
+2019
 .endmacro
 
 . /////////////////////////////////////////////////////////////////////////////
@@ -371,11 +371,13 @@ contributors.
 .section "Exim documentation" "SECID1"
 . Keep this example change bar when updating the documentation!
 
+.new
 .cindex "documentation"
 This edition of the Exim specification applies to version &version() of Exim.
 Substantive changes from the &previousversion; edition are marked in some
 renditions of this document; this paragraph is so marked if the rendition is
 capable of showing a change indicator.
+.wen
 
 This document is very much a reference manual; it is not a tutorial. The reader
 is expected to have some familiarity with the SMTP mail transfer protocol and
@@ -1886,11 +1888,10 @@ to your &_Local/Makefile_& and rebuild Exim.
 .section "Including TLS/SSL encryption support" "SECTinctlsssl"
 .cindex "TLS" "including support for TLS"
 .cindex "encryption" "including support for"
-.cindex "SUPPORT_TLS"
 .cindex "OpenSSL" "building Exim with"
 .cindex "GnuTLS" "building Exim with"
-Exim can be built to support encrypted SMTP connections, using the STARTTLS
-command as per RFC 2487. It can also support legacy clients that expect to
+Exim is usually built to support encrypted SMTP connections, using the STARTTLS
+command as per RFC 2487. It can also support clients that expect to
 start a TLS session immediately on connection to a non-standard port (see the
 &%tls_on_connect_ports%& runtime option and the &%-tls-on-connect%& command
 line option).
@@ -1899,35 +1900,39 @@ If you want to build Exim with TLS support, you must first install either the
 OpenSSL or GnuTLS library. There is no cryptographic code in Exim itself for
 implementing SSL.
 
+If you do not want TLS support you should set
+.code
+DISABLE_TLS=yes
+.endd
+in &_Local/Makefile_&.
+
 If OpenSSL is installed, you should set
 .code
-SUPPORT_TLS=yes
+USE_OPENSL=yes
 TLS_LIBS=-lssl -lcrypto
 .endd
 in &_Local/Makefile_&. You may also need to specify the locations of the
 OpenSSL library and include files. For example:
 .code
-SUPPORT_TLS=yes
+USE_OPENSSL=yes
 TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto
 TLS_INCLUDE=-I/usr/local/openssl/include/
 .endd
 .cindex "pkg-config" "OpenSSL"
 If you have &'pkg-config'& available, then instead you can just use:
 .code
-SUPPORT_TLS=yes
+USE_OPENSSL=yes
 USE_OPENSSL_PC=openssl
 .endd
 .cindex "USE_GNUTLS"
 If GnuTLS is installed, you should set
 .code
-SUPPORT_TLS=yes
 USE_GNUTLS=yes
 TLS_LIBS=-lgnutls -ltasn1 -lgcrypt
 .endd
 in &_Local/Makefile_&, and again you may need to specify the locations of the
 library and include files. For example:
 .code
-SUPPORT_TLS=yes
 USE_GNUTLS=yes
 TLS_LIBS=-L/usr/gnu/lib -lgnutls -ltasn1 -lgcrypt
 TLS_INCLUDE=-I/usr/gnu/include
@@ -1935,7 +1940,6 @@ TLS_INCLUDE=-I/usr/gnu/include
 .cindex "pkg-config" "GnuTLS"
 If you have &'pkg-config'& available, then instead you can just use:
 .code
-SUPPORT_TLS=yes
 USE_GNUTLS=yes
 USE_GNUTLS_PC=gnutls
 .endd
@@ -3959,6 +3963,18 @@ is sent to the sender, containing the text &"cancelled by administrator"&.
 Bounce messages are just discarded. This option can be used only by an admin
 user.
 
+.vitem &%-MG%&&~<&'queue&~name'&>&~<&'message&~id'&>&~<&'message&~id'&>&~...
+.oindex "&%-MG%&"
+.cindex queue named
+.cindex "named queues"
+.cindex "queue" "moving messages"
+This option requests that each listed message be moved from its current
+queue to the given named queue.
+The destination queue name argument is required, but can be an empty
+string to define the default queue.
+If the messages are not currently located in the default queue,
+a &%-qG<name>%& option will be required to define the source queue.
+
 .vitem &%-Mmad%&&~<&'message&~id'&>&~<&'message&~id'&>&~...
 .oindex "&%-Mmad%&"
 .cindex "delivery" "cancelling all"
@@ -6120,9 +6136,6 @@ dnslookup:
   domains = ! +local_domains
   transport = remote_smtp
   ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
-.ifdef _HAVE_DNSSEC
-  dnssec_request_domains = *
-.endif
   no_more
 .endd
 The &%domains%& option behaves as per smarthost, above.
@@ -6273,9 +6286,6 @@ Two remote transports and four local transports are defined.
 remote_smtp:
   driver = smtp
   message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
-.ifdef _HAVE_DANE
-  hosts_try_dane = *
-.endif
 .ifdef _HAVE_PRDR
   hosts_try_prdr = *
 .endif
@@ -6283,9 +6293,7 @@ remote_smtp:
 This transport is used for delivering messages over SMTP connections.
 The list of remote hosts comes from the router.
 The &%message_size_limit%& usage is a hack to avoid sending on messages
-with over-long lines.  The built-in macro _HAVE_DANE guards configuration
-to use DANE for delivery;
-see section &<<SECDANE>>& for more details.
+with over-long lines.
 
 The &%hosts_try_prdr%& option enables an efficiency SMTP option.  It is
 negotiated between client and server and not expected to cause problems
@@ -6676,11 +6684,10 @@ aliases or other indexed data referenced by an MTA. Information about cdb and
 tools for building the files can be found in several places:
 .display
 &url(https://cr.yp.to/cdb.html)
-&url(http://www.corpit.ru/mjt/tinycdb.html)
+&url(https://www.corpit.ru/mjt/tinycdb.html)
 &url(https://packages.debian.org/stable/utils/freecdb)
 &url(https://github.com/philpennock/cdbtools) (in Go)
 .endd
-. --- 2018-09-07: corpit.ru http:-only
 A cdb distribution is not needed in order to build Exim with cdb support,
 because the code for reading cdb files is included directly in Exim itself.
 However, no means of building or testing cdb files is provided with Exim, so
@@ -6765,13 +6772,10 @@ lookup types support only literal keys.
 the implicit key is the host's IP address rather than its name (see section
 &<<SECThoslispatsikey>>&).
 
-.new
 &*Warning 3*&: Do not use an IPv4-mapped IPv6 address for a key; use the
 IPv4, in dotted-quad form. (Exim converts IPv4-mapped IPv6 addresses to this
 notation before executing the lookup.)
-.wen
 .next
-.new
 .cindex lookup json
 .cindex json "lookup type"
 .cindex JSON expansions
@@ -6788,7 +6792,6 @@ The final resulting element can be a simple JSON type or a JSON object
 or array; for the latter two a string-representation os the JSON
 is returned.
 For elements of type string, the returned value is de-quoted.
-.wen
 .next
 .cindex "linear search"
 .cindex "lookup" "lsearch"
@@ -7342,7 +7345,7 @@ with the lookup.
 With &"strict"& a response from the DNS resolver that
 is not labelled as authenticated data
 is treated as equivalent to a temporary DNS error.
-The default is &"never"&.
+The default is &"lax"&.
 
 See also the &$lookup_dnssec_authenticated$& variable.
 
@@ -8708,11 +8711,9 @@ recently implemented &(iplsearch)& files do require colons in IPv6 keys
 (notated using the quoting facility) so as to distinguish them from IPv4 keys.
 For this reason, when the lookup type is &(iplsearch)&, IPv6 addresses are
 converted using colons and not dots.
-.new
 In all cases except IPv4-mapped IPv6, full, unabbreviated IPv6
 addresses are always used.
 The latter are converted to IPv4 addresses, in dotted-quad form.
-.wen
 
 Ideally, it would be nice to tidy up this anomalous situation by changing to
 colons in all cases, given that quoting is now available for &(lsearch)&.
@@ -9233,12 +9234,10 @@ options for which string expansion is performed are marked with &dagger; after
 the data type.  ACL rules always expand strings.  A couple of expansion
 conditions do not expand some of the brace-delimited branches, for security
 reasons,
-.new
 .cindex "tainted data" expansion
 .cindex expansion "tainted data"
 and expansion of data deriving from the sender (&"tainted data"&)
 is not permitted.
-.wen
 
 
 
@@ -9485,9 +9484,13 @@ set in &_Local/Makefile_&. Once loaded, Exim remembers the dynamically loaded
 object so that it doesn't reload the same object file in the same Exim process
 (but of course Exim does start new processes frequently).
 
-There may be from zero to eight arguments to the function. When compiling
-a local function that is to be called in this way, &_local_scan.h_& should be
-included. The Exim variables and functions that are defined by that API
+There may be from zero to eight arguments to the function.
+
+When compiling
+a local function that is to be called in this way,
+first &_DLFUNC_IMPL_& should be defined,
+and second &_local_scan.h_& should be included.
+The Exim variables and functions that are defined by that API
 are also available for dynamically loaded functions. The function itself
 must have the following type:
 .code
@@ -9596,10 +9599,8 @@ Matching of the key against the member names is done case-sensitively.
 For the &"json"& variant,
 if a returned value is a JSON string, it retains its leading and
 trailing quotes.
-.new
 For the &"jsons"& variant, which is intended for use with JSON strings, the
 leading and trailing quotes are removed from the returned value.
-.wen
 . XXX should be a UTF-8 compare
 
 The results of matching are handled as above.
@@ -9650,10 +9651,8 @@ there is no choice of field separator.
 For the &"json"& variant,
 if a returned value is a JSON string, it retains its leading and
 trailing quotes.
-.new
 For the &"jsons"& variant, which is intended for use with JSON strings, the
 leading and trailing quotes are removed from the returned value.
-.wen
 
 
 .vitem &*${filter{*&<&'string'&>&*}{*&<&'condition'&>&*}}*&
@@ -11000,14 +10999,12 @@ it as a 64-digit hexadecimal number, in which any letters are in upper case.
 If the string is a single variable of type certificate,
 returns the SHA-256 hash fingerprint of the certificate.
 
-.new
 The operator can also be spelled &%sha2%& and does the same as &%sha256%&
 (except for certificates, which are not supported).
 Finally, if an underbar
 and a number is appended it specifies the output length, selecting a
 member of the SHA-2 family of hash functions.
 Values of 256, 384 and 512 are accepted, with 256 being the default.
-.wen
 
 
 .vitem &*${sha3:*&<&'string'&>&*}*& &&&
@@ -11394,7 +11391,6 @@ being processed, to enable these expansion items to be nested.
 
 To scan a named list, expand it with the &*listnamed*& operator.
 
-.new
 .vitem "&*forall_json{*&<&'a JSON array'&>&*}{*&<&'a condition'&>&*}*&" &&&
        "&*forany_json{*&<&'a JSON array'&>&*}{*&<&'a condition'&>&*}*&" &&&
        "&*forall_jsons{*&<&'a JSON array'&>&*}{*&<&'a condition'&>&*}*&" &&&
@@ -11410,7 +11406,6 @@ be a JSON array.
 The array separator is not changeable.
 For the &"jsons"& variants the elements are expected to be JSON strings
 and have their quotes removed before the evaluation of the condition.
-.wen
 
 
 
@@ -12090,14 +12085,12 @@ contain the trailing slash. If &$config_file$& does not contain a slash,
 .vindex "&$config_file$&"
 The name of the main configuration file Exim is using.
 
-.new
 .vitem &$dmarc_domain_policy$& &&&
        &$dmarc_status$& &&&
        &$dmarc_status_text$& &&&
        &$dmarc_used_domains$&
 Results of DMARC verification.
 For details see section &<<SECDMARC>>&.
-.wen
 
 .vitem &$dkim_verify_status$&
 Results of DKIM verification.
@@ -12792,7 +12785,6 @@ or if not set, the value of &$qualify_domain$&.
 .cindex queues named
 The name of the spool queue in use; empty for the default queue.
 
-.new
 .vitem &$r_...$&
 .vindex &$r_...$&
 .cindex router variables
@@ -12800,7 +12792,6 @@ Values can be placed in these variables by the &%set%& option of a router.
 They can be given any name that starts with &$r_$&.
 The values persist for the address being handled through subsequent routers
 and the eventual transport.
-.wen
 
 .vitem &$rcpt_count$&
 .vindex "&$rcpt_count$&"
@@ -13364,6 +13355,7 @@ or a &%def%& condition.
 &*Note*&: Under versions of OpenSSL preceding 1.1.1,
 when a list of more than one
 file is used for &%tls_certificate%&, this variable is not reliable.
+The macro "_TLS_BAD_MULTICERT_IN_OURCERT" will be defined for those versions.
 
 .vitem &$tls_in_peercert$&
 .vindex "&$tls_in_peercert$&"
@@ -13420,11 +13412,9 @@ The deprecated &$tls_cipher$& variable is the same as &$tls_in_cipher$& during m
 but in the context of an outward SMTP delivery taking place via the &(smtp)& transport
 becomes the same as &$tls_out_cipher$&.
 
-.new
 .vitem &$tls_in_cipher_std$&
 .vindex "&$tls_in_cipher_std$&"
 As above, but returning the RFC standard name for the cipher suite.
-.wen
 
 .vitem &$tls_out_cipher$&
 .vindex "&$tls_out_cipher$&"
@@ -13434,11 +13424,9 @@ and then set to the outgoing cipher suite if one is negotiated. See chapter
 &<<CHAPTLS>>& for details of TLS support and chapter &<<CHAPsmtptrans>>& for
 details of the &(smtp)& transport.
 
-,new
 .vitem &$tls_out_cipher_std$&
 .vindex "&$tls_out_cipher_std$&"
 As above, but returning the RFC standard name for the cipher suite.
-.wen
 
 .vitem &$tls_out_dane$&
 .vindex &$tls_out_dane$&
@@ -13513,7 +13501,6 @@ the transport.
 .vindex &$tls_out_tlsa_usage$&
 Bitfield of TLSA record types found.  See section &<<SECDANE>>&.
 
-.new
 .vitem &$tls_in_ver$&
 .vindex "&$tls_in_ver$&"
 When a message is received from a remote host over an encrypted SMTP connection
@@ -13523,7 +13510,6 @@ this variable is set to the protocol version, eg &'TLS1.2'&.
 .vindex "&$tls_out_ver$&"
 When a message is being delivered to a remote host over an encrypted SMTP connection
 this variable is set to the protocol version.
-.wen
 
 
 .vitem &$tod_bsdinbox$&
@@ -14670,8 +14656,10 @@ received. See chapter &<<CHAPACL>>& for further details.
 
 .option add_environment main "string list" empty
 .cindex "environment" "set values"
-This option allows to set individual environment variables that the
-currently linked libraries and programs in child processes use.
+This option adds individual environment variables that the
+currently linked libraries and programs in child processes may use.
+Each list element should be of the form &"name=value"&.
+
 See &<<SECTpipeenv>>& for the environment of &(pipe)& transports.
 
 .option admin_groups main "string list&!!" unset
@@ -14722,11 +14710,9 @@ If it is set true, Exim's domain parsing function allows valid
 UTF-8 multicharacters to appear in domain name components, in addition to
 letters, digits, and hyphens.
 
-.new
 If Exim is built with internationalization support
 and the SMTPUTF8 ESMTP option is in use (see chapter &<<CHAPi18n>>&)
 this option can be left as default.
-.wen
 Without that,
 if you want to look up such domain names in the DNS, you must also
 adjust the value of &%dns_check_names_pattern%& to match the extended form. A
@@ -15140,6 +15126,7 @@ to handle IPv6 literal addresses.
 .option dkim_verify_hashes main "string list" "sha256 : sha512"
 .cindex DKIM "selecting signature algorithms"
 This option gives a list of hash types which are acceptable in signatures,
+.wen
 and an order of processing.
 Signatures with algorithms not in the list will be ignored.
 
@@ -15160,7 +15147,6 @@ Signatures with algorithms not in the list will be ignored.
 .option dkim_verify_minimal main boolean false
 If set to true, verification of signatures will terminate after the
 first success.
-.wen
 
 .option dkim_verify_signers main "domain list&!!" $dkim_signers
 .cindex DKIM "controlling calls to the ACL"
@@ -15253,11 +15239,9 @@ domain matches this list.
 This is a fudge to help with name servers that give big delays or otherwise do
 not work for the AAAA record type. In due course, when the world's name
 servers have all been upgraded, there should be no need for this option.
-.new
 Note that all lookups, including those done for verification, are affected;
 this will result in verify failure for IPv6 connections or ones using names
 only valid for IPv6 addresses.
-.wen
 
 
 .option dns_retrans main time 0s
@@ -15464,8 +15448,8 @@ used. See chapter &<<CHAPsecurity>>& for a discussion of security issues.
 .cindex "Exim version"
 .cindex customizing "version number"
 .cindex "version number of Exim" override
-This option allows to override the &$version_number$&/&$exim_version$& Exim reports in
-various places.  Use with care, this may fool stupid security scanners.
+This option overrides the &$version_number$&/&$exim_version$& that Exim reports in
+various places.  Use with care; this may fool stupid security scanners.
 
 
 .option extra_local_interfaces main "string list" unset
@@ -16088,10 +16072,8 @@ when Exim is entered, so it can, for example, contain a reference to the host
 name. If no specific path is set for the log files at compile or runtime,
 or if the option is unset at runtime (i.e.  &`log_file_path = `&)
 they are written in a sub-directory called &_log_& in Exim's spool directory.
-.new
 A path must start with a slash.
 To send to syslog, use the word &"syslog"&.
-.wen
 Chapter &<<CHAPlog>>& contains further details about Exim's logging, and
 section &<<SECTwhelogwri>>& describes how the contents of &%log_file_path%& are
 used. If this string is fixed at your installation (contains no expansion
@@ -16298,7 +16280,7 @@ harm. This option overrides the &%pipe_as_creator%& option of the &(pipe)&
 transport driver.
 
 
-.option openssl_options main "string list" "+no_sslv2 +no_sslv3 +single_dh_use +no_ticket"
+.option openssl_options main "string list" "+no_sslv2 +no_sslv3 +single_dh_use +no_ticket +no_renegotiation"
 .cindex "OpenSSL "compatibility options"
 This option allows an administrator to adjust the SSL options applied
 by OpenSSL to connections.  It is given as a space-separated list of items,
@@ -16439,9 +16421,9 @@ interpreter. See chapter &<<CHAPperl>>& for details of its use.
 This option is available only when Exim is built with an embedded Perl
 interpreter. See chapter &<<CHAPperl>>& for details of its use.
 
-.option perl_startup main boolean false
+.option perl_taintmode main boolean false
 .cindex "Perl"
-This Option enables the taint mode of the embedded Perl interpreter.
+This option enables the taint mode of the embedded Perl interpreter.
 
 
 .option pgsql_servers main "string list" unset
@@ -16478,7 +16460,6 @@ for each SMTP command and response. When PIPELINING is advertised, Exim assumes
 that clients will use it; &"out of order"& commands that are &"expected"& do
 not count as protocol errors (see &%smtp_max_synprot_errors%&).
 
-.new
 .option pipelining_connect_advertise_hosts main "host list&!!" *
 .cindex "pipelining" "early connection"
 .cindex "pipelining" PIPE_CONNECT
@@ -16488,8 +16469,9 @@ and from which pipeline early-connection (before MAIL) SMTP
 commands are acceptable.
 When used, the pipelining saves on roundtrip times.
 
+See also the &%hosts_pipe_connect%& smtp transport option.
+
 Currently the option name &"X_PIPE_CONNECT"& is used.
-.wen
 
 
 .option prdr_enable main boolean false
@@ -16752,7 +16734,6 @@ used. If the expansion yields an empty string, no &'Received:'& header line is
 added to the message. Otherwise, the string should start with the text
 &"Received:"& and conform to the RFC 2822 specification for &'Received:'&
 header lines.
-.new
 The default setting is:
 
 .code
@@ -16771,7 +16752,6 @@ received_header_text = Received: \
   id $message_exim_id\
   ${if def:received_for {\n\tfor $received_for}}
 .endd
-.wen
 
 The reference to the TLS cipher is omitted when Exim is built without TLS
 support. The use of conditional expansions ensures that this works for both
@@ -16950,12 +16930,6 @@ it qualifies them only if the message came from a host that matches
 &%sender_unqualified_hosts%&, or if the message was submitted locally (not
 using TCP/IP), and the &%-bnq%& option was not set.
 
-.option add_environment main "string list" empty
-.cindex "environment"
-This option allows to add individual environment variables that the
-currently linked libraries and programs in child processes use. The
-default list is empty.
-
 
 .option slow_lookup_log main integer 0
 .cindex "logging" "slow lookups"
@@ -17713,9 +17687,7 @@ separator in the usual way (&<<SECTlistsepchange>>&) to avoid confusion under IP
 &*Note*&: Under versions of OpenSSL preceding 1.1.1,
 when a list of more than one
 file is used, the &$tls_in_ourcert$& variable is unreliable.
-
-&*Note*&: OCSP stapling is not usable under OpenSSL
-when a list of more than one file is used.
+The macro "_TLS_BAD_MULTICERT_IN_OURCERT" will be defined for those versions.
 
 If the option contains &$tls_out_sni$& and Exim is built against OpenSSL, then
 if the OpenSSL build supports TLS extensions and the TLS client sends the
@@ -17766,10 +17738,8 @@ larger prime than requested.
 The value of this option is expanded and indicates the source of DH parameters
 to be used by Exim.
 
-.new
 This option is ignored for GnuTLS version 3.6.0 and later.
 The library manages parameter negotiation internally.
-.wen
 
 &*Note: The Exim Maintainers strongly recommend,
 for other TLS library versions,
@@ -17868,23 +17838,29 @@ status proof for the server's certificate, as obtained from the
 Certificate Authority.
 
 Usable for GnuTLS 3.4.4 or 3.3.17 or OpenSSL 1.1.0 (or later).
+The macro "_HAVE_TLS_OCSP" will be defined for those versions.
 
-.new
 For OpenSSL 1.1.0 or later, and
-.wen
 for GnuTLS 3.5.6 or later the expanded value of this option can be a list
 of files, to match a list given for the &%tls_certificate%& option.
 The ordering of the two lists must match.
+The macro "_HAVE_TLS_OCSP_LIST" will be defined for those versions.
 
-.new
 The file(s) should be in DER format,
-except for GnuTLS 3.6.3 or later when an optional filetype prefix
-can be used.  The prefix must be one of "DER" or "PEM", followed by
+except for GnuTLS 3.6.3 or later
+or for OpenSSL,
+when an optional filetype prefix can be used.
+The prefix must be one of "DER" or "PEM", followed by
 a single space.  If one is used it sets the format for subsequent
 files in the list; the initial format is DER.
-When a PEM format file is used it may contain multiple proofs,
-for multiple certificate chain element proofs under TLS1.3.
-.wen
+If multiple proofs are wanted, for multiple chain elements
+(this only works under TLS1.3)
+they must be coded as a combined OCSP response.
+
+Although GnuTLS will accept PEM files with multiple separate
+PEM blobs (ie. separate OCSP responses), it sends them in the
+TLS Certificate record interleaved with the certificates of the chain;
+although a GnuTLS client is happy with that, an OpenSSL client is not.
 
 .option tls_on_connect_ports main "string list" unset
 .cindex SSMTP
@@ -18193,9 +18169,7 @@ file = ${extract{mailbox}{$address_data}}
 This makes the configuration file less messy, and also reduces the number of
 lookups (though Exim does cache lookups).
 
-.new
 See also the &%set%& option below.
-.wen
 
 .vindex "&$sender_address_data$&"
 .vindex "&$address_data$&"
@@ -18402,7 +18376,7 @@ or for any deliveries caused by this router. You should not set this option
 unless you really, really know what you are doing. See also the generic
 transport option of the same name.
 
-.option dnssec_request_domains routers "domain list&!!" unset
+.option dnssec_request_domains routers "domain list&!!" *
 .cindex "MX record" "security"
 .cindex "DNSSEC" "MX lookup"
 .cindex "security" "MX lookup"
@@ -18978,7 +18952,6 @@ latter kind.
 
 This option controls whether the local part is used to form the key for retry
 hints for addresses that suffer temporary errors while being handled by this
-.new
 router. The default value is true for any router that has any of
 &%check_local_user%&,
 &%local_parts%&,
@@ -18987,7 +18960,6 @@ router. The default value is true for any router that has any of
 &%local_part_suffix%&,
 &%senders%& or
 &%require_files%&
-.wen
 set, and false otherwise. Note that this option does not apply to hints keys
 for transport delays; they are controlled by a generic transport option of the
 same name.
@@ -19124,7 +19096,6 @@ SMTP VRFY command is enabled, it must be used after MAIL if the sender address
 matters.
 
 
-.new
 .option set routers "string list" unset
 .cindex router variables
 This option may be used multiple times on a router;
@@ -19132,7 +19103,7 @@ because of this the list aspect is mostly irrelevant.
 The list separator is a semicolon but can be changed in the
 usual way.
 
-Each list-element given must be of the form $"name = value"$
+Each list-element given must be of the form &"name = value"&
 and the names used must start with the string &"r_"&.
 Values containing a list-separator should have them doubled.
 When a router runs, the strings are evaluated in order,
@@ -19143,11 +19114,10 @@ The variables can be used by the router options
 (not including any preconditions)
 and by the transport.
 Later definitions of a given named variable will override former ones.
-Varible use is via the usual &$r_...$& syntax.
+Variable use is via the usual &$r_...$& syntax.
 
 This is similar to the &%address_data%& option, except that
 many independent variables can be used, with choice of naming.
-.wen
 
 
 .option translate_ip_address routers string&!! unset
@@ -22930,14 +22900,12 @@ sometimes add other information onto the ends of message filenames.
 
 Section &<<SECID136>>& contains further information.
 
-.new
 This option should not be used when other message-handling software
 may duplicate messages by making hardlinks to the files.  When that is done Exim
 will count the message size once for each filename, in contrast with the actual
 disk usage.  When the option is not set, calculating total usage requires
 a system-call per file to get the size; the number of links is then available also
 as is used to adjust the effective size.
-.wen
 
 
 .option quota_warn_message appendfile string&!! "see below"
@@ -24591,7 +24559,7 @@ See the &%search_parents%& option in chapter &<<CHAPdnslookup>>& for more
 details.
 
 
-.option dnssec_request_domains smtp "domain list&!!" unset
+.option dnssec_request_domains smtp "domain list&!!" *
 .cindex "MX record" "security"
 .cindex "DNSSEC" "MX lookup"
 .cindex "security" "MX lookup"
@@ -24756,7 +24724,6 @@ facilities such as AUTH, PIPELINING, SIZE, and STARTTLS.
 Exim will not use the SMTP PIPELINING extension when delivering to any host
 that matches this list, even if the server host advertises PIPELINING support.
 
-.new
 .option hosts_pipe_connect smtp "host list&!!" unset
 .cindex "pipelining" "early connection"
 .cindex "pipelining" PIPE_CONNECT
@@ -24770,6 +24737,8 @@ When used, the pipelining saves on roundtrip times.
 It also turns SMTP into a client-first protocol
 so combines well with TCP Fast Open.
 
+See also the &%pipelining_connect_advertise_hosts%& main option.
+
 Note:
 When the facility is used, the transport &%helo_data%& option
 will be expanded before the &$sending_ip_address$& variable
@@ -24778,7 +24747,6 @@ A check is made for the use of that variable, without the
 presence of a &"def:"& test on it, but suitably complex coding
 can avoid the check and produce unexpected results.
 You have been warned.
-.wen
 
 
 .option hosts_avoid_tls smtp "host list&!!" unset
@@ -24819,7 +24787,6 @@ been started will not be passed to a new delivery process for sending another
 message on the same connection. See section &<<SECTmulmessam>>& for an
 explanation of when this might be needed.
 
-.new
 .option hosts_noproxy_tls smtp "host list&!!" unset
 .cindex "TLS" "passing connection"
 .cindex "multiple SMTP deliveries"
@@ -24827,7 +24794,6 @@ explanation of when this might be needed.
 For any host that matches this list, a TLS session which has
 been started will not be passed to a new delivery process for sending another
 message on the same session.
-.wen
 
 The traditional implementation closes down TLS and re-starts it in the new
 process, on the same open TCP connection, for each successive message
@@ -26481,10 +26447,8 @@ authentication mechanism (RFC 2195), and the second provides an interface to
 the Cyrus SASL authentication library.
 The third is an interface to Dovecot's authentication system, delegating the
 work via a socket interface.
-.new
 The fourth provides for negotiation of authentication done via non-SMTP means,
 as defined by RFC 4422 Appendix A.
-.wen
 The fifth provides an interface to the GNU SASL authentication library, which
 provides mechanisms but typically not data sources.
 The sixth provides direct access to Heimdal GSSAPI, geared for Kerberos, but
@@ -26909,7 +26873,19 @@ security risk; you are strongly advised to insist on the use of SMTP encryption
 use unencrypted plain text, you should not use the same passwords for SMTP
 connections as you do for login accounts.
 
-.section "Plaintext options" "SECID171"
+.section "Avoiding cleartext use" "SECTplain_TLS"
+The following generic option settings will disable &(plaintext)& authenticators when
+TLS is not being used:
+.code
+  server_advertise_condition = ${if def:tls_in_cipher }
+  client_condition =           ${if def:tls_out_cipher}
+.endd
+
+&*Note*&: a plaintext SMTP AUTH done inside TLS is not vulnerable to casual snooping,
+but is still vulnerable to a Man In The Middle attack unless certificates
+(including their names) have been properly verified.
+
+.section "Plaintext server options" "SECID171"
 .cindex "options" "&(plaintext)& authenticator (server)"
 When configured as a server, &(plaintext)& uses the following options:
 
@@ -26917,7 +26893,7 @@ When configured as a server, &(plaintext)& uses the following options:
 This is actually a global authentication option, but it must be set in order to
 configure the &(plaintext)& driver as a server. Its use is described below.
 
-.option server_prompts plaintext string&!! unset
+.option server_prompts plaintext "string list&!!" unset
 The contents of this option, after expansion, must be a colon-separated list of
 prompt strings. If expansion fails, a temporary authentication rejection is
 given.
@@ -27835,11 +27811,10 @@ of your configured trust-anchors
 (which usually means the full set of public CAs)
 and which has a mail-SAN matching the claimed identity sent by the client.
 
-Note that, up to TLS1.2, the client cert is on the wire in-clear, including the SAN,
+&*Note*&: up to TLS1.2, the client cert is on the wire in-clear, including the SAN.
 The account name is therefore guessable by an opponent.
 TLS 1.3 protects both server and client certificates, and is not vulnerable
 in this way.
-Likewise, a traditional plaintext SMTP AUTH done inside TLS is not.
 
 
 .section "Using external in a client" "SECTexternclient"
@@ -28052,16 +28027,19 @@ There is also a &%-tls-on-connect%& command line option. This overrides
 
 .section "OpenSSL vs GnuTLS" "SECTopenvsgnu"
 .cindex "TLS" "OpenSSL &'vs'& GnuTLS"
-The first TLS support in Exim was implemented using OpenSSL. Support for GnuTLS
-followed later, when the first versions of GnuTLS were released. To build Exim
-to use GnuTLS, you need to set
+TLS is supported in Exim using either the OpenSSL or GnuTLS library.
+To build Exim to use OpenSSL you need to set
 .code
-USE_GNUTLS=yes
+USE_OPENSSL=yes
 .endd
-in Local/Makefile, in addition to
+in Local/Makefile.
+
+To build Exim to use GnuTLS, you need to set
 .code
-SUPPORT_TLS=yes
+USE_GNUTLS=yes
 .endd
+in Local/Makefile.
+
 You must also set TLS_LIBS and TLS_INCLUDE appropriately, so that the
 include files and libraries for GnuTLS can be found.
 
@@ -28619,12 +28597,10 @@ transport provide the client with a certificate, which is passed to the server
 if it requests it. If the server is Exim, it will request a certificate only if
 &%tls_verify_hosts%& or &%tls_try_verify_hosts%& matches the client.
 
-.new
-Do not use a certificate which has the OCSP-must-staple extension,
+&*Note*&: Do not use a certificate which has the OCSP-must-staple extension,
 for client use (they are usable for server use).
-As TLS has no means for the client to staple before TLS 1.3 it will result
+As the TLS protocol has no means for the client to staple before TLS 1.3 it will result
 in failed connections.
-.wen
 
 If the &%tls_verify_certificates%& option is set on the &(smtp)& transport, it
 specifies a collection of expected server certificates.
@@ -29046,7 +29022,7 @@ those who use &%hosts_require_ocsp%&, should consider the interaction with DANE
 
 For client-side DANE there are three new smtp transport options, &%hosts_try_dane%&, &%hosts_require_dane%&
 and &%dane_require_tls_ciphers%&.
-The require variant will result in failure if the target host is not
+The &"require"& variant will result in failure if the target host is not
 DNSSEC-secured. To get DNSSEC-secured hostname resolution, use
 the &%dnssec_request_domains%& router or transport option.
 
@@ -29078,7 +29054,8 @@ If DANE is requested and useable (see above) the following transport options are
 If DANE is not usable, whether requested or not, and CA-anchored
 verification evaluation is wanted, the above variables should be set appropriately.
 
-Currently the (router or transport options) &%dnssec_request_domains%& must be active and &%dnssec_require_domains%& is ignored.
+The router and transport option &%dnssec_request_domains%& must not be
+set to &"never"&, and &%dnssec_require_domains%& is ignored.
 
 If verification was successful using DANE then the "CV" item in the delivery log line will show as "CV=dane".
 
@@ -31140,10 +31117,8 @@ case-sensitively; domains are checked case-insensitively. If &'Resent-To:'& or
 &'Resent-Cc:'& header lines exist, they are also checked. This condition can be
 used only in a DATA or non-SMTP ACL.
 
-.new
 There is one possible option, &`case_insensitive`&.  If this is present then
 local parts are checked case-insensitively.
-.wen
 
 There are, of course, many legitimate messages that make use of blind (bcc)
 recipients. This check should not be used on its own for blocking messages.
@@ -32751,14 +32726,12 @@ It supports a &"generic"& interface to scanners called via the shell, and
 specialized interfaces for &"daemon"& type virus scanners, which are resident
 in memory and thus are much faster.
 
-.new
 Since message data needs to have arrived,
 the condition may be only called in ACL defined by
 &%acl_smtp_data%&,
 &%acl_smtp_data_prdr%&,
 &%acl_smtp_mime%& or
 &%acl_smtp_dkim%&
-.wen
 
 A timeout of 2 minutes is applied to a scanner call (by default);
 if it expires then a defer action is taken.
@@ -34298,8 +34271,8 @@ with translation.
 This function is used in conjunction with &'smtp_printf()'&, as described
 below.
 
-.vitem &*void&~smtp_printf(char&~*,&~...)*&
-The arguments of this function are like &[printf()]&; it writes to the SMTP
+.vitem &*void&~smtp_printf(char&~*,BOOL,&~...)*&
+The arguments of this function are almost like &[printf()]&; it writes to the SMTP
 output stream. You should use this function only when there is an SMTP output
 stream, that is, when the incoming message is being received via interactive
 SMTP. This is the case when &%smtp_input%& is TRUE and &%smtp_batched_input%&
@@ -34311,6 +34284,15 @@ is involved.
 If an SMTP TLS connection is established, &'smtp_printf()'& uses the TLS
 output function, so it can be used for all forms of SMTP connection.
 
+The second argument is used to request that the data be buffered
+(when TRUE) or flushed (along with any previously buffered, when FALSE).
+This is advisory only, but likely to save on system-calls and packets
+sent when a sequence of calls to the function are made.
+
+The argument was added in Exim version 4.90 - changing the API/ABI.
+Nobody noticed until 4.93 was imminent, at which point the
+ABI version number was incremented.
+
 Strings that are written by &'smtp_printf()'& from within &[local_scan()]&
 must start with an appropriate response code: 550 if you are going to return
 LOCAL_SCAN_REJECT, 451 if you are going to return
@@ -34328,7 +34310,9 @@ the data returned via the &%return_text%& argument. The added value of using
 multiple output lines.
 
 The &'smtp_printf()'& function does not return any error indication, because it
-does not automatically flush pending output, and therefore does not test
+does not
+guarantee a flush of
+pending output, and therefore does not test
 the state of the stream. (In the main code of Exim, flushing and error
 detection is done when Exim is ready for the next SMTP input command.) If
 you want to flush the output and check for an error (for example, the
@@ -37608,7 +37592,6 @@ connection is unexpectedly dropped.
 &%millisec%&: Timestamps have a period and three decimal places of finer granularity
 appended to the seconds value.
 .next
-.new
 .cindex "log" "message id"
 &%msg_id%&: The value of the Message-ID: header.
 .next
@@ -37616,7 +37599,6 @@ appended to the seconds value.
 This will be either because the message is a bounce, or was submitted locally
 (submission mode) without one.
 The field identifier will have an asterix appended: &"id*="&.
-.wen
 .next
 .cindex "log" "outgoing interface"
 .cindex "log" "local interface"
@@ -37653,13 +37635,11 @@ The field is a single "L".
 On accept lines, where PIPELINING was offered but not used by the client,
 the field has a minus appended.
 
-.new
 .cindex "pipelining" "early connection"
 If Exim is built with the SUPPORT_PIPE_CONNECT build option
 accept "L" fields have a period appended if the feature was
 offered but not used, or an asterisk appended if used.
 Delivery "L" fields have an asterisk appended if used.
-.wen
 
 .next
 .cindex "log" "queue run"
@@ -38017,10 +37997,8 @@ Match only frozen messages.
 .vitem &*-x*&
 Match only non-frozen messages.
 
-.new
 .vitem &*-G*&&~<&'queuename'&>
 Match only messages in the given queue.  Without this, the default queue is searched.
-.wen
 .endlist
 
 The following options control the format of the output:
@@ -39708,10 +39686,8 @@ was received from the client, this records the Distinguished Name from that
 certificate.
 .endlist
 
-.new
 Any of the above may have an extra hyphen prepended, to indicate the the
 corresponding data is untrusted.
-.wen
 
 Following the options there is a list of those addresses to which the message
 is not to be delivered. This set of addresses is initialized from the command
@@ -39901,9 +39877,7 @@ These options take (expandable) strings as arguments.
 The domain(s) you want to sign with.
 After expansion, this can be a list.
 Each element in turn,
-.new
 lowercased,
-.wen
 is put into the &%$dkim_domain%& expansion variable
 while expanding the remaining signing options.
 If it is empty after expansion, DKIM signing is not done,
@@ -39958,9 +39932,7 @@ Signers MUST use RSA keys of at least 1024 bits for all keys.
 Signers SHOULD use RSA keys of at least 2048 bits.
 .endd
 
-.new
 EC keys for DKIM are defined by RFC 8463.
-.wen
 They are considerably smaller than RSA keys for equivalent protection.
 As they are a recent development, users should consider dual-signing
 (by setting a list of selectors, and an expansion for this option)
@@ -39980,12 +39952,10 @@ openssl pkey -outform DER -pubout -in dkim_ed25519.private | tail -c +13 | base6
 certtool --load_privkey=dkim_ed25519.private --pubkey_info --outder | tail -c +13 | base64
 .endd
 
-.new
 Exim also supports an alternate format
 of Ed25519 keys in DNS which was a candidate during development
 of the standard, but not adopted.
 A future release will probably drop that support.
-.wen
 
 .option dkim_hash smtp string&!! sha256
 Can be set to any one of the supported hash methods, which are:
@@ -40059,22 +40029,18 @@ RFC 6376 lists these tags as RECOMMENDED.
 
 Verification of DKIM signatures in SMTP incoming email is done for all
 messages for which an ACL control &%dkim_disable_verify%& has not been set.
-.new
 .cindex DKIM "selecting signature algorithms"
 Individual classes of signature algorithm can be ignored by changing
 the main options &%dkim_verify_hashes%& or &%dkim_verify_keytypes%&.
 The &%dkim_verify_minimal%& option can be set to cease verification
 processing for a message once the first passing signature is found.
-.wen
 
 .cindex authentication "expansion item"
 Performing verification sets up information used by the
 &%authresults%& expansion item.
 
-.new
 For most purposes the default option settings suffice and the remainder
 of this section can be ignored.
-.wen
 
 The results of verification are made available to the
 &%acl_smtp_dkim%& ACL, which can examine and modify them.
@@ -40121,13 +40087,11 @@ dkim_verify_signers = $sender_address_domain:$dkim_signers
 If a domain or identity is listed several times in the (expanded) value of
 &%dkim_verify_signers%&, the ACL is only called once for that domain or identity.
 
-.new
 Note that if the option is set using untrustworthy data
 (such as the From: header)
 care should be taken to force lowercase for domains
 and for the domain part if identities.
 The default setting can be regarded as trustworthy in this respect.
-.wen
 
 If multiple signatures match a domain (or identity), the ACL is called once
 for each matching signature.
@@ -40229,10 +40193,8 @@ algorithms (currently, rsa-sha1) have permanently failed evaluation
 
 To enforce this you must either have a DKIM ACL which checks this variable
 and overwrites the &$dkim_verify_status$& variable as discussed above,
-.new
 or have set the main option &%dkim_verify_hashes%& to exclude
 processing of such signatures.
-.wen
 
 .vitem &%$dkim_canon_body%&
 The body canonicalization method. One of 'relaxed' or 'simple'.
@@ -40347,8 +40309,12 @@ for more information of what they mean.
 
 SPF is a mechanism whereby a domain may assert which IP addresses may transmit
 messages with its domain in the envelope from, documented by RFC 7208.
-For more information on SPF see &url(http://www.openspf.org).
-. --- 2018-09-07: still not https
+For more information on SPF see &url(http://www.open-spf.org), a static copy of
+the &url(http://openspf.org).
+. --- 2019-10-28: still not https, open-spf.org is told to be a
+. --- web-archive copy of the now dead openspf.org site
+. --- See https://www.mail-archive.com/mailop@mailop.org/msg08019.html for a
+. --- discussion.
 
 Messages sent by a system not authorised will fail checking of such assertions.
 This includes retransmissions done by traditional forwarders.
@@ -40411,7 +40377,7 @@ deny spf = fail
      message = $sender_host_address is not allowed to send mail from \
                ${if def:sender_address_domain \
                     {$sender_address_domain}{$sender_helo_name}}.  \
-               Please see http://www.openspf.org/Why?scope=\
+               Please see http://www.open-spf.org/Why?scope=\
                ${if def:sender_address_domain {mfrom}{helo}};\
                identity=${if def:sender_address_domain \
                              {$sender_address}{$sender_helo_name}};\
@@ -40464,9 +40430,9 @@ In addition to SPF, you can also perform checks for so-called
 "Best-guess".  Strictly speaking, "Best-guess" is not standard
 SPF, but it is supported by the same framework that enables SPF
 capability.
-Refer to &url(http://www.openspf.org/FAQ/Best_guess_record)
+Refer to &url(http://www.open-spf.org/FAQ/Best_guess_record)
 for a description of what it means.
-. --- 2018-09-07: still not https:
+. --- 2019-10-28: still not https:
 
 To access this feature, simply use the spf_guess condition in place
 of the spf one.  For example:
@@ -40500,9 +40466,7 @@ would relax host matching rules to a broader network range.
 .cindex lookup spf
 A lookup expansion is also available. It takes an email
 address as the key and an IP address
-.new
 (v4 or v6)
-.wen
 as the database:
 
 .code
@@ -40516,7 +40480,6 @@ The lookup will return the same result strings as can appear in
 
 
 
-.new
 .section DMARC SECDMARC
 .cindex DMARC verification
 
@@ -40531,7 +40494,7 @@ the libopendmarc library is used.
 
 For building Exim yourself, obtain the library from
 &url(http://sourceforge.net/projects/opendmarc/)
-to obtain a copy, or find it in your favorite rpm package
+to obtain a copy, or find it in your favorite package
 repository.  You will need to attend to the local/Makefile feature
 SUPPORT_DMARC and the associated LDFLAGS addition.
 This description assumes
@@ -40587,7 +40550,7 @@ non-authenticated user.  It makes sense to only verify DMARC
 status of messages coming from remote, untrusted sources.  You can
 use standard conditions such as hosts, senders, etc, to decide that
 DMARC verification should *not* be performed for them and disable
-DMARC with a control setting:
+DMARC with an ACL control modifier:
 .code
   control = dmarc_disable_verify
 .endd
@@ -40598,15 +40561,15 @@ results in unintended information leakage (what lists a user might
 be subscribed to, etc).  You must configure exim to submit forensic
 reports to the owner of the domain.  If the DMARC record contains a
 forensic address and you specify the control statement below, then
-exim will send these forensic emails.  It's also advised that you
-configure a dmarc_forensic_sender because the default sender address
+exim will send these forensic emails.  It is also advised that you
+configure a &%dmarc_forensic_sender%& because the default sender address
 construction might be inadequate.
 .code
   control = dmarc_enable_forensic
 .endd
 (AGAIN: You can choose not to send these forensic reports by simply
 not putting the dmarc_enable_forensic control line at any point in
-your exim config.  If you don't tell it to send them, it will not
+your exim config.  If you don't tell exim to send them, it will not
 send them.)
 
 There are no options to either control.  Both must appear before
@@ -40615,14 +40578,14 @@ the DATA acl.
 . subsection
 
 DMARC checks cam be run on incoming SMTP  messages by using the
-"dmarc_status" ACL condition in the DATA ACL.  You are required to
-call the "spf" condition first in the ACLs, then the "dmarc_status"
+&"dmarc_status"& ACL condition in the DATA ACL.  You are required to
+call the &"spf"& condition first in the ACLs, then the &"dmarc_status"&
 condition.  Putting this condition in the ACLs is required in order
 for a DMARC check to actually occur.  All of the variables are set
 up before the DATA ACL, but there is no actual DMARC check that
-occurs until a "dmarc_status" condition is encountered in the ACLs.
+occurs until a &"dmarc_status"& condition is encountered in the ACLs.
 
-The dmarc_status condition takes a list of strings on its
+The &"dmarc_status"& condition takes a list of strings on its
 right-hand side.  These strings describe recommended action based
 on the DMARC check.  To understand what the policy recommendations
 mean, refer to the DMARC website above.  Valid strings are:
@@ -40655,28 +40618,30 @@ Several expansion variables are set before the DATA ACL is
 processed, and you can use them in this ACL.  The following
 expansion variables are available:
 
-&$dmarc_status$&
+.vlist
+.vitem &$dmarc_status$&
 .vindex &$dmarc_status$&
 .cindex DMARC result
-is a one word status indicating what the DMARC library
+A one word status indicating what the DMARC library
 thinks of the email.  It is a combination of the results of
 DMARC record lookup and the SPF/DKIM/DMARC processing results
 (if a DMARC record was found).  The actual policy declared
 in the DMARC record is in a separate expansion variable.
 
-&$dmarc_status_text$&
+.vitem &$dmarc_status_text$&
 .vindex &$dmarc_status_text$&
-is a slightly longer, human readable status.
+Slightly longer, human readable status.
 
-&$dmarc_used_domain$&
+.vitem &$dmarc_used_domain$&
 .vindex &$dmarc_used_domain$&
-is the domain which DMARC used to look up the DMARC policy record.
+The domain which DMARC used to look up the DMARC policy record.
 
-&$dmarc_domain_policy$&
+.vitem &$dmarc_domain_policy$&
 .vindex &$dmarc_domain_policy$&
-is the policy declared in the DMARC record.  Valid values
+The policy declared in the DMARC record.  Valid values
 are "none", "reject" and "quarantine".  It is blank when there
 is any error, including no DMARC record.
+.endlist
 
 . subsection
 
@@ -40691,7 +40656,7 @@ processing or failure delivery issues).
 In order to log statistics suitable to be imported by the opendmarc
 tools, you need to:
 .ilist
-Configure the global setting dmarc_history_file
+Configure the global option &%dmarc_history_file%&
 .next
 Configure cron jobs to call the appropriate opendmarc history
 import scripts and truncating the dmarc_history_file
@@ -40699,7 +40664,7 @@ import scripts and truncating the dmarc_history_file
 
 In order to send forensic reports, you need to:
 .ilist
-Configure the global setting dmarc_forensic_sender
+Configure the global option &%dmarc_forensic_sender%&
 .next
 Configure, somewhere before the DATA ACL, the control option to
 enable sending DMARC forensic reports
@@ -40745,7 +40710,6 @@ Example usage:
   warn    add_header     = :at_start:${authresults {$primary_hostname}}
 .endd
 
-.wen
 
 
 
@@ -41074,9 +41038,7 @@ Events have names which correspond to the point in process at which they fire.
 The name is placed in the variable &$event_name$& and the event action
 expansion must check this, as it will be called for every possible event type.
 
-.new
 The current list of events is:
-.wen
 .display
 &`dane:fail              after    transport  `& per connection
 &`msg:complete           after    main       `& per message
index 9f18a20732ab2db08a0593bb7e403b4746992219..9f8775f0f89ba5cc2f33a6a4dd7c562cca6ad0c0 100644 (file)
@@ -1,12 +1,10 @@
-Change log file for Exim from version 4.21
-------------------------------------------
 This document describes *changes* to previous versions, that might
 affect Exim's operation, with an unchanged configuration file.  For new
 options, and new features, see the NewStuff file next to this ChangeLog.
 
 
-Exim version 4.next
--------------------
+Exim version 4.94
+-----------------
 
 JH/01 Avoid costly startup code when not strictly needed.  This reduces time
       for some exim process initialisations.  It does mean that the logging
@@ -214,14 +212,37 @@ JH/41 With GnuTLS 3.6.0 (and later) do not attempt to manage Diffie-Hellman
       function is unnecessary and discouraged on GnuTLS 3.6.0 or later. Since
       3.6.0, DH parameters are negotiated following RFC7919."
 
+HS/06 Change the default of dnssec_request_domains to "*"
+
+JH/42 Bug 2545: Fix CHUNKING for all RCPT commands rejected.  Previously we
+      carried on and emitted a BDAT command, even when PIPELINING was not
+      active.
+
 JH/43 Bug 2465: Fix taint-handling in dsearch lookup.  Previously a nontainted
       buffer was used for the filename, resulting in a trap when tainted
       arguments (eg. $domain) were used.
 
+JH/44 With OpenSSL 1.1.1 (onwards) disable renegotiation for TLS1.2 and below;
+      recommended to avoid a possible server-load attack.  The feature can be
+      re-enabled via the openssl_options main cofiguration option.
+
+JH/45 local_scan API: documented the current smtp_printf() call. This changed
+      for version 4.90 - adding a "more data" boolean to the arguments.
+      Bumped the ABI version number also, this having been missed previously;
+      release versions 4.90 to 4.92.3 inclusive were effectively broken in
+      respect of usage of smtp_printf() by either local_scan code or libraries
+      accessed via the ${dlfunc } expansion item.  Both will need coding
+      adjustment for any calls to smtp_printf() to match the new function
+      signature; a FALSE value for the new argument is always safe.
+
 JH/46 FreeBSD: fix use of the sendfile() syscall.  The shim was not updating
       the file-offset (which the Linux syscall does, and exim expects); this
       resulted in an indefinite loop.
 
+JH/47 ARC: fix crash in signing, triggered when a configuration error failed
+      to do ARC verification.  The Authentication-Results: header line added
+      by the configuration then had no ARC item.
+
 
 Exim version 4.92
 -----------------
index 18c3d30243f2d365e39b82a371474f45b8cc58d7..763a806a579bc37f78c436954d19245772e05ad6 100644 (file)
@@ -6,15 +6,13 @@ Before a formal release, there may be quite a lot of detail so that people can
 test from the snapshots or the Git before the documentation is updated. Once
 the documentation is updated, this file is reduced to a short list.
 
-Version 4.next
---------------
+Version 4.94
+------------
 
  1. EXPERIMENTAL_SRS_NATIVE optional build feature.  See the experimental.spec
     file.
 
- 2. Variables $tls_in_ver, $tls_out_ver.
-
- 3. Channel-binding for authenticators is now supported under OpenSSL.
+ 2. Channel-binding for authenticators is now supported under OpenSSL.
     Previously it was GnuTLS-only.
 
 
@@ -47,12 +45,23 @@ Version 4.93
 
 11. Main options for DKIM verify to filter hash and key types.
 
-12. Under GnuTLS, with TLS1.3, support for full-chain OCSP stapling.
+12. With TLS1.3, support for full-chain OCSP stapling.
 
 13. Dual-certificate stacks on servers now support OCSP stapling, under OpenSSL.
 
 14: An smtp:ehlo transport event, for observability of the remote offered features.
 
+15: Support under OpenSSL for writing NSS-style key files for packet-capture
+    decode.  The environment variable SSLKEYLOGFILE is used; if an absolute path
+    it must indicate a file under the spool directory; if relative the the spool
+    directory is prepended.  Works on the server side only.  Support under 
+    GnuTLS was already there, being done purely by the library (server side
+    only, and exim must be run as root).
+
+16: Command-line option to move messages from one named queue to another.
+
+17. Variables $tls_in_ver, $tls_out_ver.
+
 
 Version 4.92
 --------------
index e9a557aec8930413d98f7ae2ee585321af5453d1..2569ad3af2b76f7d0ea371a8b00703805932fed5 100644 (file)
@@ -642,6 +642,9 @@ ARC support
 Specification: https://tools.ietf.org/html/draft-ietf-dmarc-arc-protocol-11
 Note that this is not an RFC yet, so may change.
 
+[RFC 8617 was published 2019/06.  Draft 11 was 2018/01.  A review of the
+changes has not yet been done]
+
 ARC is intended to support the utility of SPF and DKIM in the presence of
 intermediaries in the transmission path - forwarders and mailinglists -
 by establishing a cryptographically-signed chain in headers.
@@ -650,10 +653,18 @@ Normally one would only bother doing ARC-signing when functioning as
 an intermediary.  One might do verify for local destinations.
 
 ARC uses the notion of a "ADministrative Management Domain" (ADMD).
-Described in RFC 5598 (section 2.3), this is essentially the set of
-mail-handling systems that the mail transits.  A label should be chosen to
-identify the ADMD.  Messages should be ARC-verified on entry to the ADMD,
-and ARC-signed on exit from it.
+Described in RFC 5598 (section 2.3), this is essentially a set of
+mail-handling systems that mail transits that are all under the control
+of one organisation.  A label should be chosen to identify the ADMD.
+Messages should be ARC-verified on entry to the ADMD, and ARC-signed on exit
+from it.
+
+
+Building with ARC Support
+--
+Enable using EXPERIMENTAL_ARC=yes in your Local/Makefile.
+You must also have DKIM present (not disabled), and you very likely
+want to have SPF enabled.
 
 
 Verification
index e3675327f4414b224b4bcd82eaa6bf91618e53ba..a4111e5664fc1f0716c36f356e1dcb447b717d53 100755 (executable)
@@ -256,8 +256,8 @@ package Context {
 
             #my $stamp = $context->{minor} ? '_'.$context->{minor} : '';
             #$stamp .= $context->{rc} if $context->{rc};
-            my $release = $context->{v}{rc} ? $context->{v}{target_release}
-                                            : $context->{v}{last_tag};
+            my $release = $context->{quick} ? $context->{v}{last_tag}
+                                            : $context->{v}{target_release};
 
             my $variant =
                   $context->{v}{rc} ? $context->{v}{rc}
@@ -486,7 +486,7 @@ __
 
         # See also environment variables set in main, tuning compression levels
 
-        my (%size, %sha256);
+        my (%size, %sha256, %sha512);
 
         foreach my $dir ( glob( catdir( $pkg_trees, ( 'exim*-' . $context->{v}{release} ) ) ) ) {
             my $dirname = ( splitdir($dir) )[-1];
@@ -506,24 +506,30 @@ __
 
                 # calculate size and md5sum
                 $size{$basename} = -s $outfile;
-                $sha256{$basename} = do {
-                    my $sha = Digest::SHA->new(256);
-                    $sha->addfile($outfile);
-                    $sha->hexdigest;
-                };
+                $sha256{$basename} = Digest::SHA->new(256)->addfile($outfile)->hexdigest;
+                $sha512{$basename} = Digest::SHA->new(512)->addfile($outfile)->hexdigest;
             }
         }
 
         # write the sizes file
         if ($context->{sizes}) {
-            open my $sizes, '>', $_ = catfile $pkg_tars, 'sizes.txt'
-                or die "$ME: Can't open `$_': $!\n";
+            for ([ sizes => 'SIZE' => \%size ],
+                 [ sha256sums => 'SHA256' => \%sha256 ],
+                 [ sha512sums => 'SHA512' => \%sha512 ]) {
 
-            print $sizes join "\n",
-                (map { "SIZE($_) = $size{$_}" } sort keys %size),
-                (map { "SHA256($_) = $sha256{$_}" } sort keys %sha256);
+                my $outfile = catfile $pkg_tars, "00-$_->[0].txt";
+                my $tag = $_->[1];
+                my $sizes = $_->[2];
 
-            close($sizes) or die "$ME: Can't close $_: $!\n";
+                open my $out, '>', $outfile
+                    or die "$ME: Can't open `$outfile': $!\n";
+
+                print $out join "\n",
+                    (map { "$tag ($_) = $sizes->{$_}" } sort keys %$sizes),
+                    '';
+
+                close($out) or die "$ME: Can't close $outfile: $!\n";
+            }
         }
     }
 
index fef5609673c53d8ef3ef980abfa557c586df7887..1a2f8ecab05f103475a4bd881b506a2e11ebeede 100644 (file)
@@ -1,6 +1,4 @@
 # Exim: OS-specific make file for FreeBSD
-# There's no setting of CFLAGS here, to allow the system default
-# for "make" to be the default.
 
 CHOWN_COMMAND=/usr/sbin/chown
 STRIP_COMMAND=/usr/bin/strip
index b619f5e03851ff31f94867e721674ed9436ad2a6..db754da408a434654c75627f29f2f15cec62c007 100644 (file)
@@ -25,6 +25,37 @@ there have been two big upheavals...
 The rest of this document contains information about changes in 4.xx releases
 that might affect a running system.
 
+Exim version 4.93
+-----------------
+
+For a detailed list of changes that might affect Exim's operation with
+an unchanged configuration, please see the doc/ChangeLog file.
+
+Build:
+
+ * SUPPORT_DMARC replaces EXPERIMENTAL_DMARC
+
+ * DISABLE_TLS replaces SUPPORT_TLS
+
+ * Bump the version for the local_scan API.
+
+Runtime:
+
+ * smtp transport option hosts_try_fastopen defaults to "*".
+
+ * DNSSec is requested (not required) for all queries. (This seemes to
+   ask for trouble if your resolver is a systemd-resolved.)
+
+ * Generic router option retry_use_local_part defaults to "true" under specific
+   pre-conditions.
+
+ * Introduce a tainting mechanism for values read from untrusted sources.
+
+ * Use longer file names for temporary spool files (this avoids
+   name conflicts with spool on a shared file system).
+
+ * Use dsn_from main config option (was ignored previously).
+
 
 Exim version 4.92
 -----------------
index 1d916a559ba3d0eb386b707bfadcf3761935e3be..9024b6f73f5e833f5bb655e41f73e41c0522cd4a 100644 (file)
@@ -494,12 +494,12 @@ SUPPORT_DANE=yes
 #------------------------------------------------------------------------------
 # Compiling the Exim monitor: If you want to compile the Exim monitor, a
 # program that requires an X11 display, then EXIM_MONITOR should be set to the
-# value "eximon.bin". Comment out this setting to disable compilation of the
+# value "eximon.bin". De-comment this setting to enable compilation of the
 # monitor. The locations of various X11 directories for libraries and include
 # files are defaulted in the OS/Makefile-Default file, but can be overridden in
 # local OS-specific make files.
 
-EXIM_MONITOR=eximon.bin
+EXIM_MONITOR=eximon.bin
 
 
 #------------------------------------------------------------------------------
index 8e34513d0f22aaab950960232e5802153695e12d..799af39c3e72fefa9570cfda5bd6282d186c3cda 100644 (file)
@@ -1345,8 +1345,7 @@ extension to CSA, so we allow it to be turned off for proper conformance. */
 if (string_is_ip_address(domain, NULL) != 0)
   {
   if (!dns_csa_use_reverse) return CSA_UNKNOWN;
-  dns_build_reverse(domain, target);
-  domain = target;
+  domain = dns_build_reverse(domain);
   }
 
 /* Find out if we've already done the CSA check for this domain. If we have,
index 773b34c28da25758105d4f861072b98a292ed410..857e0c0468ca6095f0832e9ba6f81ec6afb1cdbb 100644 (file)
@@ -7,10 +7,8 @@
 */
 
 #include "exim.h"
-#ifdef EXPERIMENTAL_ARC
-# if !defined SUPPORT_SPF
-#  error SPF must also be enabled for ARC
-# elif defined DISABLE_DKIM
+#if defined EXPERIMENTAL_ARC
+# if defined DISABLE_DKIM
 #  error DKIM must also be enabled for ARC
 # else
 
@@ -544,7 +542,8 @@ hctx hhash_ctx;
 const uschar * s;
 int len;
 
-if (!exim_sha_init(&hhash_ctx, pdkim_hashes[hashtype].exim_hashmethod))
+if (  hashtype == -1
+   || !exim_sha_init(&hhash_ctx, pdkim_hashes[hashtype].exim_hashmethod))
   {
   DEBUG(D_acl)
       debug_printf("ARC: hash setup error, possibly nonhandled hashtype\n");
@@ -639,7 +638,7 @@ return p;
 static pdkim_bodyhash *
 arc_ams_setup_vfy_bodyhash(arc_line * ams)
 {
-int canon_head, canon_body;
+int canon_head = -1, canon_body = -1;
 long bodylen;
 
 if (!ams->c.data) ams->c.data = US"simple";    /* RFC 6376 (DKIM) default */
@@ -745,6 +744,11 @@ if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx)))
   }
 
 hashtype = pdkim_hashname_to_hashtype(ams->a_hash.data, ams->a_hash.len);
+if (hashtype == -1)
+  {
+  DEBUG(D_acl) debug_printf("ARC i=%d AMS verify bad a_hash\n", as->instance);
+  return as->ams_verify_done = arc_state_reason = US"AMS sig nonverify";
+  }
 
 if ((errstr = exim_dkim_verify(&vctx,
          pdkim_hashes[hashtype].exim_hashmethod, &hhash, &sighash)))
@@ -871,7 +875,8 @@ if (  as->instance == 1 && !arc_cv_match(hdr_as, US"none")
 
 hashtype = pdkim_hashname_to_hashtype(hdr_as->a_hash.data, hdr_as->a_hash.len);
 
-if (!exim_sha_init(&hhash_ctx, pdkim_hashes[hashtype].exim_hashmethod))
+if (  hashtype == -1
+   || !exim_sha_init(&hhash_ctx, pdkim_hashes[hashtype].exim_hashmethod))
   {
   DEBUG(D_acl)
       debug_printf("ARC: hash setup error, possibly nonhandled hashtype\n");
@@ -966,8 +971,6 @@ if ((errstr = exim_dkim_verify_init(&p->key, KEYFMT_DER, &vctx)))
   return US"fail";
   }
 
-hashtype = pdkim_hashname_to_hashtype(hdr_as->a_hash.data, hdr_as->a_hash.len);
-
 if ((errstr = exim_dkim_verify(&vctx,
              pdkim_hashes[hashtype].exim_hashmethod,
              &hhash_computed, &sighash)))
@@ -1416,10 +1419,10 @@ arc_sign_prepend_as(gstring * arcset_interim, arc_ctx * ctx,
   const uschar * privkey, unsigned options)
 {
 gstring * arcset;
-arc_set * as;
 uschar * status = arc_ar_cv_status(ar);
 arc_line * al = store_get(sizeof(header_line) + sizeof(arc_line), FALSE);
 header_line * h = (header_line *)(al+1);
+uschar * badline_str;
 
 gstring * hdata = NULL;
 int hashtype = pdkim_hashname_to_hashtype(US"sha256", 6);      /*XXX hardwired */
@@ -1437,6 +1440,7 @@ blob sig;
       - all ARC set headers, set-number order, aar then ams then as,
         including self (but with an empty b= in self)
 */
+DEBUG(D_transport) debug_printf("ARC: building AS for status '%s'\n", status);
 
 /* Construct the AS except for the signature */
 
@@ -1460,18 +1464,25 @@ ctx->arcset_chain_last->hdr_as = al;
 /* For any but "fail" chain-verify status, walk the entire chain in order by
 instance.  For fail, only the new arc-set.  Accumulate the elements walked. */
 
-for (as = Ustrcmp(status, US"fail") == 0
+for (arc_set * as = Ustrcmp(status, US"fail") == 0
        ? ctx->arcset_chain_last : ctx->arcset_chain;
      as; as = as->next)
   {
+  arc_line * l;
   /* Accumulate AAR then AMS then AS.  Relaxed canonicalisation
   is required per standard. */
 
-  h = as->hdr_aar->complete;
+  badline_str = US"aar";
+  if (!(l = as->hdr_aar)) goto badline;
+  h = l->complete;
   hdata = string_cat(hdata, pdkim_relax_header_n(h->text, h->slen, TRUE));
-  h = as->hdr_ams->complete;
+  badline_str = US"ams";
+  if (!(l = as->hdr_ams)) goto badline;
+  h = l->complete;
   hdata = string_cat(hdata, pdkim_relax_header_n(h->text, h->slen, TRUE));
-  h = as->hdr_as->complete;
+  badline_str = US"as";
+  if (!(l = as->hdr_as)) goto badline;
+  h = l->complete;
   hdata = string_cat(hdata, pdkim_relax_header_n(h->text, h->slen, !!as->next));
   }
 
@@ -1488,6 +1499,11 @@ DEBUG(D_transport) debug_printf("ARC: AS  '%.*s'\n", arcset->ptr - 2, arcset->s)
 /* Finally, append the AMS and AAR to the new AS */
 
 return string_catn(arcset, arcset_interim->s, arcset_interim->ptr);
+
+badline:
+  DEBUG(D_transport)
+    debug_printf("ARC: while building AS, missing %s in chain\n", badline_str);
+  return NULL;
 }
 
 
@@ -1738,7 +1754,13 @@ memset(&al, 0, sizeof(arc_line));
 if ((errstr = arc_parse_line(&al, &h, ARC_HDRLEN_AMS, FALSE)))
   {
   DEBUG(D_acl) if (errstr) debug_printf("ARC: %s\n", errstr);
-  return US"line parsing error";
+  goto badline;
+  }
+
+if (!al.a_hash.data)
+  {
+  DEBUG(D_acl) debug_printf("ARC: no a_hash from '%.*s'\n", h.slen, h.text);
+  goto badline;
   }
 
 /* defaults */
@@ -1757,6 +1779,9 @@ if (!(b = arc_ams_setup_vfy_bodyhash(&al)))
 should have been created here. */
 
 return NULL;
+
+badline:
+  return US"line parsing error";
 }
 
 
@@ -1848,7 +1873,7 @@ return g;
 }
 
 
-# endif /* SUPPORT_SPF */
+# endif /* DISABLE_DKIM */
 #endif /* EXPERIMENTAL_ARC */
 /* vi: aw ai sw=2
  */
index 245cc3925100bc24d05dfc3a20795a9e5b72a52b..cf38305e57c1966329e71999830ec76983b13ecf 100644 (file)
@@ -554,7 +554,6 @@ acl_check_rcpt:
 .ifdef _HAVE_PRDR
 acl_check_prdr:
   warn  set acl_m_did_prdr = y
-.endif
 
   #############################################################################
   # do lookup on filtering, with $local_part@$domain, deny on filter match
@@ -564,6 +563,7 @@ acl_check_prdr:
   #############################################################################
 
   accept
+.endif
 
 # This ACL is used after the contents of a message have been received. This
 # is the ACL in which you can test a message's headers or body, and in
@@ -663,9 +663,6 @@ smarthost:
   transport = smarthost_smtp
   route_data = ROUTER_SMARTHOST
   ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
-.ifdef _HAVE_DNSSEC
-  dnssec_request_domains = *
-.endif
   no_more
 
 .else
@@ -690,9 +687,6 @@ dnslookup:
   ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
 # if ipv6-enabled then instead use:
 # ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
-.ifdef _HAVE_DNSSEC
-  dnssec_request_domains = *
-.endif
   no_more
 
 # This closes the ROUTER_SMARTHOST ifdef around the choice of routing for
@@ -814,9 +808,6 @@ begin transports
 remote_smtp:
   driver = smtp
   message_size_limit = ${if > {$max_received_linelength}{998} {1}{0}}
-.ifdef _HAVE_DANE
-  hosts_try_dane = *
-.endif
 .ifdef _HAVE_PRDR
   hosts_try_prdr = *
 .endif
index 9b86a488b5cc3c20d47cd673dc4a43af2aa3f663..6ed3529293257d73f432540eda4497654ccd40ab 100644 (file)
@@ -1085,52 +1085,52 @@ if (dane->selectors[DANESSL_USAGE_DANE_EE])
     }
   }
 
-  if (dane->selectors[DANESSL_USAGE_DANE_TA])
+if (dane->selectors[DANESSL_USAGE_DANE_TA])
+  {
+  if ((matched = set_trust_anchor(ctx, dane, cert)) < 0)
     {
-    if ((matched = set_trust_anchor(ctx, dane, cert)) < 0)
-      {
-      X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
-      return -1;
-      }
-    if (matched)
-      {
-      /*
-       * Check that setting the untrusted chain updates the expected
-       * structure member at the expected offset.
-       */
-      X509_STORE_CTX_trusted_stack(ctx, dane->roots);
-      X509_STORE_CTX_set_chain(ctx, dane->chain);
-      OPENSSL_assert(dane->chain == X509_STORE_CTX_get0_untrusted(ctx));
-      }
+    X509_STORE_CTX_set_error(ctx, X509_V_ERR_OUT_OF_MEM);
+    return -1;
     }
+  if (matched)
+    {
+    /*
+     * Check that setting the untrusted chain updates the expected
+     * structure member at the expected offset.
+     */
+    X509_STORE_CTX_trusted_stack(ctx, dane->roots);
+    X509_STORE_CTX_set_chain(ctx, dane->chain);
+    OPENSSL_assert(dane->chain == X509_STORE_CTX_get0_untrusted(ctx));
+    }
+  }
 
-  /*
  * Name checks and usage 0/1 constraint enforcement are delayed until
  * X509_verify_cert() builds the full chain and calls our verify_chain()
  * wrapper.
  */
-  dane->verify = X509_STORE_CTX_get_verify(ctx);
-  X509_STORE_CTX_set_verify(ctx, verify_chain);
+/*
+ * Name checks and usage 0/1 constraint enforcement are delayed until
+ * X509_verify_cert() builds the full chain and calls our verify_chain()
+ * wrapper.
+ */
+dane->verify = X509_STORE_CTX_get_verify(ctx);
+X509_STORE_CTX_set_verify(ctx, verify_chain);
 
-  if (X509_verify_cert(ctx))
-    return 1;
+if (X509_verify_cert(ctx))
+  return 1;
 
-  /*
  * If the chain is invalid, clear any matching cert or hostname, to
  * protect callers that might erroneously rely on these alone without
  * checking the validation status.
  */
-  if (dane->match)
-    {
-    X509_free(dane->match);
-    dane->match = 0;
-    }
-  if (dane->mhost)
-    {
-    OPENSSL_free(dane->mhost);
-    dane->mhost = 0;
-    }
  return 0;
+/*
+ * If the chain is invalid, clear any matching cert or hostname, to
+ * protect callers that might erroneously rely on these alone without
+ * checking the validation status.
+ */
+if (dane->match)
+  {
+  X509_free(dane->match);
+  dane->match = 0;
+  }
+if (dane->mhost)
+  {
+  OPENSSL_free(dane->mhost);
+  dane->mhost = 0;
+  }
+ return 0;
 }
 
 static dane_list
index 4c86c092b0cbab6dacaf332c9d9c3aace30abad4..055f36e93448305ec8ecede0d0e63095611f9ab7 100644 (file)
@@ -2,17 +2,14 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) Wolfgang Breyha 2005 - 2015
+/* Copyright (c) Wolfgang Breyha 2005 - 2019
  * Vienna University Computer Center
  * wbreyha@gmx.net
  * See the file NOTICE for conditions of use and distribution.
  *
- * Copyright (c) The Exim Maintainers 2015 - 2018
+ * Copyright (c) The Exim Maintainers 2015 - 2019
  */
 
-/* This patch is based on code from Tom Kistners exiscan (ACL integration) and
- * the DCC local_scan patch from Christopher Bodenstein */
-
 /* Code for calling dccifd. Called from acl.c. */
 
 #include "exim.h"
 #include "dcc.h"
 #include "unistd.h"
 
-uschar dcc_header_str[256];
+#define DCC_HEADER_LIMIT 120
+
 int dcc_ok = 0;
 int dcc_rc = 0;
 
 /* This function takes a file descriptor and a buffer as input and
  * returns either 0 for success or errno in case of error. */
 
-int flushbuffer (int socket, uschar *buffer)
- {
+int flushbuffer (int socket, gstring *buffer)
+{
   int retval, rsp;
-  rsp = write(socket, buffer, Ustrlen(buffer));
+  rsp = write(socket, buffer->s, buffer->ptr);
   DEBUG(D_acl)
-    debug_printf("DCC: Result of the write() = %d\n", rsp);
-  if(rsp < 0)
-  {
+    debug_printf("DCC: flushbuffer(): Result of the write() = %d\n", rsp);
+  if(rsp < 0) {
     DEBUG(D_acl)
-      debug_printf("DCC: Error writing buffer to socket: %s\n", strerror(errno));
+      debug_printf("DCC: flushbuffer(): Error writing buffer to socket: %s\n", strerror(errno));
     retval = errno;
   }
   else {
     DEBUG(D_acl)
-      debug_printf("DCC: Wrote buffer to socket:\n%s\n", buffer);
+      debug_printf("DCC: flushbuffer(): Wrote buffer to socket:\n%.*s\n", buffer->ptr, buffer->s);
     retval = 0;
   }
   return retval;
@@ -55,38 +52,32 @@ dcc_process(uschar **listptr)
   FILE *data_file;
   uschar *dcc_default_ip_option = US"127.0.0.1";
   uschar *dcc_helo_option = US"localhost";
-  uschar *dcc_reject_message = US"Rejected by DCC";
   uschar *xtra_hdrs = NULL;
   uschar *override_client_ip  = NULL;
 
   /* from local_scan */
-  int j, k, c, retval, sockfd, resp, line;
+  int dcc_resplen, retval, sockfd, resp;
   unsigned int portnr;
   struct sockaddr_un  serv_addr;
   struct sockaddr_in  serv_addr_in;
   struct hostent *ipaddress;
   uschar sockpath[128];
   uschar sockip[40], client_ip[40];
-  uschar opts[128];
-  uschar rcpt[128], from[128];
-  uschar sendbuf[4096];
-  uschar recvbuf[4096];
-  uschar dcc_return_text[1024];
-  struct header_line *dcchdr;
+  gstring *dcc_headers;
+  gstring *sendbuf;
+  uschar *dcc_return_text;
+  struct header_line *mail_headers;
   uschar *dcc_acl_options;
-  uschar dcc_acl_options_buffer[10];
-  uschar dcc_xtra_hdrs[1024];
+  gstring *dcc_xtra_hdrs;
+  gstring *dcc_header_str;
 
   /* grep 1st option */
-  if ((dcc_acl_options = string_nextinlist(&list, &sep,
-                  dcc_acl_options_buffer, sizeof(dcc_acl_options_buffer))))
-    {
+  if ((dcc_acl_options = string_nextinlist(&list, &sep, NULL, 0))) {
     /* parse 1st option */
     if (  strcmpic(dcc_acl_options, US"false") == 0
-       || Ustrcmp(dcc_acl_options, "0") == 0
-       )
+       || Ustrcmp(dcc_acl_options, "0") == 0)
       return FAIL;     /* explicitly no matching */
-    }
+  }
   else
     return FAIL;       /* empty means "don't match anything" */
 
@@ -97,23 +88,20 @@ dcc_process(uschar **listptr)
     return dcc_rc;
 
   /* open the spooled body */
-  for (int i = 0; i < 2; i++)
-    {
+  for (int i = 0; i < 2; i++) {
     uschar message_subdir[2];
     set_subdir_str(message_subdir, message_id, i);
     if ((data_file = Ufopen(
-           spool_fname(US"input", message_subdir, message_id, US"-D"),
-           "rb")))
+           spool_fname(US"input", message_subdir, message_id, US"-D"), "rb")))
       break;
-    }
+  }
 
-  if (!data_file)
-    {
+  if (!data_file) {
     /* error while spooling */
     log_write(0, LOG_MAIN|LOG_PANIC,
-           "dcc acl condition: error while opening spool file");
+           "DCC: error while opening spool file");
     return DEFER;
-    }
+  }
 
   /* Initialize the variables */
 
@@ -124,16 +112,15 @@ dcc_process(uschar **listptr)
     else
       if( sscanf(CS dccifd_address, "%s %u", sockip, &portnr) != 2) {
         log_write(0, LOG_MAIN,
-          "dcc acl condition: warning - invalid dccifd address: '%s'", dccifd_address);
+          "DCC: warning - invalid dccifd address: '%s'", dccifd_address);
         (void)fclose(data_file);
         return DEFER;
       }
   }
 
-  /* opts is what we send as dccifd options - see man dccifd */
+  /* dcc_headers is what we send as dccifd options - see man dccifd */
   /* We don't support any other option than 'header' so just copy that */
-  bzero(opts,sizeof(opts));
-  Ustrncpy(opts, dccifd_options, sizeof(opts)-1);
+  dcc_headers = string_cat(NULL, dccifd_options);
   /* if $acl_m_dcc_override_client_ip is set use it */
   if (((override_client_ip = expand_string(US"$acl_m_dcc_override_client_ip")) != NULL) &&
        (override_client_ip[0] != '\0')) {
@@ -153,42 +140,30 @@ dcc_process(uschar **listptr)
     DEBUG(D_acl)
       debug_printf("DCC: Client IP (default): %s\n", client_ip);
   }
-  /* strncat(opts, my_request, strlen(my_request)); */
-  Ustrcat(opts, US"\n");
-  Ustrncat(opts, client_ip, sizeof(opts)-Ustrlen(opts)-1);
-  Ustrncat(opts, US"\nHELO ", sizeof(opts)-Ustrlen(opts)-1);
-  Ustrncat(opts, dcc_helo_option, sizeof(opts)-Ustrlen(opts)-2);
-  Ustrcat(opts, US"\n");
+  /* build options block */
+  dcc_headers = string_append(dcc_headers, 5, US"\n", client_ip, US"\nHELO ", dcc_helo_option, US"\n");
 
   /* initialize the other variables */
-  dcchdr = header_list;
+  mail_headers = header_list;
   /* we set the default return value to DEFER */
   retval = DEFER;
 
-  bzero(sendbuf,sizeof(sendbuf));
-  bzero(dcc_header_str,sizeof(dcc_header_str));
-  bzero(rcpt,sizeof(rcpt));
-  bzero(from,sizeof(from));
-
   /* send a null return path as "<>". */
-  if (Ustrlen(sender_address) > 0)
-    Ustrncpy(from, sender_address, sizeof(from));
-  else
-    Ustrncpy(from, US"<>", sizeof(from));
-  Ustrncat(from, US"\n", sizeof(from)-Ustrlen(from)-1);
+  dcc_headers = string_cat (dcc_headers, *sender_address ? sender_address : US"<>");
+  dcc_headers = string_catn(dcc_headers, US"\n", 1);
 
   /**************************************
    * Now creating the socket connection *
    **************************************/
 
   /* If sockip contains an ip, we use a tcp socket, otherwise a UNIX socket */
-  if(Ustrcmp(sockip, "")){
+  if(Ustrcmp(sockip, "")) {
     ipaddress = gethostbyname(CS sockip);
     bzero(CS  &serv_addr_in, sizeof(serv_addr_in));
     serv_addr_in.sin_family = AF_INET;
     bcopy(CS ipaddress->h_addr, CS &serv_addr_in.sin_addr.s_addr, ipaddress->h_length);
     serv_addr_in.sin_port = htons(portnr);
-    if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) < 0){
+    if ((sockfd = socket(AF_INET, SOCK_STREAM,0)) < 0) {
       DEBUG(D_acl)
         debug_printf("DCC: Creating TCP socket connection failed: %s\n", strerror(errno));
       log_write(0,LOG_PANIC,"DCC: Creating TCP socket connection failed: %s\n", strerror(errno));
@@ -197,7 +172,7 @@ dcc_process(uschar **listptr)
       return retval;
     }
     /* Now connecting the socket (INET) */
-    if (connect(sockfd, (struct sockaddr *)&serv_addr_in, sizeof(serv_addr_in)) < 0){
+    if (connect(sockfd, (struct sockaddr *)&serv_addr_in, sizeof(serv_addr_in)) < 0) {
       DEBUG(D_acl)
         debug_printf("DCC: Connecting to TCP socket failed: %s\n", strerror(errno));
       log_write(0,LOG_PANIC,"DCC: Connecting to TCP socket failed: %s\n", strerror(errno));
@@ -205,12 +180,13 @@ dcc_process(uschar **listptr)
       (void)fclose(data_file);
       return retval;
     }
-  } else {
+  }
+  else {
     /* connecting to the dccifd UNIX socket */
     bzero(&serv_addr, sizeof(serv_addr));
     serv_addr.sun_family = AF_UNIX;
     Ustrncpy(US serv_addr.sun_path, sockpath, sizeof(serv_addr.sun_path));
-    if ((sockfd = socket(AF_UNIX, SOCK_STREAM,0)) < 0){
+    if ((sockfd = socket(AF_UNIX, SOCK_STREAM,0)) < 0) {
       DEBUG(D_acl)
         debug_printf("DCC: Creating UNIX socket connection failed: %s\n", strerror(errno));
       log_write(0,LOG_PANIC,"DCC: Creating UNIX socket connection failed: %s\n", strerror(errno));
@@ -219,9 +195,9 @@ dcc_process(uschar **listptr)
       return retval;
     }
     /* Now connecting the socket (UNIX) */
-    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
+    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
       DEBUG(D_acl)
-                            debug_printf("DCC: Connecting to UNIX socket failed: %s\n", strerror(errno));
+        debug_printf("DCC: Connecting to UNIX socket failed: %s\n", strerror(errno));
       log_write(0,LOG_PANIC,"DCC: Connecting to UNIX socket failed: %s\n", strerror(errno));
       /* if we cannot contact the socket, defer the mail */
       (void)fclose(data_file);
@@ -230,93 +206,66 @@ dcc_process(uschar **listptr)
   }
   /* the socket is open, now send the options to dccifd*/
   DEBUG(D_acl)
-    debug_printf("\nDCC: ---------------------------\nDCC: Socket opened; now sending input\nDCC: -----------------\n");
-  /* First, fill in the input buffer */
-  Ustrncpy(sendbuf, opts, sizeof(sendbuf));
-  Ustrncat(sendbuf, from, sizeof(sendbuf)-Ustrlen(sendbuf)-1);
-
-  DEBUG(D_acl)
-  {
-    debug_printf("DCC: opts = %s\nDCC: sender = %s\nDCC: rcpt count = %d\n", opts, from, recipients_count);
-    debug_printf("DCC: Sending options:\nDCC: ****************************\n");
-  }
+    debug_printf("DCC: -----------------------------------\nDCC: Socket opened; now sending input\n"
+                 "DCC: -----------------------------------\n");
 
   /* let's send each of the recipients to dccifd */
-  for (int i = 0; i < recipients_count; i++){
+  for (int i = 0; i < recipients_count; i++) {
     DEBUG(D_acl)
       debug_printf("DCC: recipient = %s\n",recipients_list[i].address);
-    if(Ustrlen(sendbuf) + Ustrlen(recipients_list[i].address) > sizeof(sendbuf))
-    {
-      DEBUG(D_acl)
-        debug_printf("DCC: Writing buffer: %s\n", sendbuf);
-      flushbuffer(sockfd, sendbuf);
-      bzero(sendbuf, sizeof(sendbuf));
-    }
-    Ustrncat(sendbuf, recipients_list[i].address, sizeof(sendbuf)-Ustrlen(sendbuf)-1);
-    Ustrncat(sendbuf, US"\r\n", sizeof(sendbuf)-Ustrlen(sendbuf)-1);
+    dcc_headers = string_append(dcc_headers, 2, recipients_list[i].address, "\n");
   }
   /* send a blank line between options and message */
-  Ustrncat(sendbuf, US"\n", sizeof(sendbuf)-Ustrlen(sendbuf)-1);
+  dcc_headers = string_catn(dcc_headers, US"\n", 1);
   /* Now we send the input buffer */
+  (void) string_from_gstring(dcc_headers);
   DEBUG(D_acl)
-    debug_printf("DCC: %s\nDCC: ****************************\n", sendbuf);
-  flushbuffer(sockfd, sendbuf);
+    debug_printf("DCC: ***********************************\nDCC: Sending options:\n%s"
+                 "DCC: ***********************************\n", dcc_headers->s);
+  if (flushbuffer(sockfd, dcc_headers) != 0) {
+      (void)fclose(data_file);
+      return retval;
+  }
 
   /* now send the message */
-  /* Clear the input buffer */
-  bzero(sendbuf, sizeof(sendbuf));
   /* First send the headers */
-  /* Now send the headers */
   DEBUG(D_acl)
-    debug_printf("DCC: Sending headers:\nDCC: ****************************\n");
-  Ustrncpy(sendbuf, dcchdr->text, sizeof(sendbuf)-2);
-  while((dcchdr=dcchdr->next)) {
-    if(dcchdr->slen > sizeof(sendbuf)-2) {
-      /* The size of the header is bigger than the size of
-       * the input buffer, so split it up in smaller parts. */
-       flushbuffer(sockfd, sendbuf);
-       bzero(sendbuf, sizeof(sendbuf));
-       j = 0;
-       while(j < dcchdr->slen)
-       {
-        for(int i = 0; i < sizeof(sendbuf)-2; i++) {
-          sendbuf[i] = dcchdr->text[j];
-          j++;
-        }
-        flushbuffer(sockfd, sendbuf);
-        bzero(sendbuf, sizeof(sendbuf));
-       }
-    } else if(Ustrlen(sendbuf) + dcchdr->slen > sizeof(sendbuf)-2) {
-      flushbuffer(sockfd, sendbuf);
-      bzero(sendbuf, sizeof(sendbuf));
-      Ustrncpy(sendbuf, dcchdr->text, sizeof(sendbuf)-2);
-    } else {
-      Ustrncat(sendbuf, dcchdr->text, sizeof(sendbuf)-Ustrlen(sendbuf)-2);
-    }
+    debug_printf("DCC: ***********************************\nDCC: Sending headers:\n");
+  sendbuf = string_get(8192);
+  sendbuf = string_catn(sendbuf, mail_headers->text, mail_headers->slen);
+  while((mail_headers=mail_headers->next)) {
+    sendbuf = string_catn(sendbuf, mail_headers->text, mail_headers->slen);
   }
 
   /* a blank line separates header from body */
-  Ustrncat(sendbuf, US"\n", sizeof(sendbuf)-Ustrlen(sendbuf)-1);
-  flushbuffer(sockfd, sendbuf);
+  sendbuf = string_catn(sendbuf, US"\r\n", 2);
+  (void) string_from_gstring(sendbuf);
+  gstring_release_unused(sendbuf);
   DEBUG(D_acl)
-    debug_printf("\nDCC: ****************************\n%s", sendbuf);
-
-  /* Clear the input buffer */
-  bzero(sendbuf, sizeof(sendbuf));
+    debug_printf("%sDCC: ***********************************\n", sendbuf->s);
+  if (flushbuffer(sockfd, sendbuf) != 0) {
+      (void)fclose(data_file);
+      return retval;
+  }
 
   /* now send the body */
   DEBUG(D_acl)
-    debug_printf("DCC: Writing body:\nDCC: ****************************\n");
+    debug_printf("DCC: ***********************************\nDCC: Writing body:\n");
   (void)fseek(data_file, SPOOL_DATA_START_OFFSET, SEEK_SET);
-  while((fread(sendbuf, 1, sizeof(sendbuf)-1, data_file)) > 0) {
-    flushbuffer(sockfd, sendbuf);
-    bzero(sendbuf, sizeof(sendbuf));
+
+  gstring filebuf = { .size = big_buffer_size, .ptr = 0, .s = big_buffer };
+
+  while((filebuf.ptr = fread(filebuf.s, 1, filebuf.size, data_file)) > 0) {
+    if (flushbuffer(sockfd, &filebuf) != 0) {
+        (void)fclose(data_file);
+        return retval;
+    }
   }
   DEBUG(D_acl)
-    debug_printf("\nDCC: ****************************\n");
+    debug_printf("DCC: ***********************************\n");
 
   /* shutdown() the socket */
-  if(shutdown(sockfd, 1) < 0){
+  if(shutdown(sockfd, SHUT_WR) < 0) {
     DEBUG(D_acl)
       debug_printf("DCC: Couldn't shutdown socket: %s\n", strerror(errno));
     log_write(0,LOG_MAIN,"DCC: Couldn't shutdown socket: %s\n", strerror(errno));
@@ -326,13 +275,14 @@ dcc_process(uschar **listptr)
     return retval;
   }
   DEBUG(D_acl)
-    debug_printf("\nDCC: -------------------------\nDCC: Input sent.\nDCC: -------------------------\n");
+    debug_printf("DCC: Input sent.\n"
+                 "DCC: +++++++++++++++++++++++++++++++++++\n"
+                 "DCC: Now receiving output from server\n"
+                 "DCC: -----------------------------------\n");
 
-    /********************************
+  /********************************
    * receiving output from dccifd *
    ********************************/
-  DEBUG(D_acl)
-    debug_printf("\nDCC: -------------------------------------\nDCC: Now receiving output from server\nDCC: -----------------------------------\n");
 
   /******************************************************************
    * We should get 3 lines:                                         *
@@ -344,91 +294,100 @@ dcc_process(uschar **listptr)
    * 3/ Third line contains the X-DCC header.                       *
    ******************************************************************/
 
-  line = 1;    /* we start at the first line of the output */
-  j = 0;       /* will be used as index for the recipients list */
-  k = 0;       /* initializing the index of the X-DCC header: dcc_header_str[k] */
+  int line = 1;    /* we start at the first line of the output */
+  int bufoffset;
 
+  dcc_header_str = string_get(DCC_HEADER_LIMIT + 2);
   /* Let's read from the socket until there's nothing left to read */
-  bzero(recvbuf, sizeof(recvbuf));
-  while((resp = read(sockfd, recvbuf, sizeof(recvbuf)-1)) > 0) {
-    /* How much did we get from the socket */
-    c = Ustrlen(recvbuf) + 1;
+  while((dcc_resplen = read(sockfd, big_buffer, big_buffer_size-1)) > 0) {
+    /* fail on read error */
+    if(dcc_resplen < 0) {
+      DEBUG(D_acl)
+        debug_printf("DCC: Error reading from socket: %s\n", strerror(errno));
+      (void)fclose(data_file);
+      return retval;
+    }
+    /* make the answer 0-terminated. only needed for debug_printf */
     DEBUG(D_acl)
-      debug_printf("DCC: Length of the output buffer is: %d\nDCC: Output buffer is:\nDCC: ------------\nDCC: %s\nDCC: -----------\n", c, recvbuf);
+      debug_printf("DCC: Length of the output buffer is: %d\nDCC: Output buffer is:\n"
+                   "DCC: -----------------------------------\n%.*s\n"
+                   "DCC: -----------------------------------\n", dcc_resplen, dcc_resplen, big_buffer);
 
     /* Now let's read each character and see what we've got */
-    for(int i = 0; i < c; i++) {
+    for(bufoffset = 0; bufoffset < dcc_resplen, line <= 2; bufoffset++) {
       /* First check if we reached the end of the line and
        * then increment the line counter */
-      if(recvbuf[i] == '\n')
+      if(big_buffer[bufoffset] == '\n')
         line++;
       else {
         /* The first character of the first line is the
          * overall response. If there's another character
          * on that line it is not correct. */
         if(line == 1) {
-          if(i == 0) {
+          if(bufoffset == 0) {
             /* Now get the value and set the
              * return value accordingly */
-            if(recvbuf[i] == 'A') {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result = A\treturning OK\n");
-              Ustrcpy(dcc_return_text, US"Mail accepted by DCC");
-              dcc_result = US"A";
-              retval = OK;
-            }
-            else if(recvbuf[i] == 'R') {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result = R\treturning FAIL\n");
-              dcc_result = US"R";
-              retval = FAIL;
-              if(sender_host_name) {
-                log_write(0, LOG_MAIN, "H=%s [%s] F=<%s>: rejected by DCC", sender_host_name, sender_host_address, sender_address);
-              }
-              else {
-                log_write(0, LOG_MAIN, "H=[%s] F=<%s>: rejected by DCC", sender_host_address, sender_address);
-              }
-              Ustrncpy(dcc_return_text, dcc_reject_message, Ustrlen(dcc_reject_message) + 1);
-            }
-            else if(recvbuf[i] == 'S') {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result  = S\treturning OK\n");
-              Ustrcpy(dcc_return_text, US"Not all recipients accepted by DCC");
-              /* Since we're in an ACL we want a global result
-               * so we accept for all */
-              dcc_result = US"A";
-              retval = OK;
-            }
-            else if(recvbuf[i] == 'G') {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result  = G\treturning FAIL\n");
-              Ustrcpy(dcc_return_text, US"Greylisted by DCC");
-              dcc_result = US"G";
-              retval = FAIL;
-            }
-            else if(recvbuf[i] == 'T') {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result = T\treturning DEFER\n");
-              retval = DEFER;
-              log_write(0,LOG_MAIN,"Temporary error with DCC: %s\n", recvbuf);
-              Ustrcpy(dcc_return_text, US"Temporary error with DCC");
-              dcc_result = US"T";
-            }
-            else {
-              DEBUG(D_acl)
-                debug_printf("DCC: Overall result = something else\treturning DEFER\n");
-              retval = DEFER;
-              log_write(0,LOG_MAIN,"Unknown DCC response: %s\n", recvbuf);
-              Ustrcpy(dcc_return_text, US"Unknown DCC response");
-              dcc_result = US"T";
+            switch(big_buffer[bufoffset]) {
+              case 'A':
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result = A\treturning OK\n");
+                dcc_return_text = US"Mail accepted by DCC";
+                dcc_result = US"A";
+                retval = OK;
+                break;
+              case 'R':
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result = R\treturning FAIL\n");
+                dcc_return_text = US"Rejected by DCC";
+                dcc_result = US"R";
+                retval = FAIL;
+                if(sender_host_name)
+                  log_write(0, LOG_MAIN, "H=%s [%s] F=<%s>: rejected by DCC",
+                             sender_host_name, sender_host_address, sender_address);
+                else
+                  log_write(0, LOG_MAIN, "H=[%s] F=<%s>: rejected by DCC",
+                             sender_host_address, sender_address);
+                break;
+              case 'S':
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result  = S\treturning OK\n");
+                dcc_return_text = US"Not all recipients accepted by DCC";
+                /* Since we're in an ACL we want a global result
+                 * so we accept for all */
+                dcc_result = US"A";
+                retval = OK;
+                break;
+              case 'G':
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result  = G\treturning FAIL\n");
+                dcc_return_text = US"Greylisted by DCC";
+                dcc_result = US"G";
+                retval = FAIL;
+                break;
+              case 'T':
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result = T\treturning DEFER\n");
+                dcc_return_text = US"Temporary error with DCC";
+                dcc_result = US"T";
+                retval = DEFER;
+                log_write(0,LOG_MAIN,"Temporary error with DCC: %s\n", big_buffer);
+                break;
+              default:
+                DEBUG(D_acl)
+                  debug_printf("DCC: Overall result = something else\treturning DEFER\n");
+               dcc_return_text = US"Unknown DCC response";
+                dcc_result = US"T";
+                retval = DEFER;
+                log_write(0,LOG_MAIN,"Unknown DCC response: %s\n", big_buffer);
+                break;
             }
           }
           else {
             /* We're on the first line but not on the first character,
              * there must be something wrong. */
-            DEBUG(D_acl) debug_printf("DCC: Line = %d but i = %d != 0"
-               "  character is %c - This is wrong!\n", line, i, recvbuf[i]);
-            log_write(0,LOG_MAIN,"Wrong header from DCC, output is %s\n", recvbuf);
+            DEBUG(D_acl) debug_printf("DCC: Line = %d but bufoffset = %d != 0"
+               "  character is %c - This is wrong!\n", line, bufoffset, big_buffer[bufoffset]);
+            log_write(0,LOG_MAIN,"Wrong header from DCC, output is %s\n", big_buffer);
           }
         }
         else if(line == 2) {
@@ -437,69 +396,65 @@ dcc_process(uschar **listptr)
            * it because we're in an acl and take the
            * global result. */
         }
-        else if(line > 2) {
-          /* The third and following lines are the X-DCC header,
-           * so we store it in dcc_header_str. */
-          /* check if we don't get more than we can handle */
-          if(k < sizeof(dcc_header_str)) {
-            dcc_header_str[k] = recvbuf[i];
-            k++;
-          }
-          else {
-            DEBUG(D_acl) debug_printf("DCC: We got more output than we can store"
-               " in the X-DCC header. Truncating at 120 characters.\n");
-          }
-        }
-        else {
-          /* Wrong line number. There must be a problem with the output. */
-          DEBUG(D_acl)
-            debug_printf("DCC: Wrong line number in output. Line number is %d\n", line);
-        }
       }
     }
-    /* we reinitialize the output buffer before we read again */
-    bzero(recvbuf,sizeof(recvbuf));
+    if(line > 2) {
+      /* The third and following lines are the X-DCC header,
+       * so we store it in dcc_header_str up to our limit. */
+      /* check if buffer contains the end of the header .."\n\n" and truncate it */
+      if ((big_buffer[dcc_resplen-1] == '\n') &&
+          (big_buffer[dcc_resplen-2] == '\n'))
+        dcc_resplen -= 2;
+      dcc_resplen -= bufoffset;
+      if (dcc_header_str->ptr + dcc_resplen > DCC_HEADER_LIMIT) {
+        dcc_resplen = DCC_HEADER_LIMIT - dcc_header_str->ptr;
+        DEBUG(D_acl) debug_printf("DCC: We got more output than we can store"
+                          "in the X-DCC header. Truncating at 120 characters.\n");
+      }
+      dcc_header_str = string_catn(dcc_header_str, &big_buffer[bufoffset], dcc_resplen);
+    }
   }
-  /* We have read everything from the socket */
-
-  /* We need to terminate the X-DCC header with a '\n' character. This needs to be k-1
-   * since dcc_header_str[k] contains '\0'. */
-  dcc_header_str[k-1] = '\n';
+  /* We have read everything from the socket. make sure the header ends with "\n" */
+  dcc_header_str = string_catn(dcc_header_str, US"\n", 1);
 
+  (void) string_from_gstring(dcc_header_str);
   /* Now let's sum up what we've got. */
   DEBUG(D_acl)
-    debug_printf("\nDCC: --------------------------\nDCC: Overall result = %d\nDCC: X-DCC header: %sReturn message: %s\nDCC: dcc_result: %s\n", retval, dcc_header_str, dcc_return_text, dcc_result);
+    debug_printf("\nDCC: --------------------------\nDCC: Overall result = %d\n"
+                 "DCC: X-DCC header: %sReturn message: %s\nDCC: dcc_result: %s\n",
+                   retval, dcc_header_str->s, dcc_return_text, dcc_result);
 
   /* We only add the X-DCC header if it starts with X-DCC */
-  if(!(Ustrncmp(dcc_header_str, "X-DCC", 5))){
-    dcc_header = dcc_header_str;
+  if(!(Ustrncmp(dcc_header_str->s, "X-DCC", 5))) {
+    dcc_header = dcc_header_str->s;
     if(dcc_direct_add_header) {
-      header_add(' ' , "%s", dcc_header_str);
+      header_add(' ' , "%s", dcc_header_str->s);
   /* since the MIME ACL already writes the .eml file to disk without DCC Header we've to erase it */
       unspool_mbox();
     }
   }
   else {
     DEBUG(D_acl)
-      debug_printf("DCC: Wrong format of the X-DCC header: %s\n", dcc_header_str);
+      debug_printf("DCC: Wrong format of the X-DCC header: %.*s\n", dcc_header_str->ptr, dcc_header_str->s);
   }
 
   /* check if we should add additional headers passed in acl_m_dcc_add_header */
   if(dcc_direct_add_header) {
     if (((xtra_hdrs = expand_string(US"$acl_m_dcc_add_header")) != NULL) && (xtra_hdrs[0] != '\0')) {
-      Ustrncpy(dcc_xtra_hdrs, xtra_hdrs, sizeof(dcc_xtra_hdrs) - 2);
-      if (dcc_xtra_hdrs[Ustrlen(dcc_xtra_hdrs)-1] != '\n')
-        Ustrcat(dcc_xtra_hdrs, US"\n");
-      header_add(' ', "%s", dcc_xtra_hdrs);
+      dcc_xtra_hdrs = string_cat(NULL, xtra_hdrs);
+      if (dcc_xtra_hdrs->s[dcc_xtra_hdrs->ptr - 1] != '\n')
+        dcc_xtra_hdrs = string_catn(dcc_xtra_hdrs, US"\n", 1);
+      header_add(' ', "%s", string_from_gstring(dcc_xtra_hdrs));
       DEBUG(D_acl)
-        debug_printf("DCC: adding additional headers in $acl_m_dcc_add_header: %s", dcc_xtra_hdrs);
+        debug_printf("DCC: adding additional headers in $acl_m_dcc_add_header: %.*s", dcc_xtra_hdrs->ptr, dcc_xtra_hdrs->s);
     }
   }
 
   dcc_ok = 1;
   /* Now return to exim main process */
   DEBUG(D_acl)
-    debug_printf("DCC: Before returning to exim main process:\nDCC: return_text = %s - retval = %d\nDCC: dcc_result = %s\n", dcc_return_text, retval, dcc_result);
+    debug_printf("DCC: Before returning to exim main process:\nDCC: return_text = %s - retval = %d\n"
+                 "DCC: dcc_result = %s\n", dcc_return_text, retval, dcc_result);
 
   (void)fclose(data_file);
   dcc_rc = retval;
index 58874add4ad420742e3ac6eac77da5c2bd9841dc..28a1174af6864fc50125f4a0395a3b5163763002 100644 (file)
@@ -5028,9 +5028,10 @@ all pipes, so I do not see a reason to use non-blocking IO here
 
   /* Otherwise, if we are running in the test harness, wait a bit, to let the
   newly created process get going before we create another process. This should
-  ensure repeatability in the tests. We only need to wait a tad. */
+  ensure repeatability in the tests. Wait long enough for most cases to complete
+  the transport. */
 
-  else testharness_pause_ms(500);
+  else testharness_pause_ms(600);
 
   continue;
 
@@ -5477,6 +5478,26 @@ fprintf(f, "Action: %s\n"
 }
 
 
+
+/* When running in the test harness, there's an option that allows us to
+fudge this time so as to get repeatability of the tests. Take the first
+time off the list. In queue runs, the list pointer gets updated in the
+calling process. */
+
+int
+test_harness_fudged_queue_time(int actual_time)
+{
+int qt;
+if (  f.running_in_test_harness && *fudged_queue_times
+   && (qt = readconf_readtime(fudged_queue_times, '/', FALSE)) >= 0)
+  {
+  DEBUG(D_deliver) debug_printf("fudged queue_times = %s\n",
+    fudged_queue_times);
+  return qt;
+  }
+return actual_time;
+}
+
 /*************************************************
 *              Deliver one message               *
 *************************************************/
@@ -6167,7 +6188,8 @@ if (process_recipients != RECIP_IGNORE)
         new->onetime_parent = recipients_list[r->pno].address;
 
       /* If DSN support is enabled, set the dsn flags and the original receipt
-         to be passed on to other DSN enabled MTAs */
+      to be passed on to other DSN enabled MTAs */
+
       new->dsn_flags = r->dsn_flags & rf_dsnflags;
       new->dsn_orcpt = r->orcpt;
       DEBUG(D_deliver) debug_printf("DSN: set orcpt: %s  flags: 0x%x\n",
@@ -7287,10 +7309,9 @@ for (address_item * a = addr_succeed; a; a = a->next)
       );
 
   /* send report if next hop not DSN aware or a router flagged "last DSN hop"
-     and a report was requested */
-  if (  (  a->dsn_aware != dsn_support_yes
-       || a->dsn_flags & rf_dsnlasthop
-        )
+  and a report was requested */
+
+  if (  (a->dsn_aware != dsn_support_yes || a->dsn_flags & rf_dsnlasthop)
      && a->dsn_flags & rf_notify_success
      )
     {
@@ -8134,21 +8155,7 @@ else if (addr_defer != (address_item *)(+1))
     int show_time;
     int queue_time = time(NULL) - received_time.tv_sec;
 
-    /* When running in the test harness, there's an option that allows us to
-    fudge this time so as to get repeatability of the tests. Take the first
-    time off the list. In queue runs, the list pointer gets updated in the
-    calling process. */
-
-    if (f.running_in_test_harness && fudged_queue_times[0] != 0)
-      {
-      int qt = readconf_readtime(fudged_queue_times, '/', FALSE);
-      if (qt >= 0)
-        {
-        DEBUG(D_deliver) debug_printf("fudged queue_times = %s\n",
-          fudged_queue_times);
-        queue_time = qt;
-        }
-      }
+    queue_time = test_harness_fudged_queue_time(queue_time);
 
     /* See how many warnings we should have sent by now */
 
index 4750f1b5210ef536dc8e9711b0c8960cfae5a3ec..6333d3cff7018e0512ea9cf27d81b6d5ee1677ed 100644 (file)
@@ -221,16 +221,15 @@ a name that can be used to look up PTR records.
 
 Arguments:
   string     the IP address as a string
-  buffer     a suitable buffer, long enough to hold the result
 
-Returns:     nothing
+Returns:     an allocated string
 */
 
-void
-dns_build_reverse(const uschar *string, uschar *buffer)
+uschar *
+dns_build_reverse(const uschar * string)
 {
-const uschar *p = string + Ustrlen(string);
-uschar *pp = buffer;
+const uschar * p = string + Ustrlen(string);
+gstring * g = NULL;
 
 /* Handle IPv4 address */
 
@@ -240,14 +239,13 @@ if (Ustrchr(string, ':') == NULL)
   {
   for (int i = 0; i < 4; i++)
     {
-    const uschar *ppp = p;
+    const uschar * ppp = p;
     while (ppp > string && ppp[-1] != '.') ppp--;
-    Ustrncpy(pp, ppp, p - ppp);
-    pp += p - ppp;
-    *pp++ = '.';
+    g = string_catn(g, ppp, p - ppp);
+    g = string_catn(g, US".", 1);
     p = ppp - 1;
     }
-  Ustrcpy(pp, US"in-addr.arpa");
+  g = string_catn(g, US"in-addr.arpa", 12);
   }
 
 /* Handle IPv6 address; convert to binary so as to fill out any
@@ -257,6 +255,8 @@ abbreviation in the textual form. */
 else
   {
   int v6[4];
+
+  g = string_get_tainted(32, is_tainted(string));
   (void)host_aton(string, v6);
 
   /* The original specification for IPv6 reverse lookup was to invert each
@@ -265,8 +265,8 @@ else
 
   for (int i = 3; i >= 0; i--)
     for (int j = 0; j < 32; j += 4)
-      pp += sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
-  Ustrcpy(pp, US"ip6.arpa.");
+      g = string_fmt_append(g, "%x.", (v6[i] >> j) & 15);
+  g = string_catn(g, US"ip6.arpa.", 9);
 
   /* Another way of doing IPv6 reverse lookups was proposed in conjunction
   with A6 records. However, it fell out of favour when they did. The
@@ -290,6 +290,7 @@ else
 
   }
 #endif
+return string_from_gstring(g);
 }
 
 
@@ -498,13 +499,13 @@ const HEADER * h = (const HEADER *) dnsa->answer;
 const uschar * auth_name;
 const uschar * trusted;
 
+if (dnsa->answerlen < 0) return FALSE;
 if (h->ad) return TRUE;
 
-/* If the resolver we ask is authoritative for the domain in question, it
-* may not set the AD but the AA bit. If we explicitly trust
-* the resolver for that domain (via a domainlist in dns_trust_aa),
-* we return TRUE to indicate a secure answer.
-*/
+/* If the resolver we ask is authoritative for the domain in question, it may
+not set the AD but the AA bit. If we explicitly trust the resolver for that
+domain (via a domainlist in dns_trust_aa), we return TRUE to indicate a secure
+answer.  */
 
 if (  !h->aa
    || !dns_trust_aa
@@ -540,12 +541,12 @@ h->aa = h->ad = 0;
  ************************************************/
 
 BOOL
-dns_is_aa(const dns_answer *dnsa)
+dns_is_aa(const dns_answer * dnsa)
 {
 #ifdef DISABLE_DNSSEC
 return FALSE;
 #else
-return ((const HEADER*)dnsa->answer)->aa;
+return dnsa->answerlen >= 0 && ((const HEADER *)dnsa->answer)->aa;
 #endif
 }
 
@@ -681,17 +682,6 @@ return rc;
 
 
 
-/* Return the TTL suitable for an NXDOMAIN result, which is given
-in the SOA.  We hope that one was returned in the lookup, and do not
-bother doing a separate lookup; if not found return a forever TTL.
-*/
-
-time_t
-dns_expire_from_soa(dns_answer * dnsa)
-{
-const HEADER * h = (const HEADER *)dnsa->answer;
-dns_scan dnss;
-
 /* This is really gross. The successful return value from res_search() is
 the packet length, which is stored in dnsa->answerlen. If we get a
 negative DNS reply then res_search() returns -1, which causes the bounds
@@ -703,12 +693,38 @@ re-implement res_search() and res_query() so that they don't muddle their
 success and packet length return values.) For added safety we only reset
 the packet length if the packet header looks plausible. */
 
-if (  h->qr == 1 && h->opcode == QUERY && h->tc == 0
+static void
+fake_dnsa_len_for_fail(dns_answer * dnsa, int type)
+{
+const HEADER * h = (const HEADER *)dnsa->answer;
+
+if (  h->qr == 1                               /* a response */
+   && h->opcode == QUERY
+   && h->tc == 0                               /* nmessage not truncated */
    && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
-   && (ntohs(h->qdcount) == 1 || f.running_in_test_harness)
-   && ntohs(h->ancount) == 0
-   && ntohs(h->nscount) >= 1)
-      dnsa->answerlen = sizeof(dnsa->answer);
+   && (  ntohs(h->qdcount) == 1                        /* one question record */
+      || f.running_in_test_harness)
+   && ntohs(h->ancount) == 0                   /* no answer records */
+   && ntohs(h->nscount) >= 1)                  /* authority records */
+  {
+  DEBUG(D_dns) debug_printf("faking res_search(%s) response length as %d\n",
+    dns_text_type(type), (int)sizeof(dnsa->answer));
+  dnsa->answerlen = sizeof(dnsa->answer);
+  }
+}
+
+
+/* Return the TTL suitable for an NXDOMAIN result, which is given
+in the SOA.  We hope that one was returned in the lookup, and do not
+bother doing a separate lookup; if not found return a forever TTL.
+*/
+
+time_t
+dns_expire_from_soa(dns_answer * dnsa, int type)
+{
+dns_scan dnss;
+
+fake_dnsa_len_for_fail(dnsa, type);
 
 for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
      rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
@@ -788,7 +804,10 @@ caching for successful lookups.
 */
 
 if ((rc = dns_fail_cache_hit(name, type)) > 0)
+  {
+  dnsa->answerlen = -1;
   return rc;
+  }
 
 #ifdef SUPPORT_I18N
 /* Convert all names to a-label form before doing lookup */
@@ -857,6 +876,7 @@ if ((type == T_A || type == T_AAAA) && string_is_ip_address(name, NULL) != 0)
 (res_search), we call fakens_search(), which recognizes certain special
 domains, and interfaces to a fake nameserver for certain special zones. */
 
+h_errno = 0;
 dnsa->answerlen = f.running_in_test_harness
   ? fakens_search(name, type, dnsa->answer, sizeof(dnsa->answer))
   : res_search(CCS name, C_IN, type, dnsa->answer, sizeof(dnsa->answer));
@@ -874,7 +894,7 @@ if (dnsa->answerlen < 0) switch (h_errno)
   case HOST_NOT_FOUND:
     DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave HOST_NOT_FOUND\n"
       "returning DNS_NOMATCH\n", name, dns_text_type(type));
-    return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NOMATCH);
+    return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
 
   case TRY_AGAIN:
     DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave TRY_AGAIN\n",
@@ -894,7 +914,7 @@ if (dnsa->answerlen < 0) switch (h_errno)
       }
     DEBUG(D_dns) debug_printf("%s is in dns_again_means_nonexist: returning "
       "DNS_NOMATCH\n", name);
-    return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NOMATCH);
+    return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NOMATCH);
 
 #else   /* For stand-alone tests */
     return dns_fail_return(name, type, 0, DNS_AGAIN);
@@ -908,7 +928,7 @@ if (dnsa->answerlen < 0) switch (h_errno)
   case NO_DATA:
     DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_DATA\n"
       "returning DNS_NODATA\n", name, dns_text_type(type));
-    return dns_fail_return(name, type, dns_expire_from_soa(dnsa), DNS_NODATA);
+    return dns_fail_return(name, type, dns_expire_from_soa(dnsa, type), DNS_NODATA);
 
   default:
     DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave unknown DNS error %d\n"
@@ -1181,23 +1201,7 @@ switch (type)
 
     if (rc == DNS_NOMATCH)
       {
-      /* This is really gross. The successful return value from res_search() is
-      the packet length, which is stored in dnsa->answerlen. If we get a
-      negative DNS reply then res_search() returns -1, which causes the bounds
-      checks for name decompression to fail when it is treated as a packet
-      length, which in turn causes the authority search to fail. The correct
-      packet length has been lost inside libresolv, so we have to guess a
-      replacement value. (The only way to fix this properly would be to
-      re-implement res_search() and res_query() so that they don't muddle their
-      success and packet length return values.) For added safety we only reset
-      the packet length if the packet header looks plausible. */
-
-      const HEADER * h = (const HEADER *)dnsa->answer;
-      if (h->qr == 1 && h->opcode == QUERY && h->tc == 0
-         && (h->rcode == NOERROR || h->rcode == NXDOMAIN)
-         && ntohs(h->qdcount) == 1 && ntohs(h->ancount) == 0
-         && ntohs(h->nscount) >= 1)
-           dnsa->answerlen = sizeof(dnsa->answer);
+      fake_dnsa_len_for_fail(dnsa, T_CSA);
 
       for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
           rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)
index c29cc6c8dd9e6b945854fd5d80f82229117131fb..9cb90c86fcc00e9a20863196548e115a9ab3cd63 100644 (file)
@@ -24,6 +24,9 @@ Returns:    TRUE if successful
 BOOL
 cleanup_environment()
 {
+int old_pool = store_pool;
+store_pool = POOL_PERM;                /* Need perm memory for any created env vars */
+
 if (!keep_environment || *keep_environment == '\0')
   {
   /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55
@@ -65,8 +68,16 @@ if (add_environment)
   int sep = 0;
   const uschar * envlist = add_environment;
 
-  while ((p = string_nextinlist(&envlist, &sep, NULL, 0))) putenv(CS p);
+  while ((p = string_nextinlist(&envlist, &sep, NULL, 0)))
+    {
+    DEBUG(D_expand) debug_printf("adding %s\n", p);
+    putenv(CS p);
+    }
   }
+#ifndef DISABLE_TLS
+tls_clean_env();
+#endif
 
+store_pool = old_pool;
 return TRUE;
 }
index f2943547667f2b50864f4bc666faf57e6490545d..8c3c8e7ed3c2fff003cda2429fa283b4b88bc598 100644 (file)
@@ -2787,6 +2787,11 @@ for (i = 1; i < argc; i++)
       msg_action = MSG_DELIVER;
       deliver_give_up = TRUE;
       }
+   else if (Ustrcmp(argrest, "G") == 0)
+      {
+      msg_action = MSG_SETQUEUE;
+      queue_name_dest = argv[++i];
+      }
     else if (Ustrcmp(argrest, "mad") == 0)
       {
       msg_action = MSG_MARK_ALL_DELIVERED;
@@ -4068,11 +4073,13 @@ count. Only an admin user can use the test interface to scan for email
 if (!f.admin_user)
   {
   BOOL debugset = (debug_selector & ~D_v) != 0;
-  if (deliver_give_up || f.daemon_listen || malware_test_file ||
-     (count_queue && queue_list_requires_admin) ||
-     (list_queue && queue_list_requires_admin) ||
-     (queue_interval >= 0 && prod_requires_admin) ||
-     (debugset && !f.running_in_test_harness))
+  if (  deliver_give_up || f.daemon_listen || malware_test_file
+     || count_queue && queue_list_requires_admin
+     || list_queue && queue_list_requires_admin
+     || queue_interval >= 0 && prod_requires_admin
+     || queue_name_dest && prod_requires_admin
+     || debugset && !f.running_in_test_harness
+     )
     exim_fail("exim:%s permission denied\n", debugset? " debugging" : "");
   }
 
@@ -4169,13 +4176,9 @@ now for those OS that require the first call to os_getloadavg() to be done as
 root. There will be further calls later for each message received. */
 
 #ifdef LOAD_AVG_NEEDS_ROOT
-if (receiving_message &&
-      (queue_only_load >= 0 ||
-        (f.is_inetd && smtp_load_reserve >= 0)
-      ))
-  {
+if (  receiving_message
+   && (queue_only_load >= 0 || (f.is_inetd && smtp_load_reserve >= 0)))
   load_average = OS_GETLOADAVG();
-  }
 #endif
 
 /* The queue_only configuration option can be overridden by -odx on the command
@@ -4301,6 +4304,11 @@ if (msg_action_arg > 0 && msg_action != MSG_DELIVER && msg_action != MSG_LOAD)
     for (i = msg_action_arg; i < argc; i++)
       if (!queue_action(argv[i], msg_action, NULL, 0, 0))
         yield = EXIT_FAILURE;
+    switch (msg_action)
+      {
+      case MSG_REMOVE: MSG_DELETE: case MSG_FREEZE: case MSG_THAW: break;
+      default: printf("\n"); break;
+      }
     }
 
   else if (!queue_action(argv[msg_action_arg], msg_action, argv, argc,
index 7959d754c81cdc077bb27fb6c411ae35d501e5a8..a631333534af8b82b9cd1d5bd13ec2e35626331a 100644 (file)
@@ -18,12 +18,14 @@ use strict;
 BEGIN { pop @INC if $INC[-1] eq '.' };
 use Getopt::Long;
 use File::Basename;
+use Pod::Usage;
 
-my($p_name)   = $0 =~ m|/?([^/]+)$|;
+my $p_name    = basename $0;
 my $p_version = "20100323.0";
-my $p_usage   = "Usage: $p_name [--help|--version] (see --help for details)";
+my $p_usage   = "Usage: $p_name [--help|--man|--version] (see --help for details)";
 my $p_cp      = <<EOM;
         Copyright (c) 2003-2010 John Jetmore <jj33\@pobox.com>
+        Copyright (c) 2019 The Exim Maintainers
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -39,7 +41,6 @@ my $p_cp      = <<EOM;
     along with this program; if not, write to the Free Software
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 EOM
-ext_usage(); # before we do anything else, check for --help
 
 $| = 1; # unbuffer STDOUT
 
@@ -48,6 +49,7 @@ GetOptions(
   'spool=s'     => \$G::spool,      # exim spool dir
   'C|Config=s'  => \$G::config,     # use alternative Exim configuration file
   'input-dir=s' => \$G::input_dir,  # name of the "input" dir
+  'queue=s'     => \$G::queue,      # name of the queue
   'finput'      => \$G::finput,     # same as "--input-dir Finput"
   'bp'          => \$G::mailq_bp,   # List the queue (noop - default)
   'bpa'         => \$G::mailq_bpa,  # ... with generated address as well
@@ -85,13 +87,15 @@ GetOptions(
   'just-vars'   => \$G::just_vars,  # only display vars, no other info
   'show-rules'  => \$G::show_rules, # display compiled match rules
   'show-tests'  => \$G::show_tests, # display tests as applied to each message
+  'man'         => sub { pod2usage(-verbose => 2, -exit => 0, -noperldoc => system('perldoc -V >/dev/null 2>&1')) },
+  'help'        => sub { pod2usage(-verbose => 1, -exit => 0) },
   'version'     => sub {
-        print basename($0) . ": $0\n",
+        print "$p_name: $0\n",
             "build: EXIM_RELEASE_VERSIONEXIM_VARIANT_VERSION\n",
             "perl(runtime): $]\n";
             exit 0;
   },
-) || exit(1);
+) or pod2usage;
 
 # if both freeze and thaw specified, only thaw as it is less destructive
 $G::freeze = undef               if ($G::freeze && $G::thaw);
@@ -128,7 +132,8 @@ $G::caseless        = $G::caseful ? 0 : 1; # nocase by default, case if both
 $spool              = defined $G::spool ? $G::spool
                      : do { chomp($_ = `$exim @{[defined $G::config ? "-C $G::config" : '']} -n -bP spool_directory`)
                              and $_ or $spool };
-my $input_dir       = $G::input_dir || ($G::finput ? "Finput" : "input");
+my $input_dir       = (defined $G::queue ? "$G::queue/" : '')
+                    . (defined $G::input_dir || ($G::finput ? "Finput" : "input"));
 my $count_only      = 1 if ($G::mailq_bpc  || $G::qgrep_c);
 my $unsorted        = 1 if ($G::mailq_bpr  || $G::mailq_bpra ||
                             $G::mailq_bpru || $G::unsorted);
@@ -898,115 +903,112 @@ sub _parse_header {
   $self->{_vars}{warning_count}    = $2;
   $self->{_vars}{message_age}      = time() - $self->{_vars}{received_time};
 
-  while (<I>) {
-    chomp();
-    if (/^(-\S+)\s*(.*$)/) {
-      my $tag = $1;
-      my $arg = $2;
-      if ($tag eq '-acl') {
-        my $t;
-        return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
-        if ($1 < $Exim::SpoolFile::ACL_C_MAX_LEGACY) {
-          $t = "acl_c$1";
-        } else {
-          $t = "acl_m" . ($1 - $Exim::SpoolFile::ACL_C_MAX_LEGACY);
-        }
-        read(I, $self->{_vars}{$t}, $2+1) || return(0);
-        chomp($self->{_vars}{$t});
-      } elsif ($tag eq '-aclc') {
-        #return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
-        return(0) if ($arg !~ /^(\S+)\s(\d+)$/);
-        my $t = "acl_c$1";
-        read(I, $self->{_vars}{$t}, $2+1) || return(0);
-        chomp($self->{_vars}{$t});
-      } elsif ($tag eq '-aclm') {
-        #return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
-        return(0) if ($arg !~ /^(\S+)\s(\d+)$/);
-        my $t = "acl_m$1";
-        read(I, $self->{_vars}{$t}, $2+1) || return(0);
-        chomp($self->{_vars}{$t});
-      } elsif ($tag eq '-local') {
-        $self->{_vars}{sender_local} = 1;
-      } elsif ($tag eq '-localerror') {
-        $self->{_vars}{local_error_message} = 1;
-      } elsif ($tag eq '-local_scan') {
-        $self->{_vars}{local_scan_data} = $arg;
-      } elsif ($tag eq '-spam_score_int') {
-        $self->{_vars}{spam_score_int} = $arg;
-        $self->{_vars}{spam_score}     = $arg / 10;
-      } elsif ($tag eq '-bmi_verdicts') {
-        $self->{_vars}{bmi_verdicts} = $arg;
-      } elsif ($tag eq '-host_lookup_deferred') {
-        $self->{_vars}{host_lookup_deferred} = 1;
-      } elsif ($tag eq '-host_lookup_failed') {
-        $self->{_vars}{host_lookup_failed} = 1;
-      } elsif ($tag eq '-body_linecount') {
-        $self->{_vars}{body_linecount} = $arg;
-      } elsif ($tag eq '-max_received_linelength') {
-        $self->{_vars}{max_received_linelength} = $arg;
-      } elsif ($tag eq '-body_zerocount') {
-        $self->{_vars}{body_zerocount} = $arg;
-      } elsif ($tag eq '-frozen') {
-        $self->{_vars}{deliver_freeze} = 1;
-        $self->{_vars}{deliver_frozen_at} = $arg;
-      } elsif ($tag eq '-allow_unqualified_recipient') {
-        $self->{_vars}{allow_unqualified_recipient} = 1;
-      } elsif ($tag eq '-allow_unqualified_sender') {
-        $self->{_vars}{allow_unqualified_sender} = 1;
-      } elsif ($tag eq '-deliver_firsttime') {
-        $self->{_vars}{deliver_firsttime} = 1;
-        $self->{_vars}{first_delivery} = 1;
-      } elsif ($tag eq '-manual_thaw') {
-        $self->{_vars}{deliver_manual_thaw} = 1;
-        $self->{_vars}{manually_thawed} = 1;
-      } elsif ($tag eq '-auth_id') {
-        $self->{_vars}{authenticated_id} = $arg;
-      } elsif ($tag eq '-auth_sender') {
-        $self->{_vars}{authenticated_sender} = $arg;
-      } elsif ($tag eq '-sender_set_untrusted') {
-        $self->{_vars}{sender_set_untrusted} = 1;
-      } elsif ($tag eq '-tls_certificate_verified') {
-        $self->{_vars}{tls_certificate_verified} = 1;
-      } elsif ($tag eq '-tls_cipher') {
-        $self->{_vars}{tls_cipher} = $arg;
-      } elsif ($tag eq '-tls_peerdn') {
-        $self->{_vars}{tls_peerdn} = $arg;
-      } elsif ($tag eq '-tls_sni') {
-        $self->{_vars}{tls_sni} = $arg;
-      } elsif ($tag eq '-host_address') {
-        $self->{_vars}{sender_host_port} = $self->_get_host_and_port(\$arg);
-        $self->{_vars}{sender_host_address} = $arg;
-      } elsif ($tag eq '-interface_address') {
-        $self->{_vars}{received_port} =
-            $self->{_vars}{interface_port} = $self->_get_host_and_port(\$arg);
-        $self->{_vars}{received_ip_address} =
-            $self->{_vars}{interface_address} = $arg;
-      } elsif ($tag eq '-active_hostname') {
-        $self->{_vars}{smtp_active_hostname} = $arg;
-      } elsif ($tag eq '-host_auth') {
-        $self->{_vars}{sender_host_authenticated} = $arg;
-      } elsif ($tag eq '-host_name') {
-        $self->{_vars}{sender_host_name} = $arg;
-      } elsif ($tag eq '-helo_name') {
-        $self->{_vars}{sender_helo_name} = $arg;
-      } elsif ($tag eq '-ident') {
-        $self->{_vars}{sender_ident} = $arg;
-      } elsif ($tag eq '-received_protocol') {
-        $self->{_vars}{received_protocol} = $arg;
-      } elsif ($tag eq '-N') {
-        $self->{_vars}{dont_deliver} = 1;
+  TAGGED: while (<I>) {
+    my ($tag, $arg) = /^-?(-\S+)(?:\s+(.*))?$/ or last TAGGED;
+    chomp;
+
+    if ($tag eq '-acl') {
+      my $t;
+      return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
+      if ($1 < $Exim::SpoolFile::ACL_C_MAX_LEGACY) {
+        $t = "acl_c$1";
       } else {
-        # unrecognized tag, save it for reference
-        $self->{$tag} = $arg;
+        $t = "acl_m" . ($1 - $Exim::SpoolFile::ACL_C_MAX_LEGACY);
       }
+      read(I, $self->{_vars}{$t}, $2+1) || return(0);
+      chomp($self->{_vars}{$t});
+    } elsif ($tag eq '-aclc') {
+      #return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
+      return(0) if ($arg !~ /^(\S+)\s(\d+)$/);
+      my $t = "acl_c$1";
+      read(I, $self->{_vars}{$t}, $2+1) || return(0);
+      chomp($self->{_vars}{$t});
+    } elsif ($tag eq '-aclm') {
+      #return(0) if ($arg !~ /^(\d+)\s(\d+)$/);
+      return(0) if ($arg !~ /^(\S+)\s(\d+)$/);
+      my $t = "acl_m$1";
+      read(I, $self->{_vars}{$t}, $2+1) || return(0);
+      chomp($self->{_vars}{$t});
+    } elsif ($tag eq '-local') {
+      $self->{_vars}{sender_local} = 1;
+    } elsif ($tag eq '-localerror') {
+      $self->{_vars}{local_error_message} = 1;
+    } elsif ($tag eq '-local_scan') {
+      $self->{_vars}{local_scan_data} = $arg;
+    } elsif ($tag eq '-spam_score_int') {
+      $self->{_vars}{spam_score_int} = $arg;
+      $self->{_vars}{spam_score}     = $arg / 10;
+    } elsif ($tag eq '-bmi_verdicts') {
+      $self->{_vars}{bmi_verdicts} = $arg;
+    } elsif ($tag eq '-host_lookup_deferred') {
+      $self->{_vars}{host_lookup_deferred} = 1;
+    } elsif ($tag eq '-host_lookup_failed') {
+      $self->{_vars}{host_lookup_failed} = 1;
+    } elsif ($tag eq '-body_linecount') {
+      $self->{_vars}{body_linecount} = $arg;
+    } elsif ($tag eq '-max_received_linelength') {
+      $self->{_vars}{max_received_linelength} = $arg;
+    } elsif ($tag eq '-body_zerocount') {
+      $self->{_vars}{body_zerocount} = $arg;
+    } elsif ($tag eq '-frozen') {
+      $self->{_vars}{deliver_freeze} = 1;
+      $self->{_vars}{deliver_frozen_at} = $arg;
+    } elsif ($tag eq '-allow_unqualified_recipient') {
+      $self->{_vars}{allow_unqualified_recipient} = 1;
+    } elsif ($tag eq '-allow_unqualified_sender') {
+      $self->{_vars}{allow_unqualified_sender} = 1;
+    } elsif ($tag eq '-deliver_firsttime') {
+      $self->{_vars}{deliver_firsttime} = 1;
+      $self->{_vars}{first_delivery} = 1;
+    } elsif ($tag eq '-manual_thaw') {
+      $self->{_vars}{deliver_manual_thaw} = 1;
+      $self->{_vars}{manually_thawed} = 1;
+    } elsif ($tag eq '-auth_id') {
+      $self->{_vars}{authenticated_id} = $arg;
+    } elsif ($tag eq '-auth_sender') {
+      $self->{_vars}{authenticated_sender} = $arg;
+    } elsif ($tag eq '-sender_set_untrusted') {
+      $self->{_vars}{sender_set_untrusted} = 1;
+    } elsif ($tag eq '-tls_certificate_verified') {
+      $self->{_vars}{tls_certificate_verified} = 1;
+    } elsif ($tag eq '-tls_cipher') {
+      $self->{_vars}{tls_cipher} = $arg;
+    } elsif ($tag eq '-tls_peerdn') {
+      $self->{_vars}{tls_peerdn} = $arg;
+    } elsif ($tag eq '-tls_sni') {
+      $self->{_vars}{tls_sni} = $arg;
+    } elsif ($tag eq '-host_address') {
+      $self->{_vars}{sender_host_port} = $self->_get_host_and_port(\$arg);
+      $self->{_vars}{sender_host_address} = $arg;
+    } elsif ($tag eq '-interface_address') {
+      $self->{_vars}{received_port} =
+          $self->{_vars}{interface_port} = $self->_get_host_and_port(\$arg);
+      $self->{_vars}{received_ip_address} =
+          $self->{_vars}{interface_address} = $arg;
+    } elsif ($tag eq '-active_hostname') {
+      $self->{_vars}{smtp_active_hostname} = $arg;
+    } elsif ($tag eq '-host_auth') {
+      $self->{_vars}{sender_host_authenticated} = $arg;
+    } elsif ($tag eq '-host_name') {
+      $self->{_vars}{sender_host_name} = $arg;
+    } elsif ($tag eq '-helo_name') {
+      $self->{_vars}{sender_helo_name} = $arg;
+    } elsif ($tag eq '-ident') {
+      $self->{_vars}{sender_ident} = $arg;
+    } elsif ($tag eq '-received_protocol') {
+      $self->{_vars}{received_protocol} = $arg;
+    } elsif ($tag eq '-N') {
+      $self->{_vars}{dont_deliver} = 1;
     } else {
-      last;
+      # unrecognized tag, save it for reference
+      $self->{$tag} = $arg;
     }
   }
 
   # when we drop out of the while loop, we have the first line of the
   # delivered tree in $_
   do {
+    chomp;
     if ($_ eq 'XX') {
       ; # noop
     } elsif ($_ =~ s/^[YN][YN]\s+//) {
@@ -1014,7 +1016,7 @@ sub _parse_header {
     } else {
       return(0);
     }
-    chomp($_ = <I>);
+    $_ = <I>;
   } while ($_ !~ /^\d+$/);
 
   $self->{_numrecips} = $_;
@@ -1264,64 +1266,53 @@ sub dump {
 
 } # BEGIN
 
-sub ext_usage {
-  if ($ARGV[0] =~ /^--help$/i) {
-    require Config;
-    $ENV{PATH} .= ":" unless $ENV{PATH} eq "";
-    $ENV{PATH} = "$ENV{PATH}$Config::Config{'installscript'}";
-    #exec("perldoc", "-F", "-U", $0) || exit 1;
-    $< = $> = 1 if ($> == 0 || $< == 0);
-    exec("perldoc", $0) || exit 1;
-    # make parser happy
-    %Config::Config = ();
-  } elsif ($ARGV[0] =~ /^--version$/i) {
-    print "$p_name version $p_version\n\n$p_cp\n";
-  } else {
-    return;
-  }
-
-  exit(0);
-}
-
 __END__
 
 =head1 NAME
 
-exipick - selectively display messages from an Exim queue
+  exipick - selectively display messages from an Exim queue
 
 =head1 SYNOPSIS
 
-exipick [<options>] [<criterion> [<criterion> ...]]
+  exipick [<options>] [<criterion> [<criterion> ...]]
+  exipick --help|--man
 
 =head1 DESCRIPTION
 
-exipick is a tool to display messages in an Exim queue.  It is very similar to exiqgrep and is, in fact, a drop in replacement for exiqgrep.  exipick allows you to select messages to be displayed using any piece of data stored in an Exim spool file.  Matching messages can be displayed in a variety of formats.
+B<exipick> is a tool to display messages in an Exim queue.  It is very similar to exiqgrep and is, in fact, a drop in replacement for exiqgrep.  B<exipick> allows you to select messages to be displayed using any piece of data stored in an Exim spool file.  Matching messages can be displayed in a variety of formats.
 
 =head1 QUICK START
 
 Delete every frozen message from queue:
+
     exipick -zi | xargs exim -Mrm
 
 Show only messages which have not yet been virus scanned:
+
     exipick '$received_protocol ne virus-scanned'
 
 Run the queue in a semi-random order:
+
     exipick -i --random | xargs exim -M
 
 Show the count and total size of all messages which either originated from localhost or have a received protocol of 'local':
+
     exipick --or --size --bpc \
             '$sender_host_address eq 127.0.0.1' \
             '$received_protocol eq local'
 
 Display all messages received on the MSA port, ordered first by the sender's email domain and then by the size of the emails:
+
     exipick --sort sender_address_domain,message_size \
             '$received_port == 587'
 
 Display only messages whose every recipient is in the example.com domain, also listing the IP address of the sending host:
+
     exipick --show-vars sender_host_address \
             '$each_recipients = example.com'
 
 Same as above, but show values for all defined variables starting with sender_ and the number of recipients:
+
     exipick --show-vars ^sender_,recipients_count \
             '$each_recipients = example.com'
 
@@ -1329,178 +1320,176 @@ Same as above, but show values for all defined variables starting with sender_ a
 
 =over 4
 
-=item --and
+=item B<--and>
 
 Display messages matching all criteria (default)
 
-=item -b
+=item B<-b>
 
 Display messages in brief format (exiqgrep)
 
-=item -bp
+=item B<-bp> | B<-l>
 
-Display messages in standard mailq format (default)
+Display messages in standard mailq format (default).
+(exiqgrep: C<-l>)
 
-=item -bpa
+=item B<-bpa>
 
-Same as -bp, show generated addresses also (exim)
+Same as C<-bp>, show generated addresses also (exim)
 
-=item -bpc
+=item B<-bpc>
 
 Show a count of matching messages (exim)
 
-=item -bpr
+=item B<-bpr>
 
-Same as '-bp --unsorted' (exim)
+Same as C<-bp --unsorted> (exim)
 
-=item -bpra
+=item B<-bpra>
 
-Same as '-bpa --unsorted' (exim)
+Same as C<-bpa --unsorted> (exim)
 
-=item -bpru
+=item B<-bpru>
 
-Same as '-bpu --unsorted' (exim)
+Same as C<-bpu --unsorted> (exim)
 
-=item -bpu
+=item B<-bpu>
 
-Same as -bp, but only show undelivered messages (exim)
+Same as C<-bp>, but only show undelivered messages (exim)
 
-=item -C | --config <config>
+=item B<-C> | B<--config> I<config>
 
-Use <config> to determine the proper spool directory. (See C<--spool>
+Use I<config> to determine the proper spool directory. (See C<--spool>
 or C<--input> for alternative ways to specify the directories to operate on.)
 
-=item -c
+=item B<-c>
 
 Show a count of matching messages (exiqgrep)
 
-=item --caseful
+=item B<--caseful>
 
-Make operators involving '=' honor case
+Make operators involving C<=> honor case
 
-=item --charset
+=item B<--charset>
 
-Override the default local character set for $header_ decoding
+Override the default local character set for C<$header_> decoding
 
-=item -f <regexp>
+=item B<-f> I<regexp>
 
-Same as '$sender_address =~ /<regexp>/' (exiqgrep).  Note that this preserves the default case sensitivity of exiqgrep's interface.
+Same as C<< $sender_address =~ /<regexp>/ >> (exiqgrep).  Note that this preserves the default case sensitivity of exiqgrep's interface.
 
-=item --finput
+=item B<--finput>
 
-Same as '--input-dir Finput'.  'Finput' is where exim copies frozen messages when compiled with SUPPORT_MOVE_FROZEN_MESSAGES.
+Same as C<--input-dir Finput>.  F<Finput> is where exim copies frozen messages when compiled with SUPPORT_MOVE_FROZEN_MESSAGES.
 
-=item --flatq
+=item B<--flatq>
 
 Use a single-line output format
 
-=item --freeze <cache file>
+=item B<--freeze> I<cache file>
 
 Save queue information in an quickly retrievable format
 
-=item --help
+=item B<--help>
 
 Display this output
 
-=item -i
+=item B<-i>
 
 Display only the message IDs (exiqgrep)
 
-=item --input-dir <inputname>
-
-Set the name of the directory under the spool directory.  By default this is "input".  If this starts with '/', the value of --spool is ignored.  See also --finput.
-
-=item -l
+=item B<--input-dir> I<inputname>
 
-Same as -bp (exiqgrep)
+Set the name of the directory under the spool directory.  By default this is F<input>.  If this starts with F</>,
+the value of C<--spool> is ignored.  See also C<--finput>.
 
-=item --not
+=item B<--not>
 
 Negate all tests.
 
-=item -o <seconds>
+=item B<-o> I<seconds>
 
-Same as '$message_age > <seconds>' (exiqgrep)
+Same as C<< $message_age > <seconds> >> (exiqgrep)
 
-=item --or
+=item B<--or>
 
 Display messages matching any criteria
 
-=item -R
+=item B<--queue> I<name>
 
-Same as --reverse (exiqgrep)
+Name of the queue (default: ''). See "named queues" in the spec.
 
-=item -r <regexp>
+=item B<-r> I<regexp>
 
-Same as '$recipients =~ /<regexp>/' (exiqgrep).  Note that this preserves the default case sensitivity of exiqgrep's interface.
+Same as C<< $recipients =~ /<regexp>/ >> (exiqgrep).  Note that this preserves the default case sensitivity of exiqgrep's interface.
 
-=item --random
+=item B<--random>
 
 Display messages in random order
 
-=item --reverse
+=item B<--reverse> | B<-R>
 
-Display messages in reverse order
+Display messages in reverse order (exiqgrep: C<-R>)
 
-=item -s <string>
+=item B<-s> I<string>
 
-Same as '$shown_message_size eq <string>' (exiqgrep)
+Same as C<< $shown_message_size eq <string> >> (exiqgrep)
 
-=item --spool <path>
+=item B<--spool> I<path>
 
-Set the path to the exim spool to use.  This value will have the argument to --input or 'input' appended, or be ignored if --input is a full path. If not specified, exipick uses the value from C<exim [-C config] -n -bP spool_directory>, and if this call fails, the  F</opt/exim/spool> from build time (F<Local/Makefile>) is used. See also --config.
+Set the path to the exim spool to use.  This value will have the arguments to C<--queue>, and C<--input> or F<input> appended, or be ignored if C<--input> is a full path. If not specified, B<exipick> uses the value from C<exim [-C config] -n -bP spool_directory>, and if this call fails, the  F</opt/exim/spool> from build time (F<Local/Makefile>) is used. See also C<--config>.
 
-=item --show-rules
+=item B<--show-rules>
 
 Show the internal representation of each criterion specified
 
-=item --show-tests
+=item B<--show-tests>
 
 Show the result of each criterion on each message
 
-=item --show-vars <variable>[,<variable>...]
+=item B<--show-vars> I<variable>[,I<variable>...]
 
-Show the value for <variable> for each displayed message.  <variable> will be a regular expression if it begins with a circumflex.
+Show the value for I<variable> for each displayed message.  I<variable> will be a regular expression if it begins with a circumflex.
 
-=item --size
+=item B<--size>
 
 Show the total bytes used by each displayed message
 
-=item --thaw <cache file>
+=item B<--thaw> I<cache file>
 
-Read queue information cached from a previous --freeze run
+Read queue information cached from a previous C<--freeze> run
 
-=item --sort <variable>[,<variable>...]
+=item B<--sort> I<variable>[,I<variable>...]
 
-Display matching messages sorted according to <variable>
+Display matching messages sorted according to I<variable>
 
-=item --unsorted
+=item B<--unsorted>
 
 Do not apply any sorting to output
 
-=item --version
+=item B<--version>
 
 Display the version of this command
 
-=item -x
+=item B<-x>
 
-Same as '!$deliver_freeze' (exiqgrep)
+Same as C<!$deliver_freeze> (exiqgrep)
 
-=item -y
+=item B<-y>
 
-Same as '$message_age < <seconds>' (exiqgrep)
+Same as C<< $message_age < <seconds> >> (exiqgrep)
 
-=item -z
+=item B<-z>
 
-Same as '$deliver_freeze' (exiqgrep)
+Same as C<$deliver_freeze> (exiqgrep)
 
 =back
 
 =head1 CRITERIA
 
-Exipick decides which messages to display by applying a test against each message.  The rules take the general form of 'VARIABLE OPERATOR VALUE'.  For example, '$message_age > 60'.  When exipick is deciding which messages to display, it checks the $message_age variable for each message.  If a message's age is greater than 60, the message will be displayed.  If the message's age is 60 or less seconds, it will not be displayed.
+B<Exipick> decides which messages to display by applying a test against each message.  The rules take the general form of "I<VARIABLE> I<OPERATOR> I<VALUE>".  For example, C<< $message_age > 60 >>.  When B<exipick> is deciding which messages to display, it checks the C<$message_age> variable for each message.  If a message's age is greater than 60, the message will be displayed.  If the message's age is 60 or less seconds, it will not be displayed.
 
-Multiple criteria can be used.  The order they are specified does not matter.  By default all criteria must evaluate to true for a message to be displayed.  If the --or option is used, a message is displayed as long as any of the criteria evaluate to true.
+Multiple criteria can be used.  The order they are specified does not matter.  By default all criteria must evaluate to true for a message to be displayed.  If the C<--or> option is used, a message is displayed as long as any of the criteria evaluate to true.
 
 See the VARIABLES and OPERATORS sections below for more details
 
@@ -1511,26 +1500,29 @@ See the VARIABLES and OPERATORS sections below for more details
 =item BOOLEAN
 
 Boolean variables are checked simply by being true or false.  There is no real operator except negation.  Examples of valid boolean tests:
-  '$deliver_freeze'
-  '!$deliver_freeze'
+
+  $deliver_freeze
+  !$deliver_freeze
 
 =item NUMERIC
 
 Valid comparisons are <, <=, >, >=, ==, and !=.  Numbers can be integers or floats.  Any number in a test suffixed with d, h, m, s, M, K, or B will be multiplied by 86400, 3600, 60, 1, 1048576, 1024, or 1 respectively.  Examples of valid numeric tests:
-  '$message_age >= 3d'
-  '$local_interface == 587'
-  '$message_size < 30K'
+
+  $message_age >= 3d
+  $local_interface == 587
+  $message_size < 30K
 
 =item STRING
 
-The string operators are =, eq, ne, =~, and !~.  With the exception of '=', the operators all match the functionality of the like-named perl operators.  eq and ne match a string exactly.  !~, =~, and = apply a perl regular expression to a string.  The '=' operator behaves just like =~ but you are not required to place // around the regular expression.  Examples of valid string tests:
-  '$received_protocol eq esmtp'
-  '$sender_address = example.com'
-  '$each_recipients =~ /^a[a-z]{2,3}@example.com$/'
+The string operators are =, eq, ne, =~, and !~.  With the exception of C<< = >>, the operators all match the functionality of the like-named perl operators.  eq and ne match a string exactly.  !~, =~, and = apply a perl regular expression to a string.  The C<< = >> operator behaves just like =~ but you are not required to place // around the regular expression.  Examples of valid string tests:
+
+  $received_protocol eq esmtp
+  $sender_address = example.com
+  $each_recipients =~ /^a[a-z]{2,3}@example.com$/
 
 =item NEGATION
 
-There are many ways to negate tests, each having a reason for existing.  Many tests can be negated using native operators.  For instance, >1 is the opposite of <=1 and eq and ne are opposites.  In addition, each individual test can be negated by adding a ! at the beginning of the test.  For instance, '!$acl_m1 =~ /^DENY$/' is the same as '$acl_m1 !~ /^DENY$/'.  Finally, every test can be specified by using the command line argument --not.  This is functionally equivalent to adding a ! to the beginning of every test.
+There are many ways to negate tests, each having a reason for existing.  Many tests can be negated using native operators.  For instance, >1 is the opposite of <=1 and eq and ne are opposites.  In addition, each individual test can be negated by adding a ! at the beginning of the test.  For instance, C<< !$acl_m1 =~ /^DENY$/ >> is the same as C<< $acl_m1 !~ /^DENY$/ >>.  Finally, every test can be specified by using the command line argument C<--not>.  This is functionally equivalent to adding a ! to the beginning of every test.
 
 =back
 
@@ -1538,7 +1530,7 @@ There are many ways to negate tests, each having a reason for existing.  Many te
 
 With a few exceptions the available variables match Exim's internal expansion variables in both name and exact contents.  There are a few notable additions and format deviations which are noted below.  Although a brief explanation is offered below, Exim's spec.txt should be consulted for full details.  It is important to remember that not every variable will be defined for every message.  For example, $sender_host_port is not defined for messages not received from a remote host.
 
-Internally, all variables are represented as strings, meaning any operator will work on any variable.  This means that '$sender_host_name > 4' is a legal criterion, even if it does not produce meaningful results.  Variables in the list below are marked with a 'type' to help in choosing which types of operators make sense to use.
+Internally, all variables are represented as strings, meaning any operator will work on any variable.  This means that C<< $sender_host_name > 4 >> is a legal criterion, even if it does not produce meaningful results.  Variables in the list below are marked with a 'type' to help in choosing which types of operators make sense to use.
 
   Identifiers
     B - Boolean variables
@@ -1550,283 +1542,283 @@ Internally, all variables are represented as strings, meaning any operator will
 
 =over 4
 
-=item S . $acl_c0-$acl_c9, $acl_m0-$acl_m9
+=item S . B<$acl_c0>-B<$acl_c9>, B<$acl_m0>-B<$acl_m9>
 
 User definable variables.
 
-=item B + $allow_unqualified_recipient
+=item B + B<$allow_unqualified_recipient>
 
 TRUE if unqualified recipient addresses are permitted in header lines.
 
-=item B + $allow_unqualified_sender
+=item B + B<$allow_unqualified_sender>
 
 TRUE if unqualified sender addresses are permitted in header lines.
 
-=item S . $authenticated_id
+=item S . B<$authenticated_id>
 
 Optional saved information from authenticators, or the login name of the calling process for locally submitted messages.
 
-=item S . $authenticated_sender
+=item S . B<$authenticated_sender>
 
 The value of AUTH= param for smtp messages, or a generated value from the calling processes login and qualify domain for locally submitted messages.
 
-=item S . $bheader_*, $bh_*
+=item S . B<$bheader_*>, B<$bh_*>
 
 Value of the header(s) with the same name with any RFC2047 words decoded if present.  See section 11.5 of Exim's spec.txt for full details.
 
-=item S + $bmi_verdicts
+=item S + B<$bmi_verdicts>
 
 The verdict string provided by a Brightmail content scan
 
-=item N . $body_linecount
+=item N . B<$body_linecount>
 
 The number of lines in the message's body.
 
-=item N . $body_zerocount
+=item N . B<$body_zerocount>
 
 The number of binary zero bytes in the message's body.
 
-=item S + $data_path
+=item S + B<$data_path>
 
 The path to the body file's location in the filesystem.
 
-=item B + $deliver_freeze
+=item B + B<$deliver_freeze>
 
 TRUE if the message is currently frozen.
 
-=item N + $deliver_frozen_at
+=item N + B<$deliver_frozen_at>
 
 The epoch time at which message was frozen.
 
-=item B + $dont_deliver
+=item B + B<$dont_deliver>
 
 TRUE if, under normal circumstances, Exim will not try to deliver the message.
 
-=item S + $each_recipients
+=item S + B<$each_recipients>
 
-This is a pseudo variable which allows you to apply a test against each address in $recipients individually.  Whereas '$recipients =~ /@aol.com/' will match if any recipient address contains aol.com, '$each_recipients =~ /@aol.com$/' will only be true if every recipient matches that pattern.  Note that this obeys --and or --or being set.  Using it with --or is very similar to just matching against $recipients, but with the added benefit of being able to use anchors at the beginning and end of each recipient address.
+This is a pseudo variable which allows you to apply a test against each address in $recipients individually.  Whereas C<< $recipients =~ /@aol.com/ >> will match if any recipient address contains aol.com, C<< $each_recipients =~ /@aol.com$/ >> will only be true if every recipient matches that pattern.  Note that this obeys C<--and> or C<--or> being set.  Using it with C<--or> is very similar to just matching against $recipients, but with the added benefit of being able to use anchors at the beginning and end of each recipient address.
 
-=item S + $each_recipients_del
+=item S + B<$each_recipients_del>
 
 Like $each_recipients, but for $recipients_del
 
-=item S + $each_recipients_undel
+=item S + B<$each_recipients_undel>
 
 Like $each_recipients, but for $recipients_undel
 
-=item B . $first_delivery
+=item B . B<$first_delivery>
 
 TRUE if the message has never been deferred.
 
-=item S . $header_*, $h_*
+=item S . B<$header_*>, B<$h_*>
 
 This will always match the contents of the corresponding $bheader_* variable currently (the same behaviour Exim displays when iconv is not installed).
 
-=item S + $header_path
+=item S + B<$header_path>
 
 The path to the header file's location in the filesystem.
 
-=item B . $host_lookup_deferred
+=item B . B<$host_lookup_deferred>
 
 TRUE if there was an attempt to look up the host's name from its IP address, but an error occurred that during the attempt.
 
-=item B . $host_lookup_failed
+=item B . B<$host_lookup_failed>
 
 TRUE if there was an attempt to look up the host's name from its IP address, but the attempt returned a negative result.
 
-=item B + $local_error_message
+=item B + B<$local_error_message>
 
 TRUE if the message is a locally-generated error message.
 
-=item S . $local_scan_data
+=item S . B<$local_scan_data>
 
 The text returned by the local_scan() function when a message is received.
 
-=item B . $manually_thawed
+=item B . B<$manually_thawed>
 
 TRUE when the message has been manually thawed.
 
-=item N . $max_received_linelength
+=item N . B<$max_received_linelength>
 
 The number of bytes in the longest line that was received as part of the message, not counting line termination characters.
 
-=item N . $message_age
+=item N . B<$message_age>
 
 The number of seconds since the message was received.
 
-=item S # $message_body
+=item S # B<$message_body>
 
 The message's body.  Unlike Exim's variable of the same name, this variable contains the entire message body.  Newlines and nulls are replaced by spaces.
 
-=item B + $message_body_missing
+=item B + B<$message_body_missing>
 
 TRUE is a message's spool data file (-D file) is missing or unreadable.
 
-=item N . $message_body_size
+=item N . B<$message_body_size>
 
 The size of the body in bytes.
 
-=item S . $message_exim_id, $message_id
+=item S . B<$message_exim_id>, B<$message_id>
 
 The unique message id that is used by Exim to identify the message.  $message_id is deprecated as of Exim 4.53.
 
-=item S . $message_headers
+=item S . B<$message_headers>
 
 A concatenation of all the header lines except for lines added by routers or transports.  RFC2047 decoding is performed
 
-=item S . $message_headers_raw
+=item S . B<$message_headers_raw>
 
 A concatenation of all the header lines except for lines added by routers or transports.  No decoding or translation is performed.
 
-=item N . $message_linecount
+=item N . B<$message_linecount>
 
 The number of lines in the entire message (body and headers).
 
-=item N . $message_size
+=item N . B<$message_size>
 
 The size of the message in bytes.
 
-=item N . $originator_gid
+=item N . B<$originator_gid>
 
 The group id under which the process that called Exim was running as when the message was received.
 
-=item S + $originator_login
+=item S + B<$originator_login>
 
 The login of the process which called Exim.
 
-=item N . $originator_uid
+=item N . B<$originator_uid>
 
 The user id under which the process that called Exim was running as when the message was received.
 
-=item S . $received_ip_address, $interface_address
+=item S . B<$received_ip_address>, B<$interface_address>
 
 The address of the local IP interface for network-originated messages.  $interface_address is deprecated as of Exim 4.64
 
-=item N . $received_port, $interface_port
+=item N . B<$received_port>, B<$interface_port>
 
 The local port number if network-originated messages.  $interface_port is deprecated as of Exim 4.64
 
-=item N . $received_count
+=item N . B<$received_count>
 
 The number of Received: header lines in the message.
 
-=item S . $received_protocol
+=item S . B<$received_protocol>
 
 The name of the protocol by which the message was received.
 
-=item N . $received_time
+=item N . B<$received_time>
 
 The epoch time at which the message was received.
 
-=item S # $recipients
+=item S # B<$recipients>
 
 The list of envelope recipients for a message.  Unlike Exim's version, this variable always contains every recipient of the message.  The recipients are separated by a comma and a space.  See also $each_recipients.
 
-=item N . $recipients_count
+=item N . B<$recipients_count>
 
 The number of envelope recipients for the message.
 
-=item S + $recipients_del
+=item S + B<$recipients_del>
 
 The list of delivered envelope recipients for a message.  This non-standard variable is in the same format as $recipients and contains the list of already-delivered recipients including any generated addresses.  See also $each_recipients_del.
 
-=item N + $recipients_del_count
+=item N + B<$recipients_del_count>
 
 The number of envelope recipients for the message which have already been delivered.  Note that this is the count of original recipients to which the message has been delivered.  It does not include generated addresses so it is possible that this number will be less than the number of addresses in the $recipients_del string.
 
-=item S + $recipients_undel
+=item S + B<$recipients_undel>
 
 The list of undelivered envelope recipients for a message.  This non-standard variable is in the same format as $recipients and contains the list of undelivered recipients.  See also $each_recipients_undel.
 
-=item N + $recipients_undel_count
+=item N + B<$recipients_undel_count>
 
 The number of envelope recipients for the message which have not yet been delivered.
 
-=item S . $reply_address
+=item S . B<$reply_address>
 
 The contents of the Reply-To: header line if one exists and it is not empty, or otherwise the contents of the From: header line.
 
-=item S . $rheader_*, $rh_*
+=item S . B<$rheader_*>, B<$rh_*>
 
 The value of the message's header(s) with the same name.  See section 11.5 of Exim's spec.txt for full description.
 
-=item S . $sender_address
+=item S . B<$sender_address>
 
 The sender's address that was received in the message's envelope.  For bounce messages, the value of this variable is the empty string.
 
-=item S . $sender_address_domain
+=item S . B<$sender_address_domain>
 
 The domain part of $sender_address.
 
-=item S . $sender_address_local_part
+=item S . B<$sender_address_local_part>
 
 The local part of $sender_address.
 
-=item S . $sender_helo_name
+=item S . B<$sender_helo_name>
 
 The HELO or EHLO value supplied for smtp or bsmtp messages.
 
-=item S . $sender_host_address
+=item S . B<$sender_host_address>
 
 The remote host's IP address.
 
-=item S . $sender_host_authenticated
+=item S . B<$sender_host_authenticated>
 
 The name of the authenticator driver which successfully authenticated the client from which the message was received.
 
-=item S . $sender_host_name
+=item S . B<$sender_host_name>
 
 The remote host's name as obtained by looking up its IP address.
 
-=item N . $sender_host_port
+=item N . B<$sender_host_port>
 
 The port number that was used on the remote host for network-originated messages.
 
-=item S . $sender_ident
+=item S . B<$sender_ident>
 
 The identification received in response to an RFC 1413 request for remote messages, the login name of the user that called Exim for locally generated messages.
 
-=item B + $sender_local
+=item B + B<$sender_local>
 
 TRUE if the message was locally generated.
 
-=item B + $sender_set_untrusted
+=item B + B<$sender_set_untrusted>
 
 TRUE if the envelope sender of this message was set by an untrusted local caller.
 
-=item S + $shown_message_size
+=item S + B<$shown_message_size>
 
 This non-standard variable contains the formatted size string.  That is, for a message whose $message_size is 66566 bytes, $shown_message_size is 65K.
 
-=item S . $smtp_active_hostname
+=item S . B<$smtp_active_hostname>
 
 The value of the active host name when the message was received, as specified by the "smtp_active_hostname" option.
 
-=item S . $spam_score
+=item S . B<$spam_score>
 
 The spam score of the message, for example '3.4' or '30.5'.  (Requires exiscan or WITH_CONTENT_SCAN)
 
-=item S . $spam_score_int
+=item S . B<$spam_score_int>
 
 The spam score of the message, multiplied by ten, as an integer value.  For instance '34' or '305'.  (Requires exiscan or WITH_CONTENT_SCAN)
 
-=item B . $tls_certificate_verified
+=item B . B<$tls_certificate_verified>
 
 TRUE if a TLS certificate was verified when the message was received.
 
-=item S . $tls_cipher
+=item S . B<$tls_cipher>
 
 The cipher suite that was negotiated for encrypted SMTP connections.
 
-=item S . $tls_peerdn
+=item S . B<$tls_peerdn>
 
 The value of the Distinguished Name of the certificate if Exim is configured to request one
 
-=item S . $tls_sni
+=item S . B<$tls_sni>
 
 The value of the Server Name Indication TLS extension sent by a client, if one was sent.
 
-=item N + $warning_count
+=item N + B<$warning_count>
 
 The number of delay warnings which have been sent for this message.
 
@@ -1838,8 +1830,12 @@ The number of delay warnings which have been sent for this message.
 
 =item EMAIL: proj-exipick@jetmore.net
 
-=item HOME: jetmore.org/john/code/#exipick
+=item HOME: L<https://jetmore.org/john/code/#exipick>
+
+This script was incorporated into the main Exim distribution some years ago.
 
 =back
 
 =cut
+
+# vim:ft=perl
index da21b87795be02b3a5c761e74b33d78092eb1d8e..ea3cf257c5f6869043b38a2959b08683c4953520 100644 (file)
@@ -48,6 +48,7 @@ extern uschar * tls_cert_fprt_md5(void *);
 extern uschar * tls_cert_fprt_sha1(void *);
 extern uschar * tls_cert_fprt_sha256(void *);
 
+extern void    tls_clean_env(void);
 extern BOOL    tls_client_start(client_conn_ctx *, smtp_connect_args *,
                  void *, tls_support *, uschar **);
 
@@ -198,8 +199,8 @@ extern BOOL    dkim_transport_write_message(transport_ctx *,
 #endif
 extern dns_address *dns_address_from_rr(dns_answer *, dns_record *);
 extern int     dns_basic_lookup(dns_answer *, const uschar *, int);
-extern void    dns_build_reverse(const uschar *, uschar *);
-extern time_t  dns_expire_from_soa(dns_answer *);
+extern uschar *dns_build_reverse(const uschar *);
+extern time_t  dns_expire_from_soa(dns_answer *, int);
 extern void    dns_init(BOOL, BOOL, BOOL);
 extern BOOL    dns_is_aa(const dns_answer *);
 extern BOOL    dns_is_secure(const dns_answer *);
@@ -541,6 +542,7 @@ extern int     strcmpic(const uschar *, const uschar *);
 extern int     strncmpic(const uschar *, const uschar *, int);
 extern uschar *strstric(uschar *, uschar *, BOOL);
 
+extern int     test_harness_fudged_queue_time(int);
 extern void    tcp_init(void);
 #ifdef EXIM_TFO_PROBE
 extern void    tfo_probe(void);
@@ -880,20 +882,33 @@ return string_sprintf("%s/%s/%s/%s",
 # endif
 
 static inline uschar *
-spool_sname(const uschar * purpose, uschar * subdir)
+spool_q_sname(const uschar * purpose, const uschar * q, uschar * subdir)
 {
 return string_sprintf("%s%s%s%s%s",
-                   queue_name, *queue_name ? "/" : "",
+                   q, *q ? "/" : "",
                    purpose,
                    *subdir ? "/" : "", subdir);
 }
 
+static inline uschar *
+spool_sname(const uschar * purpose, uschar * subdir)
+{
+return spool_q_sname(purpose, queue_name, subdir);
+}
+
+static inline uschar *
+spool_q_fname(const uschar * purpose, const uschar * q,
+       const uschar * subdir, const uschar * fname, const uschar * suffix)
+{
+return string_sprintf("%s/%s/%s/%s/%s%s",
+       spool_directory, q, purpose, subdir, fname, suffix);
+}
+
 static inline uschar *
 spool_fname(const uschar * purpose, const uschar * subdir, const uschar * fname,
                const uschar * suffix)
 {
-return string_sprintf("%s/%s/%s/%s/%s%s",
-       spool_directory, queue_name, purpose, subdir, fname, suffix);
+return spool_q_fname(purpose, queue_name, subdir, fname, suffix);
 }
 
 static inline void
@@ -926,7 +941,7 @@ static uschar buf[sizeof("0.000s")];
 if (diff->tv_sec >= 5 || !LOGGING(millisec))
   return readconf_printtime((int)diff->tv_sec);
 
-sprintf(CS buf, "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
+snprintf(CS buf, sizeof(buf), "%u.%03us", (uint)diff->tv_sec, (uint)diff->tv_usec/1000);
 return buf;
 }
 
index 8162de0c4d215368ecf660ddfe9fa2e0c2c1029f..de1149b6cd4e61fe41638e2d9ac8e20da80b8e0b 100644 (file)
@@ -1195,6 +1195,7 @@ uschar *qualify_domain_sender  = NULL;
 uschar *queue_domains          = NULL;
 int     queue_interval         = -1;
 uschar *queue_name             = US"";
+uschar *queue_name_dest        = NULL;
 uschar *queue_only_file        = NULL;
 int     queue_only_load        = -1;
 uschar *queue_run_max          = US"5";
@@ -1364,7 +1365,7 @@ router_instance  router_defaults = {
     .pass_router =             NULL,
     .redirect_router =         NULL,
 
-    .dnssec =                  { NULL, NULL },            /* dnssec_domains {require,request} */
+    .dnssec =                   { .request= US"*", .require=NULL },
 };
 
 uschar *router_name            = NULL;
index 8a3d4c56f077ec4013c474326695841380aecae1..03a56f0f2a36e8df766ecfbc1406a8687d7af275 100644 (file)
@@ -789,6 +789,7 @@ extern pid_t   queue_run_pid;          /* PID of the queue running process or 0
 extern int     queue_run_pipe;         /* Pipe for synchronizing */
 extern int     queue_interval;         /* Queue running interval */
 extern uschar *queue_name;             /* Name of queue, if nondefault spooling */
+extern uschar *queue_name_dest;               /* Destination queue, for moving messages */
 extern BOOL    queue_only;             /* TRUE to disable immediate delivery */
 extern int     queue_only_load;        /* Max load before auto-queue */
 extern BOOL    queue_only_load_latch;  /* Latch queue_only_load TRUE */
index 4081729ab0a8fd69cdfa121b2e9e1b07aa384247..3361d59123f33314ba79f70c0ac562513da99b4c 100644 (file)
@@ -138,7 +138,7 @@ if (!slow_lookup_log)
 time_msec = get_time_in_ms();
 retval = dns_lookup(dnsa, name, type, fully_qualified_name);
 if ((time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
-  log_long_lookup(US"name", name, time_msec);
+  log_long_lookup(dns_text_type(type), name, time_msec);
 return retval;
 }
 
@@ -1546,7 +1546,7 @@ hosts = gethostbyaddr(CS(&addr), sizeof(addr), AF_INET);
 if (  slow_lookup_log
    && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log
    )
-  log_long_lookup(US"name", sender_host_address, time_msec);
+  log_long_lookup(US"gethostbyaddr", sender_host_address, time_msec);
 
 /* Failed to look up the host. */
 
@@ -1646,7 +1646,6 @@ int old_pool, rc;
 int sep = 0;
 uschar *save_hostname;
 uschar **aliases;
-uschar buffer[256];
 uschar *ordername;
 const uschar *list = host_lookup_order;
 dns_answer * dnsa = store_get_dns_answer();
@@ -1672,13 +1671,14 @@ if (f.running_in_test_harness &&
 /* Do lookups directly in the DNS or via gethostbyaddr() (or equivalent), in
 the order specified by the host_lookup_order option. */
 
-while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
+while ((ordername = string_nextinlist(&list, &sep, NULL, 0)))
   {
   if (strcmpic(ordername, US"bydns") == 0)
     {
+    uschar * name = dns_build_reverse(sender_host_address);
+
     dns_init(FALSE, FALSE, FALSE);    /* dnssec ctrl by dns_dnssec_ok glbl */
-    dns_build_reverse(sender_host_address, buffer);
-    rc = dns_lookup_timerwrap(dnsa, buffer, T_PTR, NULL);
+    rc = dns_lookup_timerwrap(dnsa, name, T_PTR, NULL);
 
     /* The first record we come across is used for the name; others are
     considered to be aliases. We have to scan twice, in order to find out the
@@ -2032,7 +2032,7 @@ for (int i = 1; i <= times;
 
   if (   slow_lookup_log
       && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
-    log_long_lookup(US"name", host->name, time_msec);
+    log_long_lookup(US"gethostbyname", host->name, time_msec);
 
   if (hostdata == NULL)
     {
@@ -2648,7 +2648,7 @@ if (rc != DNS_SUCCEED  &&  whichrrs & HOST_FIND_BY_MX)
   if (dnssec_request)
     if (dns_is_secure(dnsa))
       {
-      DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name);
+      DEBUG(D_host_lookup) debug_printf("%s (MX resp) DNSSEC\n", host->name);
       dnssec = DS_YES; lookup_dnssec_authenticated = US"yes";
       }
     else
@@ -3154,6 +3154,79 @@ dns_init(FALSE, FALSE, FALSE);   /* clear the dnssec bit for getaddrbyname */
 return yield;
 }
 
+
+
+
+#ifdef SUPPORT_DANE
+/* Lookup TLSA record for host/port.
+Return:  OK            success with dnssec; DANE mode
+         DEFER         Do not use this host now, may retry later
+        FAIL_FORCED    No TLSA record; DANE not usable
+        FAIL           Do not use this connection
+*/
+
+int
+tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required)
+{
+uschar buffer[300];
+const uschar * fullname = buffer;
+int rc;
+BOOL sec;
+
+/* TLSA lookup string */
+(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
+
+rc = dns_lookup_timerwrap(dnsa, buffer, T_TLSA, &fullname);
+sec = dns_is_secure(dnsa);
+DEBUG(D_transport)
+  debug_printf("TLSA lookup ret %d %sDNSSEC\n", rc, sec ? "" : "not ");
+
+switch (rc)
+  {
+  case DNS_AGAIN:
+    return DEFER; /* just defer this TLS'd conn */
+
+  case DNS_SUCCEED:
+    if (sec)
+      {
+      DEBUG(D_transport)
+       {
+       dns_scan dnss;
+       for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
+            rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
+         if (rr->type == T_TLSA && rr->size > 3)
+           {
+           uint16_t payload_length = rr->size - 3;
+           uschar s[MAX_TLSA_EXPANDED_SIZE], * sp = s, * p = US rr->data;
+
+           sp += sprintf(CS sp, "%d ", *p++); /* usage */
+           sp += sprintf(CS sp, "%d ", *p++); /* selector */
+           sp += sprintf(CS sp, "%d ", *p++); /* matchtype */
+           while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4))
+             sp += sprintf(CS sp, "%02x", *p++);
+
+           debug_printf(" %s\n", s);
+           }
+       }
+      return OK;
+      }
+    log_write(0, LOG_MAIN,
+      "DANE error: TLSA lookup for %s not DNSSEC", host->name);
+    /*FALLTRHOUGH*/
+
+  case DNS_NODATA:     /* no TLSA RR for this lookup */
+  case DNS_NOMATCH:    /* no records at all for this lookup */
+    return dane_required ? FAIL : FAIL_FORCED;
+
+  default:
+  case DNS_FAIL:
+    return dane_required ? FAIL : DEFER;
+  }
+}
+#endif /*SUPPORT_DANE*/
+
+
+
 /*************************************************
 **************************************************
 *             Stand-alone test program           *
index fb878591e499abaf625532d503dc0fe84c85e85f..e0a97088f37b7087b9332ecf6c6c1f161115feb6 100644 (file)
@@ -98,8 +98,8 @@ ABI is changed in a non backward compatible way. The minor number is increased
 each time a new feature is added (in a way that doesn't break backward
 compatibility). */
 
-#define LOCAL_SCAN_ABI_VERSION_MAJOR 2
-#define LOCAL_SCAN_ABI_VERSION_MINOR 0
+#define LOCAL_SCAN_ABI_VERSION_MAJOR 3
+#define LOCAL_SCAN_ABI_VERSION_MINOR 1
 #define LOCAL_SCAN_ABI_VERSION \
   LOCAL_SCAN_ABI_VERSION_MAJOR.LOCAL_SCAN_ABI_VERSION_MINOR
 
@@ -193,7 +193,7 @@ extern void    smtp_vprintf(const char *, BOOL, va_list);
        string_sprintf_trc(fmt, US __FUNCTION__, __LINE__, __VA_ARGS__)
 extern uschar *string_sprintf_trc(const char *, const uschar *, unsigned, ...) ALMOST_PRINTF(1,4);
 
-#ifdef LOCAL_SCAN
+#if defined(LOCAL_SCAN) || defined(DLFUNC_IMPL)
 /* When compiling a local_scan() file we want to rename a published API, so that
 we can use an inlined implementation in the compiles of the main Exim files,
 with the original name. */
@@ -203,8 +203,8 @@ with the original name. */
 # define string_copy_taint(s, t) string_copy_taint_function((s), (t))
 
 extern uschar * string_copy_function(const uschar *);
-extern uschar * string_copyn_function(const uschar *);
-extern uschar * string_copy_taint_function(const uschar *);
+extern uschar * string_copyn_function(const uschar *, int n);
+extern uschar * string_copy_taint_function(const uschar *, BOOL tainted);
 #endif
 
 /* End of local_scan.h */
index 272734456215ce6dcbd8137ea83d8197ed8de30d..94809e5d83956314bf08f3253acf0ab60945bd31 100644 (file)
@@ -112,7 +112,7 @@ terminates option processing.  Recognised options are:
 causes the whole lookup to defer only if none of the DNS queries succeeds; and
 'never', where all defers are as if the lookup failed. The default is 'lax'.
 
-- 'dnssec_FOO', with 'strict', 'lax' and 'never' (default).  The meanings are
+- 'dnssec_FOO', with 'strict', 'lax' (default), and 'never'.  The meanings are
 require, try and don't-try dnssec respectively.
 
 - 'retrans_VAL', set the timeout value.  VAL is an Exim time specification
@@ -136,7 +136,7 @@ dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
 int rc;
 int sep = 0;
 int defer_mode = PASS;
-int dnssec_mode = OK;
+int dnssec_mode = PASS;
 int save_retrans = dns_retrans;
 int save_retry =   dns_retry;
 int type;
@@ -312,7 +312,6 @@ if (!outsep2) switch(type)
 
 while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
   {
-  uschar rbuffer[256];
   int searchtype = type == T_CSA ? T_SRV :         /* record type we want */
                    type == T_MXH ? T_MX :
                    type == T_ZNS ? T_NS : type;
@@ -325,10 +324,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
 
   if ((type == T_PTR || type == T_CSA) &&
       string_is_ip_address(domain, NULL) != 0)
-    {
-    dns_build_reverse(domain, rbuffer);
-    domain = rbuffer;
-    }
+    domain = dns_build_reverse(domain);
 
   do
     {
index a9653f45ba2ed2518d04a7d255ecbe0893f137a8..cc96c85163f84e9df39e0fe3303f96fafe3066ca 100644 (file)
@@ -842,7 +842,7 @@ enum {
 
 enum { MSG_DELIVER, MSG_FREEZE, MSG_REMOVE, MSG_THAW, MSG_ADD_RECIPIENT,
        MSG_MARK_ALL_DELIVERED, MSG_MARK_DELIVERED, MSG_EDIT_SENDER,
-       MSG_SHOW_COPY, MSG_LOAD,
+       MSG_SHOW_COPY, MSG_LOAD, MSG_SETQUEUE,
        /* These ones must be last: a test for >= MSG_SHOW_BODY is used
        to test for actions that list individual spool files. */
        MSG_SHOW_BODY, MSG_SHOW_HEADER, MSG_SHOW_LOG };
index 9fa38b3e719acda703967dd3876b7c487d49a3a3..7fcfbc76a46aa4c46d2ee3080080be898e0a3609 100644 (file)
@@ -2029,6 +2029,8 @@ pdkim_set_bodyhash(pdkim_ctx * ctx, int hashtype, int canon_method,
 {
 pdkim_bodyhash * b;
 
+if (hashtype == -1 || canon_method == -1) return NULL;
+
 for (b = ctx->bodyhash; b; b = b->next)
   if (  hashtype == b->hashtype
      && canon_method == b->canon_method
index d8c160a3af8527e01e4826289eef05f359ad240c..d9ff133759cf8e326947d38c1c8dca342009d910 100644 (file)
@@ -664,8 +664,8 @@ for (int i = queue_run_in_order ? -1 : 0;
 
     if (f.running_in_test_harness && !f.queue_2stage)
       {
-      uschar *fqtnext = Ustrchr(fudged_queue_times, '/');
-      if (fqtnext != NULL) fudged_queue_times = fqtnext + 1;
+      uschar * fqtnext = Ustrchr(fudged_queue_times, '/');
+      if (fqtnext) fudged_queue_times = fqtnext + 1;
       }
     }                                  /* End loop for list of messages */
 
@@ -1265,6 +1265,14 @@ switch(action)
     }
 
 
+  case MSG_SETQUEUE:
+    /* The global "queue_name_dest" is used as destination, "queue_name"
+    as source */
+
+    spool_move_message(id, message_subdir, US"", US"");
+    break;
+
+
   case MSG_MARK_ALL_DELIVERED:
   for (int i = 0; i < recipients_count; i++)
     tree_add_nonrecipient(recipients_list[i].address);
index 713a1a9efe9fb0b898881548d93b0f489fc9333e..08014c9af480ef00993feda19e487044a688613d 100644 (file)
@@ -3270,19 +3270,6 @@ if (f.trusted_config && Ustrcmp(filename, US"/dev/null"))
     }
   }
 
-/* Do a dummy store-allocation of a size related to the (toplevel) file size.
-This assumes we will need this much storage to handle all the allocations
-during startup; it won't help when .include is being used.  When it does, it
-will cut down on the number of store blocks (and malloc calls, and sbrk
-syscalls).  It also assume we're on the relevant pool. */
-
-if (statbuf.st_size > 8192)
-  {
-  rmark r = store_mark();
-  void * dummy = store_get((int)statbuf.st_size, FALSE);
-  store_reset(r);
-  }
-
 /* Process the main configuration settings. They all begin with a lower case
 letter. If we see something starting with an upper case letter, it is taken as
 a macro definition. */
index 580fe9f91f88097a9cd9d4d79b637aa1421c4bc1..9e2b39c4e37d93694a0995a69ece91db3f68375b 100644 (file)
@@ -877,6 +877,8 @@ flush for non-TLS connections. The smtp_fflush() function is available for
 checking that: for convenience, TLS output errors are remembered here so that
 they are also picked up later by smtp_fflush().
 
+This function is exposed to the local_scan API; do not change the signature.
+
 Arguments:
   format      format string
   more       further data expected
@@ -897,7 +899,10 @@ va_end(ap);
 
 /* This is split off so that verify.c:respond_printf() can, in effect, call
 smtp_printf(), bearing in mind that in C a vararg function can't directly
-call another vararg function, only a function which accepts a va_list. */
+call another vararg function, only a function which accepts a va_list.
+
+This function is exposed to the local_scan API; do not change the signature.
+*/
 /*XXX consider passing caller-info in, for string_vformat-onward */
 
 void
index 1aa68f18115f94aa451aee187446e0d3f12d681f..1955b5d968cf7646142a0b7c665cf38f8c70dc82 100644 (file)
@@ -165,6 +165,12 @@ if (!(spf_server = SPF_server_new_dns(dc, debug)))
   DEBUG(D_receive) debug_printf("spf: SPF_server_new() failed.\n");
   return FALSE;
   }
+  /* Quick hack to override the outdated explanation URL.
+  See https://www.mail-archive.com/mailop@mailop.org/msg08019.html */
+  SPF_server_set_explanation(spf_server, "Please%_see%_http://www.open-spf.org/Why?id=%{S}&ip=%{C}&receiver=%{R}", &spf_response);
+  if (SPF_response_errcode(spf_response) != SPF_E_SUCCESS)
+    log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", SPF_strerror(SPF_response_errcode(spf_response)));
+
 return TRUE;
 }
 
index cbd2751acbdb3d71b5f69accc5e922c426188051..8d5f5a7296fe286ef80caacd70271970e0169aff 100644 (file)
@@ -423,12 +423,16 @@ if (sscanf(CS big_buffer, TIME_T_FMT " %d", &received_time.tv_sec, &warning_coun
 received_time.tv_usec = 0;
 
 message_age = time(NULL) - received_time.tv_sec;
+#ifndef COMPILE_UTILITY
+if (f.running_in_test_harness)
+  message_age = test_harness_fudged_queue_time(message_age);
+#endif
 
 #ifndef COMPILE_UTILITY
 DEBUG(D_deliver) debug_printf("user=%s uid=%ld gid=%ld sender=%s\n",
   originator_login, (long int)originator_uid, (long int)originator_gid,
   sender_address);
-#endif  /* COMPILE_UTILITY */
+#endif
 
 /* Now there may be a number of optional lines, each starting with "-". If you
 add a new setting here, make sure you set the default above.
index c766b147d1cf9aeb47a159c7caec94a1759abe48..892ea2f52fd1bb574f2dd699ab29414fb332726f 100644 (file)
@@ -406,8 +406,6 @@ return statbuf.st_size - size_correction;
 }
 
 
-#ifdef SUPPORT_MOVE_FROZEN_MESSAGES
-
 /************************************************
 *              Make a hard link                 *
 ************************************************/
@@ -418,6 +416,7 @@ start-up time.
 
 Arguments:
   dir        base directory name
+  dq        destiinationqueue name
   subdir     subdirectory name
   id         message id
   suffix     suffix to add to id
@@ -430,11 +429,11 @@ Returns:     TRUE if all went well
 */
 
 static BOOL
-make_link(uschar *dir, uschar *subdir, uschar *id, uschar *suffix, uschar *from,
-  uschar *to, BOOL noentok)
+make_link(uschar *dir, uschar * dq, uschar *subdir, uschar *id, uschar *suffix,
+  uschar *from, uschar *to, BOOL noentok)
 {
 uschar * fname = spool_fname(string_sprintf("%s%s", from, dir), subdir, id, suffix);
-uschar * tname = spool_fname(string_sprintf("%s%s", to,   dir), subdir, id, suffix);
+uschar * tname = spool_q_fname(string_sprintf("%s%s", to,   dir), dq, subdir, id, suffix);
 if (Ulink(fname, tname) < 0 && (!noentok || errno != ENOENT))
   {
   log_write(0, LOG_MAIN|LOG_PANIC, "link(\"%s\", \"%s\") failed while moving "
@@ -488,8 +487,7 @@ return TRUE;
 
 /* Move the files for a message (-H, -D, and msglog) from one directory (or
 hierarchy) to another. It is assume that there is no -J file in existence when
-this is done. At present, this is used only when move_frozen_messages is set,
-so compile it only when that support is configured.
+this is done.
 
 Arguments:
   id          the id of the message to be delivered
@@ -504,13 +502,15 @@ Returns:      TRUE if all is well
 BOOL
 spool_move_message(uschar *id, uschar *subdir, uschar *from, uschar *to)
 {
+uschar * dest_qname = queue_name_dest ? queue_name_dest : queue_name;
+
 /* Create any output directories that do not exist. */
 
 (void) directory_make(spool_directory,
-  spool_sname(string_sprintf("%sinput", to), subdir),
+  spool_q_sname(string_sprintf("%sinput", to), dest_qname, subdir),
   INPUT_DIRECTORY_MODE, TRUE);
 (void) directory_make(spool_directory,
-  spool_sname(string_sprintf("%smsglog", to), subdir),
+  spool_q_sname(string_sprintf("%smsglog", to), dest_qname, subdir),
   INPUT_DIRECTORY_MODE, TRUE);
 
 /* Move the message by first creating new hard links for all the files, and
@@ -522,9 +522,9 @@ rule of waiting for a -H file before doing anything. When moving messages off
 the mail spool, the -D file should be open and locked at the time, thus keeping
 Exim's hands off. */
 
-if (!make_link(US"msglog", subdir, id, US"", from, to, TRUE) ||
-    !make_link(US"input",  subdir, id, US"-D", from, to, FALSE) ||
-    !make_link(US"input",  subdir, id, US"-H", from, to, FALSE))
+if (!make_link(US"msglog", dest_qname, subdir, id, US"", from, to, TRUE) ||
+    !make_link(US"input",  dest_qname, subdir, id, US"-D", from, to, FALSE) ||
+    !make_link(US"input",  dest_qname, subdir, id, US"-H", from, to, FALSE))
   return FALSE;
 
 if (!break_link(US"input",  subdir, id, US"-H", from, FALSE) ||
@@ -532,13 +532,15 @@ if (!break_link(US"input",  subdir, id, US"-H", from, FALSE) ||
     !break_link(US"msglog", subdir, id, US"", from, TRUE))
   return FALSE;
 
-log_write(0, LOG_MAIN, "moved from %sinput, %smsglog to %sinput, %smsglog",
-   from, from, to, to);
+log_write(0, LOG_MAIN, "moved from %s%s%s%sinput, %smsglog to %s%s%s%sinput, %smsglog",
+   *queue_name?"(":"", *queue_name?queue_name:US"", *queue_name?") ":"",
+   from, from,
+   *dest_qname?"(":"", *dest_qname?dest_qname:US"", *dest_qname?") ":"",
+   to, to);
 
 return TRUE;
 }
 
-#endif
 
 /* End of spool_out.c */
 /* vi: aw ai sw=2
index 007ec877ef5d1c491527e210ab2b8e778ab283ba..a208070547ea8706d49bcf15632d4a6e719f7621 100644 (file)
@@ -411,7 +411,8 @@ return ss;
 
 
 
-#if defined(HAVE_LOCAL_SCAN) && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
+#if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
+       && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
 /*************************************************
 *            Copy and save string                *
 *************************************************/
index 7b0f2f6adb01248dd0b4c273d2c6ba0a2104d459..837b991df47e906092f51ef9af9845df962ab046 100644 (file)
@@ -74,6 +74,12 @@ require current GnuTLS, then we'll drop support for the ancient libraries).
 # define GNUTLS_AUTO_GLOBAL_INIT
 # define GNUTLS_AUTO_PKCS11_MANUAL
 #endif
+#if (GNUTLS_VERSION_NUMBER >= 0x030404) \
+  || (GNUTLS_VERSION_NUMBER >= 0x030311) && (GNUTLS_VERSION_NUMBER & 0xffff00 == 0x030300)
+# ifndef DISABLE_OCSP
+#  define EXIM_HAVE_OCSP
+# endif
+#endif
 #if GNUTLS_VERSION_NUMBER >= 0x030500
 # define SUPPORT_GNUTLS_KEYLOG
 #endif
@@ -127,6 +133,12 @@ builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING );
 # ifdef EXIM_HAVE_TLS1_3
 builtin_macro_create(US"_HAVE_TLS1_3");
 # endif
+# ifdef EXIM_HAVE_OCSP
+builtin_macro_create(US"_HAVE_TLS_OCSP");
+# endif
+# ifdef SUPPORT_SRV_OCSP_STACK
+builtin_macro_create(US"_HAVE_TLS_OCSP_LIST");
+# endif
 }
 #else
 
@@ -2271,17 +2283,17 @@ post_handshake_debug(exim_gnutls_state_st * state)
 #ifdef SUPPORT_GNUTLS_SESS_DESC
 debug_printf("%s\n", gnutls_session_get_desc(state->session));
 #endif
-#ifdef SUPPORT_GNUTLS_KEYLOG
 
+#ifdef SUPPORT_GNUTLS_KEYLOG
 # ifdef EXIM_HAVE_TLS1_3
 if (gnutls_protocol_get_version(state->session) < GNUTLS_TLS1_3)
-#else
+# else
 if (TRUE)
-#endif
+# endif
   {
   gnutls_datum_t c, s;
   gstring * gc, * gs;
-  /* we only want the client random and the master secret */
+  /* For TLS1.2 we only want the client random and the master secret */
   gnutls_session_get_random(state->session, &c, &s);
   gnutls_session_get_master_secret(state->session, &s);
   gc = ddump(&c);
@@ -2294,7 +2306,8 @@ else
     " add SSLKEYLOGFILE to keep_environment in the exim config\n"
     " run exim as root\n"
     " if using sudo, add SSLKEYLOGFILE to env_keep in /etc/sudoers\n"
-    " (works for TLS1.2 also, and saves cut-paste into file)\n");
+    " (works for TLS1.2 also, and saves cut-paste into file)"
+    " Trying to use add_environment for this will not work\n");
 #endif
 }
 
index 7e3cc3f78e053355603716b8f2e57973b2793930..a236bc0c68c0028497f80157c75750c2d150b3b5 100644 (file)
@@ -76,6 +76,9 @@ change this guard and punt the issue for a while longer. */
 #  define EXIM_HAVE_SESSION_TICKET
 #  define EXIM_HAVE_OPESSL_TRACE
 #  define EXIM_HAVE_OPESSL_GET0_SERIAL
+#  ifndef DISABLE_OCSP
+#   define EXIM_HAVE_OCSP
+#  endif
 # else
 #  define EXIM_NEED_OPENSSL_INIT
 # endif
@@ -102,6 +105,8 @@ change this guard and punt the issue for a while longer. */
 #  define OPENSSL_HAVE_KEYLOG_CB
 #  define OPENSSL_HAVE_NUM_TICKETS
 #  define EXIM_HAVE_OPENSSL_CIPHER_STD_NAME
+# else
+#  define OPENSSL_BAD_SRVR_OURCERT
 # endif
 #endif
 
@@ -146,6 +151,11 @@ This list is current as of:
   ==>  1.0.1b  <==
 Plus SSL_OP_SAFARI_ECDHE_ECDSA_BUG from 2013-June patch/discussion on openssl-dev
 Plus SSL_OP_NO_TLSv1_3 for 1.1.2-dev
+Plus SSL_OP_NO_RENEGOTIATION for 1.1.1
+
+XXX could we autobuild this list, as with predefined-macros?
+Seems just parsing ssl.h for SSL_OP_.* would be enough.
+Also allow a numeric literal?
 */
 static exim_openssl_option exim_openssl_options[] = {
 /* KEEP SORTED ALPHABETICALLY! */
@@ -185,6 +195,9 @@ static exim_openssl_option exim_openssl_options[] = {
 #ifdef SSL_OP_NO_COMPRESSION
   { US"no_compression", SSL_OP_NO_COMPRESSION },
 #endif
+#ifdef SSL_OP_NO_RENEGOTIATION
+  { US"no_renegotiation", SSL_OP_NO_RENEGOTIATION },
+#endif
 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
   { US"no_session_resumption_on_renegotiation", SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION },
 #endif
@@ -266,6 +279,13 @@ builtin_macro_create_var(US"_RESUME_DECODE", RESUME_DECODE_STRING );
 # ifdef SSL_OP_NO_TLSv1_3
 builtin_macro_create(US"_HAVE_TLS1_3");
 # endif
+# ifdef OPENSSL_BAD_SRVR_OURCERT
+builtin_macro_create(US"_TLS_BAD_MULTICERT_IN_OURCERT");
+# endif
+# ifdef EXIM_HAVE_OCSP
+builtin_macro_create(US"_HAVE_TLS_OCSP");
+builtin_macro_create(US"_HAVE_TLS_OCSP_LIST");
+# endif
 }
 #else
 
@@ -841,7 +861,13 @@ DEBUG(D_tls)
 static void
 keylog_callback(const SSL *ssl, const char *line)
 {
+char * filename;
+FILE * fp;
 DEBUG(D_tls) debug_printf("%.200s\n", line);
+if (!(filename = getenv("SSLKEYLOGFILE"))) return;
+if (!(fp = fopen(filename, "a"))) return;
+fprintf(fp, "%s\n", line);
+fclose(fp);
 }
 #endif
 
@@ -1200,12 +1226,13 @@ Arguments:
   sctx            the SSL_CTX* to update
   cbinfo          various parts of session state
   filename        the filename putatively holding an OCSP response
+  is_pem         file is PEM format; otherwise is DER
 
 */
 
 static void
 ocsp_load_response(SSL_CTX * sctx, tls_ext_ctx_cb * cbinfo,
-  const uschar * filename)
+  const uschar * filename, BOOL is_pem)
 {
 BIO * bio;
 OCSP_RESPONSE * resp;
@@ -1216,7 +1243,8 @@ STACK_OF(X509) * sk;
 unsigned long verify_flags;
 int status, reason, i;
 
-DEBUG(D_tls) debug_printf("tls_ocsp_file        '%s'\n", filename);
+DEBUG(D_tls)
+  debug_printf("tls_ocsp_file (%s)  '%s'\n", is_pem ? "PEM" : "DER", filename);
 
 if (!(bio = BIO_new_file(CS filename, "rb")))
   {
@@ -1225,8 +1253,26 @@ if (!(bio = BIO_new_file(CS filename, "rb")))
   return;
   }
 
-resp = d2i_OCSP_RESPONSE_bio(bio, NULL);
+if (is_pem)
+  {
+  uschar * data, * freep;
+  char * dummy;
+  long len;
+  if (!PEM_read_bio(bio, &dummy, &dummy, &data, &len))
+    {
+    DEBUG(D_tls) debug_printf("Failed to read PEM file \"%s\"\n",
+       filename);
+    return;
+    }
+debug_printf("read pem file\n");
+  freep = data;
+  resp = d2i_OCSP_RESPONSE(NULL, CUSS &data, len);
+  OPENSSL_free(freep);
+  }
+else
+  resp = d2i_OCSP_RESPONSE_bio(bio, NULL);
 BIO_free(bio);
+
 if (!resp)
   {
   DEBUG(D_tls) debug_printf("Error reading OCSP response.\n");
@@ -1512,6 +1558,7 @@ else
       const uschar * olist = cbinfo->u_ocsp.server.file;
       int osep = 0;
       uschar * ofile;
+      BOOL fmt_pem = FALSE;
 
       if (olist)
        if (!expand_check(olist, US"tls_ocsp_file", USS &olist, errstr))
@@ -1540,7 +1587,19 @@ else
 #ifndef DISABLE_OCSP
        if (olist)
          if ((ofile = string_nextinlist(&olist, &osep, NULL, 0)))
-           ocsp_load_response(sctx, cbinfo, ofile);
+           {
+           if (Ustrncmp(ofile, US"PEM ", 4) == 0)
+             {
+             fmt_pem = TRUE;
+             ofile += 4;
+             }
+           else if (Ustrncmp(ofile, US"DER ", 4) == 0)
+             {
+             fmt_pem = FALSE;
+             ofile += 4;
+             }
+           ocsp_load_response(sctx, cbinfo, ofile, fmt_pem);
+           }
          else
            DEBUG(D_tls) debug_printf("ran out of ocsp file list\n");
 #endif
@@ -1802,13 +1861,13 @@ OCSP_RESPONSE * rsp;
 OCSP_BASICRESP * bs;
 int i;
 
-DEBUG(D_tls) debug_printf("Received TLS status response (OCSP stapling):");
+DEBUG(D_tls) debug_printf("Received TLS status callback (OCSP stapling):\n");
 len = SSL_get_tlsext_status_ocsp_resp(s, &p);
 if(!p)
  {
   /* Expect this when we requested ocsp but got none */
   if (cbinfo->u_ocsp.client.verify_required && LOGGING(tls_cipher))
-    log_write(0, LOG_MAIN, "Received TLS status callback, null content");
+    log_write(0, LOG_MAIN, "Required TLS certificate status not received");
   else
     DEBUG(D_tls) debug_printf(" null\n");
   return cbinfo->u_ocsp.client.verify_required ? 0 : 1;
@@ -1844,8 +1903,9 @@ if (!(bs = OCSP_response_get1_basic(rsp)))
 */
   {
     BIO * bp = NULL;
-    int status, reason;
-    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+#ifndef EXIM_HAVE_OCSP_RESP_COUNT
+    STACK_OF(OCSP_SINGLERESP) * sresp = bs->tbsResponseData->responses;
+#endif
 
     DEBUG(D_tls) bp = BIO_new_fp(debug_file, BIO_NOCLOSE);
 
@@ -1855,19 +1915,23 @@ if (!(bs = OCSP_response_get1_basic(rsp)))
     /* DEBUG(D_tls) x509_store_dump_cert_s_names(cbinfo->u_ocsp.client.verify_store); */
 
     if ((i = OCSP_basic_verify(bs, cbinfo->verify_stack,
-             cbinfo->u_ocsp.client.verify_store, 0)) <= 0)
-      {
-      tls_out.ocsp = OCSP_FAILED;
-      if (LOGGING(tls_cipher)) log_write(0, LOG_MAIN,
-             "Received TLS cert status response, itself unverifiable: %s",
-             ERR_reason_error_string(ERR_peek_error()));
-      BIO_printf(bp, "OCSP response verify failure\n");
-      ERR_print_errors(bp);
-      OCSP_RESPONSE_print(bp, rsp, 0);
-      goto failed;
-      }
+             cbinfo->u_ocsp.client.verify_store, OCSP_NOEXPLICIT)) <= 0)
+      if (ERR_peek_error())
+       {
+       tls_out.ocsp = OCSP_FAILED;
+       if (LOGGING(tls_cipher)) log_write(0, LOG_MAIN,
+               "Received TLS cert status response, itself unverifiable: %s",
+               ERR_reason_error_string(ERR_peek_error()));
+       BIO_printf(bp, "OCSP response verify failure\n");
+       ERR_print_errors(bp);
+       OCSP_RESPONSE_print(bp, rsp, 0);
+       goto failed;
+       }
+      else
+       DEBUG(D_tls) debug_printf("no explicit trust for OCSP signing"
+         " in the root CA certificate; ignoring\n");
 
-    BIO_printf(bp, "OCSP response well-formed and signed OK\n");
+    DEBUG(D_tls) debug_printf("OCSP response well-formed and signed OK\n");
 
     /*XXX So we have a good stapled OCSP status.  How do we know
     it is for the cert of interest?  OpenSSL 1.1.0 has a routine
@@ -1877,60 +1941,65 @@ if (!(bs = OCSP_response_get1_basic(rsp)))
 
     For now, carry on blindly accepting the resp. */
 
-      {
-      OCSP_SINGLERESP * single;
-
+    for (int idx =
 #ifdef EXIM_HAVE_OCSP_RESP_COUNT
-      if (OCSP_resp_count(bs) != 1)
+           OCSP_resp_count(bs) - 1;
 #else
-      STACK_OF(OCSP_SINGLERESP) * sresp = bs->tbsResponseData->responses;
-      if (sk_OCSP_SINGLERESP_num(sresp) != 1)
+           sk_OCSP_SINGLERESP_num(sresp) - 1;
 #endif
-        {
-       tls_out.ocsp = OCSP_FAILED;
-        log_write(0, LOG_MAIN, "OCSP stapling "
-           "with multiple responses not handled");
-        goto failed;
-        }
-      single = OCSP_resp_get0(bs, 0);
+        idx >= 0; idx--)
+      {
+      OCSP_SINGLERESP * single = OCSP_resp_get0(bs, idx);
+      int status, reason;
+      ASN1_GENERALIZEDTIME * rev, * thisupd, * nextupd;
+
+  /*XXX so I can see putting a loop in here to handle a rsp with >1 singleresp
+  - but what happens with a GnuTLS-style input?
+
+  we could do with a debug label for each singleresp
+  - it has a certID with a serialNumber, but I see no API to get that
+  */
       status = OCSP_single_get0_status(single, &reason, &rev,
                  &thisupd, &nextupd);
-      }
 
-    DEBUG(D_tls) time_print(bp, "This OCSP Update", thisupd);
-    DEBUG(D_tls) if(nextupd) time_print(bp, "Next OCSP Update", nextupd);
-    if (!OCSP_check_validity(thisupd, nextupd,
-         EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE))
-      {
-      tls_out.ocsp = OCSP_FAILED;
-      DEBUG(D_tls) ERR_print_errors(bp);
-      log_write(0, LOG_MAIN, "Server OSCP dates invalid");
-      }
-    else
-      {
+      DEBUG(D_tls) time_print(bp, "This OCSP Update", thisupd);
+      DEBUG(D_tls) if(nextupd) time_print(bp, "Next OCSP Update", nextupd);
+      if (!OCSP_check_validity(thisupd, nextupd,
+           EXIM_OCSP_SKEW_SECONDS, EXIM_OCSP_MAX_AGE))
+       {
+       tls_out.ocsp = OCSP_FAILED;
+       DEBUG(D_tls) ERR_print_errors(bp);
+       log_write(0, LOG_MAIN, "Server OSCP dates invalid");
+       goto failed;
+       }
+
       DEBUG(D_tls) BIO_printf(bp, "Certificate status: %s\n",
                    OCSP_cert_status_str(status));
       switch(status)
        {
        case V_OCSP_CERTSTATUS_GOOD:
-         tls_out.ocsp = OCSP_VFIED;
-         i = 1;
-         goto good;
+         continue;     /* the idx loop */
        case V_OCSP_CERTSTATUS_REVOKED:
-         tls_out.ocsp = OCSP_FAILED;
          log_write(0, LOG_MAIN, "Server certificate revoked%s%s",
              reason != -1 ? "; reason: " : "",
              reason != -1 ? OCSP_crl_reason_str(reason) : "");
          DEBUG(D_tls) time_print(bp, "Revocation Time", rev);
          break;
        default:
-         tls_out.ocsp = OCSP_FAILED;
          log_write(0, LOG_MAIN,
              "Server certificate status unknown, in OCSP stapling");
          break;
        }
+
+      goto failed;
       }
+
+    i = 1;
+    tls_out.ocsp = OCSP_VFIED;
+    goto good;
+
   failed:
+    tls_out.ocsp = OCSP_FAILED;
     i = cbinfo->u_ocsp.client.verify_required ? 0 : 1;
   good:
     BIO_free(bp);
@@ -2300,7 +2369,11 @@ if (tlsp->peercert)
     for resumption next to the TLS session, and used here. */
 
     if (!tlsp->verify_override)
-      tlsp->certificate_verified = SSL_get_verify_result(ssl) == X509_V_OK;
+      tlsp->certificate_verified =
+#ifdef SUPPORT_DANE
+       tlsp->dane_verified ||
+#endif
+       SSL_get_verify_result(ssl) == X509_V_OK;
     }
 }
 
@@ -2671,8 +2744,14 @@ if (rc <= 0)
 
     /* Handle genuine errors */
     case SSL_ERROR_SSL:
-      (void) tls_error(US"SSL_accept", NULL, sigalrm_seen ? US"timed out" : NULL, errstr);
+      {
+      uschar * s = US"SSL_accept";
+      unsigned long e = ERR_peek_error();
+      if (ERR_GET_REASON(e) == SSL_R_WRONG_VERSION_NUMBER)
+       s = string_sprintf("%s (%s)", s, SSL_get_version(server_ssl));
+      (void) tls_error(s, NULL, sigalrm_seen ? US"timed out" : NULL, errstr);
       return FAIL;
+      }
 
     default:
       DEBUG(D_tls) debug_printf("Got SSL error %d\n", error);
@@ -3945,7 +4024,7 @@ BOOL
 tls_openssl_options_parse(uschar *option_spec, long *results)
 {
 long result, item;
-uschar *end;
+uschar * exp, * end;
 uschar keep_c;
 BOOL adding, item_parsed;
 
@@ -3953,7 +4032,7 @@ BOOL adding, item_parsed;
 result = SSL_OP_NO_TICKET;
 
 /* Prior to 4.80 we or'd in SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; removed
- * from default because it increases BEAST susceptibility. */
+from default because it increases BEAST susceptibility. */
 #ifdef SSL_OP_NO_SSLv2
 result |= SSL_OP_NO_SSLv2;
 #endif
@@ -3963,6 +4042,9 @@ result |= SSL_OP_NO_SSLv3;
 #ifdef SSL_OP_SINGLE_DH_USE
 result |= SSL_OP_SINGLE_DH_USE;
 #endif
+#ifdef SSL_OP_NO_RENEGOTIATION
+result |= SSL_OP_NO_RENEGOTIATION;
+#endif
 
 if (!option_spec)
   {
@@ -3970,7 +4052,10 @@ if (!option_spec)
   return TRUE;
   }
 
-for (uschar * s = option_spec; *s; /**/)
+if (!expand_check(option_spec, US"openssl_options", &exp, &end))
+  return FALSE;
+
+for (uschar * s = exp; *s; /**/)
   {
   while (isspace(*s)) ++s;
   if (*s == '\0')
@@ -3992,7 +4077,7 @@ for (uschar * s = option_spec; *s; /**/)
     DEBUG(D_tls) debug_printf("openssl option setting unrecognised: \"%s\"\n", s);
     return FALSE;
     }
-  DEBUG(D_tls) debug_printf("openssl option, %s %8lx: %lx (%s)\n",
+  DEBUG(D_tls) debug_printf("openssl option, %s %08lx: %08lx (%s)\n",
       adding ? "adding to    " : "removing from", result, item, s);
   if (adding)
     result |= item;
index d47156cdc5ea555778ce3a5e4ea15378a775aa57..f9509121804ee997c1c3035cc349a4b60c3483ac 100644 (file)
@@ -369,6 +369,38 @@ return FALSE;
 }
 
 
+/* Environment cleanup: The GnuTLS library uses SSLKEYLOGFILE in the environment
+and writes a file by that name.  Our OpenSSL code does the same, using keying
+info from the library API.
+The GnuTLS support only works if exim is run by root, not taking advantage of
+the setuid bit.
+You can use either the external environment (modulo the keep_environment config)
+or the add_environment config option for SSLKEYLOGFILE; the latter takes
+precedence.
+
+If the path is absolute, require it starts with the spooldir; otherwise delete
+the env variable.  If relative, prefix the spooldir.
+*/
+void
+tls_clean_env(void)
+{
+uschar * path = US getenv("SSLKEYLOGFILE");
+if (path)
+  if (!*path)
+    unsetenv("SSLKEYLOGFILE");
+  else if (*path != '/')
+    {
+    DEBUG(D_tls)
+      debug_printf("prepending spooldir to  env SSLKEYLOGFILE\n");
+    setenv("SSLKEYLOGFILE", CCS string_sprintf("%s/%s", spool_directory, path), 1);
+    }
+  else if (Ustrncmp(path, spool_directory, Ustrlen(spool_directory)) != 0)
+    {
+    DEBUG(D_tls)
+      debug_printf("removing env SSLKEYLOGFILE=%s: not under spooldir\n", path);
+    unsetenv("SSLKEYLOGFILE");
+    }
+}
 
 /*************************************************
 *       Drop privs for checking TLS config      *
index 9088fc6046a0f23d223ace6525961403d773145a..e7123f9eb90d89a22ec07fee07b01dc1f1079045 100644 (file)
@@ -62,17 +62,17 @@ gettimeofday(&now, NULL);
 switch(type)
   {
   case tod_epoch:
-    (void) sprintf(CS timebuf, TIME_T_FMT, now.tv_sec);  /* Unix epoch format */
+    (void) snprintf(CS timebuf, sizeof(timebuf), TIME_T_FMT, now.tv_sec);  /* Unix epoch format */
     return timebuf;    /* NB the above will be wrong if time_t is FP */
 
   case tod_epoch_l:
     /* Unix epoch/usec format */
-    (void) sprintf(CS timebuf, TIME_T_FMT "%06ld", now.tv_sec, (long) now.tv_usec );
+    (void) snprintf(CS timebuf, sizeof(timebuf), TIME_T_FMT "%06ld", now.tv_sec, (long) now.tv_usec );
     return timebuf;
 
   case tod_zulu:
     t = gmtime(&now.tv_sec);
-    (void) sprintf(CS timebuf, "%04u%02u%02u%02u%02u%02uZ",
+    (void) snprintf(CS timebuf, sizeof(timebuf), "%04u%02u%02u%02u%02u%02uZ",
       1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon, (uint)t->tm_mday, (uint)t->tm_hour, (uint)t->tm_min,
       (uint)t->tm_sec);
     return timebuf;
@@ -91,13 +91,13 @@ switch(type)
   case tod_log_bare:          /* Format used in logging without timezone */
 #ifndef COMPILE_UTILITY
     if (LOGGING(millisec))
-      sprintf(CS timebuf, "%04u-%02u-%02u %02u:%02u:%02u.%03u",
+      snprintf(CS timebuf, sizeof(timebuf), "%04u-%02u-%02u %02u:%02u:%02u.%03u",
        1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon, (uint)t->tm_mday,
        (uint)t->tm_hour, (uint)t->tm_min, (uint)t->tm_sec,
        (uint)(now.tv_usec/1000));
     else
 #endif
-      sprintf(CS timebuf, "%04u-%02u-%02u %02u:%02u:%02u",
+      snprintf(CS timebuf, sizeof(timebuf), "%04u-%02u-%02u %02u:%02u:%02u",
        1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon, (uint)t->tm_mday,
        (uint)t->tm_hour, (uint)t->tm_min, (uint)t->tm_sec);
 
@@ -109,20 +109,20 @@ switch(type)
 #ifdef TESTING_LOG_DATESTAMP
   case tod_log_datestamp_daily:
   case tod_log_datestamp_monthly:
-    sprintf(CS timebuf, "%04u%02u%02u%02u%02u",
+    snprintf(CS timebuf, sizeof(timebuf), "%04u%02u%02u%02u%02u",
       1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon, (uint)t->tm_mday,
       (uint)t->tm_hour, (uint)t->tm_min);
     break;
 
 #else
   case tod_log_datestamp_daily:
-    sprintf(CS timebuf, "%04u%02u%02u",
+    snprintf(CS timebuf, sizeof(timebuf), "%04u%02u%02u",
       1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon, (uint)t->tm_mday);
     break;
 
   case tod_log_datestamp_monthly:
 #ifndef COMPILE_UTILITY
-    sprintf(CS timebuf, "%04u%02u",
+    snprintf(CS timebuf, sizeof(timebuf), "%04u%02u",
       1900 + (uint)t->tm_year, 1 + (uint)t->tm_mon);
 #endif
     break;
@@ -170,14 +170,14 @@ switch(type)
        case tod_log_zone:          /* Format used in logging with timezone */
 #ifndef COMPILE_UTILITY
          if (LOGGING(millisec))
-           (void) sprintf(CS timebuf,
+           (void) snprintf(CS timebuf, sizeof(timebuf),
              "%04u-%02u-%02u %02u:%02u:%02u.%03u %+03d%02d",
              1900 + (uint)local.tm_year, 1 + (uint)local.tm_mon, (uint)local.tm_mday,
              (uint)local.tm_hour, (uint)local.tm_min, (uint)local.tm_sec, (uint)(now.tv_usec/1000),
              diff_hour, diff_min);
          else
 #endif
-           (void) sprintf(CS timebuf,
+           (void) snprintf(CS timebuf, sizeof(timebuf),
              "%04u-%02u-%02u %02u:%02u:%02u %+03d%02d",
              1900 + (uint)local.tm_year, 1 + (uint)local.tm_mon, (uint)local.tm_mday,
              (uint)local.tm_hour, (uint)local.tm_min, (uint)local.tm_sec,
@@ -185,7 +185,7 @@ switch(type)
          break;
 
        case tod_zone:              /* Just the timezone offset */
-         (void) sprintf(CS timebuf, "%+03d%02d", diff_hour, diff_min);
+         (void) snprintf(CS timebuf, sizeof(timebuf), "%+03d%02d", diff_hour, diff_min);
          break;
 
        /* tod_mbx: format used in MBX mailboxes - subtly different to tod_full */
@@ -194,11 +194,11 @@ switch(type)
        case tod_mbx:
            {
            int len;
-           (void) sprintf(CS timebuf, "%02u-", (uint)local.tm_mday);
+           (void) snprintf(CS timebuf, sizeof(timebuf), "%02u-", (uint)local.tm_mday);
            len = Ustrlen(timebuf);
            len += Ustrftime(timebuf + len, sizeof(timebuf) - len, "%b-%Y %H:%M:%S",
              &local);
-           (void) sprintf(CS timebuf + len, " %+03d%02d", diff_hour, diff_min);
+           (void) snprintf(CS timebuf + len, sizeof(timebuf)-len, " %+03d%02d", diff_hour, diff_min);
            }
          break;
          #endif
@@ -209,11 +209,11 @@ switch(type)
        default:
            {
            int len = Ustrftime(timebuf, sizeof(timebuf), "%a, ", &local);
-           (void) sprintf(CS timebuf + len, "%02u ", (uint)local.tm_mday);
+           (void) snprintf(CS timebuf + len, sizeof(timebuf)-len, "%02u ", (uint)local.tm_mday);
            len += Ustrlen(timebuf + len);
            len += Ustrftime(timebuf + len, sizeof(timebuf) - len, "%b %Y %H:%M:%S",
              &local);
-           (void) sprintf(CS timebuf + len, " %+03d%02d", diff_hour, diff_min);
+           (void) snprintf(CS timebuf + len, sizeof(timebuf)-len, " %+03d%02d", diff_hour, diff_min);
            }
          break;
        }
index 7ea079fac17f06122f01de9bfaa92e104ff93adc..a91770225738e5148b1cf7ad8f2301d930e82ad7 100644 (file)
@@ -281,7 +281,7 @@ smtp_transport_options_block smtp_transport_option_defaults = {
   .gethostbyname =             FALSE,
   .dns_qualify_single =                TRUE,
   .dns_search_parents =                FALSE,
-  .dnssec = { .request=NULL, .require=NULL },
+  .dnssec = { .request= US"*", .require=NULL },
   .delay_after_cutoff =                TRUE,
   .hosts_override =            FALSE,
   .hosts_randomize =           FALSE,
@@ -1658,77 +1658,6 @@ return FALSE;
 
 
 
-#ifdef SUPPORT_DANE
-/* Lookup TLSA record for host/port.
-Return:  OK            success with dnssec; DANE mode
-         DEFER         Do not use this host now, may retry later
-        FAIL_FORCED    No TLSA record; DANE not usable
-        FAIL           Do not use this connection
-*/
-
-int
-tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required)
-{
-/* move this out to host.c given the similarity to dns_lookup() ? */
-uschar buffer[300];
-const uschar * fullname = buffer;
-int rc;
-BOOL sec;
-
-/* TLSA lookup string */
-(void)sprintf(CS buffer, "_%d._tcp.%.256s", host->port, host->name);
-
-rc = dns_lookup(dnsa, buffer, T_TLSA, &fullname);
-sec = dns_is_secure(dnsa);
-DEBUG(D_transport)
-  debug_printf("TLSA lookup ret %d %sDNSSEC\n", rc, sec ? "" : "not ");
-
-switch (rc)
-  {
-  case DNS_AGAIN:
-    return DEFER; /* just defer this TLS'd conn */
-
-  case DNS_SUCCEED:
-    if (sec)
-      {
-      DEBUG(D_transport)
-       {
-       dns_scan dnss;
-       for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
-            rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
-         if (rr->type == T_TLSA && rr->size > 3)
-           {
-           uint16_t payload_length = rr->size - 3;
-           uschar s[MAX_TLSA_EXPANDED_SIZE], * sp = s, * p = US rr->data;
-
-           sp += sprintf(CS sp, "%d ", *p++); /* usage */
-           sp += sprintf(CS sp, "%d ", *p++); /* selector */
-           sp += sprintf(CS sp, "%d ", *p++); /* matchtype */
-           while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4))
-             sp += sprintf(CS sp, "%02x", *p++);
-
-           debug_printf(" %s\n", s);
-           }
-       }
-      return OK;
-      }
-    log_write(0, LOG_MAIN,
-      "DANE error: TLSA lookup for %s not DNSSEC", host->name);
-    /*FALLTRHOUGH*/
-
-  case DNS_NODATA:     /* no TLSA RR for this lookup */
-  case DNS_NOMATCH:    /* no records at all for this lookup */
-    return dane_required ? FAIL : FAIL_FORCED;
-
-  default:
-  case DNS_FAIL:
-    return dane_required ? FAIL : DEFER;
-  }
-}
-#endif
-
-
-
 typedef struct smtp_compare_s
 {
     uschar                          *current_sender_address;
@@ -3694,7 +3623,8 @@ for handling the SMTP dot-handling protocol, flagging to apply to headers as
 well as body. Set the appropriate timeout value to be used for each chunk.
 (Haven't been able to make it work using select() for writing yet.) */
 
-if (!(sx.peer_offered & OPTION_CHUNKING) && !sx.ok)
+if (  !sx.ok
+   && (!(sx.peer_offered & OPTION_CHUNKING) || !pipelining_active))
   {
   /* Save the first address of the next batch. */
   sx.first_addr = sx.next_addr;
index 1a44de1eaf6a240dd25662f8f3d20068243ea7ee..b68d604428b73b8f3c9b4f39dc05255430713c6b 100644 (file)
@@ -3482,7 +3482,7 @@ else
       dns_basic_lookup(), we have a dnslist cache entry allocated and
       tree-inserted. So we may as well use it. */
 
-      time_t soa_negttl = dns_expire_from_soa(dnsa);
+      time_t soa_negttl = dns_expire_from_soa(dnsa, T_A);
       cb->expiry = soa_negttl ? soa_negttl : time(NULL) + ttl;
       break;
       }
diff --git a/test/aux-fixed/exim-ca/example.com/server1.example.com/fullchain.ocsp.resp.pem b/test/aux-fixed/exim-ca/example.com/server1.example.com/fullchain.ocsp.resp.pem
new file mode 100644 (file)
index 0000000..9667e06
--- /dev/null
@@ -0,0 +1,52 @@
+OCSP Response Information:
+       Response Status: Successful
+       Response Type: Basic OCSP Response
+       Version: 1
+       Responder ID: CN=clica CA rsa,O=example.com
+       Produced At: Thu Oct 10 20:08:22 UTC 2019
+       Responses:
+               Certificate ID:
+                       Hash Algorithm: SHA256
+                       Issuer Name Hash: 5af082e51d62fe01fd706baebeb878db64e68f76e74a36f36d914297ddee24b8
+                       Issuer Key Hash: 333db14364b98e78a33dd8a4fae8d8378ea9b0f5fbca97b25685aa0d32116091
+                       Serial Number: 65
+               Certificate Status: good
+               This Update: Thu Oct 10 20:08:22 UTC 2019
+               Next Update: Tue Oct 09 20:08:22 UTC 2029
+               Certificate ID:
+                       Hash Algorithm: SHA256
+                       Issuer Name Hash: bfa7275a566efd4be2df82dbd9d1290d470186f6ff2acd8c16659f342ab56109
+                       Issuer Key Hash: 208f9d28c7c0bc914144dfa8c0be3d5b3bfcebb622c8a8dc27e865fc06ca0e12
+                       Serial Number: 42
+               Certificate Status: good
+               This Update: Thu Oct 10 20:08:22 UTC 2019
+               Next Update: Tue Oct 09 20:08:22 UTC 2029
+               Certificate ID:
+                       Hash Algorithm: SHA256
+                       Issuer Name Hash: bfa7275a566efd4be2df82dbd9d1290d470186f6ff2acd8c16659f342ab56109
+                       Issuer Key Hash: 208f9d28c7c0bc914144dfa8c0be3d5b3bfcebb622c8a8dc27e865fc06ca0e12
+                       Serial Number: 41
+               Certificate Status: good
+               This Update: Thu Oct 10 20:08:22 UTC 2019
+               Next Update: Tue Oct 09 20:08:22 UTC 2029
+       Extensions:
+       Signature Algorithm: RSA-SHA256
+
+-----BEGIN OCSP RESPONSE-----
+MIIC/AoBAKCCAvUwggLxBgkrBgEFBQcwAQEEggLiMIIC3jCCAcahLzAtMRQwEgYD
+VQQKEwtleGFtcGxlLmNvbTEVMBMGA1UEAxMMY2xpY2EgQ0EgcnNhGA8yMDE5MTAx
+MDIwMDgyMlowggGAMH4wVjANBglghkgBZQMEAgEFAAQgWvCC5R1i/gH9cGuuvrh4
+22Tmj3bnSjbzbZFCl93uJLgEIDM9sUNkuY54oz3YpPro2DeOqbD1+8qXslaFqg0y
+EWCRAgFlgAAYDzIwMTkxMDEwMjAwODIyWqARGA8yMDI5MTAwOTIwMDgyMlowfjBW
+MA0GCWCGSAFlAwQCAQUABCC/pydaVm79S+LfgtvZ0SkNRwGG9v8qzYwWZZ80KrVh
+CQQgII+dKMfAvJFBRN+owL49Wzv867YiyKjcJ+hl/AbKDhICAUKAABgPMjAxOTEw
+MTAyMDA4MjJaoBEYDzIwMjkxMDA5MjAwODIyWjB+MFYwDQYJYIZIAWUDBAIBBQAE
+IL+nJ1pWbv1L4t+C29nRKQ1HAYb2/yrNjBZlnzQqtWEJBCAgj50ox8C8kUFE36jA
+vj1bO/zrtiLIqNwn6GX8BsoOEgIBQYAAGA8yMDE5MTAxMDIwMDgyMlqgERgPMjAy
+OTEwMDkyMDA4MjJaMA0GCSqGSIb3DQEBCwUAA4IBAQBm8uLIawRny88oLSzr7sxj
+IgGjhC+S2OXWjAlTxErHoEsJ0JPKkQAt/s5YLy4IKiPbCg6CIm9KotgE4vnpMFjg
+297pSrdYKdtb2iBPKq5afB2Iv6ET78L/j2HhBFyJaxlt6lhI0Ly6JE75IbUrdP24
+c5uIh+KpJaC60bTZehgcRnrw9fR7HJ5W9ln9mbOZDggNQeM9hmFLUmQYPQWxav2x
+IjCYAZOfIp8ficETnLhuDuILsohFRnQnFAaf1YTgvW2zoKLMeLUWzMm8a6IoBpXQ
+0ecpPJs2FFiaYL78EcRNN47YbClcfDQRAjTvlSZupk59YuxedlwiH6uc7Cwa3RnN
+-----END OCSP RESPONSE-----
index 8efda889fe658cbffb4f9153b7d79c81df96743e..6998108b0bff135379b520a11613d13c73b73731 100755 (executable)
@@ -75,12 +75,6 @@ do
 
 ####
 
- # so, for full-chain OCSP we sill want an OCSP resp for the Signer cert and also (?) one for the
- # CA cert itself.  The existing bits below only create for the leaf certs, next layer down.
- #
- # First test will be just adding OCSP for the Signer cert. Presumably we could use the CA cert
- # to sign that.
-
     # create OCSP reqs & resps
     CADIR=$idir/CA
 
@@ -160,11 +154,11 @@ EOF
     done
 
     # convert one good leaf-resp to PEM
-    $server=server1
+    server=server1
     RESP=$idir/$server.$iname/$server.$iname.ocsp.signernocert.good.resp
     ocsptool -S $RESP -j > $RESP.pem
 
-    # Then, ocsp request and responses for the signer cert
+    # Then, ocsp request and (valid, revoked) responses for the signer cert
     REQ=$CADIR/Signer.ocsp.req
     RESP=$CADIR/Signer.ocsp.signernocert.good.resp
     openssl ocsp -issuer $CADIR/CA.pem -sha256 -cert $CADIR/Signer.pem -no_nonce -reqout $REQ
@@ -177,11 +171,18 @@ EOF
        -ndays 3652 -reqin $REQ -respout $RESP
     ocsptool -S $RESP -j > $RESP.pem
 
-    # Then, ocsp request and response for the CA cert
-    REQ=$CADIR/CA.ocsp.req
-    RESP=$CADIR/CA.ocsp.signernocert.good.resp
-    openssl ocsp -issuer $CADIR/CA.pem -sha256 -cert $CADIR/CA.pem -no_nonce -reqout $REQ
-    openssl ocsp $IVALID -rsigner $CADIR/CA.pem -rkey $CADIR/CA.key -CA $CADIR/CA.pem -resp_no_certs -noverify \
+    # Finally, a full-chain all-good request and response
+    REQ=$idir/$server.$iname/fullchain.ocsp.req
+    leafcert=$idir/$server.$iname/$server.$iname.pem
+    signercert=$CADIR/Signer.pem
+    cacert=$CADIR/CA.pem
+    openssl ocsp -sha256 -no_nonce -reqout $REQ \
+       -issuer $signercert -cert $leafcert \
+       -issuer $cacert     -cert $CADIR/Signer.pem -cert $CADIR/CA.pem
+
+    RESP=$idir/$server.$iname/fullchain.ocsp.resp
+    authorities=$idir/$server.$iname/ca_chain.pem
+    openssl ocsp $IVALID -rsigner $CADIR/CA.pem -rkey $CADIR/CA.key -CA $authorities -resp_no_certs -noverify \
        -ndays 3652 -reqin $REQ -respout $RESP
     ocsptool -S $RESP -j > $RESP.pem
 
index ad9501ed043c23ed7fb01051a2fa22938ffb40c2..541817668b0b57098e9583fe2c5f965b5f11ac32 100644 (file)
@@ -1,4 +1,5 @@
-keep_environment = PATH:SSLKEYLOGFILE:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+add_environment = SSLKEYLOGFILE=DIR/spool/sslkeys
 exim_path = EXIM_PATH
 host_lookup_order = bydns
 spool_directory = DIR/spool
index 628d2ec4d57f0ac4e6d5182e634708c7ff7f4c3e..7b3180dec589311e66e2f2ab3e15e0b39fcc497c 100644 (file)
@@ -7,8 +7,8 @@ primary_hostname = myhost.test.ex
 
 # ----- Main settings -----
 
-ignore_bounce_errors_after = 2s
-timeout_frozen_after = 5s
+ignore_bounce_errors_after = 4s
+timeout_frozen_after = 10s
 queue_run_in_order
 
 
index 7359e16336d239e7053d5b74e6b8eed1f9e05fff..b9235339773b0913d18ac2995cbe285d9f3e18f4 100644 (file)
@@ -11,7 +11,7 @@ primary_hostname = myhost.test.ex
 .ifdef OPT
 dsn_advertise_hosts = *
 .endif
-delay_warning = 3s : 24h
+delay_warning = 6s : 24h
 
 accept_8bitmime = false
 pipelining_advertise_hosts = :
@@ -90,5 +90,5 @@ tofile:
 
 begin retry
 
-*      *       F,1m,3s
+*      *       F,2m,10s
 # End
diff --git a/test/confs/1023 b/test/confs/1023
new file mode 120000 (symlink)
index 0000000..2478c95
--- /dev/null
@@ -0,0 +1 @@
+1003
\ No newline at end of file
diff --git a/test/confs/5602 b/test/confs/5602
deleted file mode 120000 (symlink)
index 4602aa5..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5652
\ No newline at end of file
diff --git a/test/confs/5612 b/test/confs/5612
new file mode 120000 (symlink)
index 0000000..7d60415
--- /dev/null
@@ -0,0 +1 @@
+5665
\ No newline at end of file
diff --git a/test/confs/5615 b/test/confs/5615
new file mode 120000 (symlink)
index 0000000..a21fc1b
--- /dev/null
@@ -0,0 +1 @@
+5670
\ No newline at end of file
diff --git a/test/confs/5652 b/test/confs/5652
deleted file mode 100644 (file)
index 673ec66..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-# Exim test configuration 5652
-# OCSP stapling, server, multiple leaf-certs
-
-.include DIR/aux-var/tls_conf_prefix
-
-primary_hostname = server1.example.com
-
-# ----- Main settings -----
-
-acl_smtp_mail = check_mail
-acl_smtp_rcpt = check_recipient
-
-log_selector = +tls_peerdn
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-CADIR = DIR/aux-fixed/exim-ca
-DRSA = CADIR/example.com
-DECDSA = CADIR/example_ec.com
-
-tls_certificate = DRSA/server1.example.com/server1.example.com.pem \
-             : DECDSA/server1.example_ec.com/server1.example_ec.com.pem
-tls_privatekey =  DRSA/server1.example.com/server1.example.com.unlocked.key \
-             : DECDSA/server1.example_ec.com/server1.example_ec.com.unlocked.key
-tls_ocsp_file =   DRSA/server1.example.com/server1.example.com.ocsp.good.resp \
-             : DECDSA/server1.example_ec.com/server1.example_ec.com.ocsp.good.resp
-
-
-.ifdef _HAVE_GNUTLS
-tls_require_ciphers = NORMAL:!VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.0
-.endif
-.ifdef _OPT_OPENSSL_NO_TLSV1_3_X
-openssl_options = +no_tlsv1_3
-.endif
-
-# ------ ACL ------
-
-begin acl
-
-check_mail:
-  accept   logwrite = acl_mail: ocsp in status: $tls_in_ocsp \
-    (${listextract {${eval:$tls_in_ocsp+1}} \
-               {notreq:notresp:vfynotdone:failed:verified}})
-
-check_recipient:
-  accept
-
-
-# ----- Routers -----
-
-begin routers
-
-client:
-  driver = manualroute
-  condition = ${if !eq {SERVER}{server}}
-  route_list = * 127.0.0.1
-  self = send
-  transport = remote_delivery
-  errors_to = ""
-
-srvr:
-  driver = accept
-  retry_use_local_part
-  transport = local_delivery
-
-
-# ----- Transports -----
-
-begin transports
-
-remote_delivery:
-  driver =                     smtp
-  port =                       PORT_D
-  hosts_try_fastopen =         :
-  hosts_require_tls =          *
-.ifdef _HAVE_GNUTLS
-  tls_require_ciphers =                NONE:\
-                               ${if eq {SELECTOR}{auth_ecdsa} \
-                                       {+SIGN-ECDSA-SHA512:+VERS-TLS-ALL:+KX-ALL:} \
-                                       {+SIGN-RSA-SHA256:+VERS-TLS-ALL:+ECDHE-RSA:+DHE-RSA:+RSA:}}\
-                               +CIPHER-ALL:+MAC-ALL:+COMP-NULL:+CURVE-ALL:+CTYPE-X509
-.endif
-.ifdef _HAVE_OPENSSL
-  tls_require_ciphers =                ${if eq {SELECTOR}{auth_ecdsa} {ECDSA:RSA:!COMPLEMENTOFDEFAULT} {RSA}}
-.endif
-  hosts_require_ocsp =         *
-  tls_verify_certificates =    CADIR/\
-                               ${if eq {SELECTOR}{auth_ecdsa} \
-                                       {example_ec.com/server1.example_ec.com/ca_chain.pem}\
-                                       {example.com/server1.example.com/ca_chain.pem}}
-  tls_verify_cert_hostnames =  :
-
-local_delivery:
-  driver = appendfile
-  file = DIR/test-mail/$local_part
-  headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
-  user = CALLER
-
-# End
diff --git a/test/confs/5655 b/test/confs/5655
deleted file mode 100644 (file)
index 0f6fe1b..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# Exim test configuration 5655
-# OCSP stapling, server, multiple chain-element OCSP
-
-.include DIR/aux-var/tls_conf_prefix
-
-primary_hostname = server1.example.com
-
-# ----- Main settings -----
-
-acl_smtp_connect = accept logwrite = ${env {SSLKEYLOGFILE}}
-acl_smtp_mail = check_mail
-acl_smtp_rcpt = check_recipient
-
-log_selector = +tls_peerdn
-
-queue_only
-queue_run_in_order
-
-tls_advertise_hosts = *
-
-CADIR = DIR/aux-fixed/exim-ca
-DRSA = CADIR/example.com
-DECDSA = CADIR/example_ec.com
-
-tls_certificate = DRSA/server1.example.com/fullchain.pem \
-             : DECDSA/server1.example_ec.com/server1.example_ec.com.pem
-tls_privatekey =  DRSA/server1.example.com/server1.example.com.unlocked.key \
-             : DECDSA/server1.example_ec.com/server1.example_ec.com.unlocked.key
-
-.ifndef CONTROL
-tls_ocsp_file =   PEM DIR/tmp/ocsp/triple.ocsp.pem \
-             : DER DECDSA/server1.example_ec.com/server1.example_ec.com.ocsp.good.resp
-.else
-tls_ocsp_file =   PEM DIR/tmp/ocsp/double_r.ocsp.pem \
-             : DER DECDSA/server1.example_ec.com/server1.example_ec.com.ocsp.good.resp
-.endif
-
-
-.ifdef _HAVE_GNUTLS
-tls_require_ciphers = ${if eq {LIMIT}{TLS1.2} {NORMAL:!VERS-ALL:+VERS-TLS1.2} {}}
-.endif
-
-# ------ ACL ------
-
-begin acl
-
-check_mail:
-  accept   logwrite = acl_mail: ocsp in status: $tls_in_ocsp \
-    (${listextract {${eval:$tls_in_ocsp+1}} \
-               {notreq:notresp:vfynotdone:failed:verified}})
-
-check_recipient:
-  accept
-
-
-# ----- Routers -----
-
-begin routers
-
-client:
-  driver = manualroute
-  condition = ${if !eq {SERVER}{server}}
-  route_list = * 127.0.0.1
-  self = send
-  transport = remote_delivery
-  errors_to = ""
-
-srvr:
-  driver = accept
-  retry_use_local_part
-  transport = local_delivery
-
-
-# ----- Transports -----
-
-begin transports
-
-remote_delivery:
-  driver =                     smtp
-  port =                       PORT_D
-  hosts_require_tls =          *
-.ifdef _HAVE_GNUTLS
-
-  tls_require_ciphers =                ${if eq {LIMIT}{TLS1.2} \
-                                 {NONE:\
-                                   ${if eq {OPT}{rsa} \
-                                     {+SIGN-RSA-SHA256:+VERS-TLS-ALL:+ECDHE-RSA:+DHE-RSA:+RSA} \
-                                     {+SIGN-ECDSA-SHA512:+VERS-TLS-ALL:+KX-ALL}}\
-                                 :+CIPHER-ALL:+MAC-ALL:+COMP-NULL:+CURVE-ALL:+CTYPE-X509} \
-                                 {}}
-  tls_verify_certificates =    CADIR/\
-                                 ${if eq {OPT}{rsa} \
-                                   {example.com/server1.example.com} \
-                                   {example_ec.com/server1.example_ec.com}}\
-                               /ca_chain.pem
-.endif
-  hosts_require_ocsp =         *
-  tls_verify_cert_hostnames =  :
-
-local_delivery:
-  driver = appendfile
-  file = DIR/test-mail/$local_part
-  headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
-  user = CALLER
-
-# End
diff --git a/test/confs/5665 b/test/confs/5665
new file mode 100644 (file)
index 0000000..673ec66
--- /dev/null
@@ -0,0 +1,102 @@
+# Exim test configuration 5652
+# OCSP stapling, server, multiple leaf-certs
+
+.include DIR/aux-var/tls_conf_prefix
+
+primary_hostname = server1.example.com
+
+# ----- Main settings -----
+
+acl_smtp_mail = check_mail
+acl_smtp_rcpt = check_recipient
+
+log_selector = +tls_peerdn
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+CADIR = DIR/aux-fixed/exim-ca
+DRSA = CADIR/example.com
+DECDSA = CADIR/example_ec.com
+
+tls_certificate = DRSA/server1.example.com/server1.example.com.pem \
+             : DECDSA/server1.example_ec.com/server1.example_ec.com.pem
+tls_privatekey =  DRSA/server1.example.com/server1.example.com.unlocked.key \
+             : DECDSA/server1.example_ec.com/server1.example_ec.com.unlocked.key
+tls_ocsp_file =   DRSA/server1.example.com/server1.example.com.ocsp.good.resp \
+             : DECDSA/server1.example_ec.com/server1.example_ec.com.ocsp.good.resp
+
+
+.ifdef _HAVE_GNUTLS
+tls_require_ciphers = NORMAL:!VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.0
+.endif
+.ifdef _OPT_OPENSSL_NO_TLSV1_3_X
+openssl_options = +no_tlsv1_3
+.endif
+
+# ------ ACL ------
+
+begin acl
+
+check_mail:
+  accept   logwrite = acl_mail: ocsp in status: $tls_in_ocsp \
+    (${listextract {${eval:$tls_in_ocsp+1}} \
+               {notreq:notresp:vfynotdone:failed:verified}})
+
+check_recipient:
+  accept
+
+
+# ----- Routers -----
+
+begin routers
+
+client:
+  driver = manualroute
+  condition = ${if !eq {SERVER}{server}}
+  route_list = * 127.0.0.1
+  self = send
+  transport = remote_delivery
+  errors_to = ""
+
+srvr:
+  driver = accept
+  retry_use_local_part
+  transport = local_delivery
+
+
+# ----- Transports -----
+
+begin transports
+
+remote_delivery:
+  driver =                     smtp
+  port =                       PORT_D
+  hosts_try_fastopen =         :
+  hosts_require_tls =          *
+.ifdef _HAVE_GNUTLS
+  tls_require_ciphers =                NONE:\
+                               ${if eq {SELECTOR}{auth_ecdsa} \
+                                       {+SIGN-ECDSA-SHA512:+VERS-TLS-ALL:+KX-ALL:} \
+                                       {+SIGN-RSA-SHA256:+VERS-TLS-ALL:+ECDHE-RSA:+DHE-RSA:+RSA:}}\
+                               +CIPHER-ALL:+MAC-ALL:+COMP-NULL:+CURVE-ALL:+CTYPE-X509
+.endif
+.ifdef _HAVE_OPENSSL
+  tls_require_ciphers =                ${if eq {SELECTOR}{auth_ecdsa} {ECDSA:RSA:!COMPLEMENTOFDEFAULT} {RSA}}
+.endif
+  hosts_require_ocsp =         *
+  tls_verify_certificates =    CADIR/\
+                               ${if eq {SELECTOR}{auth_ecdsa} \
+                                       {example_ec.com/server1.example_ec.com/ca_chain.pem}\
+                                       {example.com/server1.example.com/ca_chain.pem}}
+  tls_verify_cert_hostnames =  :
+
+local_delivery:
+  driver = appendfile
+  file = DIR/test-mail/$local_part
+  headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
+  user = CALLER
+
+# End
diff --git a/test/confs/5670 b/test/confs/5670
new file mode 100644 (file)
index 0000000..6fbd7c1
--- /dev/null
@@ -0,0 +1,103 @@
+# Exim test configuration 5655
+# OCSP stapling, server, multiple chain-element OCSP.  Both GnuTLS and OpenSSL.
+
+.include DIR/aux-var/tls_conf_prefix
+
+primary_hostname = server1.example.com
+
+# ----- Main settings -----
+
+acl_smtp_mail = check_mail
+acl_smtp_rcpt = check_recipient
+
+log_selector = +tls_peerdn
+
+queue_only
+queue_run_in_order
+
+tls_advertise_hosts = *
+
+CADIR = DIR/aux-fixed/exim-ca
+DRSA = CADIR/example.com
+DECDSA = CADIR/example_ec.com
+
+tls_certificate = DRSA/server1.example.com/fullchain.pem
+tls_privatekey =  DRSA/server1.example.com/server1.example.com.unlocked.key
+
+.ifndef CONTROL
+tls_ocsp_file =   PEM DRSA/server1.example.com/fullchain.ocsp.resp.pem
+.else
+tls_ocsp_file =   PEM DIR/tmp/ocsp/double_r.ocsp.pem
+.endif
+
+
+.ifdef _HAVE_GNUTLS
+tls_require_ciphers = ${if eq {LIMIT}{TLS1.2} {NORMAL:!VERS-ALL:+VERS-TLS1.2} {}}
+.endif
+.ifdef _HAVE_OPENSSL
+.ifdef  LIMIT
+openssl_options = ${if eq {LIMIT}{TLS1.2} {+no_tlsv1_3} {}}
+.endif
+.endif
+
+# ------ ACL ------
+
+begin acl
+
+check_mail:
+  accept   logwrite = acl_mail: ocsp in status: $tls_in_ocsp \
+    (${listextract {${eval:$tls_in_ocsp+1}} \
+               {notreq:notresp:vfynotdone:failed:verified}})
+
+check_recipient:
+  accept
+
+
+# ----- Routers -----
+
+begin routers
+
+client:
+  driver = manualroute
+  condition = ${if !eq {SERVER}{server}}
+  route_list = * 127.0.0.1
+  self = send
+  transport = remote_delivery
+  errors_to = ""
+
+srvr:
+  driver = accept
+  retry_use_local_part
+  transport = local_delivery
+
+
+# ----- Transports -----
+
+begin transports
+
+remote_delivery:
+  driver =                     smtp
+  port =                       PORT_D
+  hosts_require_tls =          *
+
+.ifdef _HAVE_GNUTLS
+  tls_require_ciphers =                ${if eq {LIMIT}{TLS1.2} \
+                                 {NONE:\
+                                     +SIGN-RSA-SHA256:+VERS-TLS-ALL:+ECDHE-RSA:+DHE-RSA:+RSA\
+                                 :+CIPHER-ALL:+MAC-ALL:+COMP-NULL:+CURVE-ALL:+CTYPE-X509} \
+                                 {}}
+.endif
+.ifdef _HAVE_OPENSSL
+  tls_require_ciphers =                RSA
+.endif
+  tls_verify_certificates =    CADIR/example.com/server1.example.com/ca_chain.pem
+  hosts_require_ocsp =         *
+  tls_verify_cert_hostnames =  :
+
+local_delivery:
+  driver = appendfile
+  file = DIR/test-mail/$local_part
+  headers_add = TLS: cipher=$tls_cipher peerdn=$tls_peerdn
+  user = CALLER
+
+# End
diff --git a/test/dnszones-src/db.kitterman.org b/test/dnszones-src/db.kitterman.org
new file mode 100644 (file)
index 0000000..bc4e19c
--- /dev/null
@@ -0,0 +1,30 @@
+; This is a testing zone file for use when testing DNS handling in Exim. This
+; is a fake zone of no real use. The zone name is
+; test.ex. This file is passed through the substitution mechanism before being
+; used by the fakens auxiliary program. This inserts the actual IP addresses
+; of the local host into the zone.
+
+; NOTE (1): apart from ::1, IPv6 addresses must always have 8 components. Do
+; not abbreviate them by using the :: feature. Leading zeros in components may,
+; however, be omitted.
+
+; NOTE (2): the fakens program is very simple and assumes that the buffer into
+; which is puts the response is always going to be big enough. In other words,
+; the expectation is for just a few RRs for each query.
+
+; NOTE (3): the top-level networks for testing addresses are parameterized by
+; the use of V4NET and V6NET. These networks should be such that no real
+; host ever uses them.
+;
+; Several prefixes may be used, see the source in src/fakens.c for a complete list
+; and description.
+
+kitterman.org.     NS      exim.kitterman.org.
+kitterman.org.     SOA     exim.kitterman.org. hostmaster.exim.kitterman.org 1430683638 1200 120 604800 3000
+
+; Record copied 2019/10/22
+
+ed25519._domainkey TXT   "v=DKIM1; k=ed25519; p=yi50DjK5O9pqbFpNHklsv9lqaS0ArSYu02qp1S0DW1Y="
+
+
+; End
index 8c1cb73dfd0a81fee40c255079f9cfe35656cd27..246b105781f5915b905612fb2602f429feec4963 100644 (file)
 1999-03-02 09:44:33 10HmbA-0005vi-00 => alternate <alternate@test.ex> F=<CALLER@the.local.host.name> R=all T=dump
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 End queue run: pid=pppp
+1999-03-02 09:44:33 using queue ''
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss for normal@test.ex
+1999-03-02 09:44:33 using queue 'alternate'
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local-smtp S=sss Q=alternate for alternate@test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 moved from input, msglog to (third) input, msglog
+1999-03-02 09:44:33 10HmbC-0005vi-00 moved from (alternate) input, msglog to (third) input, msglog
+1999-03-02 09:44:33 10HmbB-0005vi-00 moved from (third) input, msglog to input, msglog
+1999-03-02 09:44:33 10HmbC-0005vi-00 moved from (third) input, msglog to input, msglog
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, -qGlowpri/3s, not listening for SMTP
index a572e11f31dd768c7442c4dad4c0c737b115e7f5..ad992d9a28dc83f6ebd238221f155e67c064ab3e 100644 (file)
 1999-03-02 09:44:33 End queue run: pid=pppp
 1999-03-02 09:44:33 playout
 1999-03-02 09:44:33 Start queue run: pid=pppp
-1999-03-02 09:44:33 10HmbB-0005vi-00 event tcp:connect
-1999-03-02 09:44:33 10HmbB-0005vi-00 event smtp:connect
-1999-03-02 09:44:33 10HmbB-0005vi-00 event smtp:ehlo
-1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:rcpt:host:defer
-1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:rcpt:defer
-1999-03-02 09:44:33 10HmbB-0005vi-00 event tcp:close
-1999-03-02 09:44:33 10HmbB-0005vi-00 == rmt_defer@test.ex R=r2 T=smtp defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<rmt_defer@test.ex>: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmbB-0005vi-00 == rmt_defer@test.ex routing defer (-51): retry time not reached
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for c@dump.ex
-1999-03-02 09:44:33 10HmbC-0005vi-00 event tcp:connect
-1999-03-02 09:44:33 10HmbC-0005vi-00 event smtp:connect
-1999-03-02 09:44:33 10HmbC-0005vi-00 event smtp:ehlo
-1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:rcpt:host:defer
-1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:rcpt:defer
-1999-03-02 09:44:33 10HmbC-0005vi-00 event tcp:close
-1999-03-02 09:44:33 10HmbC-0005vi-00 == rmt_defer@test.ex R=r2 T=smtp defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<rmt_defer@test.ex>: 451 Temporary local problem - please try later
+1999-03-02 09:44:33 10HmbC-0005vi-00 == rmt_defer@test.ex routing defer (-51): retry time not reached
 1999-03-02 09:44:33 End queue run: pid=pppp
 1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:fail:internal
 1999-03-02 09:44:33 10HmbB-0005vi-00 event msg:complete
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<c@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
 1999-03-02 09:44:33 10HmbC-0005vi-00 <= d@dump.ex H=(testclient) [ip4.ip4.ip4.ip4] P=esmtp S=sss for rmt_defer@test.ex
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<d@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
-1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<c@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
-1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<d@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
 1999-03-02 09:44:33 10HmbE-0005vi-00 <= e@dump.ex H=(testclient) [ip4.ip4.ip4.ip4] P=esmtp S=sss for rmt_reject@test.ex
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<e@dump.ex> rejected RCPT <rmt_reject@test.ex>
index 28c972b5d5856ad65971bfd3364ec0be218c9333..0ca87207577a8410cd46b52ad3abc16233fe1a04 100644 (file)
 1999-03-02 09:44:33 10HmbB-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for e@test.ex
 1999-03-02 09:44:33 10HmbB-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 400 not right now
 1999-03-02 09:44:33 10HmbB-0005vi-00 == e@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 400 not right now
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for p@test.ex
-1999-03-02 09:44:33 10HmbC-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat"
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for ebad@test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 ** ebad@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<ebad@test.ex>: 550 sorry, no
+1999-03-02 09:44:33 10HmbC-0005vi-00 ebad@test.ex: error ignored
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for q@test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written): Connection timed out
-1999-03-02 09:44:33 10HmbD-0005vi-00 == q@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written)
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for r@test.ex
-1999-03-02 09:44:33 10HmbE-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat"
-1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for s@test.ex
-1999-03-02 09:44:33 10HmbF-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 550 unacceptable mail-from
-1999-03-02 09:44:33 10HmbF-0005vi-00 s@test.ex: error ignored
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for p@test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat"
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for q@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written): Connection timed out
+1999-03-02 09:44:33 10HmbE-0005vi-00 == q@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written)
+1999-03-02 09:44:33 10HmbF-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for r@test.ex
+1999-03-02 09:44:33 10HmbF-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat"
 1999-03-02 09:44:33 10HmbF-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbG-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for s1@test.ex
-1999-03-02 09:44:33 10HmbG-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from
-1999-03-02 09:44:33 10HmbG-0005vi-00 == s1@test.ex R=to_server T=remote_smtp defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from
-1999-03-02 09:44:33 10HmbH-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for t@test.ex
-1999-03-02 09:44:33 10HmbH-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<t@test.ex>: 550 no such recipient
-1999-03-02 09:44:33 10HmbH-0005vi-00 t@test.ex: error ignored
-1999-03-02 09:44:33 10HmbH-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbI-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for u@test.ex
-1999-03-02 09:44:33 10HmbI-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 500 oops bdat
-1999-03-02 09:44:33 10HmbI-0005vi-00 u@test.ex: error ignored
+1999-03-02 09:44:33 10HmbG-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for s@test.ex
+1999-03-02 09:44:33 10HmbG-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 550 unacceptable mail-from
+1999-03-02 09:44:33 10HmbG-0005vi-00 s@test.ex: error ignored
+1999-03-02 09:44:33 10HmbG-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbH-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for s1@test.ex
+1999-03-02 09:44:33 10HmbH-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from
+1999-03-02 09:44:33 10HmbH-0005vi-00 == s1@test.ex R=to_server T=remote_smtp defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from
+1999-03-02 09:44:33 10HmbI-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for t@test.ex
+1999-03-02 09:44:33 10HmbI-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:<t@test.ex>: 550 no such recipient
+1999-03-02 09:44:33 10HmbI-0005vi-00 t@test.ex: error ignored
 1999-03-02 09:44:33 10HmbI-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbJ-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for v@test.ex
-1999-03-02 09:44:33 10HmbJ-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat
-1999-03-02 09:44:33 10HmbJ-0005vi-00 == v@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat
+1999-03-02 09:44:33 10HmbJ-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for u@test.ex
+1999-03-02 09:44:33 10HmbJ-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 500 oops bdat
+1999-03-02 09:44:33 10HmbJ-0005vi-00 u@test.ex: error ignored
+1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbK-0005vi-00 <= sender@source.dom U=root P=local-bsmtp S=sss for v@test.ex
+1999-03-02 09:44:33 10HmbK-0005vi-00 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat
+1999-03-02 09:44:33 10HmbK-0005vi-00 == v@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat
index 2ecb7666444fe1be8c9ace227d80e46e0cfa3d93..4dc4d637c705372672068831a3db9f191492934c 100644 (file)
@@ -1,25 +1,21 @@
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 Start queue run: pid=pppp -qf
-1999-03-02 09:44:33 10HmaY-0005vi-00 => user4@h1.test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmaY-0005vi-00 => user4@h1.test.ex R=client T=send_to_server1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbB-0005vi-00"
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => user6@h2.test.ex R=client T=send_to_server2 H=::1 [::1] C="250 OK id=10HmbD-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => user6@h3.test.ex R=client T=send_to_server3 H=::1 [::1] C="250 OK id=10HmbC-0005vi-00"
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbA-0005vi-00 => user6@h3.test.ex R=client T=send_to_server3 H=::1 [::1] C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 => user6@h4.test.ex R=client T=send_to_server4 H=::1 [::1] C="250 OK id=10HmbD-0005vi-00"
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 => user6@h4.test.ex R=client T=send_to_server4 H=::1 [::1] C="250 OK id=10HmbF-0005vi-00"
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaX-0005vi-00 == user6@h5.test.ex R=client T=send_to_server5 defer (-1): failed to expand "interface" option for send_to_server5 transport: condition name expected, but found ""
 1999-03-02 09:44:33 End queue run: pid=pppp -qf
 
 ******** SERVER ********
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D (IPv6 and IPv4)
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6] P=esmtp S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex
 1999-03-02 09:44:33 no host name found for IP address ::1
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [::1] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [::1] P=esmtp S=sss id=E10HmaZ-0005vi-00@myhost.test.ex
 1999-03-02 09:44:33 no host name found for IP address ::1
-1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [::1] P=esmtp S=sss id=E10HmbB-0005vi-00@myhost.test.ex
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [::1] P=esmtp S=sss id=E10HmbA-0005vi-00@myhost.test.ex
diff --git a/test/log/1023 b/test/log/1023
new file mode 100644 (file)
index 0000000..d946d9c
--- /dev/null
@@ -0,0 +1,9 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmaX-0005vi-00 => user6@h2.test.ex R=client T=send_to_server2 H=::1 [::1] C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D (IPv6 and IPv4)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
index bddb8e97397e839c6fae8d46e614146c78a8993e..91761cd68e3539ba775949ed048a7715ef777880 100644 (file)
 1999-03-02 09:44:33 der_b64 MIIDuDCCAqCgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwNzEUMBIGA1UEChMLZXhhbXBsZS5jb20xHzAdBgNVBAMTFmNsaWNhIFNpZ25pbmcgQ2VydCByc2EwHhcNMTIxMTAxMTI0MDA0WhcNMzcxMjAxMTI0MDA0WjAeMRwwGgYDVQQDExNzZXJ2ZXIyLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA52Rfiv2Igy0NiaKN5gc0VPLbEoHngkdJWv3wEORp+iFl6skQRbsCylT8djJ2pvHstFpnzSodF3Wwjj2/EDuj3iKBzN9HeXJOvJz8j9Si1xkgCxJeUjPGgYcvKdxybaZAOpi9l3xwPCCEXN4JBq/WaQQ9+eP1PczeMNfvFtXma+VcHXG743ttPOv7eSMr0JxQl3zjQvYGOhFP/KAw6jh/N6YPqii9kV0cC/ubeVzpqJ5/+hndx5YrmAu39N5qzwWujhDPkFNSgCJUhfkEiMaQiPxFxDTbUzWnQ5jpAQ5El4WJVkGWkqxose1bOjSSNzFPJt59YtxxJC3IWN3UtGODTwIDAQABo4HmMIHjMA4GA1UdDwEB/wQEAwIE8DAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTgYDVR0jBEcwRYANQUFidHdDeGNYZ2IwUaExpC8wLTEUMBIGA1UEChMLZXhhbXBsZS5jb20xFTATBgNVBAMTDGNsaWNhIENBIHJzYYIBQjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vc2NwLmV4YW1wbGUuY29tLzApBgNVHREEIjAgghNzZXJ2ZXIyLmV4YW1wbGUuY29tggkqLnRlc3QuZXgwDQYJKoZIhvcNAQELBQADggEBALHOkZkvHLpNm0QSof09vmmdNFE6/+0TCIoPExeqqSOsy4NsF+Ha46WttjJRSVtbhRxF8jxEU7btPiFgQUaOcJZTwQPDhmQSOPNO8GS46oJ57aQ7U7O+X3M1sVS5Pa2IzE6vrJSh349/CNbTA8WPQdWLlxVJhJXAcZNtaEu6lCsZuDSMTpAsW5I4+snyrm3yvP5t0eD28K5LgCKePX962drkAOP6XGQ51VnbMQ7b1TSdQedtYKIpR3VKUvG5Ky/+0c+Rmwfi2aQ8oXXwekzJyS5jvovdVVsdhO68It+Rz/zursN5Pn+Gj1YuQNUs2nDrGHN+VIIFpgWUjLZO4bcJctY=
 1999-03-02 09:44:33 cipher: TLS1.x:ke-RSA-AES256-SHAnnn:xxx
 1999-03-02 09:44:33 cipher_ TLS1.x:ke_RSA_WITH_ci_mac
+<<<<<<< HEAD
+1999-03-02 09:44:33 ver:    TLS1.x
+=======
 1999-03-02 09:44:33 ver:    TLSv1.x
+>>>>>>> 4.next
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server2.example.com" S=sss
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
 1999-03-02 09:44:33 Our cert SN: <CN=server1.example_ec.com>
index 195cb4b7b87cad77ce1995f4c2fe102d1501208a..1e8af6531879b5fc5f60665d5fd09dc9a5af7ef1 100644 (file)
@@ -18,7 +18,7 @@
 1999-03-02 09:44:33 Authentication-Results: myhost.test.ex;\n  spf=pass smtp.mailfrom=example.com
 1999-03-02 09:44:33 spf_result         neutral (guess <yes>)
 1999-03-02 09:44:33 spf_header_comment myhost.test.ex: ip4.ip4.ip4.ip4 is neither permitted nor denied by domain of test.example.com
-1999-03-02 09:44:33 spf_smtp_comment   Please see http://www.openspf.org/Why?id=b%40test.example.com&ip=ip4.ip4.ip4.ip4&receiver=myhost.test.ex : Reason: mechanism
+1999-03-02 09:44:33 spf_smtp_comment   Please see http://www.open-spf.org/Why?id=b%40test.example.com&ip=ip4.ip4.ip4.ip4&receiver=myhost.test.ex : Reason: mechanism
 1999-03-02 09:44:33 spf_received       Received-SPF: neutral (myhost.test.ex: ip4.ip4.ip4.ip4 is neither permitted nor denied by domain of test.example.com) client-ip=ip4.ip4.ip4.ip4; envelope-from=b@test.example.com; helo=testclient;
 1999-03-02 09:44:33 Authentication-Results: myhost.test.ex;\n  spf=neutral (best guess record for domain) smtp.mailfrom=test.example.com
 1999-03-02 09:44:33 H=(testclient) [ip4.ip4.ip4.ip4] F=<b@test.example.com> rejected RCPT <fred@test.ex>
index e9a22fc75cd49122b8bf9d8b97246ac7bfbd3606..93969ab65995c685e81e4a2eee6595d9b97e1038 100644 (file)
@@ -8,7 +8,7 @@
 1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss for CALLER@test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 Received TLS status callback, null content
+1999-03-02 09:44:33 10HmbD-0005vi-00 Required TLS certificate status not received
 1999-03-02 09:44:33 10HmbD-0005vi-00 == CALLER@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (SSL_connect): error: <<detail omitted>>
 1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbE-0005vi-00 Server certificate revoked; reason: superseded
diff --git a/test/log/5602 b/test/log/5602
deleted file mode 100644 (file)
index 95a283e..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-1999-03-02 09:44:33 1: Server sends good staple on request, to client requiring RSA auth
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 2: Server sends good staple on request, to client preferring ECDSA auth
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => ecdsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example_ec.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
index 200f32113ebec6e934542ef1297a944c180f1737..5b8405aaf6fae0f8c1f6ce156d4a7eacd66e6f80 100644 (file)
@@ -2,13 +2,13 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbB-0005vi-00"
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbD-0005vi-00 Received TLS status callback, null content
+1999-03-02 09:44:33 10HmbD-0005vi-00 Required TLS certificate status not received
 1999-03-02 09:44:33 10HmbD-0005vi-00 == CALLER@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (SSL_connect): error: <<detail omitted>>
 1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmbE-0005vi-00 Server certificate revoked; reason: superseded
 1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <norequire@test.ex> R=server
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 10HmbA-0005vi-00 client claims: ocsp status 0 (notreq)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 client claims: ocsp status 0 (notreq)
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
+1999-03-02 09:44:33 10HmbB-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbC-0005vi-00 client claims: ocsp status 4 (verified)
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbB-0005vi-00@server1.example.com
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbA-0005vi-00@server1.example.com
 1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@test.ex> R=server
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
diff --git a/test/log/5612 b/test/log/5612
new file mode 100644 (file)
index 0000000..95a283e
--- /dev/null
@@ -0,0 +1,16 @@
+1999-03-02 09:44:33 1: Server sends good staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 2: Server sends good staple on request, to client preferring ECDSA auth
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => ecdsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example_ec.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
diff --git a/test/log/5615 b/test/log/5615
new file mode 100644 (file)
index 0000000..314fd91
--- /dev/null
@@ -0,0 +1,16 @@
+1999-03-02 09:44:33 1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="/CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
index 2b2af41c9f9673534c4f81426dc4a734b09c48ad..bcd662f5b8a7bc943f0dafd284b6a43120397ea9 100644 (file)
@@ -2,11 +2,11 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 => norequire@test.ex R=client T=send_to_server2 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => nostaple@test.ex R=client T=send_to_server1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbB-0005vi-00"
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER@test.ex R=client T=send_to_server3 H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
+1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmbD-0005vi-00 == CALLER@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (certificate status check failed)
 1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: <norequire@test.ex> R=server
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 10HmbA-0005vi-00 client claims: OCSP status 0 (notreq)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
-1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
-1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbB-0005vi-00 client claims: OCSP status 0 (notreq)
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com H=the.local.host.name (server1.example.com) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
+1999-03-02 09:44:33 10HmbB-0005vi-00 => :blackhole: <nostaple@test.ex> R=server
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbC-0005vi-00 client claims: OCSP status 4 (verified)
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbB-0005vi-00@server1.example.com
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@server1.example.com H=(helo.data.changed) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmbA-0005vi-00@server1.example.com
 1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@test.ex> R=server
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
diff --git a/test/log/5652 b/test/log/5652
deleted file mode 100644 (file)
index cf31aa3..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-1999-03-02 09:44:33 1: Server sends good staple on request, to client requiring RSA auth
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 2: Server sends good staple on request, to client preferring ECDSA auth
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => ecdsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example_ec.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
diff --git a/test/log/5655 b/test/log/5655
deleted file mode 100644 (file)
index 4cb16c2..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-1999-03-02 09:44:33 1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
-1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
-1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 3: TLS1.3 Server sends bad nonleaf staple, client detects it
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 == rsa.auth@test.ex R=client T=remote_delivery defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (certificate status check failed)
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** rsa.auth@test.ex: retry timeout exceeded
-1999-03-02 09:44:33 10HmbB-0005vi-00 rsa.auth@test.ex: error ignored
-1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
-
-******** SERVER ********
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 
-1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 
-1999-03-02 09:44:33 acl_mail: ocsp in status: 1 (notresp)
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
-1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
-1999-03-02 09:44:33 
-1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): The TLS connection was non-properly terminated.
diff --git a/test/log/5665 b/test/log/5665
new file mode 100644 (file)
index 0000000..cf31aa3
--- /dev/null
@@ -0,0 +1,16 @@
+1999-03-02 09:44:33 1: Server sends good staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 2: Server sends good staple on request, to client preferring ECDSA auth
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => ecdsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example_ec.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-ECDSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
diff --git a/test/log/5670 b/test/log/5670
new file mode 100644 (file)
index 0000000..9936c85
--- /dev/null
@@ -0,0 +1,24 @@
+1999-03-02 09:44:33 1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmaY-0005vi-00"
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => rsa.auth@test.ex R=client T=remote_delivery H=127.0.0.1 [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbA-0005vi-00"
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
+1999-03-02 09:44:33 3: TLS1.3 Server sends bad nonleaf staple, client detects it
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbB-0005vi-00 == rsa.auth@test.ex R=client T=remote_delivery defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (certificate status check failed)
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** rsa.auth@test.ex: retry timeout exceeded
+1999-03-02 09:44:33 10HmbB-0005vi-00 rsa.auth@test.ex: error ignored
+1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 4 (verified)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaX-0005vi-00@server1.example.com
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 acl_mail: ocsp in status: 1 (notresp)
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (server1.example.com) [127.0.0.1] P=esmtps X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=no S=sss id=E10HmaZ-0005vi-00@server1.example.com
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 TLS error on connection from localhost [127.0.0.1] (recv): The TLS connection was non-properly terminated.
index 621aefb1446d551fee1c18fe8a3d45324b212524..5b74bfbd1d74ed17f9a59b10d3a1dc4c2007ab36 100644 (file)
@@ -15,7 +15,7 @@
 1999-03-02 09:44:33 10HmbD-0005vi-00 client ocsp status: 4 (verified)
 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss for failrequire@test.ex
-1999-03-02 09:44:33 10HmbF-0005vi-00 Received TLS status callback, null content
+1999-03-02 09:44:33 10HmbF-0005vi-00 Required TLS certificate status not received
 1999-03-02 09:44:33 10HmbF-0005vi-00 client ocsp status: 1 (notresp)
 1999-03-02 09:44:33 10HmbF-0005vi-00 == failrequire@test.ex R=client T=send_to_server3 defer (-37) H=127.0.0.1 [127.0.0.1]: TLS session: (SSL_connect): error: <<detail omitted>>
 1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@server1.example.com U=CALLER P=local S=sss for failrevoked@test.ex
index 98282ecc2e88ec8205109586ac8d7a520ffe07c6..c1da057cf1d8bbf89d8bfb993f005f8b54559141 100644 (file)
@@ -8,7 +8,7 @@
 1999-03-02 09:44:33 10HmbB-0005vi-00 => CALLER@localhost.test.ex R=client T=send_to_server H=localhost.test.ex [127.0.0.1] X=TLS1.x:ke-RSA-AES256-SHAnnn:xxx CV=yes DN="CN=server1.example.com" C="250 OK id=10HmbC-0005vi-00"
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for CALLER@dane256ee.test.ex
-1999-03-02 09:44:33 10HmbD-0005vi-00 => CALLER@dane256ee.test.ex R=client T=send_to_server H=dane256ee.test.ex [ip4.ip4.ip4.ip4] X=TLS1.2:RSA_CAMELLIA_256_GCM-SHAnnn:256 CV=dane DN="CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
+1999-03-02 09:44:33 10HmbD-0005vi-00 => CALLER@dane256ee.test.ex R=client T=send_to_server H=dane256ee.test.ex [ip4.ip4.ip4.ip4] X=TLS1.x:RSA__CAMELLIA_256_GCM:256 CV=dane DN="CN=server1.example.com" C="250 OK id=10HmbE-0005vi-00"
 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
 
 ******** SERVER ********
@@ -26,6 +26,6 @@
 1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: <CALLER@localhost.test.ex> R=server
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 "rcpt ACL"
-1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.2:RSA_CAMELLIA_256_GCM-SHAnnn:256 CV=no S=sss id=E10HmbD-0005vi-00@myhost.test.ex for CALLER@dane256ee.test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:RSA__CAMELLIA_256_GCM:256 CV=no S=sss id=E10HmbD-0005vi-00@myhost.test.ex for CALLER@dane256ee.test.ex
 1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: <CALLER@dane256ee.test.ex> R=server
 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
index 3b9bea1a09b4e12d4a3dfd46abcf7337529a0459..555a47591da59ab58b0d90f7ad9dbfe6c110f976 100644 (file)
@@ -3,6 +3,4 @@
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<a@dump.ex> rejected RCPT <rmt_reject@test.ex>
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<c@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<d@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
-1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<c@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
-1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<d@dump.ex> temporarily rejected RCPT <rmt_defer@test.ex>
 1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F=<e@dump.ex> rejected RCPT <rmt_reject@test.ex>
index 30315044fa6f62e3dd74ea4246450bab8209fce6..f53b9d72bf7c2e4beb00b3cbbc98a6582080b8f0 100755 (executable)
@@ -64,7 +64,7 @@ my $force_continue = 0;
 my $force_update = 0;
 my $log_failed_filename = 'failed-summary.log';
 my $log_summary_filename = 'run-summary.log';
-my $more = 'less -XF';
+my @more = qw'less -XF';
 my $optargs = '';
 my $save_output = 0;
 my $server_opts = '';
@@ -800,6 +800,12 @@ RESET_AFTER_EXTRA_LINE_READ:
   # Also, the length of space at the end of the host line is dependent
   # on the length of the longest line, so strip it also on otherwise
   # un-rewritten lines like localhost
+  #
+  # host 127.0.0.1     [127.0.0.1]
+  # host 10.0.0.1      [10.0.0.1]-
+  #
+  # host 127.0.0.1     [127.0.0.1]--
+  # host 169.16.16.16  [169.16.16.10]
 
   s/^\s+host\s(\S+)\s+(\S+)/  host $1 $2/;
   s/^\s+(host\s\S+\s\S+)\s+(port=.*)/  host $1 $2/;
@@ -811,7 +817,7 @@ RESET_AFTER_EXTRA_LINE_READ:
   s/(^|\W)\K\Q$parm_ipv6_stripped\E/ip6:ip6:ip6:ip6:ip6:ip6:ip6:ip6/g;
   s/\b\Q$parm_ipv4r\E\b/ip4-reverse/g;
   s/(^|\W)\K\Q$parm_ipv6r\E/ip6-reverse/g;
-  s/^(\s+host\s\S+\s+\[\S+\]) +$/$1 /;
+  s/^\s+host\s\S+\s+\[\S+\]\K +$//;     # strip, not collapse the trailing whitespace
 
 
   # ======== Test network IP addresses ========
@@ -1118,6 +1124,7 @@ RESET_AFTER_EXTRA_LINE_READ:
     next if /DNS lookup of \S+ \(AAAA\) using fakens/;
     next if / in dns_ipv4_lookup?/;
     next if / writing neg-cache entry for .*AAAA/;
+    next if /^faking res_search\(AAAA\) response length as 65535/;
 
     if (/DNS lookup of \S+ \(AAAA\) gave NO_DATA/)
       {
@@ -1125,6 +1132,17 @@ RESET_AFTER_EXTRA_LINE_READ:
       next;
       }
 
+    # Non-TLS bulds have a different Recieved: header expansion
+    s/^((.*)\t}}}}by \$primary_hostname \$\{if def:received_protocol \{with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/;
+    s/^((\s*).*considering: with \$received_protocol }})\(Exim \$version_number\)$/$1\${if def:tls_in_cipher_std { tls \$tls_in_cipher_std\n$2\t}}(Exim \$version_number)/;
+    if (/condition: def:tls_in_cipher_std$/)
+      {
+      $_= <IN>; $_= <IN>; $_= <IN>; $_= <IN>;
+      $_= <IN>; $_= <IN>; $_= <IN>; $_= <IN>;
+      $_= <IN>; $_= <IN>; $_= <IN>; next;
+      }
+
+
     # Skip tls_advertise_hosts and hosts_require_tls checks when the options
     # are unset, because tls ain't always there.
 
@@ -1364,7 +1382,7 @@ RESET_AFTER_EXTRA_LINE_READ:
 
     # openssl version variances
     s/(TLS error on connection [^:]*: error:)[0-9A-F]{8}(:system library):(?:fopen|func\(4095\)):(No such file or directory)$/$1xxxxxxxx$2:fopen:$3/;
-    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/(DANE attempt failed.*error:)[0-9A-F]{8}(:SSL routines:)(?:(?i)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./;
     s/ARC: AMS signing: privkey PEM-block import: error:\K[0-9A-F]{8}:(PEM routines):get_name:(no start line)/0906D06C:$1:PEM_read_bio:$2/;
 
@@ -1554,7 +1572,7 @@ if (! -e $sf_current)
       print "\n";
       print "------------ $f -----------\n"
         if (defined $rf && -s $rf && defined $rsf && -s $rsf);
-      system("$more '$f'");
+      system @more => $f;
       }
     }
 
@@ -1636,26 +1654,25 @@ if (-e $sf_current)
         }
       }
 
-    open(MUNGED, '>', $mf) || tests_exit(-1, "Failed to open $mf: $!");
-    for ($i = 0; $i < @munged; $i++)
-      { print MUNGED $munged[$i]; }
-    close(MUNGED);
+    open(my $fh, '>', $mf) or tests_exit(-1, "Failed to open $mf: $!");
+    print $fh @munged;
     }
 
   # Deal with log sorting
 
   if ($sortfile)
     {
-    my(@munged, $i, $j);
 
-    open(MUNGED, $mf) || tests_exit(-1, "Failed to open $mf: $!");
-    @munged = <MUNGED>;
-    close(MUNGED);
+    my @munged = do {
+      open(my $fh, '<', $mf) or tests_exit(-1, "Failed to open $mf: $!");
+      <$fh>;
+    };
 
-    for ($i = 0; $i < @munged; $i++)
+    for (my $i = 0; $i < @munged; $i++)
       {
       if ($munged[$i] =~ /^[-\d]{10}\s[:\d]{8}\s[-A-Za-z\d]{16}\s[-=*]>/)
         {
+        my $j;
         for ($j = $i + 1; $j < @munged; $j++)
           {
           last if $munged[$j] !~
@@ -1667,11 +1684,9 @@ if (-e $sf_current)
         }
       }
 
-    open(MUNGED, ">$mf") || tests_exit(-1, "Failed to open $mf: $!");
-    print MUNGED "**NOTE: The delivery lines in this file have been sorted.\n";
-    for ($i = 0; $i < @munged; $i++)
-      { print MUNGED $munged[$i]; }
-    close(MUNGED);
+    open(my $fh, '>', $mf) or tests_exit(-1, "Failed to open $mf: $!");
+    print $fh "**NOTE: The delivery lines in this file have been sorted.\n";
+    print $fh @munged;
     }
 
   # Do the comparison
@@ -1681,7 +1696,7 @@ if (-e $sf_current)
   # Handle comparison failure
 
   print "** Comparison of $mf with $sf_current failed";
-  system("$more test-cf");
+  system @more => 'test-cf';
 
   print "\n";
   for (;;)
@@ -1712,8 +1727,7 @@ else
     # if we deal with a flavour file, we can't delete it, because next time the generic
     # file would be used again
     if ($sf_current eq $sf_flavour) {
-      open(FOO, ">$sf_current");
-      close(FOO);
+      open(my $fh, '>', $sf_current);
     }
     else {
       tests_exit(-1, "Failed to unlink $sf_current") if !unlink($sf_current);
@@ -1779,7 +1793,7 @@ $munges =
     },
 
     'debug_pid' =>
-    { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d{1,5}/ppppp/g' },
+    { 'stderr' => 's/(^\s{0,4}|(?<=Process )|(?<=child ))\d+/ppppp/g' },
 
     'optional_dsn_info' =>
     { 'mail' => '/^(X-(Remote-MTA-(smtp-greeting|helo-response)|Exim-Diagnostic|(body|message)-linecount):|Remote-MTA: X-ip;)/'
@@ -2175,34 +2189,37 @@ if (/^dbmbuild\s+(\S+)\s+(\S+)/)
 
 if (/^dump\s+(\S+)/)
   {
-  my($which) = $1;
-  my(@temp);
+  my $which  = $1;
   print ">> ./eximdir/exim_dumpdb $parm_cwd/spool $which\n" if $debug;
-  open(IN, "./eximdir/exim_dumpdb $parm_cwd/spool $which |");
-  open(OUT, ">>test-stdout");
-  print OUT "+++++++++++++++++++++++++++\n";
+  open(my $in, "-|", './eximdir/exim_dumpdb', "$parm_cwd/spool", $which) or die "Can't run exim_dumpdb: $!";
+  open(my $out, ">>test-stdout");
+  print $out "+++++++++++++++++++++++++++\n";
 
   if ($which eq "retry")
     {
-    $/ = "\n  ";
-    @temp = <IN>;
-    $/ = "\n";
-
-    @temp = sort {
-                   my($aa) = split(' ', $a);
-                   my($bb) = split(' ', $b);
-                   return $aa cmp $bb;
-                 } @temp;
-
+    # the sort key is the first part of the retry db dump line, but for
+    # sorting we (temporarly) replace the own hosts ipv4 with a munged
+    # version, which matches the munging that is done later
+    # Why? We must ensure sure, that 127.0.0.1 always sorts first
+    # map-sort-map: Schwartz's transformation
+    # test 0099
+    my @temp = map  { $_->[1] }
+               sort { $a->[0] cmp $b->[0] }
+               #map  { [ (split)[0] =~ s/\Q$parm_ipv4/ip4.ip4.ip4.ip4/gr, $_ ] }  # this is too modern for 5.10.1
+               map  {
+                (my $k = (split)[0]) =~ s/\Q$parm_ipv4/ip4.ip4.ip4.ip4/g;
+                [ $k, $_ ]
+               }
+               do { local $/ = "\n  "; <$in> };
     foreach $item (@temp)
       {
       $item =~ s/^\s*(.*)\n(.*)\n?\s*$/$1\n$2/m;
-      print OUT "  $item\n";
+      print $out "  $item\n";
       }
     }
   else
     {
-    @temp = <IN>;
+    my @temp = <$in>;
     if ($which eq "callout")
       {
       @temp = sort {
@@ -2211,11 +2228,9 @@ if (/^dump\s+(\S+)/)
                    return $aa cmp $bb;
                    } @temp;
       }
-    print OUT @temp;
+    print $out @temp;
     }
-
-  close(IN);
-  close(OUT);
+  close($in); # close it explicitly, otherwise $? does not get set
   return 1;
   }
 
@@ -2558,9 +2573,24 @@ elsif (/^((?i:[A-Z\d_]+=\S+\s+)+)?(\d+)?\s*(sudo(?:\s+-u\s+(\w+))?\s+)?exim(_\S+
 
   if ($args =~ /\$msg/)
     {
-    my @listcmd  = ("$parm_cwd/eximdir/exim", '-bp',
+    my($queuespec);
+    if ($args =~ /-qG\w+/) { $queuespec = $&; }
+
+    my @listcmd;
+
+    if (defined $queuespec)
+      {
+      @listcmd  = ("$parm_cwd/eximdir/exim", '-bp',
+                  $queuespec,
+                   "-DEXIM_PATH=$parm_cwd/eximdir/exim",
+                   -C => "$parm_cwd/test-config");
+      }
+    else
+      {
+      @listcmd  = ("$parm_cwd/eximdir/exim", '-bp',
                    "-DEXIM_PATH=$parm_cwd/eximdir/exim",
                    -C => "$parm_cwd/test-config");
+      }
     print ">> Getting queue list from:\n>>    @listcmd\n" if $debug;
     # We need the message ids sorted in ascending order.
     # Message id is: <timestamp>-<pid>-<fractional-time>. On some systems (*BSD) the
@@ -2785,7 +2815,7 @@ umask 022;
 #       Check for the "less" command             #
 ##################################################
 
-$more = 'more' if system('which less >/dev/null 2>&1') != 0;
+@more = 'more' if system('which less >/dev/null 2>&1') != 0;
 
 
 
@@ -2810,7 +2840,7 @@ Getopt::Long::Configure qw(no_getopt_compat);
 GetOptions(
     'debug'    => sub { $debug          = 1; $cr   = "\n" },
     'diff'     => sub { $cf             = 'diff -u' },
-    'continue' => sub { $force_continue = 1; $more = 'cat' },
+    'continue' => sub { $force_continue = 1; @more = 'cat' },
     'update'   => \$force_update,
     'ipv4!'    => \$have_ipv4,
     'ipv6!'    => \$have_ipv6,
@@ -3437,14 +3467,15 @@ while (not ($parm_ipv4 and $parm_ipv6) and defined($_ = <IFCONFIG>))
 
   if (not $parm_ipv4 and /^\s*inet(?:\saddr(?:ess))?:?\s*(\d+\.\d+\.\d+\.\d+)(?:\/\d+)?\s/i)
     {
-    # It would ne nice to be able to vary the /16 used for manyhome; we could take
+    # It would be nice to be able to vary the /16 used for manyhome; we could take
     # an option to runtest used here - but we'd also have to pass it on to fakens.
     # Possibly an environment variable?
     next if $1 eq '0.0.0.0' or $1 =~ /^(?:127|10\.250)\./;
     $parm_ipv4 = $1;
     }
 
-  if (not $parm_ipv6 and /^\s*inet6(?:\saddr(?:ess))?:?\s*([abcdef\d:]+)(?:%[^ \/]+)?(?:\/\d+)?/i)
+  if (   (not $parm_ipv6 or $parm_ipv6 =~ /%/)
+     and /^\s*inet6(?:\saddr(?:ess))?:?\s*([abcdef\d:]+)(?:%[^ \/]+)?(?:\/\d+)?/i)
     {
     next if $1 eq '::' or $1 eq '::1' or $1 =~ /^ff00/i or $1 =~ /^fe80::1/i;
     $parm_ipv6 = $1;
@@ -3813,6 +3844,10 @@ DIR: for (my $i = 0; $i < @test_dirs; $i++)
        }
        unlink("$parm_cwd/test-config");
         }
+      elsif (/^ipv6-non-linklocal/)
+       {
+       if ($parm_ipv6 =~ /%/) { $wantthis = 0; last; }
+       }
       else
         {
         tests_exit(-1, "Unknown line in \"scripts/$testdir/REQUIRES\": \"$_\"");
@@ -3953,7 +3988,7 @@ if ($have_ipv4 && $parm_ipv4 ne "127.0.0.1")
       tests_exit(-1, "Failed  to open $parm_cwd/dnszones/db.ip4.$components[0]: $!");
     print OUT "$components[3].$components[2].$components[1]  PTR  $parm_hostname.\n\n";
     close(OUT);
-    } 
+    }
   else
     {
     open(OUT, ">$parm_cwd/dnszones/db.ip4.$components[0]") ||
@@ -4305,11 +4340,11 @@ foreach $test (@test_list)
         last if /^[rc]$/i;
         if (/^e$/i)
           {
-          system("$more test-stderr");
+          system @more => 'test-stderr';
           }
         elsif (/^o$/i)
           {
-          system("$more test-stdout");
+          system @more => 'test-stdout';
           }
         }
 
index 64afd80144bdaa982afda7b95cb508b0427b7f56..2739f29e1888954fd1864f07e53db4601af4da68 100644 (file)
@@ -6,11 +6,11 @@ sudo exim -Mf $msg1
 ****
 # now 2 frozen, one of which is a bounce
 # check that ignore_bounce_errors_after finishes off the frozen bounce (only)
-millisleep 2500
-exim -qf
+#sleep 5
+exim -Tqt 5s/5s/ -qf
 ****
-sleep 3
+#sleep 6
 # check that timeout_frozen_after finishes off the (remaining) frozen
-exim -q
+exim -Tqt 11s/11s -q
 ****
 no_msglog_check
index dedc73d2337fd89100ad6ce13b3890b635a45603..ddf17f8d9550d9f029948b724bdecfa532629d82 100644 (file)
@@ -72,4 +72,51 @@ sudo mv DIR/spool/alternate/input/* DIR/spool/input/
 exim -q
 ****
 #
+#
+# Native queue transfer
+### load messages
+exim -bs
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO: <normal@test.ex>
+DATA
+Subject: test
+
+foo
+.
+RSET
+MAIL FROM:<CALLER@myhost.test.ex>
+RCPT TO: <alternate@test.ex>
+DATA
+Subject: test
+
+foo
+.
+QUIT
+****
+### default q
+exim -bp
+****
+### alternate q
+exim -bp -qGalternate
+****
+#
+exim -MG third $msg1
+****
+exim -qGalternate -MG third $msg1
+****
+### third q
+exim -bp -qGthird
+****
+exim -qGthird -MG '' $msg1 $msg2
+****
+### default q
+exim -bp
+****
+### alternate q
+exim -bp -qGalternate
+****
+### third q
+exim -bp -qGthird
+****
+#
 no_stderr_check
index 13d395f02f29309b542b1097847b6c068dc30f7c..69a53c6918120cc8a7d7f7d51838c6d193228a05 100644 (file)
@@ -76,8 +76,9 @@ exim -q
 #
 # Client requests notification of deferral.  First time of trying, we get
 # a defer but queue-time probably has not hit the 1st retry time yet, so no DSN
-# will be sent and the message remains queued.  Later, after a sleep, we will
-# try again.
+# will be sent and the message remains queued.  Then, claiming time has elapsed,
+# we will look again (expecting a delay-DSN to be produced).  We won't see a
+# retry since the actual retry time has not passed.
 exim -z defer/delay
 ****
 client HOSTIPV4 PORT_D
@@ -126,7 +127,6 @@ QUIT
 ****
 exim -q
 ****
-sleep 3
 #
 #
 #
@@ -134,7 +134,7 @@ sleep 3
 # We should see the notify for c@dump.ex but not d@dump.ex
 exim -z playout
 ****
-exim -q
+exim -Tqt 10s/ -q
 ****
 sleep 1
 exim -Mrm $msg1 $msg2
index 2157e61a87a061e31d39f2c4e9190eaf2dabe93e..fa72256c0a436560de0a996ac1f56ad035227029 100644 (file)
@@ -140,6 +140,31 @@ RCPT TO:<e@test.ex>
 DATA
 Subject: foo
 
+data
+.
+QUIT
+****
+#
+#
+# Server rejects RCPT.  Client should not proceed to BDAT.
+server PORT_S
+220 Greetings
+EHLO
+250-Hello there
+250 CHUNKING
+MAIL FROM
+250 OK
+RCPT TO
+550 sorry, no
+QUIT
+****
+sudo exim -odf -bS
+EHLO test
+MAIL FROM:<sender@source.dom>
+RCPT TO:<ebad@test.ex>
+DATA
+Subject: foo
+
 data
 .
 QUIT
index 1be6923b010756d85c4beeeb50098e958140c566..e52a1f57bd444a32b9ac86793d5cf5c2596446ab 100644 (file)
@@ -9,11 +9,6 @@ exim user4@h1.test.ex
 1
 interface: <; ::1 ; HOSTIPV4
 ****
-exim user6@h2.test.ex
-
-2
-interface: <; HOSTIPV6 ; HOSTIPV4
-****
 exim user6@h3.test.ex
 
 3
diff --git a/test/scripts/1020-Linklocal-ipv6/1023 b/test/scripts/1020-Linklocal-ipv6/1023
new file mode 100644 (file)
index 0000000..2e5be66
--- /dev/null
@@ -0,0 +1,20 @@
+# interface selection (v4 vs v6) in outgoing SMTP, non-linklocal
+need_ipv4
+need_ipv6
+#
+exim -DSERVER=server -bd -oX PORT_D
+****
+#
+# This tries to send to ::1 from HOSTIPV6 - which is ok until HOSTIPV6
+# is a link-local addr (with a scope-id specifying the link).  Then,
+# it seems, ::1 is not on that link (for Linux & FreeBSD, at least).  The connect
+# times out and the testcase fails.
+exim user6@h2.test.ex
+
+2
+interface: <; HOSTIPV6 ; HOSTIPV4
+****
+exim -qf
+****
+killdaemon
+no_msglog_check
diff --git a/test/scripts/1020-Linklocal-ipv6/REQUIRES b/test/scripts/1020-Linklocal-ipv6/REQUIRES
new file mode 100644 (file)
index 0000000..f8edd3e
--- /dev/null
@@ -0,0 +1,2 @@
+support IPv6
+ipv6-non-linklocal
index 504676e7c330ff7c672665770971f14d3e1bc82b..22558dfa7faed312a85ea0d230dd2cfef944f627 100644 (file)
@@ -79,8 +79,7 @@ QUIT
 #
 
 # This should pass, an independently-generated sample from Scott Kitterman.
-# I don't want to retain this longterm as it hits an external DNS record,
-# not under the testsuite.
+# We use a copied version of his DNS record.
 client 127.0.0.1 PORT_D
 ??? 220
 HELO xxx
diff --git a/test/scripts/5600-OCSP-OpenSSL/5602 b/test/scripts/5600-OCSP-OpenSSL/5602
deleted file mode 100644 (file)
index 02c27ce..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# OCSP stapling, server, multiple leaf-certs
-# This will fail on OpenSSL versions before 1.1.0
-#
-#
-#
-exim -z '1: Server sends good staple on request, to client requiring RSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server
-****
-exim -odf -DSELECTOR=auth_rsa rsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-#
-#
-#
-#
-exim -z '2: Server sends good staple on request, to client preferring ECDSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server
-****
-exim -odf -DSELECTOR=auth_ecdsa ecdsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-no_msglog_check
diff --git a/test/scripts/5612-OCSP-OpenSSL-multileaf/5612 b/test/scripts/5612-OCSP-OpenSSL-multileaf/5612
new file mode 100644 (file)
index 0000000..02c27ce
--- /dev/null
@@ -0,0 +1,32 @@
+# OCSP stapling, server, multiple leaf-certs
+# This will fail on OpenSSL versions before 1.1.0
+#
+#
+#
+exim -z '1: Server sends good staple on request, to client requiring RSA auth'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server
+****
+exim -odf -DSELECTOR=auth_rsa rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+#
+#
+exim -z '2: Server sends good staple on request, to client preferring ECDSA auth'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server
+****
+exim -odf -DSELECTOR=auth_ecdsa ecdsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+no_msglog_check
diff --git a/test/scripts/5612-OCSP-OpenSSL-multileaf/REQUIRES b/test/scripts/5612-OCSP-OpenSSL-multileaf/REQUIRES
new file mode 100644 (file)
index 0000000..0d1bd9f
--- /dev/null
@@ -0,0 +1,4 @@
+support OpenSSL
+support OCSP
+running IPv4
+feature _HAVE_TLS_OCSP_LIST
diff --git a/test/scripts/5615-OCSP-OpenSSL-1.3/5615 b/test/scripts/5615-OCSP-OpenSSL-1.3/5615
new file mode 100644 (file)
index 0000000..17d5f7a
--- /dev/null
@@ -0,0 +1,54 @@
+# OCSP stapling, server, multiple chain-element OCSP
+#
+#
+#
+#
+exim -z '1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.2
+****
+#
+exim -odf -DOPT=rsa -DLIMIT=TLS1.2 rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+exim -z '2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth'
+****
+#
+# Works when the (single) proof file has an ocsp-response with 3 statusses.
+# Contrast with with GnuTLS which can do either that or have 3 proof files
+# each with one status.
+#
+exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3
+****
+exim -odf -DOPT=rsa rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+##
+##
+#exim -z '3: TLS1.3 Server sends bad nonleaf staple, client detects it'
+#****
+##
+#EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3 -DCONTROL=bad
+#****
+#exim -odf -DOPT=rsa rsa.auth@test.ex
+#Subject: test
+#
+#.
+#****
+#killdaemon
+##
+##
+#
+#
+sudo rm -fr tmp/
+no_msglog_check
diff --git a/test/scripts/5615-OCSP-OpenSSL-1.3/REQUIRES b/test/scripts/5615-OCSP-OpenSSL-1.3/REQUIRES
new file mode 100644 (file)
index 0000000..7df03fb
--- /dev/null
@@ -0,0 +1,4 @@
+support OpenSSL
+support OCSP
+running IPv4
+feature _HAVE_TLS1_3
diff --git a/test/scripts/5650-OCSP-GnuTLS/5652 b/test/scripts/5650-OCSP-GnuTLS/5652
deleted file mode 100644 (file)
index 07fda29..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# OCSP stapling, server, multiple leaf-certs
-#
-#
-#
-exim -z '1: Server sends good staple on request, to client requiring RSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server
-****
-exim -odf -DSELECTOR=auth_rsa rsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-#
-#
-#
-#
-exim -z '2: Server sends good staple on request, to client preferring ECDSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server
-****
-exim -odf -DSELECTOR=auth_ecdsa ecdsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-no_msglog_check
diff --git a/test/scripts/5655-OCSP-GnuTLS-1.3/5655 b/test/scripts/5655-OCSP-GnuTLS-1.3/5655
deleted file mode 100644 (file)
index 25ebdfd..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-# OCSP stapling, server, multiple chain-element OCSP
-#
-#
-#
-mkdir -p DIR/tmp/ocsp
-sudo chown -R EXIMUSER:EXIMGROUP tmp
-sudo chmod -R a+rwx DIR/tmp/ocsp
-perl
-chdir 'aux-fixed/exim-ca/example.com';
-system 'cat server1.example.com/server1.example.com.ocsp.signernocert.good.resp.pem CA/Signer.ocsp.signernocert.good.resp.pem CA/CA.ocsp.signernocert.good.resp.pem > DIR/tmp/ocsp/triple.ocsp.pem';
-system 'cat server1.example.com/server1.example.com.ocsp.signernocert.good.resp.pem CA/Signer.ocsp.signernocert.revoked.resp.pem > DIR/tmp/ocsp/double_r.ocsp.pem';
-****
-#
-#
-exim -z '1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.2
-****
-#
-exim -odf -DOPT=rsa -DLIMIT=TLS1.2 rsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-#
-#
-exim -z '2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth'
-****
-#
-exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3
-****
-exim -odf -DOPT=rsa rsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-#
-#
-#
-exim -z '3: TLS1.3 Server sends bad nonleaf staple, client detects it'
-****
-#
-EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3 -DCONTROL=bad
-****
-exim -odf -DOPT=rsa rsa.auth@test.ex
-Subject: test
-
-.
-****
-killdaemon
-#
-#
-#
-#
-sudo rm -fr tmp/
-no_msglog_check
diff --git a/test/scripts/5655-OCSP-GnuTLS-1.3/REQUIRES b/test/scripts/5655-OCSP-GnuTLS-1.3/REQUIRES
deleted file mode 100644 (file)
index ab5a972..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-support GnuTLS
-support OCSP
-running IPv4
-feature _HAVE_TLS1_3
diff --git a/test/scripts/5665-OCSP-GnuTLS-multileaf/5665 b/test/scripts/5665-OCSP-GnuTLS-multileaf/5665
new file mode 100644 (file)
index 0000000..07fda29
--- /dev/null
@@ -0,0 +1,31 @@
+# OCSP stapling, server, multiple leaf-certs
+#
+#
+#
+exim -z '1: Server sends good staple on request, to client requiring RSA auth'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server
+****
+exim -odf -DSELECTOR=auth_rsa rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+#
+#
+exim -z '2: Server sends good staple on request, to client preferring ECDSA auth'
+****
+#
+exim -bd -oX PORT_D -DSERVER=server
+****
+exim -odf -DSELECTOR=auth_ecdsa ecdsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+no_msglog_check
diff --git a/test/scripts/5665-OCSP-GnuTLS-multileaf/REQUIRES b/test/scripts/5665-OCSP-GnuTLS-multileaf/REQUIRES
new file mode 100644 (file)
index 0000000..37e377d
--- /dev/null
@@ -0,0 +1,4 @@
+support GnuTLS
+support OCSP
+running IPv4
+feature _HAVE_TLS_OCSP_LIST
diff --git a/test/scripts/5670-OCSP-GnuTLS-1.3/5670 b/test/scripts/5670-OCSP-GnuTLS-1.3/5670
new file mode 100644 (file)
index 0000000..1df75fb
--- /dev/null
@@ -0,0 +1,59 @@
+# OCSP stapling, server, multiple chain-element OCSP
+#
+#
+#
+mkdir -p DIR/tmp/ocsp
+sudo chown -R EXIMUSER:EXIMGROUP tmp
+sudo chmod -R a+rwx DIR/tmp/ocsp
+perl
+chdir 'aux-fixed/exim-ca/example.com';
+system 'cat server1.example.com/server1.example.com.ocsp.signernocert.good.resp.pem CA/Signer.ocsp.signernocert.revoked.resp.pem > DIR/tmp/ocsp/double_r.ocsp.pem';
+****
+#
+#
+exim -z '1: TLS1.2 Server sends good leaf-staple on request, to client requiring RSA auth'
+****
+#
+sudo exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.2
+****
+#
+exim -odf -DOPT=rsa -DLIMIT=TLS1.2 rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+exim -z '2: TLS1.3 Server sends good 3-element staple on request, to client requiring RSA auth'
+****
+#
+# Prefix with sudo to get SSLKEYLOGFILE to work.  Only works on the server.
+exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3
+****
+exim -odf -DOPT=rsa rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+#
+exim -z '3: TLS1.3 Server sends bad nonleaf staple, client detects it'
+****
+#
+EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK=y exim -bd -oX PORT_D -DSERVER=server -DLIMIT=TLS1.3 -DCONTROL=bad
+****
+exim -odf -DOPT=rsa rsa.auth@test.ex
+Subject: test
+
+.
+****
+killdaemon
+#
+#
+#
+#
+sudo rm -fr tmp/
+no_msglog_check
diff --git a/test/scripts/5670-OCSP-GnuTLS-1.3/REQUIRES b/test/scripts/5670-OCSP-GnuTLS-1.3/REQUIRES
new file mode 100644 (file)
index 0000000..ab5a972
--- /dev/null
@@ -0,0 +1,4 @@
+support GnuTLS
+support OCSP
+running IPv4
+feature _HAVE_TLS1_3
index 6d8a99df553405c8076f1ef6fe7353b0739c2ae9..2c82c5a82858504ea1c486a604d2a52dd87c7865 100644 (file)
@@ -313,8 +313,8 @@ Arguments:
   qtypelen    the length of qtype
   pkptr       points to the output buffer pointer; this is updated
   countptr    points to the record count; this is updated
-  dnssec      points to the AD flag indicator; this is updated
-  aa          points to the AA flag indicator; this is updated
+  dnssec_p    points to the AD flag indicator; this is updated
+  aa_p        points to the AA flag indicator; this is updated
 
 Returns:      0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or
               PASS_ON - the latter if a "PASS ON NOT FOUND" line is seen
@@ -322,7 +322,7 @@ Returns:      0 on success, else HOST_NOT_FOUND or NO_DATA or NO_RECOVERY or
 
 static int
 find_records(FILE *f, uschar *zone, uschar *domain, uschar *qtype,
-  int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec, BOOL * aa)
+  int qtypelen, uschar **pkptr, int *countptr, BOOL * dnssec_p, BOOL * aa_p)
 {
 int yield = HOST_NOT_FOUND;
 int domainlen = Ustrlen(domain);
@@ -448,8 +448,8 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
   if (yield == HOST_NOT_FOUND)
     {
     yield = NO_DATA;
-    if (dnssec) *dnssec = TRUE;     /* cancelled by first nonsecure rec found */
-    if (aa) *aa = TRUE;             /* cancelled by first non-aa rec found */
+    if (dnssec_p) *dnssec_p = TRUE;     /* cancelled by first nonsecure rec found */
+    if (aa_p) *aa_p = TRUE;             /* cancelled by first non-aa rec found */
     }
 
   /* Compare RR types; a CNAME record is always returned */
@@ -468,11 +468,11 @@ while (fgets(CS buffer, sizeof(buffer), f) != NULL)
   if (delay)
     millisleep(delay);
 
-  if (dnssec && !rr_sec)
-    *dnssec = FALSE;                    /* cancel AD return */
+  if (dnssec_p && !rr_sec)
+    *dnssec_p = FALSE;                    /* cancel AD return */
 
-  if (aa && !rr_aa)
-    *aa = FALSE;                        /* cancel AA return */
+  if (aa_p && !rr_aa)
+    *aa_p = FALSE;                        /* cancel AA return */
 
   if (rr_ignore) continue;
 
@@ -668,8 +668,8 @@ uschar qtype[12];
 uschar packet[2048 * 32 + 32];
 HEADER *header = (HEADER *)packet;
 uschar *pk = packet;
-BOOL dnssec;
-BOOL aa;
+BOOL dnssec = FALSE;
+BOOL aa = FALSE;
 
 signal(SIGALRM, alarmfn);
 
@@ -683,15 +683,14 @@ if (argc != 4)
 
 (void)sprintf(CS buffer, "%s/dnszones", argv[1]);
 
-d = opendir(CCS buffer);
-if (d == NULL)
+if (!(d = opendir(CCS buffer)))
   {
   fprintf(stderr, "fakens: failed to opendir %s: %s\n", buffer,
     strerror(errno));
   return NO_RECOVERY;
   }
 
-while ((de = readdir(d)) != NULL)
+while ((de = readdir(d)))
   {
   uschar *name = US de->d_name;
   if (Ustrncmp(name, "qualify.", 8) == 0)
@@ -778,7 +777,7 @@ if (!(f = fopen(CS buffer, "r")))
 
 header->qr = 1;     /* query */
 header->opcode = QUERY; /* standard query */
-header->tc = 0;     /* no trucation */
+header->tc = 0;     /* no truncation */
 
 /* Find the records we want, and add them to the result. */
 
index 4cf1260687d640d49e34bc6e4f9a4f296f35b377..c1f1ecf2171c173b8908b59f5b73c53cd63dabc0 100644 (file)
@@ -159,7 +159,8 @@ putchar('\n');
 #define udn 2    /* Unix domain socket number */
 #define skn 2    /* Potential number of sockets */
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
 int i;
 int port = 0;
index d2891b87ab80bc6e9448d1dee06831da8bd4b8ee..0de971e4a3787940d42a9271e4a6c6f07f3b78b1 100644 (file)
@@ -240,7 +240,9 @@ new DNS lookup for 99.99.99.V4NET.rbl.test.ex
 DNS lookup of 99.99.99.V4NET.rbl.test.ex (A) using fakens
 DNS lookup of 99.99.99.V4NET.rbl.test.ex (A) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(A) response length as 65535
  writing neg-cache entry for 99.99.99.V4NET.rbl.test.ex-A-xxxx, ttl 3000
+faking res_search(A) response length as 65535
 dnslists: wrote cache entry, ttl=3000
 DNS lookup for 99.99.99.V4NET.rbl.test.ex failed
 => that means V4NET.99.99.99 is not listed at rbl.test.ex
index fc573ce9b701e72fe037e8a3cc43f8c4ea9d0c7f..42092c03d2c14fa132f600efcb1efcb7d4abf485 100644 (file)
@@ -18,7 +18,7 @@ domain = mxt6.test.ex
 routed by lookuphost router
   envelope to: xx@mxt6.test.ex
   transport: remote_smtp
-  host ten-1.test.ex [V4NET.0.0.1] MX=5
+  host ten-1.test.ex [V4NET.0.0.1] MX=5 dnssec=no
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
index 715ca795c04bb299a35a9e1fd58994f952561081..7db741e6d3728938442762b640a5a26d7425fb95 100644 (file)
@@ -35,6 +35,7 @@ LOG: SMTP data timeout (message abandoned) on connection from [V4NET.0.0.1] F=<u
 Exim version x.yz ....
 changed uid/gid: forcing real = effective
   uid=uuuu gid=CALLER_GID pid=pppp
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
 changed uid/gid: privilege not needed
index b4e5e8b2d975160b8e9d50fc1038b1b4bc02eb3d..ad17fd9c1b80f48c1da9b707b6b620008ae3568b 100644 (file)
@@ -15,9 +15,9 @@ domain = mxt9.test.ex
 routed by lookuphost router
   envelope to: xxx@mxt9.test.ex
   transport: <none>
-  host ten-1.test.ex [V4NET.0.0.1] MX=5
-  host ten-2.test.ex [V4NET.0.0.2] MX=6
-  host ten-3.test.ex [V4NET.0.0.3] MX=7
+  host ten-1.test.ex [V4NET.0.0.1] MX=5 dnssec=no
+  host ten-2.test.ex [V4NET.0.0.2] MX=6 dnssec=no
+  host ten-3.test.ex [V4NET.0.0.3] MX=7 dnssec=no
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
@@ -36,9 +36,9 @@ domain = mxt9a.test.ex
 routed by lookuphost router
   envelope to: xxx@mxt9a.test.ex
   transport: <none>
-  host ten-1.test.ex [V4NET.0.0.1] MX=5
-  host ten-2.test.ex [V4NET.0.0.2] MX=6
-  host ten-3.test.ex [V4NET.0.0.3] MX=7
+  host ten-1.test.ex [V4NET.0.0.1] MX=5 dnssec=no
+  host ten-2.test.ex [V4NET.0.0.2] MX=6 dnssec=no
+  host ten-3.test.ex [V4NET.0.0.3] MX=7 dnssec=no
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
@@ -57,7 +57,7 @@ domain = mxt9b.test.ex
 routed by lookuphost router
   envelope to: xxx@mxt9b.test.ex
   transport: <none>
-  host ten-1.test.ex [V4NET.0.0.1] MX=5
-  host ten-2.test.ex [V4NET.0.0.2] MX=6
-  host ten-3.test.ex [V4NET.0.0.3] MX=7
+  host ten-1.test.ex [V4NET.0.0.1] MX=5 dnssec=no
+  host ten-2.test.ex [V4NET.0.0.2] MX=6 dnssec=no
+  host ten-3.test.ex [V4NET.0.0.3] MX=7 dnssec=no
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
index cd1151a2bc64865deee1c9fc5602def76690fb39..79a6f4ab1bda3483bfc01c6a7114eb9248432bc1 100644 (file)
@@ -12,6 +12,7 @@
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@mxt10.test.ex
 >>> calling domainlist router
+>>> mxt10.test.ex in "*"? yes (matched "*")
 >>> domainlist router declined for x@mxt10.test.ex
 >>> "more" is false: skipping remaining routers
 >>> no more routers
@@ -34,6 +35,7 @@ LOG: H=[V4NET.9.8.7] F=<x@mxt10.test.ex> rejected RCPT <x@y>: Sender verify fail
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@ten-1.test.ex
 >>> calling domainlist router
+>>> ten-1.test.ex in "*"? yes (matched "*")
 >>> routed by domainlist router
 >>> ----------- end verify ------------
 >>> require: condition test succeeded in ACL "check_recipient"
@@ -42,6 +44,7 @@ LOG: H=[V4NET.9.8.7] F=<x@mxt10.test.ex> rejected RCPT <x@y>: Sender verify fail
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@mxt10.test.ex
 >>> calling domainlist router
+>>> mxt10.test.ex in "*"? yes (matched "*")
 >>> domainlist router declined for x@mxt10.test.ex
 >>> "more" is false: skipping remaining routers
 >>> no more routers
index 88f106933fe17da497c53eb14d1663c87bf44d43..d4a6676eba0944c09d9d69a4a3f5b4e50dffcd0c 100644 (file)
@@ -23,7 +23,7 @@ domain = mxt6.test.ex
 routed by lookuphost router
   envelope to: xx@mxt6.test.ex
   transport: remote_smtp
-  host ten-1.test.ex [V4NET.0.0.1] MX=5
+  host ten-1.test.ex [V4NET.0.0.1] MX=5 dnssec=no
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
 configuration file is TESTSUITE/test-config
index b2f1c655c3f8220685c497ed693138ae1283b0ef..684b2b428c522c8aec104fbd1fea70d6b27bde96 100644 (file)
@@ -81,6 +81,7 @@ LOG: H=[V4NET.0.0.0] F=<user@bad.domain2> rejected RCPT <userx@test.ex>: Sender
 >>> fail_sender2 router declined for user@ten-1.test.ex
 >>> ten-1.test.ex in "! +local_domains"? yes (end of list)
 >>> calling lookuphost router
+>>> ten-1.test.ex in "*"? yes (matched "*")
 >>> routed by lookuphost router
 >>> ----------- end verify ------------
 >>> require: condition test succeeded in ACL "check_recipient"
index 44f567bc69b1468f28088acb431474f9f0ec2ec8..98d82f8e8c94bda44819f7a81578e6b32742e40e 100644 (file)
@@ -30,6 +30,7 @@ userx in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for userx@test.again.dns
   domain = test.again.dns
+test.again.dns in "*"? yes (matched "*")
 DNS lookup of test.again.dns (MX) using fakens
 DNS lookup of test.again.dns (MX) gave TRY_AGAIN
 test.again.dns in dns_again_means_nonexist? no (option unset)
@@ -60,6 +61,7 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@test.again.dns
   domain = test.again.dns
+test.again.dns in "*"? yes (matched "*")
 DNS lookup of test.again.dns-MX: using cached value DNS_AGAIN
 lookuphost router: defer for abcd@test.again.dns
   message: host lookup did not complete
@@ -86,10 +88,13 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex (MX) using fakens
 DNS lookup of ten-1.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000
+ten-1.test.ex (MX resp) DNSSEC
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
 fully qualified name = ten-1.test.ex
@@ -128,6 +133,7 @@ expanded list of hosts = 'test.again.dns' options = 'bydns'
 set transport smtp
 finding IP address for test.again.dns
 doing DNS lookup
+test.again.dns in "*"? yes (matched "*")
 DNS lookup of test.again.dns (A) using fakens
 DNS lookup of test.again.dns (A) gave TRY_AGAIN
 test.again.dns in dns_again_means_nonexist? no (option unset)
@@ -159,6 +165,7 @@ original list of hosts = '$domain' options = 'bydns'
 expanded list of hosts = 'test.again.dns' options = 'bydns'
 finding IP address for test.again.dns
 doing DNS lookup
+test.again.dns in "*"? yes (matched "*")
 DNS lookup of test.again.dns-A: using cached value DNS_AGAIN
 useryz router: defer for userz@test.again.dns
   message: host lookup for test.again.dns did not complete (DNS timeout?)
@@ -185,6 +192,7 @@ xyz in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for xyz@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
@@ -232,6 +240,7 @@ userx in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for userx@test.fail.dns
   domain = test.fail.dns
+test.fail.dns in "*"? yes (matched "*")
 DNS lookup of test.fail.dns (MX) using fakens
 DNS lookup of test.fail.dns (MX) gave NO_RECOVERY
 returning DNS_FAIL
@@ -261,6 +270,7 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@test.fail.dns
   domain = test.fail.dns
+test.fail.dns in "*"? yes (matched "*")
 DNS lookup of test.fail.dns-MX: using cached value DNS_FAIL
 lookuphost router: defer for abcd@test.fail.dns
   message: host lookup did not complete
@@ -287,10 +297,13 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex (MX) using fakens
 DNS lookup of ten-1.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000
+ten-1.test.ex (MX resp) DNSSEC
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
 fully qualified name = ten-1.test.ex
@@ -329,6 +342,7 @@ expanded list of hosts = 'test.fail.dns' options = 'bydns'
 set transport smtp
 finding IP address for test.fail.dns
 doing DNS lookup
+test.fail.dns in "*"? yes (matched "*")
 DNS lookup of test.fail.dns (A) using fakens
 DNS lookup of test.fail.dns (A) gave NO_RECOVERY
 returning DNS_FAIL
@@ -359,6 +373,7 @@ original list of hosts = '$domain' options = 'bydns'
 expanded list of hosts = 'test.fail.dns' options = 'bydns'
 finding IP address for test.fail.dns
 doing DNS lookup
+test.fail.dns in "*"? yes (matched "*")
 DNS lookup of test.fail.dns-A: using cached value DNS_FAIL
 useryz router: defer for userz@test.fail.dns
   message: host lookup for test.fail.dns did not complete (DNS timeout?)
@@ -385,6 +400,7 @@ xyz in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for xyz@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
@@ -432,9 +448,11 @@ userx in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for userx@nonexist.test.ex
   domain = nonexist.test.ex
+nonexist.test.ex in "*"? yes (matched "*")
 DNS lookup of nonexist.test.ex (MX) using fakens
 DNS lookup of nonexist.test.ex (MX) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(MX) response length as 65535
  writing neg-cache entry for nonexist.test.ex-MX-xxxx, ttl 3000
 lookuphost router declined for userx@nonexist.test.ex
 "more" is false: skipping remaining routers
@@ -462,6 +480,7 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@nonexist.test.ex
   domain = nonexist.test.ex
+nonexist.test.ex in "*"? yes (matched "*")
 DNS lookup of nonexist.test.ex-MX: using cached value DNS_NOMATCH
 lookuphost router declined for abcd@nonexist.test.ex
 "more" is false: skipping remaining routers
@@ -489,10 +508,13 @@ abcd in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for abcd@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex (MX) using fakens
 DNS lookup of ten-1.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000
+ten-1.test.ex (MX resp) DNSSEC
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
 fully qualified name = ten-1.test.ex
@@ -531,9 +553,11 @@ expanded list of hosts = 'nonexist.test.ex' options = 'bydns'
 set transport smtp
 finding IP address for nonexist.test.ex
 doing DNS lookup
+nonexist.test.ex in "*"? yes (matched "*")
 DNS lookup of nonexist.test.ex (A) using fakens
 DNS lookup of nonexist.test.ex (A) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(A) response length as 65535
  writing neg-cache entry for nonexist.test.ex-A-xxxx, ttl 3000
 useryz router: defer for usery@nonexist.test.ex
   message: lookup of host "nonexist.test.ex" failed in useryz router
@@ -561,6 +585,7 @@ original list of hosts = '$domain' options = 'bydns'
 expanded list of hosts = 'nonexist.test.ex' options = 'bydns'
 finding IP address for nonexist.test.ex
 doing DNS lookup
+nonexist.test.ex in "*"? yes (matched "*")
 DNS lookup of nonexist.test.ex-A: using cached value DNS_NOMATCH
 useryz router: defer for userz@nonexist.test.ex
   message: lookup of host "nonexist.test.ex" failed in useryz router
@@ -587,6 +612,7 @@ xyz in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for xyz@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex-MX: using cached value DNS_NODATA
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
@@ -624,6 +650,7 @@ srv in "^srv"? yes (matched "^srv")
 calling srv router
 srv router called for srv@test.again.dns
   domain = test.again.dns
+test.again.dns in "*"? yes (matched "*")
 DNS lookup of _smtp._tcp.test.again.dns (SRV) using fakens
 DNS lookup of _smtp._tcp.test.again.dns (SRV) gave TRY_AGAIN
 _smtp._tcp.test.again.dns in dns_again_means_nonexist? no (option unset)
@@ -645,6 +672,7 @@ srv in "^srv"? yes (matched "^srv")
 calling srv router
 srv router called for srv@test.fail.dns
   domain = test.fail.dns
+test.fail.dns in "*"? yes (matched "*")
 DNS lookup of _smtp._tcp.test.fail.dns (SRV) using fakens
 DNS lookup of _smtp._tcp.test.fail.dns (SRV) gave NO_RECOVERY
 returning DNS_FAIL
@@ -697,9 +725,11 @@ userx in "!userd"? yes (end of list)
 calling lookuphost router
 lookuphost router called for userx@nonexist.example.com
   domain = nonexist.example.com
+nonexist.example.com in "*"? yes (matched "*")
 DNS lookup of nonexist.example.com (MX) using fakens
 DNS lookup of nonexist.example.com (MX) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(MX) response length as 65535
  writing neg-cache entry for nonexist.example.com-MX-xxxx, ttl 2
 lookuphost router declined for userx@nonexist.example.com
 "more" is false: skipping remaining routers
@@ -738,10 +768,12 @@ checking "condition" "${acl {delay}}"...
 calling delay router
 delay router called for userd@nonexist.example.com
   domain = nonexist.example.com
+nonexist.example.com in "*"? yes (matched "*")
 DNS lookup of nonexist.example.com-MX: cached value DNS_NOMATCH past valid time
 DNS lookup of nonexist.example.com (MX) using fakens
 DNS lookup of nonexist.example.com (MX) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(MX) response length as 65535
  update neg-cache entry for nonexist.example.com-MX-xxxx, ttl 2
 delay router declined for userd@nonexist.example.com
 "more" is false: skipping remaining routers
index f8219ff8edcaee31e1bfb6254d2b62ea389d2b8b..834155bf9f9c9ea914af408687087071bbd389b3 100644 (file)
@@ -288,13 +288,17 @@ unknown in "+never_localparts : +n2_localparts : !+local_localparts"? yes (end o
 calling r2 router
 r2 router called for unknown@test.ex
   domain = test.ex
+test.ex in "*"? yes (matched "*")
 DNS lookup of test.ex (MX) using fakens
 DNS lookup of test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for test.ex-MX-xxxx, ttl 3000
+test.ex (MX resp) DNSSEC
 DNS lookup of test.ex (A) using fakens
 DNS lookup of test.ex (A) gave NO_DATA
 returning DNS_NODATA
+faking res_search(A) response length as 65535
  writing neg-cache entry for test.ex-A-xxxx, ttl 3000
 r2 router declined for unknown@test.ex
 --------> r3 router <--------
index 151a237aab62fda9f4cd43af0873465dae065162..3f9891c570c38b7b650f8968b9ccf240fd241280 100644 (file)
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@ten-1
 >>> calling dnslookup router
+>>> ten-1 in "*"? yes (matched "*")
 >>> re-routed to x@ten-1.test.ex
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@ten-1.test.ex
 >>> calling dnslookup router
+>>> ten-1.test.ex in "*"? yes (matched "*")
 >>> routed by dnslookup router
 >>> ----------- end verify ------------
 >>> deny: condition test failed in ACL "check_rcpt"
index 5081d02d7c8a9278217214151df7d4acf4dc9964..cd96418fec494fa088bd1b491bd548958deb2fb5 100644 (file)
@@ -96,15 +96,20 @@ recurse.test.ex in "!thishost.test.ex : !recurse.test.ex.test.ex"? yes (end of l
 calling r1 router
 r1 router called for kilos@recurse.test.ex
   domain = recurse.test.ex
+recurse.test.ex in "*"? yes (matched "*")
 DNS lookup of recurse.test.ex (MX) using fakens
 DNS lookup of recurse.test.ex (MX) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(MX) response length as 65535
  writing neg-cache entry for recurse.test.ex-MX-xxxx, ttl 3000
 r1 router widened recurse.test.ex to recurse.test.ex.test.ex
+recurse.test.ex.test.ex in "*"? yes (matched "*")
 DNS lookup of recurse.test.ex.test.ex (MX) using fakens
 DNS lookup of recurse.test.ex.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for recurse.test.ex.test.ex-MX-xxxx, ttl 3000
+recurse.test.ex.test.ex (MX resp) DNSSEC
 DNS lookup of recurse.test.ex.test.ex (A) using fakens
 DNS lookup of recurse.test.ex.test.ex (A) succeeded
 fully qualified name = recurse.test.ex.test.ex
index 314a8ba3ae9f403259411609006dac2226b38e19..a469f8aae094f13005d030c14ec921fdd7448aae 100644 (file)
@@ -1,6 +1,7 @@
 Exim version x.yz ....
 changed uid/gid: forcing real = effective
   uid=uuuu gid=CALLER_GID pid=pppp
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
 changed uid/gid: privilege not needed
@@ -118,18 +119,6 @@ Data file written for message 10HmaX-0005vi-00
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -189,6 +178,7 @@ exec TESTSUITE/eximdir/exim -DEXIM_PATH=TESTSUITE/eximdir/exim -C TESTSUITE/test
 Exim version x.yz ....
 changed uid/gid: forcing real = effective
   uid=uuuu gid=EXIM_GID pid=pppp
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 trusted user
 admin user
index 8aba8f1e48ba6695f219da3c17c98efeb55fe316..39c797009d0f0b679cf5d774478188ec013d6fb7 100644 (file)
@@ -22,6 +22,7 @@ mxt13.test.ex in "! +local_domains"? yes (end of list)
 calling dnslookup router
 dnslookup router called for k@mxt13.test.ex
   domain = mxt13.test.ex
+mxt13.test.ex in "*"? yes (matched "*")
 DNS lookup of mxt13.test.ex (MX) using fakens
 DNS lookup of mxt13.test.ex (MX) succeeded
 DNS lookup of other1.test.ex (A) using fakens
@@ -46,6 +47,6 @@ domain = mxt13.test.ex
 routed by dnslookup router
   envelope to: k@mxt13.test.ex
   transport: smtp
-  host other1.test.ex [V4NET.12.4.5] MX=4
+  host other1.test.ex [V4NET.12.4.5] MX=4 dnssec=no
 search_tidyup called
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
index dda5191a2b0e733635a93079ca00117ea3217a8a..4e49b711461e78a8a64e7af7009e9f8cb17a1c7e 100644 (file)
@@ -26,6 +26,7 @@ local_part=x domain=uppercase.test.ex
 calling r1 router
 r1 router called for x@uppercase.test.ex
   domain = uppercase.test.ex
+uppercase.test.ex (MX resp) DNSSEC
 local host found for non-MX address
 fully qualified name = UpperCase.test.ex
 uppercase.test.ex 127.0.0.1 mx=-1 sort=xx 
index 9b863225cc0d6a47187af8a6fe420b5b81771312..2911efa80df804cd89910b0791c83ed31a6a5098 100644 (file)
@@ -12,6 +12,7 @@
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@ten-1.test.ex
 >>> calling r1 router
+>>> ten-1.test.ex in "*"? yes (matched "*")
 >>> routed by r1 router
 >>> Attempting full verification using callout
 >>> callout cache: no domain record found for ten-1.test.ex
index 4dc214435cc9a0ee86337f69f72b146bdf4229f1..c74dc0349c268c07acd87a963faaac744b2af3f1 100644 (file)
@@ -19,16 +19,20 @@ checking domains
 DNS lookup of ten-1 (MX) using fakens
 DNS lookup of ten-1 (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1-MX-xxxx, ttl 3000
 Address records are not being sought
 ten-1 in "!@mx_any"? yes (end of list)
 calling all router
 all router called for x@ten-1
   domain = ten-1
+ten-1 in "*"? yes (matched "*")
 DNS lookup of ten-1 (MX) using fakens
 DNS lookup of ten-1 (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1-MX-xxxx, ttl 3000
+ten-1 (MX resp) DNSSEC
 DNS lookup of ten-1 (A) using fakens
 DNS lookup of ten-1 (A) succeeded
 fully qualified name = ten-1.test.ex
@@ -46,16 +50,20 @@ checking domains
 DNS lookup of ten-1.test.ex (MX) using fakens
 DNS lookup of ten-1.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000
 Address records are not being sought
 ten-1.test.ex in "!@mx_any"? yes (end of list)
 calling all router
 all router called for x@ten-1.test.ex
   domain = ten-1.test.ex
+ten-1.test.ex in "*"? yes (matched "*")
 DNS lookup of ten-1.test.ex (MX) using fakens
 DNS lookup of ten-1.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for ten-1.test.ex-MX-xxxx, ttl 3000
+ten-1.test.ex (MX resp) DNSSEC
 DNS lookup of ten-1.test.ex (A) using fakens
 DNS lookup of ten-1.test.ex (A) succeeded
 fully qualified name = ten-1.test.ex
index bf37946ac8d42aad55de8c43436f20b752ada7f7..9f9e1538ecfbcc6dc986266a47a83d347b1e1deb 100644 (file)
@@ -18,6 +18,7 @@ local_part=x domain=mxt1c.test.ex
 calling r1 router
 r1 router called for x@mxt1c.test.ex
   domain = mxt1c.test.ex
+mxt1c.test.ex in "*"? yes (matched "*")
 DNS lookup of mxt1c.test.ex (MX) using fakens
 DNS lookup of mxt1c.test.ex (MX) succeeded
 DNS lookup of dontqualify (A) using fakens
index 140ab775e97b5824cbf90f8e081e5fb7f1d22025..9c6466e9d1a0fc2398a5c0e8e421bf8b203f2e83 100644 (file)
@@ -88,12 +88,12 @@ LOG: MAIN
   H=127.0.0.1 [127.0.0.1] Connection refused
 set_process_info: pppp delivering 10HmaZ-0005vi-00: just tried 127.0.0.1 [127.0.0.1]:PORT_S for CALLER@the.local.host.name: result DEFER
 added retry item for T:127.0.0.1:127.0.0.1:1224: errno=dd more_errno=dd,A flags=2
-set_process_info: pppp delivering 10HmaZ-0005vi-00: waiting for a remote delivery subprocess to finish
 all IP addresses skipped or deferred at least one address
 updating wait-t1 database
 added to list for 127.0.0.1
 Leaving t1 transport
 set_process_info: pppp delivering 10HmaZ-0005vi-00 (just run t1 for CALLER@the.local.host.name in subprocess)
+set_process_info: pppp delivering 10HmaZ-0005vi-00: waiting for a remote delivery subprocess to finish
 set_process_info: pppp delivering 10HmaZ-0005vi-00
 LOG: MAIN
   == CALLER@the.local.host.name R=r1 T=t1 defer (dd): Connection refused
index dc2bfa520c37e9d33a329abdfb4d4e0c255e431b..60d05a6b3f4e8156c013f48b90314144c21089fe 100644 (file)
@@ -16,6 +16,7 @@
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing x@mxt2.test.ex
 >>> calling r1 router
+>>> mxt2.test.ex in "*"? yes (matched "*")
 >>> r1 router declined for x@mxt2.test.ex
 >>> no more routers
 >>> ----------- end verify ------------
index 4d05db641c3e82aaf77efeec5f9883d611ff4f8e..4f4e07b02228b50d2877baebfdac3d43844e2645 100644 (file)
@@ -1,4 +1,5 @@
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  ╭considering: ${tod_full}
@@ -83,18 +84,6 @@ admin user
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -131,6 +120,7 @@ LOG: MAIN
   <= CALLER@test.ex U=CALLER P=local S=sss
 created log directory TESTSUITE/spool/log
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 trusted user
 admin user
@@ -176,6 +166,7 @@ LOG: MAIN
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
 LOG: smtp_connection MAIN
index d9987696fba5db12817ac9fe3e04e066e8ee77ab..f2e5e37b1086cd1d33ee85be2989f271f5c516a3 100644 (file)
@@ -18,13 +18,16 @@ local_part=userx domain=alias-eximtesthost
 calling dns router
 dns router called for userx@alias-eximtesthost
   domain = alias-eximtesthost
+alias-eximtesthost in "*"? yes (matched "*")
 DNS lookup of alias-eximtesthost (MX) using fakens
 DNS lookup of alias-eximtesthost (MX) succeeded
 CNAME found: change to eximtesthost.test.ex
 DNS lookup of eximtesthost.test.ex (MX) using fakens
 DNS lookup of eximtesthost.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for eximtesthost.test.ex-MX-xxxx, ttl 3000
+alias-eximtesthost (MX resp) DNSSEC
 DNS lookup of alias-eximtesthost (A) using fakens
 DNS lookup of alias-eximtesthost (A) succeeded
 CNAME found: change to eximtesthost.test.ex
@@ -45,6 +48,7 @@ local_part=userx domain=alias-eximtesthost.test.ex
 calling dns router
 dns router called for userx@alias-eximtesthost.test.ex
   domain = alias-eximtesthost.test.ex
+alias-eximtesthost.test.ex in "*"? yes (matched "*")
 DNS lookup of alias-eximtesthost.test.ex (MX) using fakens
 DNS lookup of alias-eximtesthost.test.ex (MX) succeeded
 CNAME found: change to eximtesthost.test.ex
@@ -89,13 +93,16 @@ local_part=userx domain=alias-eximtesthost.test.ex
 calling dns router
 dns router called for userx@alias-eximtesthost.test.ex
   domain = alias-eximtesthost.test.ex
+alias-eximtesthost.test.ex in "*"? yes (matched "*")
 DNS lookup of alias-eximtesthost.test.ex (MX) using fakens
 DNS lookup of alias-eximtesthost.test.ex (MX) succeeded
 CNAME found: change to eximtesthost.test.ex
 DNS lookup of eximtesthost.test.ex (MX) using fakens
 DNS lookup of eximtesthost.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for eximtesthost.test.ex-MX-xxxx, ttl 3000
+alias-eximtesthost.test.ex (MX resp) DNSSEC
 DNS lookup of alias-eximtesthost.test.ex (A) using fakens
 DNS lookup of alias-eximtesthost.test.ex (A) succeeded
 CNAME found: change to eximtesthost.test.ex
index ddaacf4317729ff8fdeef07a05187478330987e2..cc24461c96e76b7ff7d0537c7078070d34d62fec 100644 (file)
@@ -12,7 +12,8 @@
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing should_log@delay1500.test.ex
 >>> calling all router
-LOG: Long name lookup for 'delay1500.test.ex': ssss msec
+>>> delay1500.test.ex in "*"? yes (matched "*")
+LOG: Long A lookup for 'delay1500.test.ex': ssss msec
 >>> local host found for non-MX address
 >>> routed by all router
 >>> ----------- end verify ------------
@@ -32,6 +33,7 @@ LOG: Long name lookup for 'delay1500.test.ex': ssss msec
 >>> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 >>> routing should_not_log@delay500.test.ex
 >>> calling all router
+>>> delay500.test.ex in "*"? yes (matched "*")
 >>> local host found for non-MX address
 >>> routed by all router
 >>> ----------- end verify ------------
index d569343d094c82af738a5ecb0b1bf098ad4e4df6..4c88e098ff68b0b8f71c133ef7316cafc75dd08f 100644 (file)
@@ -13,11 +13,13 @@ DNS lookup of 46.test.ex (A) succeeded
 DNS lookup of v6.test.ex (MX) using fakens
 DNS lookup of v6.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for v6.test.ex-MX-xxxx, ttl 3000
 DNS lookup of v6.test.ex (AAAA) succeeded
 DNS lookup of v6.test.ex (A) using fakens
 DNS lookup of v6.test.ex (A) gave NO_DATA
 returning DNS_NODATA
+faking res_search(A) response length as 65535
  writing neg-cache entry for v6.test.ex-A-xxxx, ttl 3000
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
@@ -33,10 +35,12 @@ DNS lookup of 46.test.ex (A) succeeded
 DNS lookup of v6.test.ex (MX) using fakens
 DNS lookup of v6.test.ex (MX) gave NO_DATA
 returning DNS_NODATA
+faking res_search(MX) response length as 65535
  writing neg-cache entry for v6.test.ex-MX-xxxx, ttl 3000
 DNS lookup of v6.test.ex (A) using fakens
 DNS lookup of v6.test.ex (A) gave NO_DATA
 returning DNS_NODATA
+faking res_search(A) response length as 65535
  writing neg-cache entry for v6.test.ex-A-xxxx, ttl 3000
 >>>>>>>>>>>>>>>> Exim pid=pppp (main) terminating with rc=2 >>>>>>>>>>>>>>>>
 
index 23ac937466bdf7886c9e444dca7f99fb4dab6d2f..23d3d6a5ff15286cf3ede5cfdfe4723b8422b6dd 100644 (file)
@@ -99,6 +99,7 @@ dnsdb key: unknown
 DNS lookup of unknown (TXT) using fakens
 DNS lookup of unknown (TXT) gave HOST_NOT_FOUND
 returning DNS_NOMATCH
+faking res_search(TXT) response length as 65535
  writing neg-cache entry for unknown-TXT-xxxx, ttl 3000
 lookup failed
 unknown in "dnsdb;unknown"? no (end of list)
index 9ba2a62a2f1cd9178147b2853a09d0878eced0c2..49b5e51b7e6c3013c4aa9078c4b672d857119a1b 100644 (file)
@@ -1,5 +1,6 @@
 1999-03-02 09:44:33 this is a warning at TESTSUITE/aux-fixed/3000.pl line 25.
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
 dropping to exim gid; retaining priv uid
index f68fdd8f426547b7110657d10e1e30db3a7c8d61..2ae0bde590e9343e3b15eb3acf378636d9da8933 100644 (file)
@@ -15,6 +15,7 @@
 >>> calling skipped router
 >>> skipped router declined for userx@test.again.dns
 >>> calling temp router
+>>> test.again.dns in "*"? yes (matched "*")
 >>> test.again.dns in dns_again_means_nonexist? no (option unset)
 >>> temp router: defer for userx@test.again.dns
 >>>   message: host lookup did not complete
@@ -36,6 +37,7 @@ LOG: H=[1.2.3.4] F=<userx@test.ex> temporarily rejected RCPT <userx@test.again.d
 >>> routing r1-userx@test.again.dns
 >>> test.again.dns in "!testdb;fail"? yes (end of list)
 >>> calling r1 router
+>>> test.again.dns in "*"? yes (matched "*")
 >>> test.again.dns in dns_again_means_nonexist? no (option unset)
 >>> r1 router: defer for r1-userx@test.again.dns
 >>>   message: host lookup did not complete
index 9953eee7cd2f31e396d237708388f899e4a8f940..b29fee2e723846d96ccb3a5bd50b547566f434b5 100644 (file)
@@ -1,4 +1,5 @@
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -219,18 +220,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -284,6 +273,7 @@ LOG: smtp_connection MAIN
   SMTP connection from CALLER closed by QUIT
 >>>>>>>>>>>>>>>> Exim pid=pppp (msg setup toplevel) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -472,18 +462,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -537,6 +515,7 @@ LOG: smtp_connection MAIN
   SMTP connection from CALLER closed by QUIT
 >>>>>>>>>>>>>>>> Exim pid=pppp (msg setup toplevel) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -725,18 +704,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
index d8325430732e5e101ced85b36dbe013a14fdf213..b06eb8d33fc6565b1474d05bb9ba19f06809a643 100644 (file)
@@ -1,4 +1,5 @@
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -220,18 +221,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -285,6 +274,7 @@ LOG: smtp_connection MAIN
   SMTP connection from CALLER closed by QUIT
 >>>>>>>>>>>>>>>> Exim pid=pppp (msg setup toplevel) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -473,18 +463,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
@@ -538,6 +516,7 @@ LOG: smtp_connection MAIN
   SMTP connection from CALLER closed by QUIT
 >>>>>>>>>>>>>>>> Exim pid=pppp (msg setup toplevel) terminating with rc=0 >>>>>>>>>>>>>>>>
 Exim version x.yz ....
+adding SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 configuration file is TESTSUITE/test-config
 admin user
  in hosts_connection_nolog? no (option unset)
@@ -726,18 +705,6 @@ end of inline ACL: ACCEPT
        for $received_for}}
   ├──expanding:  ($tls_in_ver)
   ├─────result:  ()
-  ╰───skipping: result is not used
- ├──condition: def:tls_in_cipher_std
- ├─────result: false
-  ╭───scanning:  tls $tls_in_cipher_std
-       }}(Exim $version_number)
-       ${if def:sender_address {(envelope-from <$sender_address>)
-       }}id $message_exim_id${if def:received_for {
-       for $received_for}}
-  ├──expanding:  tls $tls_in_cipher_std
-       
-  ├─────result:  tls 
-       
   ╰───skipping: result is not used
  ├──condition: def:sender_address
  ├─────result: true
index 32ccd89447737bbc12f379be2ad08fafb86eb602..431221c89c88456f17169c664d0f2c1f92111dcc 100644 (file)
@@ -23,7 +23,7 @@ no_check_local_user
 condition = 
 debug_print = 
 no_disable_logging
-dnssec_request_domains = 
+dnssec_request_domains = *
 dnssec_require_domains = 
 domains = 
 driver = accept
index a88a851b0227dacd31310590861680b54df5f882..756f7f851d49db0c1af9f6e18b94dc2c5bd79ac2 100644 (file)
@@ -97,17 +97,17 @@ y@batch4
 userx@bdomain1
   router = r3, transport = smtp2
   host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
-  host 127.0.0.1 [127.0.0.1] 
+  host 127.0.0.1 [127.0.0.1]
   host the.local.host.name [ip4.ip4.ip4.ip4]
 userx@bdomain2
   router = r3, transport = smtp2
   host the.local.host.name [ip4.ip4.ip4.ip4]
-  host 127.0.0.1 [127.0.0.1] 
+  host 127.0.0.1 [127.0.0.1]
   host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
 userx@bdomain3
   router = r3, transport = smtp2
   host ipv4.ipv4.ipv4.ipv4 [ipv4.ipv4.ipv4.ipv4]
-  host 127.0.0.1 [127.0.0.1] 
+  host 127.0.0.1 [127.0.0.1]
   host the.local.host.name [ip4.ip4.ip4.ip4]
 
 ******** SERVER ********
index d951172b7882a1d3cbce61289e61cffbf2ce7981..120a1d4a85a75ab1946023585e07f20d3c44965a 100644 (file)
@@ -1,4 +1,4 @@
 xx@yy
   router = r1, transport = t1
-  host 1.2.3.4 [1.2.3.4] 
+  host 1.2.3.4 [1.2.3.4]
   host other2.test.ex [V4NET.12.3.2]
index 7914594b4eda8a5b79dc7cc47162312759f46506..1229b0ef83d816d4e485116ed20bc67759c4e245 100644 (file)
@@ -48,7 +48,7 @@ x@manual.route
   router = r1, transport = t1
   host ten-1.test.ex [V4NET.0.0.1] MX=5
   host eximtesthost.test.ex [ip4.ip4.ip4.ip4] MX=5
-  host ten-6.test.ex [V4NET.0.0.6] 
+  host ten-6.test.ex [V4NET.0.0.6]
 x@manual.route is undeliverable: lowest numbered MX record points to local host
 x@random.manual.route cannot be resolved at this time: lookup of host "localhost.test.ex" failed in r2 router
 x@random.manual.route
index 0b3a5a62acfbcb280d806f00fd28483f51a482df..12c761c90998d08f69f828f3a3002ea9715e7d4e 100644 (file)
@@ -8,7 +8,7 @@ no_check_local_user
 condition = 
 debug_print = 
 no_disable_logging
-dnssec_request_domains = 
+dnssec_request_domains = *
 dnssec_require_domains = 
 domains = 
 driver = accept
index 06cc972a146817f81d301d5f2a26e415a1f07e51..4d428078f3cc70ede0514e057cfdac98c1079ca8 100644 (file)
@@ -41,7 +41,7 @@ data_timeout = 5m
 delay_after_cutoff
 dns_qualify_single
 no_dns_search_parents
-dnssec_request_domains = 
+dnssec_request_domains = *
 dnssec_require_domains = 
 dscp = 
 fallback_hosts = 
@@ -78,7 +78,8 @@ OPT =
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/tls_conf_prefix"
-keep_environment = PATH:SSLKEYLOGFILE:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+add_environment = SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 exim_path = TESTSUITE/eximdir/exim
 host_lookup_order = bydns
 spool_directory = TESTSUITE/spool
@@ -119,7 +120,8 @@ OPT =
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/tls_conf_prefix"
-keep_environment = PATH:SSLKEYLOGFILE:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+add_environment = SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 exim_path = TESTSUITE/eximdir/exim
 host_lookup_order = bydns
 spool_directory = TESTSUITE/spool
index a15ecdd5dd3a2d31a4fa3f7c8da979ec9b0a936c..0a0e014eeb77708025b6366c2e0af22800151968 100644 (file)
 354 Enter message, ending with "." on a line by itself\r
 250 OK id=10HmbA-0005vi-00\r
 221 the.local.host.name closing connection\r
+### load messages
+220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbB-0005vi-00\r
+250 Reset OK\r
+250 OK\r
+250 Accepted\r
+354 Enter message, ending with "." on a line by itself\r
+250 OK id=10HmbC-0005vi-00\r
+221 the.local.host.name closing connection\r
+### default q
+ 0m   sss 10HmbB-0005vi-00 <CALLER@the.local.host.name>
+          normal@test.ex
+
+### alternate q
+ 0m   sss 10HmbC-0005vi-00 <CALLER@the.local.host.name>
+          alternate@test.ex
+
+Message 10HmbB-0005vi-00 
+Message 10HmbC-0005vi-00 
+### third q
+ 0m   sss 10HmbB-0005vi-00 <CALLER@the.local.host.name>
+          normal@test.ex
+
+ 0m   sss 10HmbC-0005vi-00 <CALLER@the.local.host.name>
+          alternate@test.ex
+
+Message 10HmbB-0005vi-00 Message 10HmbC-0005vi-00 
+### default q
+ 0m   sss 10HmbB-0005vi-00 <CALLER@the.local.host.name>
+          normal@test.ex
+
+ 0m   sss 10HmbC-0005vi-00 <CALLER@the.local.host.name>
+          alternate@test.ex
+
+### alternate q
+### third q
 
 ******** SERVER ********
 ### default q
 ### alternate q
+### load messages
+### default q
+### alternate q
+### third q
+### default q
+### alternate q
+### third q
index 7a0cb7a82c69cefaf070075b175862fa46168c35..a56ec1b629c2d248b85bc8ae1c944dc668b93331 100644 (file)
@@ -4,7 +4,8 @@
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/std_conf_prefix"
 # 1 "TESTSUITE/aux-var/tls_conf_prefix"
-keep_environment = PATH:SSLKEYLOGFILE:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+keep_environment = PATH:EXIM_TESTHARNESS_DISABLE_OCSPVALIDITYCHECK
+add_environment = SSLKEYLOGFILE=TESTSUITE/spool/sslkeys
 exim_path = TESTSUITE/eximdir/exim
 host_lookup_order = bydns
 spool_directory = TESTSUITE/spool
index dc6209432ddd87ed6972759e76d667e69bc37375..88755665fa1904b867c3938a094889fc2824a629 100644 (file)
@@ -78,6 +78,18 @@ Connection request from [127.0.0.1]
 220 Greetings
 EHLO testhost.test.ex
 250-Hello there
+250 CHUNKING
+MAIL FROM:<>
+250 OK
+RCPT TO:<ebad@test.ex>
+550 sorry, no
+QUIT
+End of script
+Listening on port 1224 ... 
+Connection request from [127.0.0.1]
+220 Greetings
+EHLO testhost.test.ex
+250-Hello there
 250-PIPELINING
 250 CHUNKING
 MAIL FROM:<>
index 2657c47a9131b455a6622a6caaf777a53a867edc..1457c08d24d40f9dbaf469ed19fb6ecd9c52adce 100644 (file)
@@ -5,7 +5,7 @@ dnslookup@mx46.test.ex
 manualroute@test.ex
   router = r2, transport = smtp
   host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
-  host 46.test.ex [V4NET.0.0.4] 
+  host 46.test.ex [V4NET.0.0.4]
 dnslookup@v6.test.ex
   router = r1, transport = smtp
   host v6.test.ex [V6NET:ffff:836f:a00:a:800:200a:c032]
index 673bf0a2f11638f03387caee29795e8e84c4f622..7e86fa1825ce9441e14a6771e08fc96fc848f7ec 100644 (file)
@@ -1,7 +1,7 @@
 x@46.test.ex
   router = r1, transport = t1
   host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
-  host 46.test.ex [V4NET.0.0.4] 
+  host 46.test.ex [V4NET.0.0.4]
 x@mx46.test.ex
   router = r1, transport = t1
   host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031] MX=46
@@ -46,7 +46,7 @@ x@mx46.test.ex
   host 46.test.ex [V4NET.0.0.4] MX=46
 x@mx46.test.ex
   router = r0, transport = t1
-  host 46.test.ex [V4NET.0.0.4] 
+  host 46.test.ex [V4NET.0.0.4]
   host 46.test.ex [V6NET:ffff:836f:a00:a:800:200a:c031]
 x@mx46.test.ex
   router = r0, transport = t1
index 89a34ad4980b1c20413107c74aa04a7f6b688865..12c77344b1b6f5b4d48e25d964b4790610d646b3 100644 (file)
@@ -14,4 +14,4 @@ userx@other1.test.ex
 userx@other99.test.ex cannot be resolved at this time: host non-exist.test.ex not found when translating other99.test.ex [V4NET.99.0.1]
 userx@other99.test.ex
   router = lookuphost, transport = smtp
-  host non-exist.test.ex [unknown] 
+  host non-exist.test.ex [unknown]