diff options
author | Todd Lyons <tlyons@exim.org> | 2014-04-23 05:26:34 -0700 |
---|---|---|
committer | Todd Lyons <tlyons@exim.org> | 2014-04-23 05:26:34 -0700 |
commit | 44649fdb169979af3c5a08b10889d1ecee48a469 (patch) | |
tree | 2e497be61f6055533eede3de61b777e11f7f8e19 | |
parent | f9f6757065aab65e0f8ad1497e11b8c7ab83cd69 (diff) | |
parent | c0c4d23c07e2356baae2bd2c6d72339db117b9e6 (diff) |
Merge branch 'master' of git://git.exim.org/exim
72 files changed, 668 insertions, 196 deletions
diff --git a/doc/doc-docbook/filter.xfpt b/doc/doc-docbook/filter.xfpt index 19ad586c3..8cac5d5c8 100644 --- a/doc/doc-docbook/filter.xfpt +++ b/doc/doc-docbook/filter.xfpt @@ -48,7 +48,7 @@ . Copyright year. Update this (only) when changing content. .macro copyyear -2013 +2014 .endmacro . =========================================================================== diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 86090290b..3542557c4 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -17622,6 +17622,29 @@ when there is a DNS lookup error. +.option dnssec_request_domains dnslookup "domain list&!!" unset +.cindex "MX record" "security" +.cindex "DNSSEC" "MX lookup" +.cindex "security" "MX lookup" +.cindex "DNS" "DNSSEC" +DNS lookups for domains matching &%dnssec_request_domains%& will be done with +the dnssec request bit set. +This applies to all of the SRV, MX A6, AAAA, A lookup sequence. + + + +.option dnssec_require_domains dnslookup "domain list&!!" unset +.cindex "MX record" "security" +.cindex "DNSSEC" "MX lookup" +.cindex "security" "MX lookup" +.cindex "DNS" "DNSSEC" +DNS lookups for domains matching &%dnssec_request_domains%& will be done with +the dnssec request bit set. Any returns not having the Authenticated Data bit +(AD bit) set wil be ignored and logged as a host-lookup failure. +This applies to all of the SRV, MX A6, AAAA, A lookup sequence. + + + .option mx_domains dnslookup "domain list&!!" unset .cindex "MX record" "required to exist" .cindex "SRV record" "required to exist" @@ -34633,9 +34656,13 @@ This utility is a Perl script contributed by Matt Hubbard. It runs .code exim -bpu .endd -to obtain a queue listing with undelivered recipients only, and then greps the -output to select messages that match given criteria. The following selection -options are available: +or (in case &*-a*& switch is specified) +.code +exim -bp +.endd + +to obtain a queue listing, and then greps the output to select messages +that match given criteria. The following selection options are available: .vlist .vitem &*-f*&&~<&'regex'&> @@ -34682,6 +34709,9 @@ Brief format &-- one line per message. .vitem &*-R*& Display messages in reverse order. + +.vitem &*-a*& +Include delivered recipients in queue listing. .endlist There is one more option, &%-h%&, which outputs a list of options. diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index e41dc3e02..6252956a6 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -82,6 +82,12 @@ TL/07 Add new dmarc expansion variable $dmarc_domain_policy to directly is a combined value of both the record presence and the result of the analysis. +JH/13 Fix handling of $tls_cipher et.al. in (non-verify) transport. Bug 1455. + +JH/14 New options dnssec_request_domains, dnssec_require_domains on the + dnslookup router (applying to the forward lookup). + + Exim version 4.82 ----------------- diff --git a/doc/doc-txt/experimental-spec.txt b/doc/doc-txt/experimental-spec.txt index 265e1211b..f21609662 100644 --- a/doc/doc-txt/experimental-spec.txt +++ b/doc/doc-txt/experimental-spec.txt @@ -1087,10 +1087,16 @@ Proxy Protocol server at 192.168.1.2 will look like this: 3. In the ACL's the following expansion variables are available. -proxy_host_address The src IP of the proxy server making the connection -proxy_host_port The src port the proxy server is using -proxy_session Boolean, yes/no, the connected host is required to use - Proxy Protocol. +proxy_host_address The (internal) src IP of the proxy server + making the connection to the Exim server. +proxy_host_port The (internal) src port the proxy server is + using to connect to the Exim server. +proxy_target_address The dest (public) IP of the remote host to + the proxy server. +proxy_target_port The dest port the remote host is using to + connect to the proxy server. +proxy_session Boolean, yes/no, the connected host is required + to use Proxy Protocol. There is no expansion for a failed proxy session, however you can detect it by checking if $proxy_session is true but $proxy_host is empty. As @@ -1110,6 +1116,13 @@ an example, in my connect ACL, I have: [$sender_host_address] through proxy protocol \ host $proxy_host_address + # Possibly more clear + warn logwrite = Remote Source Address: $sender_host_address:$sender_host_port + logwrite = Proxy Target Address: $proxy_target_address:$proxy_target_port + logwrite = Proxy Internal Address: $proxy_host_address:$proxy_host_port + logwrite = Internal Server Address: $received_ip_address:$received_port + + 4. Runtime issues to be aware of: - Since the real connections are all coming from your proxy, and the per host connection tracking is done before Proxy Protocol is diff --git a/src/Makefile b/src/Makefile index 161167f3f..b913aec8a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ # appropriate links, and then creating and running the main makefile in that # directory. -# Copyright (c) University of Cambridge, 1995 - 2013 +# Copyright (c) University of Cambridge, 1995 - 2014 # See the file NOTICE for conditions of use and distribution. # IRIX make uses the shell that is in the SHELL variable, which often defaults @@ -90,7 +90,8 @@ distclean:; $(RM_COMMAND) -rf build-* cscope* cscope.files: FRC echo "-q" > $@ echo "-p3" >> $@ - find src Local -name "*.[cshyl]" -print \ + find src Local OS -name "*.[cshyl]" -print \ + -o -name "os.h*" -print \ -o -name "*akefile*" -print \ -o -name EDITME -print >> $@ diff --git a/src/exim_monitor/em_log.c b/src/exim_monitor/em_log.c index 757936dea..6efd9c0c9 100644 --- a/src/exim_monitor/em_log.c +++ b/src/exim_monitor/em_log.c @@ -2,7 +2,7 @@ * Exim Monitor * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* This module contains code for scanning the main log, diff --git a/src/scripts/Configure-Makefile b/src/scripts/Configure-Makefile index 5e8a72683..eeb26eeb1 100755 --- a/src/scripts/Configure-Makefile +++ b/src/scripts/Configure-Makefile @@ -142,6 +142,10 @@ then fi if [ ".$need_this" != "." ]; then tls_include=`pkg-config --cflags $pc_value` + if [ $? -ne 0 ]; then + echo >&2 "*** Missing pkg-config for package $pc_value (for Exim $var build option)" + exit 1 + fi tls_libs=`pkg-config --libs $pc_value` echo "TLS_INCLUDE=$tls_include" echo "TLS_LIBS=$tls_libs" @@ -161,6 +165,10 @@ then else # main binary cflags=`pkg-config --cflags $pc_value` + if [ $? -ne 0 ]; then + echo >&2 "*** Missing pkg-config for package $pc_value (for Exim $var build option)" + exit 1 + fi libs=`pkg-config --libs $pc_value` if [ "$var" != "${var#LOOKUP_}" ]; then echo "LOOKUP_INCLUDE += $cflags" @@ -178,6 +186,10 @@ then case $PCRE_CONFIG in yes|YES|y|Y) cflags=`pcre-config --cflags` + if [ $? -ne 0 ]; then + echo >&2 "*** Missing pcre-config for regular expression support" + exit 1 + fi libs=`pcre-config --libs` if [ ".$cflags" != "." ]; then echo "INCLUDE += $cflags" @@ -196,6 +208,10 @@ then echo "# End of pkg-config fixups" echo ) >> $mft + subexit=$? + if [ $subexit -ne 0 ]; then + exit $subexit + fi fi rm -f $mftt diff --git a/src/src/acl.c b/src/src/acl.c index 4fda03b77..9d0842c1d 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Code for handling Access Control Lists (ACLs) */ diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index 0f4822745..1874f3238 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru> - * Copyright (c) 2006-2013 The Exim Maintainers + * Copyright (c) 2006-2014 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 diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 962b90d68..6f7295ca1 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* The default settings for Exim configuration variables. A #define without diff --git a/src/src/daemon.c b/src/src/daemon.c index caf494a24..66ed22440 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with running Exim as a daemon */ diff --git a/src/src/deliver.c b/src/src/deliver.c index 121f7c2e0..1e7a8a18a 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* The main code for delivering a message. */ diff --git a/src/src/dmarc.c b/src/src/dmarc.c index 05de69353..b2336b388 100644 --- a/src/src/dmarc.c +++ b/src/src/dmarc.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ /* Experimental DMARC support. - Copyright (c) Todd Lyons <tlyons@exim.org> 2012, 2013 + Copyright (c) Todd Lyons <tlyons@exim.org> 2012 - 2014 License: GPL */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; diff --git a/src/src/dmarc.h b/src/src/dmarc.h index 088d86494..ee78450a6 100644 --- a/src/src/dmarc.h +++ b/src/src/dmarc.h @@ -3,7 +3,7 @@ *************************************************/ /* Experimental DMARC support. - Copyright (c) Todd Lyons <tlyons@exim.org> 2012, 2013 + Copyright (c) Todd Lyons <tlyons@exim.org> 2012 - 2014 License: GPL */ /* Portions Copyright (c) 2012, 2013, The Trusted Domain Project; diff --git a/src/src/dns.c b/src/src/dns.c index 2aeb5af62..6efb88d58 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for interfacing with the DNS. */ @@ -159,12 +159,13 @@ the first time we have been here, and set the resolver options. Arguments: qualify_single TRUE to set the RES_DEFNAMES option search_parents TRUE to set the RES_DNSRCH option + use_dnssec TRUE to set the RES_USE_DNSSEC option Returns: nothing */ void -dns_init(BOOL qualify_single, BOOL search_parents) +dns_init(BOOL qualify_single, BOOL search_parents, BOOL use_dnssec) { res_state resp = os_get_dns_resolver_res(); @@ -206,6 +207,8 @@ if (dns_use_edns0 >= 0) # ifndef RES_USE_EDNS0 # error Have RES_USE_DNSSEC but not RES_USE_EDNS0? Something hinky ... # endif +if (use_dnssec) + resp->options |= RES_USE_DNSSEC; if (dns_dnssec_ok >= 0) { if (dns_use_edns0 == 0 && dns_dnssec_ok != 0) @@ -228,6 +231,9 @@ if (dns_dnssec_ok >= 0) DEBUG(D_resolver) debug_printf("Unable to %sset DNSSEC without resolver support.\n", dns_dnssec_ok ? "" : "un"); +if (use_dnssec) + DEBUG(D_resolver) + debug_printf("Unable to set DNSSEC without resolver support.\n"); # endif #endif /* DISABLE_DNSSEC */ @@ -1249,4 +1255,6 @@ else return yield; } +/* vi: aw ai sw=2 +*/ /* End of dns.c */ diff --git a/src/src/drtables.c b/src/src/drtables.c index d48945e90..c2d866850 100644 --- a/src/src/drtables.c +++ b/src/src/drtables.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/exigrep.src b/src/src/exigrep.src index 7b35da866..2d3b40cbf 100644 --- a/src/src/exigrep.src +++ b/src/src/exigrep.src @@ -2,7 +2,7 @@ use strict; -# Copyright (c) 2007-2013 University of Cambridge. +# Copyright (c) 2007-2014 University of Cambridge. # See the file NOTICE for conditions of use and distribution. # Except when they appear in comments, the following placeholders in this diff --git a/src/src/exim.c b/src/src/exim.c index 1637c891e..3ab657fea 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/exim.h b/src/src/exim.h index c72c1f10a..b824b48f3 100644 --- a/src/src/exim.h +++ b/src/src/exim.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/eximstats.src b/src/src/eximstats.src index 66777c9ee..4370b4eab 100644 --- a/src/src/eximstats.src +++ b/src/src/eximstats.src @@ -1,6 +1,6 @@ #!PERL_COMMAND -w -# Copyright (c) 2001-2013 University of Cambridge. +# Copyright (c) 2001-2014 University of Cambridge. # See the file NOTICE for conditions of use and distribution. # Perl script to generate statistics from one or more Exim log files. diff --git a/src/src/exiqgrep.src b/src/src/exiqgrep.src index e05589073..05c1b9ed0 100644 --- a/src/src/exiqgrep.src +++ b/src/src/exiqgrep.src @@ -43,8 +43,9 @@ if ($^O eq 'darwin') { # aka MacOS X $base = 62; }; -getopts('hf:r:y:o:s:zxlibRc',\%opt); +getopts('hf:r:y:o:s:zxlibRca',\%opt); if ($opt{h}) { &help; exit;} +if ($opt{a}) { $eargs = '-bp'; } # Read message queue output into hash &collect(); @@ -78,6 +79,7 @@ Display options: -i Message IDs only -b Brief Format -R Reverse order + -a All recipients (including delivered) EOF } diff --git a/src/src/expand.c b/src/src/expand.c index d2ac8ca79..fd4f65abb 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -565,6 +565,8 @@ static var_entry var_table[] = { { "proxy_host_address", vtype_stringptr, &proxy_host_address }, { "proxy_host_port", vtype_int, &proxy_host_port }, { "proxy_session", vtype_bool, &proxy_session }, + { "proxy_target_address",vtype_stringptr, &proxy_target_address }, + { "proxy_target_port", vtype_int, &proxy_target_port }, #endif { "prvscheck_address", vtype_stringptr, &prvscheck_address }, { "prvscheck_keynum", vtype_stringptr, &prvscheck_keynum }, diff --git a/src/src/functions.h b/src/src/functions.h index 35500a165..599afd206 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -45,7 +45,7 @@ extern void tls_version_report(FILE *); #ifndef USE_GNUTLS extern BOOL tls_openssl_options_parse(uschar *, long *); #endif -#endif +#endif /*SUPPORT_TLS*/ /* Everything else... */ @@ -115,7 +115,7 @@ extern BOOL dkim_transport_write_message(address_item *, int, int, #endif extern dns_address *dns_address_from_rr(dns_answer *, dns_record *); extern void dns_build_reverse(uschar *, uschar *); -extern void dns_init(BOOL, BOOL); +extern void dns_init(BOOL, BOOL, BOOL); extern int dns_basic_lookup(dns_answer *, uschar *, int); extern BOOL dns_is_secure(dns_answer *); extern int dns_lookup(dns_answer *, uschar *, int, uschar **); @@ -157,7 +157,7 @@ extern void host_build_log_info(void); extern void host_build_sender_fullhost(void); extern BOOL host_find_byname(host_item *, uschar *, int, uschar **, BOOL); extern int host_find_bydns(host_item *, uschar *, int, uschar *, uschar *, - uschar *,uschar **, BOOL *); + uschar *, uschar *, uschar *, uschar **, BOOL *); extern ip_address_item *host_find_interfaces(void); extern BOOL host_is_in_net(uschar *, uschar *, int); extern BOOL host_is_tls_on_connect_port(int); @@ -374,6 +374,7 @@ extern int strncmpic(const uschar *, const uschar *, int); extern uschar *strstric(uschar *, uschar *, BOOL); extern uschar *tod_stamp(int); +extern void tls_modify_variables(tls_support *); extern BOOL transport_check_waiting(uschar *, uschar *, int, uschar *, BOOL *); extern void transport_init(void); diff --git a/src/src/globals.c b/src/src/globals.c index 839b91dcc..fbc3787f9 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* All the global variables are defined together in this one module, so @@ -925,6 +925,8 @@ int proxy_host_port = 0; uschar *proxy_required_hosts = US""; BOOL proxy_session = FALSE; BOOL proxy_session_failed = FALSE; +uschar *proxy_target_address = US""; +int proxy_target_port = 0; #endif uschar *prvscheck_address = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 1cc39fc09..e18bddc01 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Almost all the global variables are defined together in this one header, so @@ -595,11 +595,13 @@ extern uschar *process_log_path; /* Alternate path */ extern BOOL prod_requires_admin; /* TRUE if prodding requires admin */ #ifdef EXPERIMENTAL_PROXY -extern uschar *proxy_host_address; /* IP of proxy server */ -extern int proxy_host_port; /* Port of proxy server */ +extern uschar *proxy_host_address; /* IP of host being proxied */ +extern int proxy_host_port; /* Port of host being proxied */ extern uschar *proxy_required_hosts; /* Hostlist which (require) use proxy protocol */ extern BOOL proxy_session; /* TRUE if receiving mail from valid proxy */ extern BOOL proxy_session_failed; /* TRUE if required proxy negotiation failed */ +extern uschar *proxy_target_address; /* IP of proxy server inbound */ +extern int proxy_target_port; /* Port of proxy server inbound */ #endif extern uschar *prvscheck_address; /* Set during prvscheck expansion item */ diff --git a/src/src/host.c b/src/src/host.c index 785eea412..495a44d58 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -1622,7 +1622,7 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) { if (strcmpic(ordername, US"bydns") == 0) { - dns_init(FALSE, FALSE); + dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */ dns_build_reverse(sender_host_address, buffer); rc = dns_lookup(&dnsa, buffer, T_PTR, NULL); @@ -1919,7 +1919,8 @@ if (running_in_test_harness) some circumstances when the get..byname() function actually calls the DNS. */ dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0, - (flags & HOST_FIND_SEARCH_PARENTS) != 0); + (flags & HOST_FIND_SEARCH_PARENTS) != 0, + FALSE); /*XXX dnssec? */ /* In an IPv6 world, unless IPv6 has been disabled, we need to scan for both kinds of address, so go round the loop twice. Note that we have ensured that @@ -2195,6 +2196,7 @@ Arguments: fully_qualified_name if not NULL, return fully qualified name here if the contents are different (i.e. it must be preset to something) + dnnssec_require if TRUE check the DNS result AD bit Returns: HOST_FIND_FAILED couldn't find A record HOST_FIND_AGAIN try again later @@ -2204,7 +2206,8 @@ Returns: HOST_FIND_FAILED couldn't find A record static int set_address_from_dns(host_item *host, host_item **lastptr, - uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name) + uschar *ignore_target_hosts, BOOL allow_ip, uschar **fully_qualified_name, + BOOL dnssec_require) { dns_record *rr; host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ @@ -2287,6 +2290,12 @@ for (; i >= 0; i--) if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE; continue; } + if (dnssec_require && !dns_is_secure(&dnsa)) + { + log_write(L_host_lookup_failed, LOG_MAIN, "dnssec fail on %s for %.256s", + i>1 ? "A6" : i>0 ? "AAAA" : "A", host->name); + continue; + } /* Lookup succeeded: fill in the given host item with the first non-ignored address found; create additional items for any others. A single A6 record @@ -2433,6 +2442,8 @@ Arguments: srv_service when SRV used, the service name srv_fail_domains DNS errors for these domains => assume nonexist mx_fail_domains DNS errors for these domains => assume nonexist + dnssec_request_domains => make dnssec request + dnssec_require_domains => ditto and nonexist failures fully_qualified_name if not NULL, return fully-qualified name removed set TRUE if local host was removed from the list @@ -2450,6 +2461,7 @@ Returns: HOST_FIND_FAILED Failed to find the host or domain; int host_find_bydns(host_item *host, uschar *ignore_target_hosts, int whichrrs, uschar *srv_service, uschar *srv_fail_domains, uschar *mx_fail_domains, + uschar *dnssec_request_domains, uschar *dnssec_require_domains, uschar **fully_qualified_name, BOOL *removed) { host_item *h, *last; @@ -2459,6 +2471,10 @@ int ind_type = 0; int yield; dns_answer dnsa; dns_scan dnss; +BOOL dnssec_request = match_isinlist(host->name, &dnssec_request_domains, + 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; +BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains, + 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK; /* Set the default fully qualified name to the incoming name, initialize the resolver if necessary, set up the relevant options, and initialize the flag @@ -2466,7 +2482,9 @@ that gets set for DNS syntax check errors. */ if (fully_qualified_name != NULL) *fully_qualified_name = host->name; dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0, - (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0); + (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0, + dnssec_request || dnssec_require + ); host_find_failed_syntax = FALSE; /* First, if requested, look for SRV records. The service name is given; we @@ -2494,13 +2512,19 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0) /* On DNS failures, we give the "try again" error unless the domain is listed as one for which we continue. */ + if (rc == DNS_SUCCEED && dnssec_require && !dns_is_secure(&dnsa)) + { + log_write(L_host_lookup_failed, LOG_MAIN, + "dnssec fail on SRV for %.256s", host->name); + rc = DNS_FAIL; + } if (rc == DNS_FAIL || rc == DNS_AGAIN) { #ifndef STAND_ALONE if (match_isinlist(host->name, &srv_fail_domains, 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) != OK) #endif - return HOST_FIND_AGAIN; + { yield = HOST_FIND_AGAIN; goto out; } DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA " "(domain in srv_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN"); } @@ -2517,16 +2541,29 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) { ind_type = T_MX; rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name); - if (rc == DNS_NOMATCH) return HOST_FIND_FAILED; - if (rc == DNS_FAIL || rc == DNS_AGAIN) - { - #ifndef STAND_ALONE - if (match_isinlist(host->name, &mx_fail_domains, 0, NULL, NULL, MCL_DOMAIN, - TRUE, NULL) != OK) - #endif - return HOST_FIND_AGAIN; - DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA " - "(domain in mx_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN"); + switch (rc) + { + case DNS_NOMATCH: + yield = HOST_FIND_FAILED; goto out; + + case DNS_SUCCEED: + if (!dnssec_require || dns_is_secure(&dnsa)) + break; + log_write(L_host_lookup_failed, LOG_MAIN, + "dnssec fail on MX for %.256s", host->name); + rc = DNS_FAIL; + /*FALLTRHOUGH*/ + + case DNS_FAIL: + case DNS_AGAIN: + #ifndef STAND_ALONE + if (match_isinlist(host->name, &mx_fail_domains, 0, NULL, NULL, MCL_DOMAIN, + TRUE, NULL) != OK) + #endif + { yield = HOST_FIND_AGAIN; goto out; } + DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA " + "(domain in mx_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN"); + break; } } @@ -2539,14 +2576,15 @@ if (rc != DNS_SUCCEED) if ((whichrrs & HOST_FIND_BY_A) == 0) { DEBUG(D_host_lookup) debug_printf("Address records are not being sought\n"); - return HOST_FIND_FAILED; + yield = HOST_FIND_FAILED; + goto out; } last = host; /* End of local chainlet */ host->mx = MX_NONE; host->port = PORT_NONE; rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE, - fully_qualified_name); + fully_qualified_name, dnssec_require); /* If one or more address records have been found, check that none of them are local. Since we know the host items all have their IP addresses @@ -2573,7 +2611,8 @@ if (rc != DNS_SUCCEED) } } - return rc; + yield = rc; + goto out; } /* We have found one or more MX or SRV records. Sort them according to @@ -2757,7 +2796,8 @@ if (ind_type == T_SRV) if (host == last && host->name[0] == 0) { DEBUG(D_host_lookup) debug_printf("the single SRV record is \".\"\n"); - return HOST_FIND_FAILED; + yield = HOST_FIND_FAILED; + goto out; } DEBUG(D_host_lookup) @@ -2867,12 +2907,14 @@ otherwise invalid host names obtained from MX or SRV records can cause trouble if they happen to match something local. */ yield = HOST_FIND_FAILED; /* Default yield */ -dns_init(FALSE, FALSE); /* Disable qualify_single and search_parents */ +dns_init(FALSE, FALSE, /* Disable qualify_single and search_parents */ + dnssec_request || dnssec_require); for (h = host; h != last->next; h = h->next) { if (h->address != NULL) continue; /* Inserted by a multihomed host */ - rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, NULL); + rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, + NULL, dnssec_require); if (rc != HOST_FOUND) { h->status = hstatus_unusable; @@ -2981,6 +3023,9 @@ DEBUG(D_host_lookup) } } +out: + +dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */ return yield; } @@ -3002,6 +3047,8 @@ int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A; BOOL byname = FALSE; BOOL qualify_single = TRUE; BOOL search_parents = FALSE; +BOOL request_dnssec = FALSE; +BOOL require_dnssec = FALSE; uschar **argv = USS cargv; uschar buffer[256]; @@ -3021,7 +3068,7 @@ if (argc > 1) primary_hostname = argv[1]; /* So that debug level changes can be done first */ -dns_init(qualify_single, search_parents); +dns_init(qualify_single, search_parents, FALSE); printf("Testing host lookup\n"); printf("> "); @@ -3047,10 +3094,14 @@ while (Ufgets(buffer, 256, stdin) != NULL) whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX; else if (Ustrcmp(buffer, "srv+mx+a") == 0) whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A; - else if (Ustrcmp(buffer, "qualify_single") == 0) qualify_single = TRUE; + else if (Ustrcmp(buffer, "qualify_single") == 0) qualify_single = TRUE; else if (Ustrcmp(buffer, "no_qualify_single") == 0) qualify_single = FALSE; - else if (Ustrcmp(buffer, "search_parents") == 0) search_parents = TRUE; + else if (Ustrcmp(buffer, "search_parents") == 0) search_parents = TRUE; else if (Ustrcmp(buffer, "no_search_parents") == 0) search_parents = FALSE; + else if (Ustrcmp(buffer, "request_dnssec") == 0) request_dnssec = TRUE; + else if (Ustrcmp(buffer, "no_request_dnssec") == 0) request_dnssec = FALSE; + else if (Ustrcmp(buffer, "require_dnssec") == 0) require_dnssec = TRUE; + else if (Ustrcmp(buffer, "no_reqiret_dnssec") == 0) require_dnssec = FALSE; else if (Ustrcmp(buffer, "test_harness") == 0) running_in_test_harness = !running_in_test_harness; else if (Ustrcmp(buffer, "ipv6") == 0) disable_ipv6 = !disable_ipv6; @@ -3083,11 +3134,12 @@ while (Ufgets(buffer, 256, stdin) != NULL) if (qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE; if (search_parents) flags |= HOST_FIND_SEARCH_PARENTS; - rc = byname? - host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE) - : - host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL, - &fully_qualified_name, NULL); + rc = byname + ? host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE) + : host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL, + request_dnssec ? &h.name : NULL, + require_dnssec ? &h.name : NULL, + &fully_qualified_name, NULL); if (rc == HOST_FIND_FAILED) printf("Failed\n"); else if (rc == HOST_FIND_AGAIN) printf("Again\n"); @@ -3146,4 +3198,6 @@ return 0; } #endif /* STAND_ALONE */ +/* vi: aw ai sw=2 +*/ /* End of host.c */ diff --git a/src/src/ip.c b/src/src/ip.c index a820998ca..0211adc1e 100644 --- a/src/src/ip.c +++ b/src/src/ip.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for doing things with sockets. With the advent of IPv6 this has diff --git a/src/src/log.c b/src/src/log.c index 1a5d38866..c80c34751 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for writing log files. The code for maintaining datestamped diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index beba09508..a1eb2b658 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -241,7 +241,7 @@ if ((equals = Ustrchr(keystring, '=')) != NULL) /* Initialize the resolver in case this is the first time it has been used. */ -dns_init(FALSE, FALSE); +dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */ /* The remainder of the string must be a list of domains. As long as the lookup for at least one of them succeeds, we return success. Failure means that none diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index 7071dc259..27780db49 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Many thanks to Stuart Lynne for contributing the original code for this diff --git a/src/src/macros.h b/src/src/macros.h index 3f3810127..fc3776c84 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/malware.c b/src/src/malware.c index 01209d684..7b3453f72 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-2013 */ +/* Copyright (c) Tom Kistner <tom@duncanthrax.net> 2003-2014 */ /* License: GPL */ /* Code for calling virus (malware) scanners. Called from acl.c. */ diff --git a/src/src/match.c b/src/src/match.c index 66ae3dddb..97a098205 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -221,6 +221,8 @@ if (cb->at_is_special && pattern[0] == '@') NULL, /* service name not relevant */ NULL, /* srv_fail_domains not relevant */ NULL, /* mx_fail_domains not relevant */ + NULL, /* no dnssec request XXX ? */ + NULL, /* no dnssec require XXX ? */ NULL, /* no feedback FQDN */ &removed); /* feedback if local removed */ diff --git a/src/src/moan.c b/src/src/moan.c index 5ae6f85f7..4d7b51b9a 100644 --- a/src/src/moan.c +++ b/src/src/moan.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for sending messages to sender or to mailmaster. */ diff --git a/src/src/readconf.c b/src/src/readconf.c index 81e3bc267..a0238d25f 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for reading the configuration file, and for displaying diff --git a/src/src/route.c b/src/src/route.c index c83233e97..271175e4b 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with routing, and the list of generic router options. */ diff --git a/src/src/routers/dnslookup.c b/src/src/routers/dnslookup.c index 057a2a15d..c8fd3f991 100644 --- a/src/src/routers/dnslookup.c +++ b/src/src/routers/dnslookup.c @@ -18,6 +18,10 @@ optionlist dnslookup_router_options[] = { (void *)(offsetof(dnslookup_router_options_block, check_secondary_mx)) }, { "check_srv", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, check_srv)) }, + { "dnssec_request_domains", opt_stringptr, + (void *)(offsetof(dnslookup_router_options_block, dnssec_request_domains)) }, + { "dnssec_require_domains", opt_stringptr, + (void *)(offsetof(dnslookup_router_options_block, dnssec_require_domains)) }, { "mx_domains", opt_stringptr, (void *)(offsetof(dnslookup_router_options_block, mx_domains)) }, { "mx_fail_domains", opt_stringptr, @@ -53,7 +57,9 @@ dnslookup_router_options_block dnslookup_router_option_defaults = { NULL, /* mx_domains */ NULL, /* mx_fail_domains */ NULL, /* srv_fail_domains */ - NULL /* check_srv */ + NULL, /* check_srv */ + NULL, /* dnssec_request_domains */ + NULL /* dnssec_require_domains */ }; @@ -261,7 +267,9 @@ for (;;) } rc = host_find_bydns(&h, rblock->ignore_target_hosts, flags, srv_service, - ob->srv_fail_domains, ob->mx_fail_domains, &fully_qualified_name, &removed); + ob->srv_fail_domains, ob->mx_fail_domains, + ob->dnssec_request_domains, ob->dnssec_require_domains, + &fully_qualified_name, &removed); if (removed) setflag(addr, af_local_host_removed); /* If host found with only address records, test for the domain's being in diff --git a/src/src/routers/dnslookup.h b/src/src/routers/dnslookup.h index b0c384367..518b7f478 100644 --- a/src/src/routers/dnslookup.h +++ b/src/src/routers/dnslookup.h @@ -17,6 +17,8 @@ typedef struct { uschar *mx_fail_domains; uschar *srv_fail_domains; uschar *check_srv; + uschar *dnssec_request_domains; + uschar *dnssec_require_domains; } dnslookup_router_options_block; /* Data for reading the private options. */ diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c index c44ba70b8..a4a13b04f 100644 --- a/src/src/routers/rf_get_munge_headers.c +++ b/src/src/routers/rf_get_munge_headers.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" diff --git a/src/src/routers/rf_lookup_hostlist.c b/src/src/routers/rf_lookup_hostlist.c index eadcd5df7..0eae31e61 100644 --- a/src/src/routers/rf_lookup_hostlist.c +++ b/src/src/routers/rf_lookup_hostlist.c @@ -94,6 +94,8 @@ for (h = addr->host_list; h != NULL; h = next_h) NULL, /* SRV service not relevant */ NULL, /* failing srv domains not relevant */ NULL, /* no special mx failing domains */ + NULL, /* no dnssec request XXX ? */ + NULL, /* no dnssec require XXX ? */ NULL, /* fully_qualified_name */ NULL); /* indicate local host removed */ } @@ -117,7 +119,9 @@ for (h = addr->host_list; h != NULL; h = next_h) BOOL removed; DEBUG(D_route|D_host_lookup) debug_printf("doing DNS lookup\n"); rc = host_find_bydns(h, ignore_target_hosts, HOST_FIND_BY_A, NULL, NULL, - NULL, &canonical_name, &removed); + NULL, + NULL, NULL, /*XXX dnssec? */ + &canonical_name, &removed); if (rc == HOST_FOUND) { if (removed) setflag(addr, af_local_host_removed); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index fbfe1ed7b..27ff13785 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for handling an incoming SMTP call. */ @@ -603,22 +603,6 @@ return proxy_session; /************************************************* -* Flush waiting input string * -*************************************************/ -static void -flush_input() -{ -int rc; - -rc = smtp_getc(); -while (rc != '\n') /* End of input string */ - { - rc = smtp_getc(); - } -} - - -/************************************************* * Setup host for proxy protocol * *************************************************/ /* The function configures the connection based on a header from the @@ -664,12 +648,18 @@ union { } v2; } hdr; +/* Temp variables used in PPv2 address:port parsing */ +uint16_t tmpport; +char tmpip[INET_ADDRSTRLEN]; +struct sockaddr_in tmpaddr; +char tmpip6[INET6_ADDRSTRLEN]; +struct sockaddr_in6 tmpaddr6; + +int get_ok = 0; int size, ret, fd; -uschar *tmpip; const char v2sig[13] = "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02"; uschar *iptype; /* To display debug info */ struct timeval tv; -int get_ok = 0; socklen_t vslen = 0; struct timeval tvtmp; @@ -690,7 +680,9 @@ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, do { - ret = recv(fd, &hdr, sizeof(hdr), MSG_PEEK); + /* The inbound host was declared to be a Proxy Protocol host, so + don't do a PEEK into the data, actually slurp it up. */ + ret = recv(fd, &hdr, sizeof(hdr), 0); } while (ret == -1 && errno == EINTR); @@ -715,20 +707,63 @@ if (ret >= 16 && case 0x01: /* PROXY command */ switch (hdr.v2.fam) { - case 0x11: /* TCPv4 */ - tmpip = string_sprintf("%s", hdr.v2.addr.ip4.src_addr); - if (!string_is_ip_address(tmpip,NULL)) + case 0x11: /* TCPv4 address type */ + iptype = US"IPv4"; + tmpaddr.sin_addr.s_addr = hdr.v2.addr.ip4.src_addr; + inet_ntop(AF_INET, &(tmpaddr.sin_addr), (char *)&tmpip, sizeof(tmpip)); + if (!string_is_ip_address(US tmpip,NULL)) + { + DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype); return ERRNO_PROXYFAIL; - sender_host_address = tmpip; - sender_host_port = hdr.v2.addr.ip4.src_port; + } + proxy_host_address = sender_host_address; + sender_host_address = string_copy(US tmpip); + tmpport = ntohs(hdr.v2.addr.ip4.src_port); + proxy_host_port = sender_host_port; + sender_host_port = tmpport; + /* Save dest ip/port */ + tmpaddr.sin_addr.s_addr = hdr.v2.addr.ip4.dst_addr; + inet_ntop(AF_INET, &(tmpaddr.sin_addr), (char *)&tmpip, sizeof(tmpip)); + if (!string_is_ip_address(US tmpip,NULL)) + { + DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype); + return ERRNO_PROXYFAIL; + } + proxy_target_address = string_copy(US tmpip); + tmpport = ntohs(hdr.v2.addr.ip4.dst_port); + proxy_target_port = tmpport; goto done; - case 0x21: /* TCPv6 */ - tmpip = string_sprintf("%s", hdr.v2.addr.ip6.src_addr); - if (!string_is_ip_address(tmpip,NULL)) + case 0x21: /* TCPv6 address type */ + iptype = US"IPv6"; + memmove(tmpaddr6.sin6_addr.s6_addr, hdr.v2.addr.ip6.src_addr, 16); + inet_ntop(AF_INET6, &(tmpaddr6.sin6_addr), (char *)&tmpip6, sizeof(tmpip6)); + if (!string_is_ip_address(US tmpip6,NULL)) + { + DEBUG(D_receive) debug_printf("Invalid %s source IP\n", iptype); return ERRNO_PROXYFAIL; - sender_host_address = tmpip; - sender_host_port = hdr.v2.addr.ip6.src_port; + } + proxy_host_address = sender_host_address; + sender_host_address = string_copy(US tmpip6); + tmpport = ntohs(hdr.v2.addr.ip6.src_port); + proxy_host_port = sender_host_port; + sender_host_port = tmpport; + /* Save dest ip/port */ + memmove(tmpaddr6.sin6_addr.s6_addr, hdr.v2.addr.ip6.dst_addr, 16); + inet_ntop(AF_INET6, &(tmpaddr6.sin6_addr), (char *)&tmpip6, sizeof(tmpip6)); + if (!string_is_ip_address(US tmpip6,NULL)) + { + DEBUG(D_receive) debug_printf("Invalid %s dest port\n", iptype); + return ERRNO_PROXYFAIL; + } + proxy_target_address = string_copy(US tmpip6); + tmpport = ntohs(hdr.v2.addr.ip6.dst_port); + proxy_target_port = tmpport; goto done; + default: + DEBUG(D_receive) + debug_printf("Unsupported PROXYv2 connection type: 0x%02x\n", + hdr.v2.fam); + goto proxyfail; } /* Unsupported protocol, keep local connection address */ break; @@ -736,7 +771,9 @@ if (ret >= 16 && /* Keep local connection address for LOCAL */ break; default: - DEBUG(D_receive) debug_printf("Unsupported PROXYv2 command\n"); + DEBUG(D_receive) + debug_printf("Unsupported PROXYv2 command: 0x%02x\n", + hdr.v2.cmd); goto proxyfail; } } @@ -816,7 +853,7 @@ else if (ret >= 8 && debug_printf("Proxy dest arg is not an %s address\n", iptype); goto proxyfail; } - /* Should save dest ip somewhere? */ + proxy_target_address = p; p = sp + 1; if ((sp = Ustrchr(p, ' ')) == NULL) { @@ -846,29 +883,27 @@ else if (ret >= 8 && debug_printf("Proxy dest port '%s' not an integer\n", p); goto proxyfail; } - /* Should save dest port somewhere? */ + proxy_target_port = tmp_port; /* Already checked for /r /n above. Good V1 header received. */ goto done; } else { /* Wrong protocol */ - DEBUG(D_receive) debug_printf("Wrong proxy protocol specified\n"); + DEBUG(D_receive) debug_printf("Invalid proxy protocol version negotiation\n"); goto proxyfail; } proxyfail: restore_socket_timeout(fd, get_ok, tvtmp, vslen); /* Don't flush any potential buffer contents. Any input should cause a -synchronization failure or we just don't want to speak SMTP to them */ + synchronization failure */ return FALSE; done: restore_socket_timeout(fd, get_ok, tvtmp, vslen); -flush_input(); DEBUG(D_receive) - debug_printf("Valid %s sender from Proxy Protocol header\n", - iptype); + debug_printf("Valid %s sender from Proxy Protocol header\n", iptype); return proxy_session; } #endif @@ -1164,6 +1199,15 @@ return string_sprintf("SMTP connection from %s", hostname); #ifdef SUPPORT_TLS +/* Append TLS-related information to a log line + +Arguments: + s String under construction: allocated string to extend, or NULL + sizep Pointer to current allocation size (update on return), or NULL + ptrp Pointer to index for new entries in string (update on return), or NULL + +Returns: Allocated string or NULL +*/ static uschar * s_tlslog(uschar * s, int * sizep, int * ptrp) { @@ -1189,8 +1233,6 @@ s_tlslog(uschar * s, int * sizep, int * ptrp) if (sizep) *sizep = size; if (ptrp) *ptrp = ptr; } - else - s = US""; return s; } #endif @@ -2715,14 +2757,17 @@ the connection is not forcibly to be dropped, return 0. Otherwise, log why it is closing if required and return 2. */ if (log_reject_target != 0) - log_write(0, log_reject_target, "%s%s %s%srejected %s%s", - host_and_ident(TRUE), + { #ifdef SUPPORT_TLS - s_tlslog(NULL, NULL, NULL), + uschar * s = s_tlslog(NULL, NULL, NULL); + if (!s) s = US""; #else - "", + uschar * s = US""; #endif + log_write(0, log_reject_target, "%s%s %s%srejected %s%s", + host_and_ident(TRUE), s, sender_info, (rc == FAIL)? US"" : US"temporarily ", what, log_msg); + } if (!drop) return 0; diff --git a/src/src/spf.c b/src/src/spf.c index 0f215e3b5..7167f5778 100644 --- a/src/src/spf.c +++ b/src/src/spf.c @@ -3,7 +3,7 @@ *************************************************/ /* Experimental SPF support. - Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 + Copyright (c) Tom Kistner <tom@duncanthrax.net> 2004 - 2014 License: GPL */ /* Code for calling spf checks via libspf-alt. Called from acl.c. */ diff --git a/src/src/string.c b/src/src/string.c index eb73fae3e..365eaec03 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2012 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Miscellaneous string-handling functions. Some are not required for diff --git a/src/src/structs.h b/src/src/structs.h index b89d2cad3..eb430851d 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index 5600d6bb8..cbd44d6f2 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Copyright (c) Phil Pennock 2012 */ @@ -1228,25 +1228,23 @@ unsigned int verify; *error = NULL; -rc = peer_status(state); -if (rc != OK) +if ((rc = peer_status(state)) != OK) { verify = GNUTLS_CERT_INVALID; - *error = "not supplied"; + *error = "certificate not supplied"; } else - { rc = gnutls_certificate_verify_peers2(state->session, &verify); - } /* Handle the result of verification. INVALID seems to be set as well as REVOKED, but leave the test for both. */ -if ((rc < 0) || (verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) != 0) +if (rc < 0 || verify & (GNUTLS_CERT_INVALID|GNUTLS_CERT_REVOKED)) { state->peer_cert_verified = FALSE; - if (*error == NULL) - *error = ((verify & GNUTLS_CERT_REVOKED) != 0) ? "revoked" : "invalid"; + if (!*error) + *error = verify & GNUTLS_CERT_REVOKED + ? "certificate revoked" : "certificate invalid"; DEBUG(D_tls) debug_printf("TLS certificate verification failed (%s): peerdn=%s\n", diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index a64f85dea..bdf910acc 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Portions Copyright (c) The OpenSSL Project 1999 */ @@ -1923,6 +1923,11 @@ one version of OpenSSL but the run-time linker picks up another version, it can result in serious failures, including crashing with a SIGSEGV. So report the version found by the compiler and the run-time version. +Note: some OS vendors backport security fixes without changing the version +number/string, and the version date remains unchanged. The _build_ date +will change, so we can more usefully assist with version diagnosis by also +reporting the build date. + Arguments: a FILE* to print the results to Returns: nothing */ @@ -1931,9 +1936,13 @@ void tls_version_report(FILE *f) { fprintf(f, "Library version: OpenSSL: Compile: %s\n" - " Runtime: %s\n", + " Runtime: %s\n" + " : %s\n", OPENSSL_VERSION_TEXT, - SSLeay_version(SSLEAY_VERSION)); + SSLeay_version(SSLEAY_VERSION), + SSLeay_version(SSLEAY_BUILT_ON)); +/* third line is 38 characters for the %s and the line is 73 chars long; +the OpenSSL output includes a "built on: " prefix already. */ } diff --git a/src/src/tls.c b/src/src/tls.c index 0625c48b8..972785284 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -181,4 +181,16 @@ return ssl_xfer_buffer_lwm < ssl_xfer_buffer_hwm; #endif /* SUPPORT_TLS */ +void +tls_modify_variables(tls_support * dest_tsp) +{ +modify_variable(US"tls_bits", &dest_tsp->bits); +modify_variable(US"tls_certificate_verified", &dest_tsp->certificate_verified); +modify_variable(US"tls_cipher", &dest_tsp->cipher); +modify_variable(US"tls_peerdn", &dest_tsp->peerdn); +#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS) +modify_variable(US"tls_sni", &dest_tsp->sni); +#endif +} + /* End of tls.c */ diff --git a/src/src/transport.c b/src/src/transport.c index d4495393b..92de4b92b 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* General functions concerned with transportation, and generic options for all diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index 7a1e7c471..84bbeb939 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index ceb24b891..3366a6dcf 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ diff --git a/src/src/transports/pipe.h b/src/src/transports/pipe.h index 6417361ca..ed5c142b3 100644 --- a/src/src/transports/pipe.h +++ b/src/src/transports/pipe.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Private structure for the private options. */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 938844799..57b66b881 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -1213,13 +1213,6 @@ outblock.authenticating = FALSE; /* Reset the parameters of a TLS session. */ -tls_in.bits = 0; -tls_in.cipher = NULL; /* for back-compatible behaviour */ -tls_in.peerdn = NULL; -#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS) -tls_in.sni = NULL; -#endif - tls_out.bits = 0; tls_out.cipher = NULL; /* the one we may use for this transport */ tls_out.peerdn = NULL; @@ -1227,6 +1220,12 @@ tls_out.peerdn = NULL; tls_out.sni = NULL; #endif +/* Flip the legacy TLS-related variables over to the outbound set in case +they're used in the context of the transport. Don't bother resetting +afterward as we're in a subprocess. */ + +tls_modify_variables(&tls_out); + #ifndef SUPPORT_TLS if (smtps) { @@ -2817,6 +2816,7 @@ for (cutoff_retry = 0; expired && rc = host_find_byname(host, NULL, flags, &canonical_name, TRUE); else rc = host_find_bydns(host, NULL, flags, NULL, NULL, NULL, + NULL, NULL, /*XXX todo: smtp tpt hosts_require_dnssec */ &canonical_name, NULL); /* Update the host (and any additional blocks, resulting from diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index fc4e014c1..6d33802ab 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2013 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Private structure for the private options and other private data. */ diff --git a/src/src/verify.c b/src/src/verify.c index 8cc67f1b1..f799ff1de 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1576,13 +1576,7 @@ if (address[0] == 0) return OK; they're used in the context of a transport used by verification. Reset them at exit from this routine. */ -modify_variable(US"tls_bits", &tls_out.bits); -modify_variable(US"tls_certificate_verified", &tls_out.certificate_verified); -modify_variable(US"tls_cipher", &tls_out.cipher); -modify_variable(US"tls_peerdn", &tls_out.peerdn); -#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS) -modify_variable(US"tls_sni", &tls_out.sni); -#endif +tls_modify_variables(&tls_out); /* Save a copy of the sender address for re-instating if we change it to <> while verifying a sender address (a nice bit of self-reference there). */ @@ -1756,6 +1750,7 @@ while (addr_new != NULL) (void)host_find_byname(host, NULL, flags, &canonical_name, TRUE); else (void)host_find_bydns(host, NULL, flags, NULL, NULL, NULL, + NULL, NULL, /*XXX todo: dnssec */ &canonical_name, NULL); } } @@ -2041,14 +2036,7 @@ for (addr_list = addr_local, i = 0; i < 2; addr_list = addr_remote, i++) the -bv or -bt case). */ out: - -modify_variable(US"tls_bits", &tls_in.bits); -modify_variable(US"tls_certificate_verified", &tls_in.certificate_verified); -modify_variable(US"tls_cipher", &tls_in.cipher); -modify_variable(US"tls_peerdn", &tls_in.peerdn); -#if defined(SUPPORT_TLS) && !defined(USE_GNUTLS) -modify_variable(US"tls_sni", &tls_in.sni); -#endif +tls_modify_variables(&tls_in); return yield; } @@ -3559,7 +3547,7 @@ revadd[0] = 0; /* In case this is the first time the DNS resolver is being used. */ -dns_init(FALSE, FALSE); +dns_init(FALSE, FALSE, FALSE); /*XXX dnssec? */ /* Loop through all the domains supplied, until something matches */ diff --git a/src/util/proxy_protocol_client.pl b/src/util/proxy_protocol_client.pl new file mode 100644 index 000000000..7cfc13ddc --- /dev/null +++ b/src/util/proxy_protocol_client.pl @@ -0,0 +1,250 @@ +#!/usr/bin/perl +# +# Copyright (C) 2014 Todd Lyons +# License GPLv2: GNU GPL version 2 +# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html> +# +# This script emulates a proxy which uses Proxy Protocol to communicate +# to a backend server. It should be run from an IP which is configured +# to be a Proxy Protocol connection (or not, if you are testing error +# scenarios) because Proxy Protocol specs require not to fall back to a +# non-proxied mode. +# +# The script is interactive, so when you run it, you are expected to +# perform whatever conversation is required for the protocol being +# tested. It uses STDIN/STDOUT, so you can also pipe output to/from the +# script. It was originally written to test Exim's Proxy Protocol +# code, and it could be tested like this: +# +# swaks --pipe 'perl proxy_protocol_client.pl --server-ip +# host.internal.lan' --from user@example.com --to user@example.net +# +use strict; +use warnings; +use IO::Select; +use IO::Socket; +use Getopt::Long; +use Data::Dumper; + +my %opts; +GetOptions( \%opts, + 'help', + '6|ipv6', + 'dest-ip:s', + 'dest-port:i', + 'source-ip:s', + 'source-port:i', + 'server-ip:s', + 'server-port:i', + 'version:i' +); +&usage() if ($opts{help} || !$opts{'server-ip'}); + +my ($dest_ip,$source_ip,$dest_port,$source_port); +my %socket_map; +my $status_line = "Testing Proxy Protocol Version " . + ($opts{version} ? $opts{version} : '2') . + ":\n"; + +# All ip's and ports are in network byte order in version 2 mode, but are +# simple strings when in version 1 mode. The binary_pack_*() functions +# return the required data for the Proxy Protocol version being used. + +# Use provided source or fall back to www.mrball.net +$source_ip = $opts{'source-ip'} ? binary_pack_ip($opts{'source-ip'}) : + $opts{6} ? + binary_pack_ip("2001:470:d:367::50") : + binary_pack_ip("208.89.139.252"); +$source_port = $opts{'source-port'} ? + binary_pack_port($opts{'source-port'}) : + binary_pack_port(43118); + +$status_line .= "-> " if (!$opts{version} || $opts{version} == 2); + +# Use provided dest or fall back to mail.exim.org +$dest_ip = $opts{'dest-ip'} ? binary_pack_ip($opts{'dest-ip'}) : + $opts{6} ? + binary_pack_ip("2001:630:212:8:204:23ff:fed6:b664") : + binary_pack_ip("131.111.8.192"); +$dest_port = $opts{'dest-port'} ? + binary_pack_port($opts{'dest-port'}) : + binary_pack_port(25); + +# The IP and port of the Proxy Protocol backend real server being tested, +# don't binary pack it. +my $server_ip = $opts{'server-ip'}; +my $server_port = $opts{'server-port'} ? $opts{'server-port'} : 25; + +my $s = IO::Select->new(); # for socket polling + +sub generate_preamble { + my @preamble; + if (!$opts{version} || $opts{version} == 2) { + @preamble = ( + "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", # 12 byte v2 header + "\x02", # declares v2 + "\x01", # connection is proxied + $opts{6} ? "\x21" : "\x11", # inet6/4 and TCP (stream) + $opts{6} ? "\x24" : "\x0b", # 36 bytes / 12 bytes + $source_ip, + $dest_ip, + $source_port, + $dest_port + ); + } + else { + @preamble = ( + "PROXY", " ", # Request proxy mode + $opts{6} ? "TCP6" : "TCP4", " ", # inet6/4 and TCP (stream) + $source_ip, " ", + $dest_ip, " ", + $source_port, " ", + $dest_port, + "\x0d\x0a" + ); + $status_line .= join "", @preamble; + } + print "\n", $status_line, "\n"; + print "\n" if (!$opts{version} || $opts{version} == 2); + return @preamble; +} + +sub binary_pack_port { + my $port = shift(); + if ($opts{version} && $opts{version} == 1) { + return $port + if ($port && $port =~ /^\d+$/ && $port > 0 && $port < 65536); + die "Not a valid port: $port"; + } + $status_line .= $port." "; + $port = pack "S", $port; + return $port; +} + +sub binary_pack_ip { + my $ip = shift(); + if ( $ip =~ m/\./ && !$opts{6}) { + if (IP4_valid($ip)) { + return $ip if ($opts{version} && $opts{version} == 1); + $status_line .= $ip.":"; + $ip = pack "C*", split /\./, $ip; + } + else { die "Invalid IPv4: $ip"; } + } + elsif ($ip =~ m/:/ && $opts{6}) { + $ip = pad_ipv6($ip); + if (IP6_valid($ip)) { + return $ip if ($opts{version} && $opts{version} == 1); + $status_line .= $ip.":"; + $ip = pack "S>*", map hex, split /:/, $ip; + } + else { die "Invalid IPv6: $ip"; } + } + else { die "Mismatching IP families passed: $ip"; } + return $ip; +} + +sub pad_ipv6 { + my $ip = shift(); + my @ip = split /:/, $ip; + my $segments = scalar @ip; + return $ip if ($segments == 8); + $ip = ""; + for (my $count=1; $count <= $segments; $count++) { + my $block = $ip[$count-1]; + if ($block) { + $ip .= $block; + $ip .= ":" unless $count == $segments; + } + elsif ($count == 1) { + # Somebody passed us ::1, fix it, but it's not really valid + $ip = "0:"; + } + else { + $ip .= join ":", map "0", 0..(8-$segments); + $ip .= ":"; + } + } + return $ip; +} + +sub IP6_valid { + my $ip = shift; + $ip = lc($ip); + return 0 unless ($ip =~ /^[0-9a-f:]+$/); + my @ip = split /:/, $ip; + return 0 if (scalar @ip != 8); + return 1; +} + +sub IP4_valid { + my $ip = shift; + $ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + foreach ($1,$2,$3,$4){ + if ($_ <256 && $_ >0) {next;} + return 0; + } + return 1; +} + +sub go_interactive { + my $continue = 1; + while($continue) { + # Check for input on both ends, recheck every 5 sec + for my $socket ($s->can_read(5)) { + my $remote = $socket_map{$socket}; + my $buffer; + my $read = $socket->sysread($buffer, 4096); + if ($read) { + $remote->syswrite($buffer); + } + else { + $continue = 0; + } + } + } +} + +sub connect_stdin_to_proxy { + my $sock = new IO::Socket::INET( + PeerAddr => $server_ip, + PeerPort => $server_port, + Proto => 'tcp' + ); + + die "Could not create socket: $!\n" unless $sock; + # Add sockets to the Select group + $s->add(\*STDIN); + $s->add($sock); + # Tie the sockets together using this hash + $socket_map{\*STDIN} = $sock; + $socket_map{$sock} = \*STDOUT; + return $sock; +} + +sub usage { + chomp(my $prog = `basename $0`); + print <<EOF; +Usage: $prog [required] [optional] + Required: + --server-ip IP of server to test proxy configuration, + a hostname is ok, but for only this setting + Optional: + --server-port Port server is listening on (default 25) + --6 IPv6 source/dest (default IPv4), if none specified, + some default, reverse resolvable IP's are used for + the source and dest ip/port + --dest-ip Public IP of the proxy server + --dest-port Port of public IP of proxy server + --source-ip IP connecting to the proxy server + --source-port Port of IP connecting to the proxy server + --help This output +EOF + exit; +} + + +my $sock = connect_stdin_to_proxy(); +my @preamble = generate_preamble(); +print $sock @preamble; +go_interactive(); diff --git a/test/confs/2024 b/test/confs/2024 index a677c4c86..c59e975de 100644 --- a/test/confs/2024 +++ b/test/confs/2024 @@ -24,6 +24,7 @@ tls_certificate = CERT tls_privatekey = CERT tls_verify_hosts = HOSTIPV4 -tls_verify_certificates = TVC +#tls_verify_certificates = TVC +tls_verify_certificates = CERT # End diff --git a/test/confs/2026 b/test/confs/2026 index 4185e0b79..d70c5a2db 100644 --- a/test/confs/2026 +++ b/test/confs/2026 @@ -5,7 +5,11 @@ host_lookup_order = bydns primary_hostname = myhost.test.ex rfc1413_query_timeout = 0s spool_directory = DIR/spool +.ifdef SERVER log_file_path = DIR/spool/log/%slog +.else +log_file_path = DIR/spool/log/%D-%slog +.endif gecos_pattern = "" gecos_name = CALLER_NAME @@ -14,6 +18,7 @@ gecos_name = CALLER_NAME acl_smtp_rcpt = check_rcpt log_selector = +tls_peerdn + tls_advertise_hosts = HOSTIPV4 tls_certificate = DIR/aux-fixed/cert1 tls_privatekey = DIR/aux-fixed/cert1 @@ -25,12 +30,12 @@ begin acl check_rcpt: accept local_parts = userx + control = queue_only defer local_parts = usery hosts = 127.0.0.1 - accept - + accept control = queue_only # ----- Routers ----- diff --git a/test/confs/3465 b/test/confs/3465 index 161fff526..83592a678 100644 --- a/test/confs/3465 +++ b/test/confs/3465 @@ -70,5 +70,9 @@ t1: hosts_require_auth = * allow_localhost + # These can be made visible by adding "-d-all+deliver+transport+tls" to the script 1st queuerun + headers_add = X-tls-cipher: <$tls_cipher> + headers_add = X-tls-out-cipher: <$tls_out_cipher> + # End diff --git a/test/log/0547 b/test/log/0547 index 6a5b233e0..3b86d2bd5 100644 --- a/test/log/0547 +++ b/test/log/0547 @@ -1,4 +1,5 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 no MAIL in SMTP connection from [127.0.0.1] D=0s 1999-03-02 09:44:33 no MAIL in SMTP connection from [127.0.0.1] D=0s C=QUIT 1999-03-02 09:44:33 H=(x.y.z) [127.0.0.1] rejected VRFY a@b.c 1999-03-02 09:44:33 no MAIL in SMTP connection from (x.y.z) [127.0.0.1] D=0s C=EHLO,VRFY,QUIT diff --git a/test/log/2000 b/test/log/2000 index 6c690bf9e..6685d5944 100644 --- a/test/log/2000 +++ b/test/log/2000 @@ -1,6 +1,6 @@ 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 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmaX-0005vi-00 TLS session failure: delivering unencrypted to 127.0.0.1 [127.0.0.1] (not in hosts_require_tls) 1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed diff --git a/test/log/2001 b/test/log/2001 index a6a3ea8b4..da5a78a93 100644 --- a/test/log/2001 +++ b/test/log/2001 @@ -1,10 +1,10 @@ 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 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmaX-0005vi-00 == CALLER@test.ex R=client T=send_to_server defer (-37): failure while setting up TLS session 1999-03-02 09:44:33 End queue run: pid=pppp -qf 1999-03-02 09:44:33 Start queue run: pid=pppp -qf -1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to 127.0.0.1 [127.0.0.1] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmaX-0005vi-00 == CALLER@test.ex R=client T=send_to_server defer (-37): failure while setting up TLS session 1999-03-02 09:44:33 End queue run: pid=pppp -qf diff --git a/test/log/2012 b/test/log/2012 index 1474a0bb2..dbb3273af 100644 --- a/test/log/2012 +++ b/test/log/2012 @@ -3,17 +3,17 @@ 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 Start queue run: pid=pppp -qf -1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmaX-0005vi-00 == userx@test.ex R=client_x T=send_to_server_failcert defer (-37): failure while setting up TLS session 1999-03-02 09:44:33 10HmaX-0005vi-00 ** userx@test.ex: retry timeout exceeded 1999-03-02 09:44:33 10HmaX-0005vi-00 userx@test.ex: error ignored 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaY-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmaY-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=client_y T=send_to_server_retry H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" 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 => userz@test.ex R=client_z T=send_to_server_crypt H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" 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 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 10HmbA-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 10HmbA-0005vi-00 TLS session failure: delivering unencrypted to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (not in hosts_require_tls) 1999-03-02 09:44:33 10HmbA-0005vi-00 => userq@test.ex R=client_q T=send_to_server_req_fail H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbD-0005vi-00" 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed diff --git a/test/log/2014 b/test/log/2014 index 7ed753049..39531ddc3 100644 --- a/test/log/2014 +++ b/test/log/2014 @@ -1,8 +1,8 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 1999-03-02 09:44:33 TLS error on connection from (rhu1.barb) [ip4.ip4.ip4.ip4] (gnutls_handshake): The peer did not send any certificate. 1999-03-02 09:44:33 H=(rhu2tls.barb) [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn= -1999-03-02 09:44:33 TLS error on connection from (rhu5.barb) [ip4.ip4.ip4.ip4] (certificate verification failed): invalid +1999-03-02 09:44:33 TLS error on connection from (rhu5.barb) [ip4.ip4.ip4.ip4] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 H=[127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn=C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 -1999-03-02 09:44:33 TLS error on connection from (rhu7.barb) [ip4.ip4.ip4.ip4] (certificate verification failed): revoked +1999-03-02 09:44:33 TLS error on connection from (rhu7.barb) [ip4.ip4.ip4.ip4] (certificate verification failed): certificate revoked 1999-03-02 09:44:33 H=[127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" F=<userx@test.ex> rejected RCPT <userx@test.ex>: certificate not verified: peerdn=C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock diff --git a/test/log/2024 b/test/log/2024 index c45da6e89..117382b5a 100644 --- a/test/log/2024 +++ b/test/log/2024 @@ -1,4 +1,4 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 -1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (gnutls_handshake): The peer did not send any certificate. +1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (certificate verification failed): certificate invalid 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 1999-03-02 09:44:33 TLS error on connection from (rhu.barb) [ip4.ip4.ip4.ip4] (cert/key setup: cert=/non/exist key=/non/exist): Error while reading file. diff --git a/test/log/2025 b/test/log/2025 index aa2745cfc..fafc68d5b 100644 --- a/test/log/2025 +++ b/test/log/2025 @@ -1,6 +1,6 @@ 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 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (gnutls_handshake): A TLS packet with unexpected length was received. +1999-03-02 09:44:33 10HmaX-0005vi-00 a TLS session is required for ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4], but an attempt to start TLS failed 1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" 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 diff --git a/test/log/2026 b/test/log/2026 index 8c8ab7af0..f01644496 100644 --- a/test/log/2026 +++ b/test/log/2026 @@ -1,13 +1,6 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 -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 H=localhost (myhost.test.ex) [127.0.0.1] F=<CALLER@myhost.test.ex> temporarily rejected RCPT <usery@myhost.test.ex> -1999-03-02 09:44:33 10HmaX-0005vi-00 SMTP error from remote mail server after RCPT TO:<usery@myhost.test.ex>: host 127.0.0.1 [127.0.0.1]: 451 Temporary local problem - please try later -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex -1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@myhost.test.ex> R=r0 T=t2 -1999-03-02 09:44:33 10HmaY-0005vi-00 Completed -1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 S=sss id=E10HmaX-0005vi-00@myhost.test.ex -1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@myhost.test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00" -1999-03-02 09:44:33 10HmaX-0005vi-00 => usery@myhost.test.ex R=r1 T=t1 H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 DN="C=UK,O=The Exim Maintainers,OU=Test Suite,CN=Phil Pennock" C="250 OK id=10HmaZ-0005vi-00" -1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaZ-0005vi-00 => usery <usery@myhost.test.ex> R=r0 T=t2 -1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 no immediate delivery: queued by ACL +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=the.local.host.name (myhost.test.ex) [ip4.ip4.ip4.ip4] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 S=sss id=E10HmaY-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaZ-0005vi-00 no immediate delivery: queued by ACL diff --git a/test/log/2027 b/test/log/2027 index 547303822..a54d4a5a9 100644 --- a/test/log/2027 +++ b/test/log/2027 @@ -3,7 +3,7 @@ 1999-03-02 09:44:33 Start queue run: pid=pppp -qf 1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 C="250 OK id=10HmaZ-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaY-0005vi-00 TLS error on connection to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (gnutls_handshake): A TLS packet with unexpected length was received. +1999-03-02 09:44:33 10HmaY-0005vi-00 a TLS session is required for ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4], but an attempt to start TLS failed 1999-03-02 09:44:33 10HmaY-0005vi-00 TLS session failure: delivering unencrypted to ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] (not in hosts_require_tls) 1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=client T=send_to_server H=ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4] C="250 OK id=10HmbA-0005vi-00" 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed diff --git a/test/log/2029 b/test/log/2029 index fc79930b2..e4510feb1 100644 --- a/test/log/2029 +++ b/test/log/2029 @@ -1,3 +1,3 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 -1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection from [127.0.0.1] (recv): A TLS packet with unexpected length was received. +1999-03-02 09:44:33 10HmaX-0005vi-00 TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated. 1999-03-02 09:44:33 10HmaX-0005vi-00 SMTP connection lost after final dot H=[127.0.0.1] P=smtps diff --git a/test/log/3454 b/test/log/3454 index cb4757977..e6e0cb963 100644 --- a/test/log/3454 +++ b/test/log/3454 @@ -1,5 +1,5 @@ 1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 -1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): A TLS packet with unexpected length was received. +1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated. 1999-03-02 09:44:33 TLS error on connection from [127.0.0.1] (send): The specified session has been invalidated for some reason. 1999-03-02 09:44:33 no MAIL in SMTP connection from [127.0.0.1] D=0s X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 C=EHLO,STARTTLS,AUTH 1999-03-02 09:44:33 no MAIL in SMTP connection from (foobar) [127.0.0.1] D=0s A=plain:userx X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 C=EHLO,STARTTLS,EHLO,AUTH,QUIT diff --git a/test/runtest b/test/runtest index 443d7fcf4..89fd1f73e 100755 --- a/test/runtest +++ b/test/runtest @@ -512,6 +512,8 @@ RESET_AFTER_EXTRA_LINE_READ: s/\bDHE-RSA-AES256-SHA\b/AES256-SHA/g; # GnuTLS have seen: + # TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256 + # TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128 # TLS1.2:RSA_AES_256_CBC_SHA1:256 (canonical) # TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128 # @@ -520,12 +522,22 @@ RESET_AFTER_EXTRA_LINE_READ: # X=TLS1.1:RSA_AES_256_CBC_SHA1:256 # X=TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256 # and as stand-alone cipher: + # ECDHE-RSA-AES256-SHA # DHE-RSA-AES256-SHA256 # DHE-RSA-AES256-SHA # picking latter as canonical simply because regex easier that way. s/\bDHE_RSA_AES_128_CBC_SHA1:128/RSA_AES_256_CBC_SHA1:256/g; - s/TLS1.[012]:(DHE_)?RSA_AES_256_CBC_SHA(1|256):256/TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256/g; - s/\bDHE-RSA-AES256-SHA256\b/DHE-RSA-AES256-SHA/g; + s/TLS1.[012]:((EC)?DHE_)?RSA_AES_(256|128)_(CBC|GCM)_SHA(1|256|384):(256|128)/TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256/g; + s/\b(ECDHE-RSA-AES256-SHA|DHE-RSA-AES256-SHA256)\b/AES256-SHA/g; + + # GnuTLS library error message changes + s/No certificate was found/The peer did not send any certificate/g; +#(dodgy test?) s/\(certificate verification failed\): invalid/\(gnutls_handshake\): The peer did not send any certificate./g; + s/\(gnutls_priority_set\): No or insufficient priorities were set/\(gnutls_handshake\): Could not negotiate a supported cipher suite/g; + + # (replace old with new, hoping that old only happens in one situation) + s/TLS error on connection to \d{1,3}(.\d{1,3}){3} \[\d{1,3}(.\d{1,3}){3}\] \(gnutls_handshake\): A TLS packet with unexpected length was received./a TLS session is required for ip4.ip4.ip4.ip4 [ip4.ip4.ip4.ip4], but an attempt to start TLS failed/g; + s/TLS error on connection from \[127.0.0.1\] \(recv\): A TLS packet with unexpected length was received./TLS error on connection from [127.0.0.1] (recv): The TLS connection was non-properly terminated./g; # ======== Caller's login, uid, gid, home, gecos ======== diff --git a/test/scripts/2000-GnuTLS/2026 b/test/scripts/2000-GnuTLS/2026 index 18361c62f..e94d7c5d0 100644 --- a/test/scripts/2000-GnuTLS/2026 +++ b/test/scripts/2000-GnuTLS/2026 @@ -7,3 +7,4 @@ exim -odi userx usery # Wait to allow delivery to finish before killing the daemon sleep 1 killdaemon +no_msglog_check diff --git a/test/stdout/2024 b/test/stdout/2024 index 2e30f7dd6..ecedd4193 100644 --- a/test/stdout/2024 +++ b/test/stdout/2024 @@ -20,7 +20,7 @@ Key file = aux-fixed/cert2 ??? 220 <<< 220 TLS go ahead Attempting to start TLS -Failed to start TLS +Succeeded in starting TLS End of script Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected Certificate file = aux-fixed/cert2 |