From: Wolfgang Breyha Date: Sat, 15 Mar 2014 14:16:05 +0000 (+0000) Subject: Add tls_verify_hosts and tls_try_verify_hosts to smtp transport. Bug 1371 X-Git-Tag: exim-4_83_RC1~68 X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=commitdiff_plain;h=e8793bad207763b266bedcb9d859e238b6a3a04e;hp=-c Add tls_verify_hosts and tls_try_verify_hosts to smtp transport. Bug 1371 Code by Wolfgang Breyha, docs and testsuite by Jeremy Harris --- e8793bad207763b266bedcb9d859e238b6a3a04e diff --combined doc/doc-docbook/spec.xfpt index cab1c82dd,abf69a00d..ae4d75ecb --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@@ -10171,14 -10171,6 +10171,14 @@@ number of larger units and output in Ex .cindex "expansion" "case forcing" .cindex "&%uc%& expansion item" This forces the letters in the string into upper-case. + +.vitem &*${utf8clean:*&<&'string'&>&*}*& +.cindex "correction of invalid utf-8 sequences in strings" +.cindex "utf-8" "utf-8 sequences" +.cindex "incorrect utf-8" +.cindex "expansion" "utf-8 forcing" +.cindex "&%utf8clean%& expansion item" +This replaces any invalid utf-8 sequence in the string by the character &`?`&. .endlist @@@ -11986,7 -11978,7 +11986,7 @@@ other times, this variable is false It is likely that you will need to coerce DNSSEC support on in the resolver library, by setting: .code -dns_use_dnssec = 1 +dns_dnssec_ok = 1 .endd Exim does not perform DNSSEC validation itself, instead leaving that to a @@@ -13198,10 -13190,10 +13198,10 @@@ See also the &'Policy controls'& sectio .row &%disable_ipv6%& "do no IPv6 processing" .row &%dns_again_means_nonexist%& "for broken domains" .row &%dns_check_names_pattern%& "pre-DNS syntax check" +.row &%dns_dnssec_ok%& "parameter for resolver" .row &%dns_ipv4_lookup%& "only v4 lookup for these domains" .row &%dns_retrans%& "parameter for resolver" .row &%dns_retry%& "parameter for resolver" -.row &%dns_use_dnssec%& "parameter for resolver" .row &%dns_use_edns0%& "parameter for resolver" .row &%hold_domains%& "hold delivery for these domains" .row &%local_interfaces%& "for routing checks" @@@ -13822,17 -13814,6 +13822,17 @@@ This option controls whether or not an reversed and looked up in the reverse DNS, as described in more detail in section &<>&. + +.option dns_dnssec_ok main integer -1 +.cindex "DNS" "resolver options" +.cindex "DNS" "DNSSEC" +If this option is set to a non-negative number then Exim will initialise the +DNS resolver library to either use or not use DNSSEC, overriding the system +default. A value of 0 coerces DNSSEC off, a value of 1 coerces DNSSEC on. + +If the resolver library does not support DNSSEC then this option has no effect. + + .option dns_ipv4_lookup main "domain list&!!" unset .cindex "IPv6" "DNS lookup for AAAA records" .cindex "DNS" "IPv6 lookup for AAAA records" @@@ -13863,6 -13844,16 +13863,6 @@@ to set in them See &%dns_retrans%& above. -.option dns_use_dnssec main integer -1 -.cindex "DNS" "resolver options" -.cindex "DNS" "DNSSEC" -If this option is set to a non-negative number then Exim will initialise the -DNS resolver library to either use or not use DNSSEC, overriding the system -default. A value of 0 coerces DNSSEC off, a value of 1 coerces DNSSEC on. - -If the resolver library does not support DNSSEC then this option has no effect. - - .option dns_use_edns0 main integer -1 .cindex "DNS" "resolver options" .cindex "DNS" "EDNS0" @@@ -23027,6 -23018,14 +23027,14 @@@ unknown state), opens a new one to the in clear. + .option tls_try_verify_hosts smtp "host list&!! unset + .cindex "TLS" "server certificate verification" + .cindex "certificate" "verification of server" + For OpenSSL only, this option gives a list of hosts for which, on encrypted connections, + certificate verification will be tried but need not succeed. + The &%tls_verify_certificates%& option must also be set. + + .option tls_verify_certificates smtp string&!! unset .cindex "TLS" "server certificate verification" .cindex "certificate" "verification of server" @@@ -23041,6 -23040,20 +23049,20 @@@ single file if you are using GnuTLS. Th &$host_address$& are set to the name and address of the server during the expansion of this option. See chapter &<>& for details of TLS. + For back-compatability, or when GnuTLS is used, + if neither tls_verify_hosts nor tls_try_verify_hosts are set + and certificate verification fails the TLS connection is closed. + + + .option tls_verify_hosts smtp "host list&!! unset + .cindex "TLS" "server certificate verification" + .cindex "certificate" "verification of server" + For OpenSSL only, this option gives a list of hosts for which. on encrypted connections, + certificate verification must succeed. + The &%tls_verify_certificates%& option must also be set. + If both this option and &%tls_try_verify_hosts%& are unset + operation is as if this option selected all hosts. + @@@ -25942,6 -25955,12 +25964,12 @@@ for OpenSSL only (not GnuTLS), a direct expected server certificates. The client verifies the server's certificate against this collection, taking into account any revoked certificates that are in the list defined by &%tls_crl%&. + Failure to verify fails the TLS connection unless either of the + &%tls_verify_hosts%& or &%tls_try_verify_hosts%& options are set. + + The &%tls_verify_hosts%& and &%tls_try_verify_hosts%& options restrict + certificate verification to the listed servers. Verification either must + or need not succeed respectively. If &%tls_require_ciphers%& is set on the &(smtp)& transport, it must contain a @@@ -27991,23 -28010,6 +28019,23 @@@ This condition checks whether the sendi send email. Details of how this works are given in section &<>&. +.new +.vitem &*verify&~=&~header_names_ascii*& +.cindex "&%verify%& ACL condition" +.cindex "&ACL;" "verifying header names only ASCII" +.cindex "header lines" "verifying header names only ASCII" +.cindex "verifying" "header names only ASCII" +This condition is relevant only in an ACL that is run after a message has been +received, that is, in an ACL specified by &%acl_smtp_data%& or +&%acl_not_smtp%&. It checks all header names (not the content) to make sure +there are no non-ASCII characters, also excluding control characters. The +allowable characters are decimal ASCII values 33 through 126. + +Exim itself will handle headers with non-ASCII characters, but it can cause +problems for downstream applications, so this option will allow their +detection and rejection in the DATA ACL's. +.wen + .vitem &*verify&~=&~header_sender/*&<&'options'&> .cindex "&%verify%& ACL condition" .cindex "&ACL;" "verifying sender in the header" @@@ -28619,13 -28621,6 +28647,13 @@@ deny condition = ${if isip4{$sender_h dnslists = some.list.example .endd +If an explicit key is being used for a DNS lookup and it may be an IPv6 +address you should specify alternate list separators for both the outer +(DNS list name) list and inner (lookup keys) list: +.code + dnslists = <; dnsbl.example.com/<|$acl_m_addrslist +.endd + .section "Rate limiting incoming messages" "SECTratelimiting" .cindex "rate limiting" "client sending" .cindex "limiting client sending rates" @@@ -29810,24 -29805,6 +29838,24 @@@ av_scanner = mksd: .endd You can safely omit this option (the default value is 1). +.vitem &%sock%& +.cindex "virus scanners" "simple socket-connected" +This is a general-purpose way of talking to simple scanner daemons +running on the local machine. +There are four options: +an address (which may be an IP addres and port, or the path of a Unix socket), +a commandline to send (may include a single %s which will be replaced with +the path to the mail file to be scanned), +an RE to trigger on from the returned data, +an RE to extract malware_name from the returned data. +For example: +.code +av_scanner = sock:127.0.0.1 6001:%s:(SPAM|VIRUS):(.*)\$ +.endd +Default for the socket specifier is &_/tmp/malware.sock_&. +Default for the commandline is &_%s\n_&. +Both regular-expressions are required. + .vitem &%sophie%& .cindex "virus scanners" "Sophos and Sophie" Sophie is a daemon that uses Sophos' &%libsavi%& library to scan for viruses. @@@ -34074,7 -34051,6 +34102,7 @@@ the following table &`R `& on &`<=`& lines: reference for local bounce &` `& on &`=>`& &`**`& and &`==`& lines: router name &`S `& size of message +&`SNI `& server name indication from TLS client hello &`ST `& shadow transport name &`T `& on &`<=`& lines: message subject (topic) &` `& on &`=>`& &`**`& and &`==`& lines: transport name @@@ -34384,8 -34360,7 +34412,8 @@@ The message that is written is &"spool .next .cindex "log" "smtp confirmation" .cindex "SMTP" "logging confirmation" -&%smtp_confirmation%&: The response to the final &"."& in the SMTP dialogue for +.cindex "LMTP" "logging confirmation" +&%smtp_confirmation%&: The response to the final &"."& in the SMTP or LMTP dialogue for outgoing messages is added to delivery log lines in the form &`C=`&<&'text'&>. A number of MTAs (including Exim) return an identifying string in this response. diff --combined doc/doc-txt/ChangeLog index 04a7ce02e,c1640f73a..c29f21cbf --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@@ -32,30 -32,8 +32,32 @@@ JH/02 Add ${listextract {number}{list}{ TL/03 Bugzilla 1433: Fix DMARC SEGV with specific From header contents. Properly escape header and check for NULL return. -JH/03 Add tls_{,try_}verify_hosts to smtp transport. OpenSSL only. +PP/01 Continue incomplete 4.82 PP/19 by fixing docs too: use dns_dnssec_ok + not dns_use_dnssec. + +JH/03 Bugzilla 1157: support log_selector smtp_confirmation for lmtp. + +TL/04 Add verify = header_names_ascii check to reject email with non-ASCII + characters in header names, implemented as a verify condition. + Contributed by Michael Fischer v. Mollard. + +TL/05 Rename SPF condition results err_perm and err_temp to standardized + results permerror and temperror. Is a backward incompatibility if + the ACL tests for either of these two results. Patch contributed by + user bes-internal on the mailing list. + +JH/04 Add ${utf8clean:} operator. Contributed by Alex Rau. + +JH/05 Bugzilla 305: Log incoming-TLS details on rejects, subject to log + selectors, in both main and reject logs. + +JH/06 Log outbound-TLS and port details, subject to log selectors, for a + failed delivery. + +JH/07 Add malware type "sock" for talking to simple daemon. + ++JH/08 Bugzilla 1371: Add tls_{,try_}verify_hosts to smtp transport. OpenSSL only. + Exim version 4.82 ----------------- diff --combined doc/doc-txt/NewStuff index c4de902c0,e4f2e29a1..95b4119d1 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@@ -14,19 -14,11 +14,24 @@@ Version 4.8 actual external source IP:host be used in exim instead of the IP of the proxy that is connecting to it. - 2. When built with OpenSSL the smtp transport now supports options + 2. New verify option header_names_ascii, which will check to make sure + there are no non-ASCII characters in header names. Exim itself handles + those non-ASCII characters, but downstream apps may not, so Exim can + detect and reject if those characters are present. + + 3. New expansion operator ${utf8clean:string} to replace malformed UTF8 + codepoints with valid ones. + + 4. New malware type "sock". Talks over a Unix or TCP socket, sending one + command line and matching a regex against the return data for trigger + and a second regex to extract malware_name. The mail spoofile name can + be included in the command line. + ++ 5. When built with OpenSSL the smtp transport now supports options + "tls_verify_hosts" and "tls_try_verify_hosts". If either is set the + certificate verification is split from the encryption operation. The + default remains that a failed verification cancels the encryption. + Version 4.82 ------------ diff --combined src/src/functions.h index a94fac3f2,32bd0bc07..e92c2455f --- a/src/src/functions.h +++ b/src/src/functions.h @@@ -30,7 -30,7 +30,7 @@@ extern int tls_client_start(int, ho # ifdef EXPERIMENTAL_OCSP uschar *, # endif - int, int); + int, int, uschar *, uschar *); extern void tls_close(BOOL, BOOL); extern int tls_feof(void); extern int tls_ferror(void); @@@ -171,8 -171,6 +171,8 @@@ extern int host_scan_for_local_host extern void invert_address(uschar *, uschar *); extern int ip_bind(int, int, uschar *, int); extern int ip_connect(int, int, uschar *, int, int); +extern int ip_connectedsocket(int, const uschar *, int, int, + int, host_item *, uschar **); extern int ip_get_address_family(int); extern void ip_keepalive(int, uschar *, BOOL); extern int ip_recv(int, uschar *, int, int); @@@ -360,7 -358,7 +360,7 @@@ extern uschar *string_dequote(uschar ** extern BOOL string_format(uschar *, int, const char *, ...) ALMOST_PRINTF(3,4); extern uschar *string_format_size(int, uschar *); extern int string_interpret_escape(uschar **); -extern int string_is_ip_address(uschar *, int *); +extern int string_is_ip_address(const uschar *, int *); extern uschar *string_log_address(address_item *, BOOL, BOOL); extern uschar *string_nextinlist(uschar **, int *, uschar *, int); extern uschar *string_open_failed(int, const char *, ...) PRINTF_FUNCTION(2,3); @@@ -404,7 -402,6 +404,7 @@@ extern int verify_check_dnsbl(uscha extern int verify_check_header_address(uschar **, uschar **, int, int, int, uschar *, uschar *, int, int *); extern int verify_check_headers(uschar **); +extern int verify_check_header_names_ascii(uschar **); extern int verify_check_host(uschar **); extern int verify_check_notblind(void); extern int verify_check_this_host(uschar **, unsigned int *, uschar*, diff --combined src/src/verify.c index 3c464fe93,c83748a12..cd91b0560 --- a/src/src/verify.c +++ b/src/src/verify.c @@@ -538,7 -538,7 +538,7 @@@ els #endif if (!(done= smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), '2', callout))) goto RESPONSE_FAILED; - + /* Not worth checking greeting line for ESMTP support */ if (!(esmtp = verify_check_this_host(&(ob->hosts_avoid_esmtp), NULL, host->name, host->address, NULL) != OK)) @@@ -641,7 -641,8 +641,8 @@@ #ifdef EXPERIMENTAL_OCSP ob->hosts_require_ocsp, #endif - ob->tls_dh_min_bits, callout); + ob->tls_dh_min_bits, callout, + ob->tls_verify_hosts, ob->tls_try_verify_hosts); /* TLS negotiation failed; give an error. Try in clear on a new connection, if the options permit it for this host. */ @@@ -705,13 -706,11 +706,13 @@@ cutthrough_delivery= FALSE; HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of transport filter\n"); } + #ifndef DISABLE_DKIM if (ob->dkim_domain) { cutthrough_delivery= FALSE; HDEBUG(D_acl|D_v) debug_printf("Cutthrough cancelled by presence of DKIM signing\n"); } + #endif } SEND_FAILED: @@@ -2157,41 -2156,6 +2158,41 @@@ return yield } +/************************************************* +* Check header names for 8-bit characters * +*************************************************/ + +/* This function checks for invalid charcters in header names. See +RFC 5322, 2.2. and RFC 6532, 3. + +Arguments: + msgptr where to put an error message + +Returns: OK + FAIL +*/ + +int +verify_check_header_names_ascii(uschar **msgptr) +{ +header_line *h; +uschar *colon, *s; + +for (h = header_list; h != NULL; h = h->next) + { + colon = Ustrchr(h->text, ':'); + for(s = h->text; s < colon; s++) + { + if ((*s < 33) || (*s > 126)) + { + *msgptr = string_sprintf("Invalid character in header \"%.*s\" found", + colon - h->text, h->text); + return FAIL; + } + } + } +return OK; +} /************************************************* * Check for blind recipients *