From aa368db3cd1fe1040bfe90ec1673e9a7c798db9b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 11 Jul 2016 11:55:34 +0100 Subject: feature advertise --- test/aux-var-src/tls_conf_prefix | 1 + test/confs/0564 | 1 + test/confs/3414 | 1 + test/confs/5601 | 1 + test/confs/5740 | 1 + test/stderr/0038 | 6 ++++++ test/stderr/0043 | 1 + test/stderr/0044 | 2 ++ test/stderr/0070 | 1 + test/stderr/0079 | 1 + test/stderr/0080 | 1 + test/stderr/0121 | 5 +++++ test/stderr/0138 | 2 ++ test/stderr/0180 | 2 ++ test/stderr/0243 | 1 + test/stderr/0303 | 3 +++ test/stderr/0371 | 1 + test/stderr/0384 | 1 + test/stderr/0487 | 1 + test/stderr/0513 | 1 + test/stderr/0524 | 4 ++++ test/stderr/0537 | 1 + test/stderr/3000 | 1 + test/stderr/3208 | 1 + test/stderr/3400 | 4 ++++ test/stderr/3408 | 2 ++ test/stderr/3410 | 3 +++ test/stderr/3500 | 3 +++ test/stderr/5204 | 1 + test/stderr/5403 | 2 ++ test/stderr/5410 | 3 +++ test/stderr/5420 | 3 +++ test/stdout/0572 | 2 ++ 33 files changed, 64 insertions(+) (limited to 'test') diff --git a/test/aux-var-src/tls_conf_prefix b/test/aux-var-src/tls_conf_prefix index 3beafd9db..39dddd98f 100644 --- a/test/aux-var-src/tls_conf_prefix +++ b/test/aux-var-src/tls_conf_prefix @@ -11,3 +11,4 @@ log_file_path = DIR/spool/log/%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = diff --git a/test/confs/0564 b/test/confs/0564 index e464f963c..6a23896ef 100644 --- a/test/confs/0564 +++ b/test/confs/0564 @@ -7,6 +7,7 @@ spool_directory = DIR/spool log_file_path = DIR/spool/log/%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = tls_advertise_hosts = # ----- Main settings ----- diff --git a/test/confs/3414 b/test/confs/3414 index e151e5fbc..64c3cf48a 100644 --- a/test/confs/3414 +++ b/test/confs/3414 @@ -11,6 +11,7 @@ spool_directory = DIR/spool log_file_path = DIR/spool/log/%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = tls_advertise_hosts = # ----- Main settings ----- diff --git a/test/confs/5601 b/test/confs/5601 index 185b06745..788f509a9 100644 --- a/test/confs/5601 +++ b/test/confs/5601 @@ -10,6 +10,7 @@ spool_directory = DIR/spool log_file_path = DIR/spool/log/SERVER%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = primary_hostname = server1.example.com diff --git a/test/confs/5740 b/test/confs/5740 index 6c4614499..2f0fc25c5 100644 --- a/test/confs/5740 +++ b/test/confs/5740 @@ -10,6 +10,7 @@ spool_directory = DIR/spool log_file_path = DIR/spool/log/SERVER%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = primary_hostname = server1.example.com diff --git a/test/stderr/0038 b/test/stderr/0038 index 9f1632db5..8137d8777 100644 --- a/test/stderr/0038 +++ b/test/stderr/0038 @@ -9,6 +9,7 @@ >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "warn" >>> check ratelimit = 0/1h/strict @@ -47,6 +48,7 @@ LOG: 10HmaX-0005vi-00 H=(test.ex) [V4NET.9.8.7] F=<> rejected after DATA >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "warn" >>> check ratelimit = 0/1h/strict @@ -84,6 +86,7 @@ LOG: 10HmaY-0005vi-00 H=(test.ex) [V4NET.9.8.7] F=<> rejected after DATA >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "warn" >>> check ratelimit = 0/1h/per_conn/strict @@ -122,6 +125,7 @@ LOG: 10HmaZ-0005vi-00 H=(test.ex) [V4NET.9.8.7] F=<> rejected after DATA >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "warn" >>> check ratelimit = 0/1h/per_conn/strict @@ -159,6 +163,7 @@ LOG: 10HmbA-0005vi-00 H=(test.ex) [V4NET.9.8.7] F=<> rejected after DATA >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "warn" >>> check ratelimit = 0/1h/per_rcpt @@ -225,6 +230,7 @@ LOG: 10HmbB-0005vi-00 H=(test.ex) [V4NET.9.8.7] F=<> rejected after DATA >>> test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt2" >>> processing "warn" >>> check ratelimit = 1/1m/per_rcpt/noupdate diff --git a/test/stderr/0043 b/test/stderr/0043 index 3c6551479..55e719332 100644 --- a/test/stderr/0043 +++ b/test/stderr/0043 @@ -9,6 +9,7 @@ >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : diff --git a/test/stderr/0044 b/test/stderr/0044 index b261277c6..7c3fb0d3f 100644 --- a/test/stderr/0044 +++ b/test/stderr/0044 @@ -9,6 +9,7 @@ >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : @@ -56,6 +57,7 @@ LOG: 10HmaX-0005vi-00 <= postmaster@exim.test.ex H=(exim.test.ex) [V4NET.11.12.1 >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : diff --git a/test/stderr/0070 b/test/stderr/0070 index c50f93612..dcfc4286c 100644 --- a/test/stderr/0070 +++ b/test/stderr/0070 @@ -258,6 +258,7 @@ MUNGED: ::1 will be omitted in what follows >>> rhubarb in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "rcpt" >>> processing "require" >>> message: helo not verified diff --git a/test/stderr/0079 b/test/stderr/0079 index 1fb29be98..c46c66aa1 100644 --- a/test/stderr/0079 +++ b/test/stderr/0079 @@ -9,6 +9,7 @@ >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : diff --git a/test/stderr/0080 b/test/stderr/0080 index c5a40d7ba..d9ea2bf81 100644 --- a/test/stderr/0080 +++ b/test/stderr/0080 @@ -9,6 +9,7 @@ >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check recipients = postmaster@exim.test.ex diff --git a/test/stderr/0121 b/test/stderr/0121 index b578cce97..97cbca9da 100644 --- a/test/stderr/0121 +++ b/test/stderr/0121 @@ -172,16 +172,21 @@ LOG: 10HmaZ-0005vi-00 H=[127.0.0.1] F= temporarily rejected after >>> foo.bar in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in smtp_accept_max_nonmail_hosts? yes (matched "*") >>> foo.bar in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> foo.bar in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> foo.bar in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> foo.bar in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) diff --git a/test/stderr/0138 b/test/stderr/0138 index 5a69cc1cc..9c30eedec 100644 --- a/test/stderr/0138 +++ b/test/stderr/0138 @@ -9,6 +9,7 @@ >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : @@ -56,6 +57,7 @@ LOG: 10HmaX-0005vi-00 <= postmaster@exim.test.ex H=(exim.test.ex) [V4NET.11.12.1 >>> exim.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : diff --git a/test/stderr/0180 b/test/stderr/0180 index 4fa53882e..7df430b70 100644 --- a/test/stderr/0180 +++ b/test/stderr/0180 @@ -9,6 +9,7 @@ >>> some.host in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in hosts_connection_nolog? no (option unset) >>> host in host_lookup? no (option unset) >>> host in host_reject_connection? no (option unset) @@ -20,3 +21,4 @@ >>> some.host in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) diff --git a/test/stderr/0243 b/test/stderr/0243 index 9b8717fde..dac2ea6e7 100644 --- a/test/stderr/0243 +++ b/test/stderr/0243 @@ -9,6 +9,7 @@ >>> xxxx in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "deny" >>> message: unrouteable address diff --git a/test/stderr/0303 b/test/stderr/0303 index cc6b08b27..598ed62ed 100644 --- a/test/stderr/0303 +++ b/test/stderr/0303 @@ -26,6 +26,7 @@ >>> V4NET.0.0.1 OK >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in hosts_connection_nolog? no (option unset) >>> host in host_lookup? no (option unset) >>> host in host_reject_connection? no (option unset) @@ -69,6 +70,7 @@ sender_rcvhost = [V4NET.2.3.4] set_process_info: pppp handling incoming connection from ([V4NET.2.3.4]) [V4NET.2.3.4] host in dsn_advertise_hosts? no (option unset) host in pipelining_advertise_hosts? yes (matched "*") +host in chunking_advertise_hosts? no (end of list) SMTP>> 250-myhost.test.ex Hello [V4NET.2.3.4] [V4NET.2.3.4] 250-SIZE 52428800 250-8BITMIME @@ -142,6 +144,7 @@ sender_rcvhost = host.name.tld ([V4NET.2.3.4]) set_process_info: pppp handling incoming connection from host.name.tld [V4NET.2.3.4] host in dsn_advertise_hosts? no (option unset) host in pipelining_advertise_hosts? yes (matched "*") +host in chunking_advertise_hosts? no (end of list) SMTP>> 250-myhost.test.ex Hello host.name.tld [V4NET.2.3.4] 250-SIZE 52428800 250-8BITMIME diff --git a/test/stderr/0371 b/test/stderr/0371 index 2eabbaa6f..5f97d4e09 100644 --- a/test/stderr/0371 +++ b/test/stderr/0371 @@ -37,6 +37,7 @@ sender_rcvhost = [V4NET.0.0.0] (helo=something) set_process_info: pppp handling incoming connection from (something) [V4NET.0.0.0] host in dsn_advertise_hosts? no (option unset) host in pipelining_advertise_hosts? yes (matched "*") +host in chunking_advertise_hosts? no (end of list) SMTP>> 250-mail.test.ex Hello something [V4NET.0.0.0] 250-SIZE 52428800 250-8BITMIME diff --git a/test/stderr/0384 b/test/stderr/0384 index 63ba003cd..1906cbd2d 100644 --- a/test/stderr/0384 +++ b/test/stderr/0384 @@ -10,6 +10,7 @@ >>> matched host address >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in smtp_accept_max_nonmail_hosts? yes (matched "*") >>> [1.2.3.4] in helo_lookup_domains? no (end of list) >>> verifying EHLO/HELO argument "[1.2.3.4]" diff --git a/test/stderr/0487 b/test/stderr/0487 index 1f4f5116e..b332f7f80 100644 --- a/test/stderr/0487 +++ b/test/stderr/0487 @@ -22,6 +22,7 @@ smtp_setup_msg entered SMTP<< ehlo x.y in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) SMTP>> 250-myhost.test.ex Hello CALLER at x.y 250-SIZE 52428800 250-8BITMIME diff --git a/test/stderr/0513 b/test/stderr/0513 index 9825070c4..864b2eaa1 100644 --- a/test/stderr/0513 +++ b/test/stderr/0513 @@ -9,6 +9,7 @@ >>> a.b.c.d in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "defer" >>> check !verify = recipient diff --git a/test/stderr/0524 b/test/stderr/0524 index 363c8dfd1..8344d34a6 100644 --- a/test/stderr/0524 +++ b/test/stderr/0524 @@ -9,6 +9,7 @@ >>> csa1.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_mail" >>> processing "accept" >>> message: CSA status is $csa_status @@ -19,6 +20,7 @@ >>> csa2.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_mail" >>> processing "accept" >>> message: CSA status is $csa_status @@ -37,6 +39,7 @@ LOG: H=(csa2.test.ex) [V4NET.9.8.7] rejected MAIL <>: client SMTP authorization >>> csa1.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_mail" >>> processing "accept" >>> message: CSA status is $csa_status @@ -48,6 +51,7 @@ LOG: H=(csa1.test.ex) [V4NET.9.8.8] rejected MAIL <>: client SMTP authorization >>> csa2.test.ex in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_mail" >>> processing "accept" >>> message: CSA status is $csa_status diff --git a/test/stderr/0537 b/test/stderr/0537 index a892e736d..c5a8b3e54 100644 --- a/test/stderr/0537 +++ b/test/stderr/0537 @@ -88,6 +88,7 @@ LOG: sender_ident=ident >>> end of ACL "connect": ACCEPT >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "mail" >>> processing "accept" >>> check acl = log diff --git a/test/stderr/3000 b/test/stderr/3000 index 7615889c8..6aea66ac5 100644 --- a/test/stderr/3000 +++ b/test/stderr/3000 @@ -59,6 +59,7 @@ LOG: smtp_connection MAIN >>> x.y.z in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_rcpt" >>> processing "accept" LOG: this is a warning at TESTSUITE/aux-fixed/3000.pl line 25. diff --git a/test/stderr/3208 b/test/stderr/3208 index 1eba14049..d25ef58ad 100644 --- a/test/stderr/3208 +++ b/test/stderr/3208 @@ -9,6 +9,7 @@ >>> remote.host in helo_lookup_domains? no (end of list) >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> test.ex in percent_hack_domains? no (matched "!test.ex") >>> using ACL "check_recipient" >>> processing "accept" diff --git a/test/stderr/3400 b/test/stderr/3400 index 6eda31374..541d08d5a 100644 --- a/test/stderr/3400 +++ b/test/stderr/3400 @@ -87,6 +87,7 @@ LOG: H=[10.0.0.2] Warning: accepted ETRN #abcd >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in "10.0.0.1"? yes (matched "10.0.0.1") >>> host in auth_advertise_hosts? yes (matched "+auth_hosts") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in smtp_accept_max_nonmail_hosts? yes (matched "*") >>> using ACL "check_vrfy" >>> processing "deny" @@ -290,6 +291,7 @@ LOG: H=(test.host) [10.0.0.1] Warning: accepted ETRN #abcd >>> host in "10.0.0.4"? no (end of list) >>> host in "10.0.0.3 : 10.0.0.4"? yes (matched "10.0.0.3") >>> host in auth_advertise_hosts? yes (matched "+auth_relay_hosts") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "warn" >>> check hosts = 10.0.0.5 @@ -385,6 +387,7 @@ LOG: H=(test.host) [10.0.0.3] F= rejected RCPT >> host in "10.0.0.1"? no (end of list) >>> host in "10.0.0.4"? yes (matched "10.0.0.4") >>> host in auth_advertise_hosts? no (matched "!+relay_hosts") +>>> host in chunking_advertise_hosts? no (end of list) Exim version x.yz .... changed uid/gid: forcing real = effective uid=uuuu gid=CALLER_GID pid=pppp @@ -437,6 +440,7 @@ host in "10.0.0.1"? no (end of list) host in "10.0.0.4"? no (end of list) host in "10.0.0.3 : 10.0.0.4"? no (end of list) host in auth_advertise_hosts? yes (matched "10.0.0.5") +host in chunking_advertise_hosts? no (end of list) SMTP>> 250-myhost.test.ex Hello CALLER at testing.testing [10.0.0.5] 250-SIZE 52428800 250-8BITMIME diff --git a/test/stderr/3408 b/test/stderr/3408 index 8c6fb8b25..3f53a120a 100644 --- a/test/stderr/3408 +++ b/test/stderr/3408 @@ -10,6 +10,7 @@ >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in auth_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "check_recipient" >>> processing "accept" >>> check hosts = : @@ -55,6 +56,7 @@ LOG: 10HmaX-0005vi-00 <= postmaster@exim.test.ex H=(exim.test.ex) [V4NET.11.12.1 >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in auth_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> plain authenticator server_condition: >>> $auth1 = >>> $auth2 = userx diff --git a/test/stderr/3410 b/test/stderr/3410 index 2a6c3d5aa..36fbdb425 100644 --- a/test/stderr/3410 +++ b/test/stderr/3410 @@ -17,6 +17,7 @@ LOG: H=[5.6.9.1] F= rejected RCPT : You must authenticate >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in auth_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> auth1 authenticator server_condition: >>> $auth1 = >>> $auth2 = userx @@ -50,6 +51,7 @@ LOG: H=[5.6.10.1] F= rejected RCPT >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in auth_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> auth1 authenticator server_condition: >>> $auth1 = >>> $auth2 = userx @@ -76,6 +78,7 @@ LOG: H=[5.6.10.1] F= rejected RCPT >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in auth_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> auth2 authenticator server_condition: >>> $auth1 = userx >>> $auth2 = secret diff --git a/test/stderr/3500 b/test/stderr/3500 index 61225ae7d..9f4a5e087 100644 --- a/test/stderr/3500 +++ b/test/stderr/3500 @@ -12,6 +12,7 @@ >>> host in "10.0.0.1 : 10.0.0.5"? no (end of list) >>> host in "10.0.0.4"? yes (matched "10.0.0.4") >>> host in auth_advertise_hosts? no (matched "!+relay_hosts") +>>> host in chunking_advertise_hosts? no (end of list) >>> host in hosts_connection_nolog? no (option unset) >>> host in host_lookup? no (option unset) >>> host in host_reject_connection? no (option unset) @@ -25,6 +26,7 @@ >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in "10.0.0.1 : 10.0.0.5"? yes (matched "10.0.0.1") >>> host in auth_advertise_hosts? yes (matched "+auth_hosts") +>>> host in chunking_advertise_hosts? no (end of list) >>> +++CRAM-MD5 $auth1="tim" $auth2="" $auth3="" >>> CRAM-MD5: user name = tim >>> challenge = <1896.697170952@postoffice.reston.mci.net> @@ -76,6 +78,7 @@ LOG: 10HmaY-0005vi-00 <= userx@some.domain H=(test.host) [10.0.0.1] P=esmtpa A=c >>> host in pipelining_advertise_hosts? yes (matched "*") >>> host in "10.0.0.1 : 10.0.0.5"? yes (matched "10.0.0.5") >>> host in auth_advertise_hosts? yes (matched "+auth_hosts") +>>> host in chunking_advertise_hosts? no (end of list) >>> +++CRAM-MD5 $auth1="tim" $auth2="" $auth3="" >>> CRAM-MD5: user name = tim >>> challenge = <1896.697170952@postoffice.reston.mci.net> diff --git a/test/stderr/5204 b/test/stderr/5204 index b6f852338..e1ed340c0 100644 --- a/test/stderr/5204 +++ b/test/stderr/5204 @@ -269,6 +269,7 @@ host in helo_accept_junk_hosts? no (option unset) some.name in helo_lookup_domains? no (end of list) host in dsn_advertise_hosts? no (option unset) host in pipelining_advertise_hosts? yes (matched "*") +host in chunking_advertise_hosts? no (end of list) processing "accept" check verify = recipient >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> diff --git a/test/stderr/5403 b/test/stderr/5403 index b088f32f1..292f09133 100644 --- a/test/stderr/5403 +++ b/test/stderr/5403 @@ -11,6 +11,7 @@ LOG: no host name found for IP address 1.2.3.4 >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "ar" >>> processing "warn" >>> check control = cutthrough_delivery @@ -39,6 +40,7 @@ LOG: 10HmaX-0005vi-00 <= CALLER@myhost.test.ex H=(myhost.test.ex) [1.2.3.4] P=es LOG: no host name found for IP address 1.2.3.4 >>> host in dsn_advertise_hosts? no (option unset) >>> host in pipelining_advertise_hosts? yes (matched "*") +>>> host in chunking_advertise_hosts? no (end of list) >>> using ACL "ar" >>> processing "warn" >>> check control = cutthrough_delivery diff --git a/test/stderr/5410 b/test/stderr/5410 index 41f6bab6f..f455075d1 100644 --- a/test/stderr/5410 +++ b/test/stderr/5410 @@ -9,6 +9,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} @@ -254,6 +255,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} @@ -468,6 +470,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} diff --git a/test/stderr/5420 b/test/stderr/5420 index 2cac1a73f..9117875ef 100644 --- a/test/stderr/5420 +++ b/test/stderr/5420 @@ -9,6 +9,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} @@ -253,6 +254,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} @@ -467,6 +469,7 @@ considering: $smtp_active_hostname ESMTP Exim $version_number $tod_full result: myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 in dsn_advertise_hosts? no (option unset) in pipelining_advertise_hosts? yes (matched "*") + in chunking_advertise_hosts? no (end of list) in tls_advertise_hosts? yes (matched "*") considering: ${if eq {SERVER}{server}{queue}{cutthrough}} considering: SERVER}{server}{queue}{cutthrough}} diff --git a/test/stdout/0572 b/test/stdout/0572 index d6efce012..dbdf4b989 100644 --- a/test/stdout/0572 +++ b/test/stdout/0572 @@ -83,6 +83,7 @@ spool_directory = TESTSUITE/spool log_file_path = TESTSUITE/spool/log/%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = # 1 "TESTSUITE/aux-var/std_conf_prefix" # 5 "TESTSUITE/test-config" primary_hostname = myhost.test.ex @@ -121,6 +122,7 @@ spool_directory = TESTSUITE/spool log_file_path = TESTSUITE/spool/log/%slog gecos_pattern = "" gecos_name = CALLER_NAME +chunking_advertise_hosts = # 1 "TESTSUITE/aux-var/std_conf_prefix" # 5 "TESTSUITE/test-config" primary_hostname = myhost.test.ex -- cgit v1.2.3 From 7e3ce68e68ab9b8906a637d352993abf361554e2 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 13 Jul 2016 21:28:18 +0100 Subject: receive flow processing --- doc/doc-docbook/spec.xfpt | 21 +++- doc/doc-txt/NewStuff | 4 + src/src/functions.h | 1 + src/src/globals.c | 4 + src/src/globals.h | 4 + src/src/macros.h | 7 ++ src/src/receive.c | 212 +++++++++++++++++++++++----------- src/src/smtp_in.c | 267 +++++++++++++++++++++++++++++++++---------- src/src/structs.h | 5 +- test/confs/0900 | 71 ++++++++++++ test/log/0900 | 9 ++ test/scripts/0000-Basic/0900 | 170 +++++++++++++++++++++++++++ test/stdout/0900 | 232 +++++++++++++++++++++++++++++++++++++ test/stdout/2122 | 2 +- 14 files changed, 879 insertions(+), 130 deletions(-) create mode 100644 test/confs/0900 create mode 100644 test/log/0900 create mode 100644 test/scripts/0000-Basic/0900 create mode 100644 test/stdout/0900 (limited to 'test') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index ca64f9f11..5c2c2ba11 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -13801,6 +13801,7 @@ See also the &'Policy controls'& section above. .table2 .row &%accept_8bitmime%& "advertise 8BITMIME" .row &%auth_advertise_hosts%& "advertise AUTH to these hosts" +.row &%chunking_advertise_hosts%& "advertise CHUNKING to these hosts" .row &%dsn_advertise_hosts%& "advertise DSN extensions to these hosts" .row &%ignore_fromline_hosts%& "allow &""From ""& from these hosts" .row &%ignore_fromline_local%& "allow &""From ""& from local SMTP" @@ -14358,6 +14359,13 @@ For non-SMTP input and for batched SMTP input, the test is done at start-up; on failure a message is written to stderr and Exim exits with a non-zero code, as it obviously cannot send an error message of any kind. +.option chunking_advertise_hosts main "host list&!!" * +.cindex CHUNKING advertisement +.cindex "RFC 3030" "CHUNKING" +The CHUNKING extension (RFC3030) will be advertised in the EHLO message to +these hosts. +Hosts may use the BDAT command as an alternate to DATA. + .option daemon_smtp_ports main string &`smtp`& .cindex "port" "for daemon" .cindex "TCP/IP" "setting listening ports" @@ -27741,6 +27749,15 @@ received, before the final response to the DATA command is sent. This is the ACL specified by &%acl_smtp_data%&, which is the second ACL that is associated with the DATA command. +.cindex CHUNKING "BDAT command" +.cindex BDAT "SMTP command" +.cindex "RFC 3030" CHUNKING +If CHUNKING was advertised and a BDAT command sequence is received, +the &%acl_smtp_predata%& ACL is not run. +.XXX why not? It should be possible, for the first BDAT. +The &%acl_smtp_data%& is run after the last BDAT command and all of +the data specified is received. + For both of these ACLs, it is not possible to reject individual recipients. An error response rejects the entire message. Unfortunately, it is known that some MTAs do not treat hard (5&'xx'&) responses to the DATA command (either @@ -35620,10 +35637,12 @@ the following table: &`F `& sender address (on delivery lines) &`H `& host name and IP address &`I `& local interface used +&`K `& CHUNKING extension used &`id `& message id for incoming message &`P `& on &`<=`& lines: protocol used &` `& on &`=>`& and &`**`& lines: return path -&`PRX `& on &'<='& and&`=>`& lines: proxy address +&`PRDR`& PRDR extension used +&`PRX `& on &'<='& and &`=>`& lines: proxy address &`Q `& alternate queue name &`QT `& on &`=>`& lines: time spent on queue so far &` `& on &"Completed"& lines: time spent on queue diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 2a776b730..c37f7cdc8 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -26,6 +26,10 @@ Version 4.88 the queue to be used for a message. A $queue_name variable gives visibility. + 6. The CHUNKING ESMTP extension from RFC 3030. May give some slight + performance increase and network load decrease. Main config option + chucking_advertise_hosts for control. + Version 4.87 ------------ diff --git a/src/src/functions.h b/src/src/functions.h index b5e3098dc..0b77aa1fe 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -100,6 +100,7 @@ extern int auth_xtextdecode(uschar *, uschar **); extern uschar *b64encode(uschar *, int); extern int b64decode(uschar *, uschar **); +extern int bdat_getc(void); extern void bits_clear(unsigned int *, size_t, int *); extern void bits_set(unsigned int *, size_t, int *); diff --git a/src/src/globals.c b/src/src/globals.c index 2e3fe4074..c86b9478d 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -185,6 +185,8 @@ incoming TCP/IP. The defaults use stdin. We never need these for any stand-alone tests. */ #ifndef STAND_ALONE +int (*lwr_receive_getc)(void) = stdin_getc; +int (*lwr_receive_ungetc)(int) = stdin_ungetc; int (*receive_getc)(void) = stdin_getc; int (*receive_ungetc)(int) = stdin_ungetc; int (*receive_feof)(void) = stdin_feof; @@ -495,6 +497,8 @@ int check_spool_space = 0; uschar *chunking_advertise_hosts = US"*"; unsigned chunking_datasize = 0; +unsigned chunking_data_left = 0; +BOOL chunking_offered = FALSE; chunking_state_t chunking_state= CHUNKING_NOT_OFFERED; uschar *client_authenticator = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 184a144f2..c5767d73a 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -138,6 +138,8 @@ extern uschar *dsn_advertise_hosts; /* host for which TLS is advertised */ /* Input-reading functions for messages, so we can use special ones for incoming TCP/IP. */ +extern int (*lwr_receive_getc)(void); +extern int (*lwr_receive_ungetc)(int); extern int (*receive_getc)(void); extern int (*receive_ungetc)(int); extern int (*receive_feof)(void); @@ -269,6 +271,8 @@ extern int check_spool_inodes; /* Minimum for message acceptance */ extern int check_spool_space; /* Minimum for message acceptance */ extern uschar *chunking_advertise_hosts; /* RFC 3030 CHUNKING */ extern unsigned chunking_datasize; +extern unsigned chunking_data_left; +extern BOOL chunking_offered; extern chunking_state_t chunking_state; extern uschar *client_authenticator; /* Authenticator name used for smtp delivery */ extern uschar *client_authenticated_id; /* "login" name used for SMTP AUTH */ diff --git a/src/src/macros.h b/src/src/macros.h index dbc49f01e..f567c7ec2 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -320,6 +320,13 @@ for having to swallow the rest of an SMTP message is whether the value is #define END_NOTENDED 3 /* Message reading not yet ended */ #define END_SIZE 4 /* Reading ended because message too big */ #define END_WERROR 5 /* Write error while reading the message */ +#define END_PROTOCOL 6 /* Protocol error in CHUNKING sequence */ + +/* result codes for bdat_getc() (which can also return EOF) */ + +#define EOD (-2) +#define ERR (-3) + /* Bit masks for debug and log selectors */ diff --git a/src/src/receive.c b/src/src/receive.c index f6bdf4742..9ff339d39 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -770,16 +770,13 @@ Arguments: Returns: One of the END_xxx values indicating why it stopped reading */ -/*XXX CHUNKING: maybe a variant routing specialised for BDAT, assuming -string RFC compliance ie. CRLF always? We still have to strip the CR -but we are not dealing with variant lunacy or looking for the end-dot */ static int read_message_data_smtp(FILE *fout) { int ch_state = 0; int ch; -register int linelength = 0; +int linelength = 0; while ((ch = (receive_getc)()) != EOF) { @@ -869,7 +866,7 @@ while ((ch = (receive_getc)()) != EOF) message_size++; linelength++; - if (fout != NULL) + if (fout) { if (fputc(ch, fout) == EOF) return END_WERROR; if (message_size > thismessage_size_limit) return END_SIZE; @@ -878,7 +875,7 @@ while ((ch = (receive_getc)()) != EOF) (void) cutthrough_put_nl(); else { - uschar c= ch; + uschar c = ch; (void) cutthrough_puts(&c, 1); } } @@ -892,6 +889,63 @@ return END_EOF; +/* Variant of the above read_message_data_smtp() specialised for RFC 3030 +CHUNKING. We assume that the incoming has proper CRLF, so only have to scan +for and strip CR. On the downside there are more protocol reasons to stop. + +Arguments: + fout a FILE to which to write the message; NULL if skipping + +Returns: One of the END_xxx values indicating why it stopped reading +*/ + +static int +read_message_bdat_smtp(FILE *fout) +{ +int ch; +int linelength = 0; + +for (;;) switch (ch = bdat_getc()) + { + case EOF: return END_EOF; + case EOD: return END_DOT; + case ERR: return END_PROTOCOL; + + case '\r': + body_linecount++; + if (linelength > max_received_linelength) + max_received_linelength = linelength; + linelength = -1; + break; + + case 0: + body_zerocount++; + /*FALLTHROUGH*/ + default: + message_size++; + linelength++; + if (fout) + { + if (fputc(ch, fout) == EOF) return END_WERROR; + if (message_size > thismessage_size_limit) return END_SIZE; + } +#ifdef notyet + if(ch == '\n') + (void) cutthrough_put_nl(); + else + { + uschar c = ch; + (void) cutthrough_puts(&c, 1); + } +#endif + break; + } +/*NOTREACHED*/ +} + + + + /************************************************* * Swallow SMTP message * *************************************************/ @@ -908,6 +962,7 @@ Returns: nothing void receive_swallow_smtp(void) { +/*XXX CHUNKING: not enough. read chunks until RSET? */ if (message_ended >= END_NOTENDED) message_ended = read_message_data_smtp(NULL); } @@ -1616,7 +1671,6 @@ next->text. */ for (;;) { -/*XXX CHUNKING: account for BDAT size & last, and do more chunks as needed */ int ch = (receive_getc)(); /* If we hit EOF on a SMTP connection, it's an error, since incoming @@ -2835,7 +2889,14 @@ if (filter_test != FTEST_NONE) return message_ended == END_DOT; } -/*XXX CHUNKING: need to cancel cutthrough under BDAT, for now */ +/*XXX CHUNKING: need to cancel cutthrough under BDAT, for now. In future, +think more if it could be handled. Cannot do onward CHUNKING unless +inbound is, but inbound chunking ought to be ok with outbound plain. +Could we do onward CHUNKING given inbound CHUNKING? +*/ +if (chunking_state > CHUNKING_OFFERED) + cancel_cutthrough_connection("chunking active"); + /* Cutthrough delivery: We have to create the Received header now rather than at the end of reception, so the timestamp behaviour is a change to the normal case. @@ -2933,8 +2994,9 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT) { if (smtp_input) { -/*XXX CHUNKING: main data read, for message body */ - message_ended = read_message_data_smtp(data_file); + message_ended = chunking_state > CHUNKING_OFFERED + ? read_message_bdat_smtp(data_file) + : read_message_data_smtp(data_file); receive_linecount++; /* The terminating "." line */ } else message_ended = read_message_data(data_file); @@ -2942,51 +3004,64 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT) receive_linecount += body_linecount; /* For BSMTP errors mainly */ message_linecount += body_linecount; - /* Handle premature termination of SMTP */ - - if (smtp_input && message_ended == END_EOF) + switch (message_ended) { - Uunlink(spool_name); /* Lose data file when closed */ - cancel_cutthrough_connection("sender closed connection"); - message_id[0] = 0; /* Indicate no message accepted */ - smtp_reply = handle_lost_connection(US""); - smtp_yield = FALSE; - goto TIDYUP; /* Skip to end of function */ - } + /* Handle premature termination of SMTP */ - /* Handle message that is too big. Don't use host_or_ident() in the log - message; we want to see the ident value even for non-remote messages. */ + case END_EOF: + if (smtp_input) + { + Uunlink(spool_name); /* Lose data file when closed */ + cancel_cutthrough_connection("sender closed connection"); + message_id[0] = 0; /* Indicate no message accepted */ + smtp_reply = handle_lost_connection(US""); + smtp_yield = FALSE; + goto TIDYUP; /* Skip to end of function */ + } + break; - if (message_ended == END_SIZE) - { - Uunlink(spool_name); /* Lose the data file when closed */ - cancel_cutthrough_connection("mail too big"); - if (smtp_input) receive_swallow_smtp(); /* Swallow incoming SMTP */ + /* Handle message that is too big. Don't use host_or_ident() in the log + message; we want to see the ident value even for non-remote messages. */ - log_write(L_size_reject, LOG_MAIN|LOG_REJECT, "rejected from <%s>%s%s%s%s: " - "message too big: read=%d max=%d", - sender_address, - (sender_fullhost == NULL)? "" : " H=", - (sender_fullhost == NULL)? US"" : sender_fullhost, - (sender_ident == NULL)? "" : " U=", - (sender_ident == NULL)? US"" : sender_ident, - message_size, - thismessage_size_limit); + case END_SIZE: + Uunlink(spool_name); /* Lose the data file when closed */ + cancel_cutthrough_connection("mail too big"); + if (smtp_input) receive_swallow_smtp(); /* Swallow incoming SMTP */ - if (smtp_input) - { - smtp_reply = US"552 Message size exceeds maximum permitted"; - message_id[0] = 0; /* Indicate no message accepted */ - goto TIDYUP; /* Skip to end of function */ - } - else - { - fseek(data_file, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET); - give_local_error(ERRMESS_TOOBIG, - string_sprintf("message too big (max=%d)", thismessage_size_limit), - US"message rejected: ", error_rc, data_file, header_list); - /* Does not return */ - } + log_write(L_size_reject, LOG_MAIN|LOG_REJECT, "rejected from <%s>%s%s%s%s: " + "message too big: read=%d max=%d", + sender_address, + (sender_fullhost == NULL)? "" : " H=", + (sender_fullhost == NULL)? US"" : sender_fullhost, + (sender_ident == NULL)? "" : " U=", + (sender_ident == NULL)? US"" : sender_ident, + message_size, + thismessage_size_limit); + + if (smtp_input) + { + smtp_reply = US"552 Message size exceeds maximum permitted"; + message_id[0] = 0; /* Indicate no message accepted */ + goto TIDYUP; /* Skip to end of function */ + } + else + { + fseek(data_file, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET); + give_local_error(ERRMESS_TOOBIG, + string_sprintf("message too big (max=%d)", thismessage_size_limit), + US"message rejected: ", error_rc, data_file, header_list); + /* Does not return */ + } + break; + + /* Handle bad BDAT protocol sequence */ + + case END_PROTOCOL: + Uunlink(spool_name); /* Lose the data file when closed */ + cancel_cutthrough_connection("sender protocol error"); + smtp_reply = US""; /* Response already sent */ + message_id[0] = 0; /* Indicate no message accepted */ + goto TIDYUP; /* Skip to end of function */ } } @@ -3169,9 +3244,8 @@ user_msg = NULL; enable_dollar_recipients = TRUE; if (recipients_count == 0) - { - blackholed_by = recipients_discarded? US"MAIL ACL" : US"RCPT ACL"; - } + blackholed_by = recipients_discarded ? US"MAIL ACL" : US"RCPT ACL"; + else { /* Handle interactive SMTP messages */ @@ -3187,18 +3261,15 @@ else dkim_exim_verify_finish(); /* Check if we must run the DKIM ACL */ - if ((acl_smtp_dkim != NULL) && - (dkim_verify_signers != NULL) && - (dkim_verify_signers[0] != '\0')) + if (acl_smtp_dkim && dkim_verify_signers && *dkim_verify_signers) { uschar *dkim_verify_signers_expanded = expand_string(dkim_verify_signers); - if (dkim_verify_signers_expanded == NULL) - { + if (!dkim_verify_signers_expanded) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of dkim_verify_signers option failed: %s", expand_string_message); - } + else { int sep = 0; @@ -3207,28 +3278,23 @@ else uschar *seen_items = NULL; int seen_items_size = 0; int seen_items_offset = 0; - uschar itembuf[256]; /* Default to OK when no items are present */ rc = OK; - while ((item = string_nextinlist(&ptr, &sep, - itembuf, - sizeof(itembuf)))) + while ((item = string_nextinlist(&ptr, &sep, NULL, 0))) { /* Prevent running ACL for an empty item */ - if (!item || (item[0] == '\0')) continue; + if (!item || !*item) continue; /* Only run ACL once for each domain or identity, no matter how often it appears in the expanded list. */ if (seen_items) { uschar *seen_item = NULL; - uschar seen_item_buf[256]; const uschar *seen_items_list = seen_items; BOOL seen_this_item = FALSE; while ((seen_item = string_nextinlist(&seen_items_list, &sep, - seen_item_buf, - sizeof(seen_item_buf)))) + NULL, 0))) if (Ustrcmp(seen_item,item) == 0) { seen_this_item = TRUE; @@ -3787,7 +3853,7 @@ if (sender_host_authenticated) #ifndef DISABLE_PRDR if (prdr_requested) - s = string_append(s, &size, &sptr, 1, US" PRDR"); + s = string_catn(s, &size, &sptr, US" PRDR", 5); #endif #ifdef SUPPORT_PROXY @@ -3795,6 +3861,9 @@ if (proxy_session && LOGGING(proxy)) s = string_append(s, &size, &sptr, 2, US" PRX=", proxy_local_address); #endif +if (chunking_state > CHUNKING_OFFERED) + s = string_catn(s, &size, &sptr, US" K", 2); + sprintf(CS big_buffer, "%d", msg_size); s = string_append(s, &size, &sptr, 2, US" S=", big_buffer); @@ -4093,8 +4162,15 @@ if (smtp_input) /* Default OK response */ + else if (chunking_state > CHUNKING_OFFERED) + { + smtp_printf("250- %u byte chunk, total %d\r\n250 OK id=%s\r\n", + chunking_datasize, message_size+message_linecount, message_id); + chunking_state = CHUNKING_OFFERED; + } else smtp_printf("250 OK id=%s\r\n", message_id); + if (host_checking) fprintf(stdout, "\n**** SMTP testing: that is not a real message id!\n\n"); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index b00537eb5..d4b3e565a 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -291,6 +291,13 @@ static int smtp_had_eof; static int smtp_had_error; +/* forward declarations */ +int bdat_ungetc(int ch); +static int smtp_read_command(BOOL check_sync); +static int synprot_error(int type, int code, uschar *data, uschar *errmess); +static void smtp_quit_handler(uschar **, uschar **); +static void smtp_rset_handler(void); + /************************************************* * SMTP version of getc() * *************************************************/ @@ -339,6 +346,118 @@ return *smtp_inptr++; +/* Get a byte from the smtp input, in CHUNKING mode. Handle ack of the +previous BDAT chunk and getting new ones when we run out. Uses the +underlying smtp_getc or tls_getc both for that and for getting the +(buffered) data byte. EOD signals (an expected) no further data. +ERR signals a protocol error, and EOF a closed input stream. + +Called from read_bdat_smtp() in receive.c for the message body, but also +by the headers read loop in receive_msg(); manipulates chunking_state +to handle the BDAT command/response. +Placed here due to the correlation with the above smtp_getc(), which it wraps, +and also by the need to do smtp command/response handling. + +Arguments: none +Returns: the next character or ERR, EOD or EOF +*/ + +int +bdat_getc(void) +{ +uschar * user_msg = NULL; +uschar * log_msg; + +for(;;) + { + if (chunking_data_left-- > 0) + return lwr_receive_getc(); + + receive_getc = lwr_receive_getc; + receive_ungetc = lwr_receive_ungetc; + + /* If not the last, ack the received chunk. The last response is delayed + until after the data ACL decides on it */ + /*XXX find that "last response" and append the chunk size */ + + if (chunking_state == CHUNKING_LAST) + return EOD; + + chunking_state = CHUNKING_OFFERED; + smtp_printf("250 %u byte chunk received\r\n", chunking_datasize); + + /* Expect another BDAT cmd from input. RFC 3030 says nothing about + QUIT, RSET or NOOP but handling them seems obvious */ + +next_cmd: + switch(smtp_read_command(TRUE)) + { + default: + (void) synprot_error(L_smtp_protocol_error, 503, NULL, + US"only BDAT permissible after non-LAST BDAT"); + + repeat_until_rset: + switch(smtp_read_command(TRUE)) + { + case QUIT_CMD: smtp_quit_handler(&user_msg, &log_msg); /*FALLTHROUGH */ + case EOF_CMD: return EOF; + case RSET_CMD: smtp_rset_handler(); return ERR; + default: if (synprot_error(L_smtp_protocol_error, 503, NULL, + US"only RSET accepted now") > 0) + return EOF; + goto repeat_until_rset; + } + + case QUIT_CMD: + smtp_quit_handler(&user_msg, &log_msg); + /*FALLTHROUGH*/ + case EOF_CMD: + return EOF; + + case RSET_CMD: + smtp_rset_handler(); + return ERR; + + case NOOP_CMD: + HAD(SCH_NOOP); + smtp_printf("250 OK\r\n"); + goto next_cmd; + + case BDAT_CMD: + { + int n; + + if (sscanf(CS smtp_cmd_data, "%u %n", &chunking_datasize, &n) < 1) + { + (void) synprot_error(L_smtp_protocol_error, 501, NULL, + US"missing size for BDAT command"); + return ERR; + } + chunking_state = strcmpic(smtp_cmd_data+n, US"LAST") == 0 + ? CHUNKING_LAST : CHUNKING_ACTIVE; + chunking_data_left = chunking_datasize; + + if (chunking_datasize == 0) + if (chunking_state == CHUNKING_LAST) + return EOD; + else + { + (void) synprot_error(L_smtp_protocol_error, 504, NULL, + US"zero size for BDAT command"); + goto repeat_until_rset; + } + + receive_getc = bdat_getc; + receive_ungetc = bdat_ungetc; + break; /* to top of main loop */ + } + } + } +} + + + + /************************************************* * SMTP version of ungetc() * *************************************************/ @@ -355,11 +474,18 @@ Returns: the character int smtp_ungetc(int ch) { -*(--smtp_inptr) = ch; +*--smtp_inptr = ch; return ch; } +int +bdat_ungetc(int ch) +{ +chunking_data_left++; +return lwr_receive_ungetc(ch); +} + /************************************************* @@ -1527,7 +1653,6 @@ authenticated_sender = NULL; bmi_run = 0; bmi_verdicts = NULL; #endif -chunking_state = CHUNKING_NOT_OFFERED; #ifndef DISABLE_DKIM dkim_signers = NULL; dkim_disable_verify = FALSE; @@ -3239,6 +3364,43 @@ return 0; +static void +smtp_quit_handler(uschar ** user_msgp, uschar ** log_msgp) +{ +HAD(SCH_QUIT); +incomplete_transaction_log(US"QUIT"); +if (acl_smtp_quit != NULL) + { + int rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, user_msgp, log_msgp); + if (rc == ERROR) + log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s", + *log_msgp); + } +if (*user_msgp) + smtp_respond(US"221", 3, TRUE, *user_msgp); +else + smtp_printf("221 %s closing connection\r\n", smtp_active_hostname); + +#ifdef SUPPORT_TLS +tls_close(TRUE, TRUE); +#endif + +log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", + smtp_get_connection_info()); +} + + +static void +smtp_rset_handler(void) +{ +HAD(SCH_RSET); +incomplete_transaction_log(US"RSET"); +smtp_printf("250 Reset OK\r\n"); +cmd_list[CMD_LIST_RSET].is_mail_cmd = FALSE; +} + + + /************************************************* * Initialize for SMTP incoming message * *************************************************/ @@ -3285,6 +3447,8 @@ for the host). Note: we do NOT reset AUTH at this point. */ smtp_reset(reset_point); message_ended = END_NOTSTARTED; +chunking_state = chunking_offered ? CHUNKING_OFFERED : CHUNKING_NOT_OFFERED; + cmd_list[CMD_LIST_RSET].is_mail_cmd = TRUE; cmd_list[CMD_LIST_HELO].is_mail_cmd = TRUE; cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE; @@ -3775,6 +3939,7 @@ while (done <= 0) { s = string_catn(s, &size, &ptr, smtp_code, 3); s = string_catn(s, &size, &ptr, US"-CHUNKING\r\n", 11); + chunking_offered = TRUE; chunking_state = CHUNKING_OFFERED; } @@ -4546,12 +4711,18 @@ while (done <= 0) if (sscanf(CS smtp_cmd_data, "%u %n", &chunking_datasize, &n) < 1) { - done = synprot_error(L_smtp_protocol_error, 503, NULL, + done = synprot_error(L_smtp_protocol_error, 501, NULL, US"missing size for BDAT command"); break; } chunking_state = strcmpic(smtp_cmd_data+n, US"LAST") == 0 ? CHUNKING_LAST : CHUNKING_ACTIVE; + chunking_data_left = chunking_datasize; + + lwr_receive_getc = receive_getc; + lwr_receive_ungetc = receive_ungetc; + receive_getc = bdat_getc; + receive_ungetc = bdat_ungetc; DEBUG(D_any) debug_printf("chunking state %d\n", (int)chunking_state); @@ -4594,45 +4765,45 @@ while (done <= 0) break; } - /* No go-ahead output for BDAT */ - - if (smtp_connection_had[smtp_ch_index-1] == SCH_BDAT) - { + if (chunking_state > CHUNKING_OFFERED) + { /* No predata ACL or go-ahead output for BDAT */ rc = OK; - break; } - - /* If there is an ACL, re-check the synchronization afterwards, since the - ACL may have delayed. To handle cutthrough delivery enforce a dummy call - to get the DATA command sent. */ - - if (acl_smtp_predata == NULL && cutthrough.fd < 0) - rc = OK; else { - uschar * acl= acl_smtp_predata ? acl_smtp_predata : US"accept"; - enable_dollar_recipients = TRUE; - rc = acl_check(ACL_WHERE_PREDATA, NULL, acl, &user_msg, - &log_msg); - enable_dollar_recipients = FALSE; - if (rc == OK && !check_sync()) goto SYNC_FAILURE; - } + /* If there is an ACL, re-check the synchronization afterwards, since the + ACL may have delayed. To handle cutthrough delivery enforce a dummy call + to get the DATA command sent. */ - if (rc == OK) - { - uschar * code; - code = US"354"; - if (user_msg == NULL) - smtp_printf("%s Enter message, ending with \".\" on a line by itself\r\n", code); - else smtp_user_msg(code, user_msg); - done = 3; - message_ended = END_NOTENDED; /* Indicate in middle of data */ + if (acl_smtp_predata == NULL && cutthrough.fd < 0) + rc = OK; + else + { + uschar * acl = acl_smtp_predata ? acl_smtp_predata : US"accept"; + enable_dollar_recipients = TRUE; + rc = acl_check(ACL_WHERE_PREDATA, NULL, acl, &user_msg, + &log_msg); + enable_dollar_recipients = FALSE; + if (rc == OK && !check_sync()) + goto SYNC_FAILURE; + + if (rc != OK) + { /* Either the ACL failed the address, or it was deferred. */ + done = smtp_handle_acl_fail(ACL_WHERE_PREDATA, rc, user_msg, log_msg); + break; + } + } + + if (user_msg) + smtp_user_msg(US"354", user_msg); + else + smtp_printf( + "354 Enter message, ending with \".\" on a line by itself\r\n"); } - /* Either the ACL failed the address, or it was deferred. */ + done = 3; + message_ended = END_NOTENDED; /* Indicate in middle of data */ - else - done = smtp_handle_acl_fail(ACL_WHERE_PREDATA, rc, user_msg, log_msg); break; @@ -4868,37 +5039,15 @@ while (done <= 0) message. */ case QUIT_CMD: - HAD(SCH_QUIT); - incomplete_transaction_log(US"QUIT"); - if (acl_smtp_quit != NULL) - { - rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg, &log_msg); - if (rc == ERROR) - log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s", - log_msg); - } - if (user_msg == NULL) - smtp_printf("221 %s closing connection\r\n", smtp_active_hostname); - else - smtp_respond(US"221", 3, TRUE, user_msg); - - #ifdef SUPPORT_TLS - tls_close(TRUE, TRUE); - #endif - + smtp_quit_handler(&user_msg, &log_msg); done = 2; - log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", - smtp_get_connection_info()); break; case RSET_CMD: - HAD(SCH_RSET); - incomplete_transaction_log(US"RSET"); + smtp_rset_handler(); smtp_reset(reset_point); toomany = FALSE; - smtp_printf("250 Reset OK\r\n"); - cmd_list[CMD_LIST_RSET].is_mail_cmd = FALSE; break; @@ -4925,7 +5074,7 @@ while (done <= 0) verify_check_host(&tls_advertise_hosts) != FAIL) Ustrcat(buffer, " STARTTLS"); #endif - Ustrcat(buffer, " HELO EHLO MAIL RCPT DATA"); + Ustrcat(buffer, " HELO EHLO MAIL RCPT DATA BDAT"); Ustrcat(buffer, " NOOP QUIT RSET HELP"); if (acl_smtp_etrn != NULL) Ustrcat(buffer, " ETRN"); if (acl_smtp_expn != NULL) Ustrcat(buffer, " EXPN"); diff --git a/src/src/structs.h b/src/src/structs.h index 2b449a648..b49f4b574 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -51,7 +51,10 @@ typedef struct ugid_block { BOOL initgroups; } ugid_block; -typedef enum {CHUNKING_NOT_OFFERED, CHUNKING_OFFERED, CHUNKING_ACTIVE, CHUNKING_LAST} chunking_state_t; +typedef enum { CHUNKING_NOT_OFFERED = -1, + CHUNKING_OFFERED, + CHUNKING_ACTIVE, + CHUNKING_LAST} chunking_state_t; /* Structure for holding information about a host for use mainly by routers, but also used when checking lists of hosts and when transporting. Looking up diff --git a/test/confs/0900 b/test/confs/0900 new file mode 100644 index 000000000..4a014cee1 --- /dev/null +++ b/test/confs/0900 @@ -0,0 +1,71 @@ +# Exim test configuration 0900 + +exim_path = EXIM_PATH +keep_environment = +host_lookup_order = bydns +spool_directory = DIR/spool +log_file_path = DIR/spool/log/SERVER%slog +gecos_pattern = "" +gecos_name = CALLER_NAME +chunking_advertise_hosts = * +tls_advertise_hosts = + + +# ----- Main settings ----- + +domainlist local_domains = @ + +acl_smtp_rcpt = check_recipient +acl_smtp_data = check_data +message_id_header_domain = ${if eq{0}{0}{some.domain}} +message_id_header_text = ${if eq{0}{0}{a@b[c]}} +trusted_users = CALLER +queue_only +smtp_receive_timeout = 2s + + +# ----- ACL ----- + +begin acl + +check_recipient: + accept hosts = : + accept domains = +local_domains + deny message = relay not permitted + +check_data: + warn message = X-acl-message-linecount: $message_linecount + accept + + +# ----- Routers ----- + +begin routers + +fail_remote_domains: + driver = redirect + domains = ! +local_domains + data = :fail: unrouteable mail domain "$domain" + +localuser: + driver = accept + check_local_user + transport = local_delivery + headers_add = X-local-user: uid=$local_user_uid gid=$local_user_gid + + +# ----- Transports ----- + +begin transports + +local_delivery: + driver = appendfile + delivery_date_add + envelope_to_add + file = DIR/test-mail/$local_part + headers_add = "X-body-linecount: $body_linecount\n\ + X-message-linecount: $message_linecount\n\ + X-received-count: $received_count" + return_path_add + +# End diff --git a/test/log/0900 b/test/log/0900 new file mode 100644 index 000000000..37d70da7c --- /dev/null +++ b/test/log/0900 @@ -0,0 +1,9 @@ + +******** SERVER ******** +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 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F= +1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data +1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data diff --git a/test/scripts/0000-Basic/0900 b/test/scripts/0000-Basic/0900 new file mode 100644 index 000000000..cb8cf63e3 --- /dev/null +++ b/test/scripts/0000-Basic/0900 @@ -0,0 +1,170 @@ +# CHUNKING reception +exim -DSERVER=server -bd -oX PORT_D +**** +# +client 127.0.0.1 PORT_D +??? 220 +ehlo tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250-CHUNKING +??? 250 HELP +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 88 last +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250- +??? 250 +quit +??? 221 +**** +# +client 127.0.0.1 PORT_D +??? 220 +ehlo tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 100 +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyfull test message + +1234567890 +??? 250 +noop +??? 250 +bdat 0 last +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 10 +To: Susan@bdat 78 last +??? 250 +random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250- +??? 250 +quit +??? 221 +**** +# +# not enough data in chunk +# +client 127.0.0.1 PORT_D +??? 220 +ehlo tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 89 last +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 421 +**** +# +# protocol failure cases +# +client 127.0.0.1 PORT_D +??? 220 +ehlo tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 88 +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250 +bdat 0 +??? 504 +quit +??? 221 +**** +# +client 127.0.0.1 PORT_D +??? 220 +ehlo tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 88 +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250 +data +??? 503 +RSET +??? 250 +EHLO tester +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +mail from:someone@some.domain +??? 250 +rcpt to:CALLER@HOSTNAME +??? 250 +bdat 88 +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250 +data +??? 503 +data +??? 503 +quit +??? 221 +**** +# +killdaemon +no_msglog_check diff --git a/test/stdout/0900 b/test/stdout/0900 new file mode 100644 index 000000000..24c591617 --- /dev/null +++ b/test/stdout/0900 @@ -0,0 +1,232 @@ +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> ehlo tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 88 last +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> quit +??? 221 +<<< 221 the.local.host.name closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> ehlo tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 100 +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyfull test message +>>> +>>> 1234567890 +??? 250 +<<< 250 100 byte chunk received +>>> noop +??? 250 +<<< 250 OK +>>> bdat 0 last +??? 250- +<<< 250- 0 byte chunk, total 100 +??? 250 +<<< 250 OK id=10HmaY-0005vi-00 +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 10 +>>> To: Susan@bdat 78 last +??? 250 +<<< 250 10 byte chunk received +>>> random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250- +<<< 250- 78 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaZ-0005vi-00 +>>> quit +??? 221 +<<< 221 the.local.host.name closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> ehlo tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 89 last +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 421 +<<< 421 the.local.host.name SMTP incoming data timeout - closing connection. +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> ehlo tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 88 +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250 +<<< 250 88 byte chunk received +>>> bdat 0 +??? 504 +<<< 504 zero size for BDAT command +>>> quit +??? 221 +<<< 221 the.local.host.name closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> ehlo tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 88 +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250 +<<< 250 88 byte chunk received +>>> data +??? 503 +<<< 503 only BDAT permissible after non-LAST BDAT +>>> RSET +??? 250 +<<< 250 Reset OK +>>> EHLO tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> mail from:someone@some.domain +??? 250 +<<< 250 OK +>>> rcpt to:CALLER@the.local.host.name +??? 250 +<<< 250 Accepted +>>> bdat 88 +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250 +<<< 250 88 byte chunk received +>>> data +??? 503 +<<< 503 only BDAT permissible after non-LAST BDAT +>>> data +??? 503 +<<< 503 only RSET accepted now +>>> quit +??? 221 +<<< 221 the.local.host.name closing connection +End of script diff --git a/test/stdout/2122 b/test/stdout/2122 index 76433323a..55feb8f41 100644 --- a/test/stdout/2122 +++ b/test/stdout/2122 @@ -37,7 +37,7 @@ Succeeded in starting TLS ??? 214- <<< 214-Commands supported: ??? 214 -<<< 214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +<<< 214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP >>> quit ??? 221 <<< 221 myhost.test.ex closing connection -- cgit v1.2.3 From 65de12cc1acfeeacf85c3fd77d244b9dc7e79bdc Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 26 Jul 2016 19:44:08 +0100 Subject: tidying --- src/src/deliver.c | 30 +++++-- src/src/functions.h | 13 ++- src/src/queue.c | 2 +- src/src/structs.h | 11 +++ src/src/transport.c | 183 +++++++++++++++++++--------------------- src/src/transports/appendfile.c | 11 ++- src/src/transports/autoreply.c | 20 +++-- src/src/transports/lmtp.c | 11 ++- src/src/transports/pipe.c | 17 ++-- src/src/transports/smtp.c | 42 ++++----- src/src/verify.c | 7 +- test/stderr/0393 | 2 +- 12 files changed, 186 insertions(+), 163 deletions(-) (limited to 'test') diff --git a/src/src/deliver.c b/src/src/deliver.c index 450b58098..81f9a9aa2 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -6906,8 +6906,8 @@ if (addr_senddsn) { FILE *f = fdopen(fd, "wb"); /* header only as required by RFC. only failure DSN needs to honor RET=FULL */ - int topt = topt_add_return_path | topt_no_body; uschar * bound; + transport_ctx tctx; DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address); @@ -6986,7 +6986,10 @@ if (addr_senddsn) return_path = sender_address; /* In case not previously set */ /* Write the original email out */ - transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0); + + bzero(&tctx, sizeof(tctx)); + tctx.options = topt_add_return_path | topt_no_body; + transport_write_message(fileno(f), &tctx, 0); fflush(f); fprintf(f,"\n--%s--\n", bound); @@ -7441,8 +7444,18 @@ wording. */ fflush(f); transport_filter_argv = NULL; /* Just in case */ return_path = sender_address; /* In case not previously set */ - transport_write_message(NULL, fileno(f), topt, - 0, dsnnotifyhdr, NULL, NULL, NULL, NULL, 0); + { /* Dummy transport for headers add */ + transport_ctx * tctx = + store_get(sizeof(*tctx) + sizeof(transport_instance)); + transport_instance * tb = (transport_instance *)(tctx+1); + + bzero(tctx, sizeof(*tctx)+sizeof(*tb)); + tctx->tblock = tb; + tctx->options = topt; + tb->add_headers = dsnnotifyhdr; + + transport_write_message(fileno(f), tctx, 0); + } fflush(f); /* we never add the final text. close the file */ @@ -7758,7 +7771,9 @@ else if (addr_defer != (address_item *)(+1)) FILE *wmf = NULL; FILE *f = fdopen(fd, "wb"); uschar * bound; - int topt; + transport_ctx tctx; + + bzero(&tctx, sizeof(tctx)); if (warn_message_file) if (!(wmf = Ufopen(warn_message_file, "rb"))) @@ -7905,11 +7920,12 @@ else if (addr_defer != (address_item *)(+1)) fflush(f); /* header only as required by RFC. only failure DSN needs to honor RET=FULL */ - topt = topt_add_return_path | topt_no_body; + tctx.options = topt_add_return_path | topt_no_body; transport_filter_argv = NULL; /* Just in case */ return_path = sender_address; /* In case not previously set */ + /* Write the original email out */ - transport_write_message(NULL, fileno(f), topt, 0, NULL, NULL, NULL, NULL, NULL, 0); + transport_write_message(fileno(f), &tctx, 0); fflush(f); fprintf(f,"\n--%s--\n", bound); diff --git a/src/src/functions.h b/src/src/functions.h index 085ed5af7..27e9ff821 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -145,9 +145,8 @@ extern uschar *deliver_get_sender_address (uschar *id); extern BOOL directory_make(const uschar *, const uschar *, int, BOOL); #ifndef DISABLE_DKIM -extern BOOL dkim_transport_write_message(address_item *, int, int, - uschar *, uschar *, uschar *, uschar *, rewrite_rule *, - int, struct ob_dkim *); +extern BOOL dkim_transport_write_message(int, transport_ctx *, + struct ob_dkim *); #endif extern dns_address *dns_address_from_rr(dns_answer *, dns_record *); extern int dns_basic_lookup(dns_answer *, const uschar *, int); @@ -469,10 +468,10 @@ extern BOOL transport_set_up_command(const uschar ***, uschar *, extern void transport_update_waiting(host_item *, uschar *); extern BOOL transport_write_block(int, uschar *, int); extern BOOL transport_write_string(int, const char *, ...); -extern BOOL transport_headers_send(address_item *, int, uschar *, uschar *, - BOOL (*)(int, uschar *, int, unsigned), BOOL, rewrite_rule *, int); -extern BOOL transport_write_message(address_item *, int, int, int, uschar *, - uschar *, uschar *, uschar *, rewrite_rule *, int); +extern BOOL transport_headers_send(address_item *, int, transport_instance *, + BOOL (*)(int, uschar *, int, unsigned), + BOOL); +extern BOOL transport_write_message(int, transport_ctx *, int); extern void tree_add_duplicate(uschar *, address_item *); extern void tree_add_nonrecipient(uschar *); extern void tree_add_unusable(host_item *); diff --git a/src/src/queue.c b/src/src/queue.c index 1b7b9f74c..7648f47ca 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -1145,7 +1145,7 @@ switch(action) case MSG_SHOW_COPY: deliver_in_buffer = store_malloc(DELIVER_IN_BUFFER_SIZE); deliver_out_buffer = store_malloc(DELIVER_OUT_BUFFER_SIZE); - transport_write_message(NULL, 1, 0, 0, NULL, NULL, NULL, NULL, NULL, 0); + transport_write_message(1, NULL, 0); break; diff --git a/src/src/structs.h b/src/src/structs.h index b49f4b574..61f8a4169 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -223,6 +223,17 @@ typedef struct transport_info { } transport_info; +/* Structure for information about a delivery-in-progress */ + +typedef struct transport_context { + transport_instance * tblock; + struct address_item * addr; + uschar * check_string; + uschar * escape_string; + int options; /* topt_* */ +} transport_ctx; + + typedef struct { uschar *request; diff --git a/src/src/transport.c b/src/src/transport.c index dfe1d7782..148c1955f 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -623,12 +623,12 @@ Arguments: Returns: TRUE on success; FALSE on failure. */ BOOL -transport_headers_send(address_item *addr, int fd, uschar *add_headers, uschar *remove_headers, +transport_headers_send(address_item *addr, int fd, transport_instance * tblock, BOOL (*sendfn)(int fd, uschar * s, int len, unsigned options), - BOOL use_crlf, rewrite_rule *rewrite_rules, int rewrite_existflags) + BOOL use_crlf) { header_line *h; -unsigned wck_flags = use_crlf ? topt_use_bdat : 0; +const uschar *list; /* Then the message's headers. Don't write any that are flagged as "old"; that means they were rewritten, or are a record of envelope rewriting, or @@ -640,10 +640,9 @@ Then check addr->prop.remove_headers too, provided that addr is not NULL. */ for (h = header_list; h; h = h->next) if (h->type != htype_old) { int i; - const uschar *list = remove_headers; - BOOL include_header = TRUE; + list = tblock ? tblock->remove_headers : NULL; for (i = 0; i < 2; i++) /* For remove_headers && addr->prop.remove_headers */ { if (list) @@ -666,9 +665,9 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) while (*ss == ' ' || *ss == '\t') ss++; if (*ss == ':') break; } - if (s != NULL) { include_header = FALSE; break; } + if (s) { include_header = FALSE; break; } } - if (addr != NULL) list = addr->prop.remove_headers; + if (addr) list = addr->prop.remove_headers; } /* If this header is to be output, try to rewrite it if there are rewriting @@ -676,14 +675,15 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) if (include_header) { - if (rewrite_rules) + if (tblock && tblock->rewrite_rules) { void *reset_point = store_get(0); header_line *hh; - if ((hh = rewrite_header(h, NULL, NULL, rewrite_rules, rewrite_existflags, FALSE))) + if ((hh = rewrite_header(h, NULL, NULL, tblock->rewrite_rules, + tblock->rewrite_existflags, FALSE))) { - if (!sendfn(fd, hh->text, hh->slen, wck_flags)) return FALSE; + if (!sendfn(fd, hh->text, hh->slen, use_crlf)) return FALSE; store_reset(reset_point); continue; /* With the next header line */ } @@ -691,7 +691,7 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) /* Either no rewriting rules, or it didn't get rewritten */ - if (!sendfn(fd, h->text, h->slen, wck_flags)) return FALSE; + if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE; } /* Header removed */ @@ -726,7 +726,7 @@ if (addr) hprev = h; if (i == 1) { - if (!sendfn(fd, h->text, h->slen, wck_flags)) return FALSE; + if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE; DEBUG(D_transport) debug_printf("added header line(s):\n%s---\n", h->text); } @@ -740,19 +740,19 @@ up any other headers. An empty string or a forced expansion failure are noops. An added header string from a transport may not end with a newline; add one if it does not. */ -if (add_headers) +if (tblock && (list = CUS tblock->add_headers)) { int sep = '\n'; uschar * s; - while ((s = string_nextinlist(CUSS &add_headers, &sep, NULL, 0))) + while ((s = string_nextinlist(&list, &sep, NULL, 0))) if ((s = expand_string(s))) { int len = Ustrlen(s); if (len > 0) { - if (!sendfn(fd, s, len, wck_flags)) return FALSE; - if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, wck_flags)) + if (!sendfn(fd, s, len, use_crlf)) return FALSE; + if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, use_crlf)) return FALSE; DEBUG(D_transport) { @@ -768,7 +768,7 @@ if (add_headers) /* Separate headers from body with a blank line */ -return sendfn(fd, US"\n", 1, wck_flags); +return sendfn(fd, US"\n", 1, use_crlf); } @@ -801,31 +801,32 @@ can include timeouts for certain transports, which are requested by setting transport_write_timeout non-zero. Arguments: - addr (chain of) addresses (for extra headers), or NULL; - only the first address is used fd file descriptor to write the message to - options bit-wise options: - add_return_path if TRUE, add a "return-path" header - add_envelope_to if TRUE, add a "envelope-to" header - add_delivery_date if TRUE, add a "delivery-date" header - use_crlf if TRUE, turn NL into CR LF - end_dot if TRUE, send a terminating "." line at the end - no_headers if TRUE, omit the headers - no_body if TRUE, omit the body - use_bdat if TRUE, prepend written data with RFC3030 BDAT hdrs - size_limit if > 0, this is a limit to the size of message written; - it is used when returning messages to their senders, - and is approximate rather than exact, owing to chunk - buffering - add_headers a string containing one or more headers to add; it is - expanded, and must be in correct RFC 822 format as - it is transmitted verbatim; NULL => no additions, - and so does empty string or forced expansion fail - remove_headers a colon-separated list of headers to remove, or NULL - check_string a string to check for at the start of lines, or NULL - escape_string a string to insert in front of any check string - rewrite_rules chain of header rewriting rules - rewrite_existflags flags for the rewriting rules + tctx + addr (chain of) addresses (for extra headers), or NULL; + only the first address is used + tblock optional transport instance block (NULL signifies NULL/0): + add_headers a string containing one or more headers to add; it is + expanded, and must be in correct RFC 822 format as + it is transmitted verbatim; NULL => no additions, + and so does empty string or forced expansion fail + remove_headers a colon-separated list of headers to remove, or NULL + rewrite_rules chain of header rewriting rules + rewrite_existflags flags for the rewriting rules + options bit-wise options: + add_return_path if TRUE, add a "return-path" header + add_envelope_to if TRUE, add a "envelope-to" header + add_delivery_date if TRUE, add a "delivery-date" header + use_crlf if TRUE, turn NL into CR LF + end_dot if TRUE, send a terminating "." line at the end + no_headers if TRUE, omit the headers + no_body if TRUE, omit the body + size_limit if > 0, this is a limit to the size of message written; + it is used when returning messages to their senders, + and is approximate rather than exact, owing to chunk + buffering + check_string a string to check for at the start of lines, or NULL + escape_string a string to insert in front of any check string Returns: TRUE on success; FALSE (with errno) on failure. In addition, the global variable transport_count @@ -833,12 +834,10 @@ Returns: TRUE on success; FALSE (with errno) on failure. */ static BOOL -internal_transport_write_message(address_item *addr, int fd, int options, - int size_limit, uschar *add_headers, uschar *remove_headers, uschar *check_string, - uschar *escape_string, rewrite_rule *rewrite_rules, int rewrite_existflags) +internal_transport_write_message(int fd, transport_ctx * tctx, int size_limit) { int len; -unsigned wck_flags = (unsigned) options; +unsigned wck_flags = (unsigned) tctx->options; off_t fsize; int size; @@ -849,11 +848,11 @@ chunk_ptr = deliver_out_buffer; /* Set up the data for start-of-line data checking and escaping */ nl_partial_match = -1; -if (check_string && escape_string) +if (tctx->check_string && tctx->escape_string) { - nl_check = check_string; + nl_check = tctx->check_string; nl_check_length = Ustrlen(nl_check); - nl_escape = escape_string; + nl_escape = tctx->escape_string; nl_escape_length = Ustrlen(nl_escape); } else @@ -863,17 +862,17 @@ else an option (set for SMTP, not otherwise). Negate the length if not wanted till after the headers. */ -if (!(options & topt_escape_headers)) +if (!(tctx->options & topt_escape_headers)) nl_check_length = -nl_check_length; /* Write the headers if required, including any that have to be added. If there are header rewriting rules, apply them. */ -if (!(options & topt_no_headers)) +if (!(tctx->options & topt_no_headers)) { /* Add return-path: if requested. */ - if (options & topt_add_return_path) + if (tctx->options & topt_add_return_path) { uschar buffer[ADDRESS_MAXLENGTH + 20]; int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH, @@ -883,7 +882,7 @@ if (!(options & topt_no_headers)) /* Add envelope-to: if requested */ - if (options & topt_add_envelope_to) + if (tctx->options & topt_add_envelope_to) { BOOL first = TRUE; address_item *p; @@ -897,7 +896,7 @@ if (!(options & topt_no_headers)) anchors for lists of addresses already handled; they have to be defined at this level becuase write_env_to() calls itself recursively. */ - for (p = addr; p; p = p->next) + for (p = tctx->addr; p; p = p->next) if (!write_env_to(p, &plist, &dlist, &first, fd, wck_flags)) return FALSE; @@ -909,7 +908,7 @@ if (!(options & topt_no_headers)) /* Add delivery-date: if requested. */ - if (options & topt_add_delivery_date) + if (tctx->options & topt_add_delivery_date) { uschar buffer[100]; int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full)); @@ -921,8 +920,8 @@ if (!(options & topt_no_headers)) were removed (e.g. Bcc). If remove_headers is not null, skip any headers that match any entries therein. Then check addr->prop.remove_headers too, provided that addr is not NULL. */ - if (!transport_headers_send(addr, fd, add_headers, remove_headers, &write_chunk, - wck_flags, rewrite_rules, rewrite_existflags)) + + if (!transport_headers_send(tctx->addr, fd, tctx->tblock, &write_chunk, wck_flags)) return FALSE; } @@ -933,18 +932,18 @@ flush that buffer with non-last BDAT prependix) plus the amount of body data (as expanded for CRLF lines). Then create and write the BDAT, and ensure that further use of write_chunk() will not prepend BDATs. */ -if (options & topt_use_bdat) +if (tctx->options & topt_use_bdat) { if ((size = chunk_ptr - deliver_out_buffer) < 0) size = 0; - if (!(options & topt_no_body)) + if (!(tctx->options & topt_no_body)) { if ((fsize = lseek(deliver_datafile, 0, SEEK_END)) < 0) return FALSE; fsize -= SPOOL_DATA_START_OFFSET; if (size_limit > 0 && fsize > size_limit) fsize = size_limit; size += fsize; - if (options & topt_use_crlf) + if (tctx->options & topt_use_crlf) size += body_linecount; /* account for CRLF-expansion */ } @@ -972,7 +971,7 @@ negative in cases where it isn't to apply to the headers). Then ensure the body is positioned at the start of its file (following the message id), then write it, applying the size limit if required. */ -if (!(options & topt_no_body)) +if (!(tctx->options & topt_no_body)) { nl_check_length = abs(nl_check_length); nl_partial_match = 0; @@ -994,7 +993,7 @@ nl_check_length = nl_escape_length = 0; /* If requested, add a terminating "." line (SMTP output). */ -if (options & topt_end_dot && !write_chunk(fd, US".\n", 2, wck_flags)) +if (tctx->options & topt_end_dot && !write_chunk(fd, US".\n", 2, wck_flags)) return FALSE; /* Write out any remaining data in the buffer before returning. */ @@ -1026,10 +1025,8 @@ Returns: TRUE on success; FALSE (with errno) for any failure */ BOOL -dkim_transport_write_message(address_item *addr, int out_fd, int options, - uschar *add_headers, uschar *remove_headers, - uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules, - int rewrite_existflags, struct ob_dkim * dkim) +dkim_transport_write_message(int out_fd, transport_ctx * tctx, + struct ob_dkim * dkim) { int dkim_fd; int save_errno = 0; @@ -1044,10 +1041,7 @@ off_t k_file_size; /* If we can't sign, just call the original function. */ if (!(dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector)) - return transport_write_message(addr, out_fd, options, - 0, add_headers, remove_headers, - check_string, escape_string, rewrite_rules, - rewrite_existflags); + return transport_write_message(out_fd, tctx, 0); dkim_spool_name = spool_fname(US"input", message_subdir, message_id, string_sprintf("-%d-K", (int)getpid())); @@ -1062,10 +1056,8 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0) /* Call original function to write the -K file; does the CRLF expansion */ -rc = transport_write_message(addr, dkim_fd, options, - 0, add_headers, remove_headers, - check_string, escape_string, rewrite_rules, - rewrite_existflags); +tctx->options &= ~topt_use_bdat; +rc = transport_write_message(dkim_fd, tctx, 0); /* Save error state. We must clean up before returning. */ if (!rc) @@ -1217,6 +1209,7 @@ set up a filtering process, fork another process to call the internal function to write to the filter, and in this process just suck from the filter and write down the given fd. At the end, tidy up the pipes and the processes. +XXX Arguments: as for internal_transport_write_message() above Returns: TRUE on success; FALSE (with errno) for any failure @@ -1224,16 +1217,16 @@ Returns: TRUE on success; FALSE (with errno) for any failure */ BOOL -transport_write_message(address_item *addr, int fd, int options, - int size_limit, uschar *add_headers, uschar *remove_headers, - uschar *check_string, uschar *escape_string, rewrite_rule *rewrite_rules, - int rewrite_existflags) +transport_write_message(int fd, transport_ctx * tctx, int size_limit) { unsigned wck_flags; BOOL last_filter_was_NL = TRUE; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; pid_t filter_pid, write_pid; +static transport_ctx dummy_tctx = { NULL, NULL, NULL, NULL, 0 }; + +if (!tctx) tctx = &dummy_tctx; transport_filter_timed_out = FALSE; @@ -1244,22 +1237,20 @@ if ( !transport_filter_argv || !*transport_filter_argv || !**transport_filter_argv ) - return internal_transport_write_message(addr, fd, options, size_limit, - add_headers, remove_headers, check_string, escape_string, - rewrite_rules, rewrite_existflags); + return internal_transport_write_message(fd, tctx, size_limit); /* Otherwise the message must be written to a filter process and read back before being written to the incoming fd. First set up the special processing to be done during the copying. */ -wck_flags = options & topt_use_crlf; +wck_flags = tctx->options & topt_use_crlf; nl_partial_match = -1; -if (check_string != NULL && escape_string != NULL) +if (tctx->check_string && tctx->escape_string) { - nl_check = check_string; + nl_check = tctx->check_string; nl_check_length = Ustrlen(nl_check); - nl_escape = escape_string; + nl_escape = tctx->escape_string; nl_escape_length = Ustrlen(nl_escape); } else nl_check_length = nl_escape_length = 0; @@ -1283,7 +1274,7 @@ filter_pid = child_open(USS transport_filter_argv, NULL, 077, if (filter_pid < 0) goto TIDY_UP; /* errno set */ DEBUG(D_transport) - debug_printf("process %d running as transport filter: write=%d read=%d\n", + debug_printf("process %d running as transport filter: fd_write=%d fd_read=%d\n", (int)filter_pid, fd_write, fd_read); /* Fork subprocess to write the message to the filter, and return the result @@ -1297,16 +1288,18 @@ if ((write_pid = fork()) == 0) (void)close(fd_read); (void)close(pfd[pipe_read]); nl_check_length = nl_escape_length = 0; - rc = internal_transport_write_message(addr, fd_write, - (options & ~(topt_use_crlf | topt_end_dot)), - size_limit, add_headers, remove_headers, NULL, NULL, - rewrite_rules, rewrite_existflags); + + tctx->check_string = tctx->escape_string = NULL; + tctx->options &= ~(topt_use_crlf | topt_end_dot | topt_use_bdat); + + rc = internal_transport_write_message(fd_write, tctx, size_limit); + save_errno = errno; if ( write(pfd[pipe_write], (void *)&rc, sizeof(BOOL)) != sizeof(BOOL) || write(pfd[pipe_write], (void *)&save_errno, sizeof(int)) != sizeof(int) - || write(pfd[pipe_write], (void *)&(addr->more_errno), sizeof(int)) + || write(pfd[pipe_write], (void *)&tctx->addr->more_errno, sizeof(int)) != sizeof(int) ) rc = FALSE; /* compiler quietening */ @@ -1403,7 +1396,7 @@ if (filter_pid > 0 && (rc = child_close(filter_pid, 30)) != 0 && yield) { yield = FALSE; save_errno = ERRNO_FILTER_FAIL; - addr->more_errno = rc; + tctx->addr->more_errno = rc; DEBUG(D_transport) debug_printf("filter process returned %d\n", rc); } @@ -1424,7 +1417,7 @@ if (write_pid > 0) if (!ok) { dummy = read(pfd[pipe_read], (void *)&save_errno, sizeof(int)); - dummy = read(pfd[pipe_read], (void *)&(addr->more_errno), sizeof(int)); + dummy = read(pfd[pipe_read], (void *)&(tctx->addr->more_errno), sizeof(int)); yield = FALSE; } } @@ -1432,7 +1425,7 @@ if (write_pid > 0) { yield = FALSE; save_errno = ERRNO_FILTER_FAIL; - addr->more_errno = rc; + tctx->addr->more_errno = rc; DEBUG(D_transport) debug_printf("writing process returned %d\n", rc); } } @@ -1446,7 +1439,7 @@ filter was not NL, insert a NL to make the SMTP protocol work. */ if (yield) { nl_check_length = nl_escape_length = 0; - if ( options & topt_end_dot + if ( tctx->options & topt_end_dot && ( last_filter_was_NL ? !write_chunk(fd, US".\n", 2, wck_flags) : !write_chunk(fd, US"\n.\n", 3, wck_flags) @@ -1466,7 +1459,7 @@ DEBUG(D_transport) { debug_printf("end of filtering transport writing: yield=%d\n", yield); if (!yield) - debug_printf("errno=%d more_errno=%d\n", errno, addr->more_errno); + debug_printf("errno=%d more_errno=%d\n", errno, tctx->addr->more_errno); } return yield; diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 5dc4ee9b5..c9d150525 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -2874,9 +2874,14 @@ at initialization time. */ if (yield == OK) { - if (!transport_write_message(addr, fd, ob->options, 0, tblock->add_headers, - tblock->remove_headers, ob->check_string, ob->escape_string, - tblock->rewrite_rules, tblock->rewrite_existflags)) + transport_ctx tctx = { + tblock, + addr, + ob->check_string, + ob->escape_string, + ob->options + }; + if (!transport_write_message(fd, &tctx, 0)) yield = DEFER; } diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 54f9ef4de..36a68b92c 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -691,6 +691,17 @@ if (return_message) US"------ This is a copy of the body of the message, without the headers.\n" : US"------ This is a copy of the message, including all the headers.\n"; + transport_ctx tctx = { + tblock, + addr, + NULL, + NULL, + (tblock->body_only ? topt_no_headers : 0) | + (tblock->headers_only ? topt_no_body : 0) | + (tblock->return_path_add ? topt_add_return_path : 0) | + (tblock->delivery_date_add ? topt_add_delivery_date : 0) | + (tblock->envelope_to_add ? topt_add_envelope_to : 0) + }; if (bounce_return_size_limit > 0 && !tblock->headers_only) { @@ -710,14 +721,7 @@ if (return_message) fflush(f); transport_count = 0; - transport_write_message(addr, fileno(f), - (tblock->body_only? topt_no_headers : 0) | - (tblock->headers_only? topt_no_body : 0) | - (tblock->return_path_add? topt_add_return_path : 0) | - (tblock->delivery_date_add? topt_add_delivery_date : 0) | - (tblock->envelope_to_add? topt_add_envelope_to : 0), - bounce_return_size_limit, tblock->add_headers, tblock->remove_headers, - NULL, NULL, tblock->rewrite_rules, tblock->rewrite_existflags); + transport_write_message(fileno(f), &tctx, bounce_return_size_limit); } /* End the message and wait for the child process to end; no timeout. */ diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index bca597893..9624ece6a 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -609,6 +609,13 @@ for (addr = addrlist; addr != NULL; addr = addr->next) if (send_data) { BOOL ok; + transport_ctx tctx = { + tblock, + addrlist, + US".", + US"..", + ob->options + }; if (!lmtp_write_command(fd_in, "DATA\r\n")) goto WRITE_FAILED; if (!lmtp_read_response(out, buffer, sizeof(buffer), '3', timeout)) @@ -628,9 +635,7 @@ if (send_data) debug_printf(" LMTP>> writing message and terminating \".\"\n"); transport_count = 0; - ok = transport_write_message(addrlist, fd_in, ob->options, 0, - tblock->add_headers, tblock->remove_headers, US".", US"..", - tblock->rewrite_rules, tblock->rewrite_existflags); + ok = transport_write_message(fd_in, &tctx, 0); /* Failure can either be some kind of I/O disaster (including timeout), or the failure of a transport filter or the expansion of added headers. */ diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index db522e54b..e3d01974a 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -555,6 +555,13 @@ uschar *envp[50]; const uschar *envlist = ob->environment; uschar *cmd, *ss; uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n"; +transport_ctx tctx = { + tblock, + addr, + ob->check_string, + ob->escape_string, + ob->options /* set at initialization time */ +}; DEBUG(D_transport) debug_printf("%s transport entered\n", tblock->name); @@ -842,23 +849,19 @@ if (ob->use_bsmtp) if (!transport_write_string(fd_in, "MAIL FROM:<%s>%s", return_path, eol)) goto END_WRITE; - for (a = addr; a != NULL; a = a->next) - { + for (a = addr; a; a = a->next) if (!transport_write_string(fd_in, "RCPT TO:<%s>%s", transport_rcpt_address(a, tblock->rcpt_include_affixes), eol)) goto END_WRITE; - } if (!transport_write_string(fd_in, "DATA%s", eol)) goto END_WRITE; } -/* Now the actual message - the options were set at initialization time */ +/* Now the actual message */ -if (!transport_write_message(addr, fd_in, ob->options, 0, tblock->add_headers, - tblock->remove_headers, ob->check_string, ob->escape_string, - tblock->rewrite_rules, tblock->rewrite_existflags)) +if (!transport_write_message(fd_in, &tctx, 0)) goto END_WRITE; /* Now any configured suffix */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index fa5711b99..33de45cd7 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2358,24 +2358,25 @@ if (!ok) ok = TRUE; else { - int options = topt_use_crlf | topt_escape_headers - | (tblock->body_only ? topt_no_headers : 0) - | (tblock->headers_only ? topt_no_body : 0) - | (tblock->return_path_add ? topt_add_return_path : 0) - | (tblock->delivery_date_add ?topt_add_delivery_date :0) - | (tblock->envelope_to_add ? topt_add_envelope_to : 0); - uschar * str_spot, * str_repl; + transport_ctx tctx = { + tblock, + addrlist, + US".", US"..", /* Escaping strings */ + topt_use_crlf | topt_escape_headers + | (tblock->body_only ? topt_no_headers : 0) + | (tblock->headers_only ? topt_no_body : 0) + | (tblock->return_path_add ? topt_add_return_path : 0) + | (tblock->delivery_date_add ? topt_add_delivery_date : 0) + | (tblock->envelope_to_add ? topt_add_envelope_to : 0) + }; if (peer_offered & PEER_OFFERED_CHUNKING) { - options |= topt_use_bdat; - str_spot = str_repl = NULL; + tctx.options |= topt_use_bdat; + tctx.check_string = tctx.escape_string = NULL; } else - { - options |= topt_end_dot; - str_spot = US"."; str_repl = US".."; - } + tctx.options |= topt_end_dot; sigalrm_seen = FALSE; transport_write_timeout = ob->data_timeout; @@ -2387,20 +2388,9 @@ else transport_count = 0; #ifndef DISABLE_DKIM - ok = dkim_transport_write_message(addrlist, inblock.sock, - options, - tblock->add_headers, tblock->remove_headers, - str_spot, str_repl, /* Escaping strings */ - tblock->rewrite_rules, tblock->rewrite_existflags, - &ob->dkim - ); + ok = dkim_transport_write_message(inblock.sock, &tctx, &ob->dkim); #else - ok = transport_write_message(addrlist, inblock.sock, - options, - 0, /* No size limit */ - tblock->add_headers, tblock->remove_headers, - str_spot, str_repl, /* Escaping strings */ - tblock->rewrite_rules, tblock->rewrite_existflags); + ok = transport_write_message(inblock.sock, &tctx, 0); #endif /* transport_write_message() uses write() because it is called from other diff --git a/src/src/verify.c b/src/src/verify.c index 7e0f066f9..f5f478edd 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1589,11 +1589,8 @@ if(cutthrough.fd < 0) HDEBUG(D_acl) debug_printf("----------- start cutthrough headers send -----------\n"); if (!transport_headers_send(&cutthrough.addr, cutthrough.fd, - cutthrough.addr.transport->add_headers, - cutthrough.addr.transport->remove_headers, - &cutthrough_write_chunk, topt_use_crlf, - cutthrough.addr.transport->rewrite_rules, - cutthrough.addr.transport->rewrite_existflags)) + cutthrough.addr.transport, + &cutthrough_write_chunk, topt_use_crlf)) return FALSE; HDEBUG(D_acl) debug_printf("----------- done cutthrough headers send ------------\n"); diff --git a/test/stderr/0393 b/test/stderr/0393 index c40aa6f52..673d9e6f9 100644 --- a/test/stderr/0393 +++ b/test/stderr/0393 @@ -27,7 +27,7 @@ lock file created mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 -process pppp running as transport filter: write=dddd read=dddd +process pppp running as transport filter: fd_write=10 fd_read=11 writing data block fd=dddd size=sss timeout=0 process pppp writing to transport filter copying from the filter -- cgit v1.2.3 From 6d5c916cc5720591335fea53242dd6b97ea56fe3 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 28 Jul 2016 22:41:17 +0100 Subject: Callback into smtp transport for BDAT commands --- src/src/deliver.c | 21 +++---- src/src/functions.h | 5 +- src/src/smtp_in.c | 10 ++- src/src/smtp_out.c | 74 +++++++++++----------- src/src/structs.h | 27 ++++++-- src/src/transport.c | 104 +++++++++++++++---------------- src/src/transports/autoreply.c | 3 +- src/src/transports/lmtp.c | 3 +- src/src/transports/pipe.c | 2 +- src/src/transports/smtp.c | 137 +++++++++++++++++++++++++++++++++++------ src/src/verify.c | 16 +++-- test/confs/0611 | 1 + 12 files changed, 262 insertions(+), 141 deletions(-) (limited to 'test') diff --git a/src/src/deliver.c b/src/src/deliver.c index 81f9a9aa2..419dee92c 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -6907,7 +6907,7 @@ if (addr_senddsn) FILE *f = fdopen(fd, "wb"); /* header only as required by RFC. only failure DSN needs to honor RET=FULL */ uschar * bound; - transport_ctx tctx; + transport_ctx tctx = {0}; DEBUG(D_deliver) debug_printf("sending error message to: %s\n", sender_address); @@ -6987,7 +6987,6 @@ if (addr_senddsn) /* Write the original email out */ - bzero(&tctx, sizeof(tctx)); tctx.options = topt_add_return_path | topt_no_body; transport_write_message(fileno(f), &tctx, 0); fflush(f); @@ -7445,16 +7444,14 @@ wording. */ transport_filter_argv = NULL; /* Just in case */ return_path = sender_address; /* In case not previously set */ { /* Dummy transport for headers add */ - transport_ctx * tctx = - store_get(sizeof(*tctx) + sizeof(transport_instance)); - transport_instance * tb = (transport_instance *)(tctx+1); + transport_ctx tctx = {0}; + transport_instance tb = {0}; - bzero(tctx, sizeof(*tctx)+sizeof(*tb)); - tctx->tblock = tb; - tctx->options = topt; - tb->add_headers = dsnnotifyhdr; + tctx.tblock = &tb; + tctx.options = topt; + tb.add_headers = dsnnotifyhdr; - transport_write_message(fileno(f), tctx, 0); + transport_write_message(fileno(f), &tctx, 0); } fflush(f); @@ -7771,9 +7768,7 @@ else if (addr_defer != (address_item *)(+1)) FILE *wmf = NULL; FILE *f = fdopen(fd, "wb"); uschar * bound; - transport_ctx tctx; - - bzero(&tctx, sizeof(tctx)); + transport_ctx tctx = {0}; if (warn_message_file) if (!(wmf = Ufopen(warn_message_file, "rb"))) diff --git a/src/src/functions.h b/src/src/functions.h index 27e9ff821..260b365df 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -468,9 +468,8 @@ extern BOOL transport_set_up_command(const uschar ***, uschar *, extern void transport_update_waiting(host_item *, uschar *); extern BOOL transport_write_block(int, uschar *, int); extern BOOL transport_write_string(int, const char *, ...); -extern BOOL transport_headers_send(address_item *, int, transport_instance *, - BOOL (*)(int, uschar *, int, unsigned), - BOOL); +extern BOOL transport_headers_send(int, transport_ctx *, + BOOL (*)(int, transport_ctx *, uschar *, int)); extern BOOL transport_write_message(int, transport_ctx *, int); extern void tree_add_duplicate(uschar *, address_item *); extern void tree_add_nonrecipient(uschar *); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index d4b3e565a..3144b39ad 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -73,7 +73,6 @@ enum { ETRN_CMD, /* This by analogy with TURN from the RFC */ STARTTLS_CMD, /* Required by the STARTTLS RFC */ TLS_AUTH_CMD, /* auto-command at start of SSL */ - BDAT_CMD, /* Implied by RFC3030 "After all MAIL and..." */ /* This is a dummy to identify the non-sync commands when pipelining */ @@ -83,6 +82,15 @@ enum { MAIL_CMD, RCPT_CMD, RSET_CMD, + /* RFC3030 section 2: "After all MAIL and RCPT responses are collected and + processed the message is sent using a series of BDAT commands" + implies that BDAT should be synchronized. However, we see Google, at least, + sending MAIL,RCPT,BDAT-LAST in a single packet, clearly not waiting for + processing of the RPCT response(s). We shall do the same, and not require + synch for BDAT. */ + + BDAT_CMD, + /* This is a dummy to identify the non-sync commands when not pipelining */ NON_SYNC_CMD_NON_PIPELINING, diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 6b4843175..76181b5f1 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -357,6 +357,7 @@ Arguments: noflush if TRUE, save the command in the output buffer, for pipelining format a format, starting with one of of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT. + If NULL, flush pipeline buffer only. ... data for the format Returns: 0 if command added to pipelining buffer, with nothing transmitted @@ -371,48 +372,51 @@ int count; int rc = 0; va_list ap; -va_start(ap, format); -if (!string_vformat(big_buffer, big_buffer_size, CS format, ap)) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " - "SMTP"); -va_end(ap); -count = Ustrlen(big_buffer); - -if (count > outblock->buffersize) - log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " - "SMTP"); - -if (count > outblock->buffersize - (outblock->ptr - outblock->buffer)) +if (format) { - rc = outblock->cmd_count; /* flush resets */ - if (!flush_buffer(outblock)) return -1; - } + va_start(ap, format); + if (!string_vformat(big_buffer, big_buffer_size, CS format, ap)) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " + "SMTP"); + va_end(ap); + count = Ustrlen(big_buffer); + + if (count > outblock->buffersize) + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "overlong write_command in outgoing " + "SMTP"); + + if (count > outblock->buffersize - (outblock->ptr - outblock->buffer)) + { + rc = outblock->cmd_count; /* flush resets */ + if (!flush_buffer(outblock)) return -1; + } -Ustrncpy(CS outblock->ptr, big_buffer, count); -outblock->ptr += count; -outblock->cmd_count++; -count -= 2; -big_buffer[count] = 0; /* remove \r\n for error message */ + Ustrncpy(CS outblock->ptr, big_buffer, count); + outblock->ptr += count; + outblock->cmd_count++; + count -= 2; + big_buffer[count] = 0; /* remove \r\n for error message */ -/* We want to hide the actual data sent in AUTH transactions from reflections -and logs. While authenticating, a flag is set in the outblock to enable this. -The AUTH command itself gets any data flattened. Other lines are flattened -completely. */ + /* We want to hide the actual data sent in AUTH transactions from reflections + and logs. While authenticating, a flag is set in the outblock to enable this. + The AUTH command itself gets any data flattened. Other lines are flattened + completely. */ -if (outblock->authenticating) - { - uschar *p = big_buffer; - if (Ustrncmp(big_buffer, "AUTH ", 5) == 0) + if (outblock->authenticating) { - p += 5; - while (isspace(*p)) p++; - while (!isspace(*p)) p++; - while (isspace(*p)) p++; + uschar *p = big_buffer; + if (Ustrncmp(big_buffer, "AUTH ", 5) == 0) + { + p += 5; + while (isspace(*p)) p++; + while (!isspace(*p)) p++; + while (isspace(*p)) p++; + } + while (*p != 0) *p++ = '*'; } - while (*p != 0) *p++ = '*'; - } -HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> %s\n", big_buffer); + HDEBUG(D_transport|D_acl|D_v) debug_printf(" SMTP>> %s\n", big_buffer); + } if (!noflush) { diff --git a/src/src/structs.h b/src/src/structs.h index 61f8a4169..2a6ca68ab 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -223,14 +223,31 @@ typedef struct transport_info { } transport_info; +/* smtp transport datachunk callback */ + +struct transport_context; +typedef int (*tpt_chunk_cmd_cb)(int fd, struct transport_context * tctx, + unsigned len, BOOL last); + /* Structure for information about a delivery-in-progress */ typedef struct transport_context { - transport_instance * tblock; - struct address_item * addr; - uschar * check_string; - uschar * escape_string; - int options; /* topt_* */ + transport_instance * tblock; /* transport */ + struct address_item * addr; + uschar * check_string; /* string replacement */ + uschar * escape_string; + int options; /* output processing topt_* */ + + /* items below only used with option topt_use_bdat */ + tpt_chunk_cmd_cb chunk_cb; /* per-datachunk callback */ + struct smtp_inblock * inblock; + struct smtp_outblock * outblock; + host_item * host; + struct address_item * first_addr; + struct address_item **sync_addr; + BOOL pending_MAIL; + BOOL * completed_address; + int cmd_count; } transport_ctx; diff --git a/src/src/transport.c b/src/src/transport.c index 148c1955f..8c81e8a9e 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -359,9 +359,7 @@ Arguments: fd file descript to write to chunk pointer to data to write len length of data to write - flags bitmap of topt_ flags for processing options - use_crlf terminate lines with CRLF - use_bdat prepend chunks with RFC3030 BDAT header + tctx transport context - processing to be done during output In addition, the static nl_xxx variables must be set as required. @@ -369,7 +367,7 @@ Returns: TRUE on success, FALSE on failure (with errno preserved) */ static BOOL -write_chunk(int fd, uschar *chunk, int len, unsigned flags) +write_chunk(int fd, transport_ctx * tctx, uschar *chunk, int len) { uschar *start = chunk; uschar *end = chunk + len; @@ -412,19 +410,23 @@ possible. */ for (ptr = start; ptr < end; ptr++) { - int ch; + int ch, len; /* Flush the buffer if it has reached the threshold - we want to leave enough room for the next uschar, plus a possible extra CR for an LF, plus the escape string. */ -/*XXX CHUNKING: need to prefix write_block with a BDAT cmd. Also possibly -reap a response from a previous BDAT first. NEED a callback into the tpt -for that */ - if (chunk_ptr - deliver_out_buffer > mlen) + /*XXX CHUNKING: probably want to increase DELIVER_OUT_BUFFER_SIZE */ + if ((len = chunk_ptr - deliver_out_buffer) > mlen) { - if (!transport_write_block(fd, deliver_out_buffer, - chunk_ptr - deliver_out_buffer)) + /* If CHUNKING, prefix with BDAT (size) NON-LAST. Also, reap responses + from previous SMTP commands. */ + + if (tctx && tctx->options & topt_use_bdat && tctx->chunk_cb) + if (tctx->chunk_cb(fd, tctx, (unsigned)len, FALSE) != OK) + return FALSE; + + if (!transport_write_block(fd, deliver_out_buffer, len)) return FALSE; chunk_ptr = deliver_out_buffer; } @@ -435,7 +437,7 @@ for that */ /* Insert CR before NL if required */ - if (flags & topt_use_crlf) *chunk_ptr++ = '\r'; + if (tctx && tctx->options & topt_use_crlf) *chunk_ptr++ = '\r'; *chunk_ptr++ = '\n'; transport_newlines++; @@ -552,14 +554,14 @@ Arguments: pdlist address of anchor of the list of processed addresses first TRUE if this is the first address; set it FALSE afterwards fd the file descriptor to write to - flags to be passed on to write_chunk() + tctx transport context - processing to be done during output Returns: FALSE if writing failed */ static BOOL write_env_to(address_item *p, struct aci **pplist, struct aci **pdlist, - BOOL *first, int fd, unsigned flags) + BOOL *first, int fd, transport_ctx * tctx) { address_item *pp; struct aci *ppp; @@ -581,7 +583,7 @@ for (pp = p;; pp = pp->parent) address_item *dup; for (dup = addr_duplicate; dup; dup = dup->next) if (dup->dupof == pp) /* a dup of our address */ - if (!write_env_to(dup, pplist, pdlist, first, fd, flags)) + if (!write_env_to(dup, pplist, pdlist, first, fd, tctx)) return FALSE; if (!pp->parent) break; } @@ -598,9 +600,9 @@ ppp->next = *pplist; *pplist = ppp; ppp->ptr = pp; -if (!*first && !write_chunk(fd, US",\n ", 3, flags)) return FALSE; +if (!*first && !write_chunk(fd, tctx, US",\n ", 3)) return FALSE; *first = FALSE; -return write_chunk(fd, pp->address, Ustrlen(pp->address), flags); +return write_chunk(fd, tctx, pp->address, Ustrlen(pp->address)); } @@ -616,19 +618,23 @@ Arguments: only the first address is used fd file descriptor to write the message to sendfn function for output (transport or verify) - use_crlf turn NL into CR LF + wck_flags + use_crlf turn NL into CR LF + use_bdat callback before chunk flush rewrite_rules chain of header rewriting rules rewrite_existflags flags for the rewriting rules + chunk_cb transport callback function for data-chunk commands Returns: TRUE on success; FALSE on failure. */ BOOL -transport_headers_send(address_item *addr, int fd, transport_instance * tblock, - BOOL (*sendfn)(int fd, uschar * s, int len, unsigned options), - BOOL use_crlf) +transport_headers_send(int fd, transport_ctx * tctx, + BOOL (*sendfn)(int fd, transport_ctx * tctx, uschar * s, int len)) { header_line *h; const uschar *list; +transport_instance * tblock = tctx ? tctx->tblock : NULL; +address_item * addr = tctx ? tctx->addr : NULL; /* Then the message's headers. Don't write any that are flagged as "old"; that means they were rewritten, or are a record of envelope rewriting, or @@ -683,7 +689,7 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) if ((hh = rewrite_header(h, NULL, NULL, tblock->rewrite_rules, tblock->rewrite_existflags, FALSE))) { - if (!sendfn(fd, hh->text, hh->slen, use_crlf)) return FALSE; + if (!sendfn(fd, tctx, hh->text, hh->slen)) return FALSE; store_reset(reset_point); continue; /* With the next header line */ } @@ -691,7 +697,7 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) /* Either no rewriting rules, or it didn't get rewritten */ - if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE; + if (!sendfn(fd, tctx, h->text, h->slen)) return FALSE; } /* Header removed */ @@ -726,7 +732,7 @@ if (addr) hprev = h; if (i == 1) { - if (!sendfn(fd, h->text, h->slen, use_crlf)) return FALSE; + if (!sendfn(fd, tctx, h->text, h->slen)) return FALSE; DEBUG(D_transport) debug_printf("added header line(s):\n%s---\n", h->text); } @@ -751,8 +757,8 @@ if (tblock && (list = CUS tblock->add_headers)) int len = Ustrlen(s); if (len > 0) { - if (!sendfn(fd, s, len, use_crlf)) return FALSE; - if (s[len-1] != '\n' && !sendfn(fd, US"\n", 1, use_crlf)) + if (!sendfn(fd, tctx, s, len)) return FALSE; + if (s[len-1] != '\n' && !sendfn(fd, tctx, US"\n", 1)) return FALSE; DEBUG(D_transport) { @@ -768,7 +774,7 @@ if (tblock && (list = CUS tblock->add_headers)) /* Separate headers from body with a blank line */ -return sendfn(fd, US"\n", 1, use_crlf); +return sendfn(fd, tctx, US"\n", 1); } @@ -837,7 +843,6 @@ static BOOL internal_transport_write_message(int fd, transport_ctx * tctx, int size_limit) { int len; -unsigned wck_flags = (unsigned) tctx->options; off_t fsize; int size; @@ -877,7 +882,7 @@ if (!(tctx->options & topt_no_headers)) uschar buffer[ADDRESS_MAXLENGTH + 20]; int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH, return_path); - if (!write_chunk(fd, buffer, n, wck_flags)) return FALSE; + if (!write_chunk(fd, tctx, buffer, n)) return FALSE; } /* Add envelope-to: if requested */ @@ -890,19 +895,19 @@ if (!(tctx->options & topt_no_headers)) struct aci *dlist = NULL; void *reset_point = store_get(0); - if (!write_chunk(fd, US"Envelope-to: ", 13, wck_flags)) return FALSE; + if (!write_chunk(fd, tctx, US"Envelope-to: ", 13)) return FALSE; /* Pick up from all the addresses. The plist and dlist variables are anchors for lists of addresses already handled; they have to be defined at this level becuase write_env_to() calls itself recursively. */ for (p = tctx->addr; p; p = p->next) - if (!write_env_to(p, &plist, &dlist, &first, fd, wck_flags)) + if (!write_env_to(p, &plist, &dlist, &first, fd, tctx)) return FALSE; /* Add a final newline and reset the store used for tracking duplicates */ - if (!write_chunk(fd, US"\n", 1, wck_flags)) return FALSE; + if (!write_chunk(fd, tctx, US"\n", 1)) return FALSE; store_reset(reset_point); } @@ -912,7 +917,7 @@ if (!(tctx->options & topt_no_headers)) { uschar buffer[100]; int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full)); - if (!write_chunk(fd, buffer, n, wck_flags)) return FALSE; + if (!write_chunk(fd, tctx, buffer, n)) return FALSE; } /* Then the message's headers. Don't write any that are flagged as "old"; @@ -921,7 +926,7 @@ if (!(tctx->options & topt_no_headers)) match any entries therein. Then check addr->prop.remove_headers too, provided that addr is not NULL. */ - if (!transport_headers_send(tctx->addr, fd, tctx->tblock, &write_chunk, wck_flags)) + if (!transport_headers_send(fd, tctx, &write_chunk)) return FALSE; } @@ -947,22 +952,13 @@ if (tctx->options & topt_use_bdat) size += body_linecount; /* account for CRLF-expansion */ } - /*XXX need an smtp_outblock here; can't really use the smtp - tpts one. so that had better have been flushed. - - WORRY: smtp cmd response sync, needs an inblock and a LOT - of tpt info. NEED a callback into the tpt. + /*XXX CHUNKING: + Emit a LAST datachunk command. */ -#ifdef notdef - smtp_write_command(&outblock, FALSE, "BDAT %d LAST\r\n", size); - if (count < 0) return FALSE; - if (count > 0) - { - } -#endif - */ + if (tctx->chunk_cb(fd, tctx, size, TRUE) != OK) + return FALSE; - wck_flags &= ~topt_use_bdat; + tctx->options &= ~topt_use_bdat; } /* If the body is required, ensure that the data for check strings (formerly @@ -979,7 +975,7 @@ if (!(tctx->options & topt_no_body)) return FALSE; while ( (len = MAX(DELIVER_IN_BUFFER_SIZE, size)) > 0 && (len = read(deliver_datafile, deliver_in_buffer, len)) > 0) - if (!write_chunk(fd, deliver_in_buffer, len, wck_flags)) + if (!write_chunk(fd, tctx, deliver_in_buffer, len)) return FALSE; /* A read error on the body will have left len == -1 and errno set. */ @@ -993,7 +989,7 @@ nl_check_length = nl_escape_length = 0; /* If requested, add a terminating "." line (SMTP output). */ -if (tctx->options & topt_end_dot && !write_chunk(fd, US".\n", 2, wck_flags)) +if (tctx->options & topt_end_dot && !write_chunk(fd, tctx, US".\n", 2)) return FALSE; /* Write out any remaining data in the buffer before returning. */ @@ -1224,7 +1220,7 @@ BOOL last_filter_was_NL = TRUE; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; pid_t filter_pid, write_pid; -static transport_ctx dummy_tctx = { NULL, NULL, NULL, NULL, 0 }; +static transport_ctx dummy_tctx = {0}; if (!tctx) tctx = &dummy_tctx; @@ -1359,7 +1355,7 @@ for (;;) if (len > 0) { - if (!write_chunk(fd, deliver_in_buffer, len, wck_flags)) goto TIDY_UP; + if (!write_chunk(fd, tctx, deliver_in_buffer, len)) goto TIDY_UP; last_filter_was_NL = (deliver_in_buffer[len-1] == '\n'); } @@ -1441,8 +1437,8 @@ if (yield) nl_check_length = nl_escape_length = 0; if ( tctx->options & topt_end_dot && ( last_filter_was_NL - ? !write_chunk(fd, US".\n", 2, wck_flags) - : !write_chunk(fd, US"\n.\n", 3, wck_flags) + ? !write_chunk(fd, tctx, US".\n", 2) + : !write_chunk(fd, tctx, US"\n.\n", 3) ) ) yield = FALSE; diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 36a68b92c..f07cd83cf 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -694,8 +694,7 @@ if (return_message) transport_ctx tctx = { tblock, addr, - NULL, - NULL, + NULL, NULL, (tblock->body_only ? topt_no_headers : 0) | (tblock->headers_only ? topt_no_body : 0) | (tblock->return_path_add ? topt_add_return_path : 0) | diff --git a/src/src/transports/lmtp.c b/src/src/transports/lmtp.c index 9624ece6a..0cc981064 100644 --- a/src/src/transports/lmtp.c +++ b/src/src/transports/lmtp.c @@ -612,8 +612,7 @@ if (send_data) transport_ctx tctx = { tblock, addrlist, - US".", - US"..", + US".", US"..", ob->options }; diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index e3d01974a..d3841e050 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -554,7 +554,7 @@ const uschar **argv; uschar *envp[50]; const uschar *envlist = ob->environment; uschar *cmd, *ss; -uschar *eol = (ob->use_crlf)? US"\r\n" : US"\n"; +uschar *eol = ob->use_crlf ? US"\r\n" : US"\n"; transport_ctx tctx = { tblock, addr, diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 33de45cd7..58a59433d 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1361,6 +1361,63 @@ return checks; } + +/* Callback for emitting a BDAT data chunk header. +Flush any buffered SMTP commands first. +Reap SMTP command responses if not the BDAT LAST. + +A nonlast request that is size zero is special-cased to only flush the +command buffer and reap all outstanding responses. + +Returns: OK or ERROR +*/ + +static int +smtp_chunk_cmd_callback(int fd, transport_ctx * tctx, + unsigned chunk_size, BOOL chunk_last) +{ +smtp_transport_options_block * ob = + (smtp_transport_options_block *)(tctx->tblock->options_block); +uschar buffer[128]; + +if ( (tctx->cmd_count = chunk_size == 0 && !chunk_last + + /* Handle flush request */ + ? smtp_write_command(tctx->outblock, FALSE, NULL) + + /* Write SMTP chunk header command */ + : smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n", + chunk_size, chunk_last ? " LAST" : "") + ) + < 0) + return ERROR; + +if (chunk_last) + return OK; + +/* Reap responses for this and any previous, and error out on failure */ +debug_printf("(look for %d responses)\n", tctx->cmd_count); + +switch(sync_responses(tctx->first_addr, tctx->tblock->rcpt_include_affixes, + tctx->sync_addr, tctx->host, tctx->cmd_count, + ob->address_retry_include_sender, + tctx->pending_MAIL, 0, + tctx->inblock, + ob->command_timeout, + buffer, sizeof(buffer))) + { + case 1: /* 2xx (only) => OK */ + case 3: /* 2xx & 5xx => OK & progress made */ + case 2: *tctx->completed_address = TRUE; /* 5xx (only) => progress made */ + case 0: return OK; /* No 2xx or 5xx, but no probs */ + + case -1: /* Timeout on RCPT */ + default: return ERROR; /* I/O error, or any MAIL/DATA error */ + } +} + + + /************************************************* * Deliver address list to given host * *************************************************/ @@ -2107,14 +2164,11 @@ for (dsn_all_lasthop = TRUE, addr = first_addr; if (smtp_use_dsn && !dsn_all_lasthop) { if (dsn_ret == dsn_ret_hdrs) - { - Ustrcpy(p, " RET=HDRS"); p += 9; - } + { Ustrcpy(p, " RET=HDRS"); p += 9; } else if (dsn_ret == dsn_ret_full) - { - Ustrcpy(p, " RET=FULL"); p += 9; - } - if (dsn_envid != NULL) + { Ustrcpy(p, " RET=FULL"); p += 9; } + + if (dsn_envid) { string_format(p, sizeof(buffer) - (p-buffer), " ENVID=%s", dsn_envid); while (*p) p++; @@ -2320,15 +2374,19 @@ if (mua_wrapper) send DATA, but if it is FALSE (in the normal, non-wrapper case), we may still have a good recipient buffered up if we are pipelining. We don't want to waste time sending DATA needlessly, so we only send it if either ok is TRUE or if we -are pipelining. The responses are all handled by sync_responses(). */ +are pipelining. The responses are all handled by sync_responses(). +If using CHUNKING, do not send a BDAT until we know how big a chunk we want +to send is. */ -if (ok || (smtp_use_pipelining && !mua_wrapper)) +if ( !(peer_offered & PEER_OFFERED_CHUNKING) + && (ok || (smtp_use_pipelining && !mua_wrapper))) { int count = smtp_write_command(&outblock, FALSE, "DATA\r\n"); + if (count < 0) goto SEND_FAILED; switch(sync_responses(first_addr, tblock->rcpt_include_affixes, &sync_addr, host, count, ob->address_retry_include_sender, pending_MAIL, - ok? +1 : -1, &inblock, ob->command_timeout, buffer, sizeof(buffer))) + ok ? +1 : -1, &inblock, ob->command_timeout, buffer, sizeof(buffer))) { case 3: ok = TRUE; /* 2xx & 5xx => OK & progress made */ case 2: completed_address = TRUE; /* 5xx (only) => progress made */ @@ -2343,10 +2401,6 @@ if (ok || (smtp_use_pipelining && !mua_wrapper)) } } -/* Save the first address of the next batch. */ - -first_addr = addr; - /* If there were no good recipients (but otherwise there have been no problems), just set ok TRUE, since we have handled address-specific errors already. Otherwise, it's OK to send the message. Use the check/escape mechanism @@ -2354,8 +2408,13 @@ for handling the SMTP dot-handling protocol, flagging to apply to headers as well as body. Set the appropriate timeout value to be used for each chunk. (Haven't been able to make it work using select() for writing yet.) */ -if (!ok) +if (!(peer_offered & PEER_OFFERED_CHUNKING) && !ok) + { + /* Save the first address of the next batch. */ + first_addr = addr; + ok = TRUE; + } else { transport_ctx tctx = { @@ -2367,24 +2426,41 @@ else | (tblock->headers_only ? topt_no_body : 0) | (tblock->return_path_add ? topt_add_return_path : 0) | (tblock->delivery_date_add ? topt_add_delivery_date : 0) - | (tblock->envelope_to_add ? topt_add_envelope_to : 0) + | (tblock->envelope_to_add ? topt_add_envelope_to : 0), }; + /* If using CHUNKING we need a callback from the generic transport + support to us, for the sending of BDAT smtp commands and the reaping + of responses. The callback needs a whole bunch of state so set up + a transport-context structure to be passed around. */ + if (peer_offered & PEER_OFFERED_CHUNKING) { - tctx.options |= topt_use_bdat; tctx.check_string = tctx.escape_string = NULL; + tctx.options |= topt_use_bdat; + tctx.chunk_cb = smtp_chunk_cmd_callback; + tctx.inblock = &inblock; + tctx.outblock = &outblock; + tctx.host = host; + tctx.first_addr = first_addr; + tctx.sync_addr = &sync_addr; + tctx.pending_MAIL = pending_MAIL; + tctx.completed_address = &completed_address; } else tctx.options |= topt_end_dot; + /* Save the first address of the next batch. */ + first_addr = addr; + sigalrm_seen = FALSE; transport_write_timeout = ob->data_timeout; smtp_command = US"sending data block"; /* For error messages */ DEBUG(D_transport|D_v) - debug_printf(" SMTP>> writing message %s\n", - peer_offered & PEER_OFFERED_CHUNKING - ? "using CHUNKING" : "and terminating \".\""); + if (peer_offered & PEER_OFFERED_CHUNKING) + debug_printf(" will write message using CHUNKING\n"); + else + debug_printf(" SMTP>> writing message and terminating \".\"\n"); transport_count = 0; #ifndef DISABLE_DKIM @@ -2417,6 +2493,27 @@ else smtp_command = US"end of data"; + if (peer_offered & PEER_OFFERED_CHUNKING && tctx.cmd_count > 1) + { + /* Reap any outstanding MAIL & RCPT commands, but not a DATA-go-ahead */ + switch(sync_responses(first_addr, tblock->rcpt_include_affixes, &sync_addr, + host, tctx.cmd_count-1, ob->address_retry_include_sender, + pending_MAIL, 0, + &inblock, ob->command_timeout, buffer, sizeof(buffer))) + { + case 3: ok = TRUE; /* 2xx & 5xx => OK & progress made */ + case 2: completed_address = TRUE; /* 5xx (only) => progress made */ + break; + + case 1: ok = TRUE; /* 2xx (only) => OK, but if LMTP, */ + if (!lmtp) completed_address = TRUE; /* can't tell about progress yet */ + case 0: break; /* No 2xx or 5xx, but no probs */ + + case -1: goto END_OFF; /* Timeout on RCPT */ + default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */ + } + } + #ifndef DISABLE_PRDR /* For PRDR we optionally get a partial-responses warning * followed by the individual responses, before going on with diff --git a/src/src/verify.c b/src/src/verify.c index f5f478edd..4c4dfc599 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1559,9 +1559,9 @@ return cutthrough_response('3', NULL) == '3'; } -/* fd and options args only to match write_chunk() */ +/* fd and tctx args only to match write_chunk() */ static BOOL -cutthrough_write_chunk(int fd, uschar * s, int len, unsigned options) +cutthrough_write_chunk(int fd, transport_ctx * tctx, uschar * s, int len) { uschar * s2; while(s && (s2 = Ustrchr(s, '\n'))) @@ -1580,6 +1580,8 @@ return TRUE; BOOL cutthrough_headers_send(void) { +transport_ctx tctx; + if(cutthrough.fd < 0) return FALSE; @@ -1588,9 +1590,13 @@ if(cutthrough.fd < 0) */ HDEBUG(D_acl) debug_printf("----------- start cutthrough headers send -----------\n"); -if (!transport_headers_send(&cutthrough.addr, cutthrough.fd, - cutthrough.addr.transport, - &cutthrough_write_chunk, topt_use_crlf)) +tctx.tblock = cutthrough.addr.transport; +tctx.addr = &cutthrough.addr; +tctx.check_string = US"."; +tctx.escape_string = US".."; +tctx.options = topt_use_crlf; + +if (!transport_headers_send(cutthrough.fd, &tctx, &cutthrough_write_chunk)) return FALSE; HDEBUG(D_acl) debug_printf("----------- done cutthrough headers send ------------\n"); diff --git a/test/confs/0611 b/test/confs/0611 index e8b4c51d4..4f6f490d3 100644 --- a/test/confs/0611 +++ b/test/confs/0611 @@ -11,6 +11,7 @@ spool_directory = DIR/spool gecos_pattern = "" gecos_name = CALLER_NAME tls_advertise_hosts = +chunking_advertise_hosts = # ----- Main settings ----- -- cgit v1.2.3 From e027f545443fd6a5ec74c48c27dcd8b6634d5bba Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 30 Jul 2016 16:29:22 +0100 Subject: basic & pipelined transmit testcases --- src/src/receive.c | 3 +- src/src/structs.h | 9 +- src/src/transport.c | 47 ++- src/src/transports/smtp.c | 151 ++++--- test/confs/0900 | 21 +- test/confs/0901 | 1 + test/confs/0902 | 1 + test/log/0217 | 44 +- test/log/0218 | 2 +- test/log/0322 | 16 +- test/log/0495 | 8 +- test/log/0497 | 6 +- test/log/0552 | 6 +- test/log/0901 | 38 ++ test/log/0902 | 31 ++ test/log/2026 | 4 +- test/scripts/0000-Basic/0217 | 16 +- test/scripts/0000-Basic/0901 | 309 +++++++++++++++ test/scripts/0000-Basic/0902 | 925 +++++++++++++++++++++++++++++++++++++++++++ test/src/server.c | 32 ++ test/stderr/0218 | 2 +- test/stderr/0495 | 4 +- test/stdout/0217 | 30 +- test/stdout/0547 | 20 +- test/stdout/0572 | 1 + test/stdout/0901 | 199 ++++++++++ test/stdout/0902 | 140 +++++++ test/stdout/2022 | 2 +- 28 files changed, 1921 insertions(+), 147 deletions(-) create mode 120000 test/confs/0901 create mode 120000 test/confs/0902 create mode 100644 test/log/0901 create mode 100644 test/log/0902 create mode 100644 test/scripts/0000-Basic/0901 create mode 100644 test/scripts/0000-Basic/0902 create mode 100644 test/stdout/0901 create mode 100644 test/stdout/0902 (limited to 'test') diff --git a/src/src/receive.c b/src/src/receive.c index 9ff339d39..3b048252d 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -682,7 +682,8 @@ while ((ch = (receive_getc)()) != EOF) case 1: /* After written "\n" */ if (ch == '.') { ch_state = 3; continue; } if (ch == '\r') { ch_state = 2; continue; } - if (ch != '\n') ch_state = 0; else linelength = -1; + if (ch == '\n') { body_linecount++; linelength = -1; } + else ch_state = 0; break; case 2: diff --git a/src/src/structs.h b/src/src/structs.h index 2a6ca68ab..e378a16a2 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -225,9 +225,13 @@ typedef struct transport_info { /* smtp transport datachunk callback */ +#define tc_reap_prev BIT(0) /* Flags: reap previous SMTP cmd responses */ +#define tc_reap_one BIT(1) /* reap one SMTP response */ +#define tc_chunk_last BIT(2) /* annotate chunk SMTP cmd as LAST */ + struct transport_context; typedef int (*tpt_chunk_cmd_cb)(int fd, struct transport_context * tctx, - unsigned len, BOOL last); + unsigned len, unsigned flags); /* Structure for information about a delivery-in-progress */ @@ -246,8 +250,11 @@ typedef struct transport_context { struct address_item * first_addr; struct address_item **sync_addr; BOOL pending_MAIL; + BOOL pending_BDAT; + BOOL good_RCPT; BOOL * completed_address; int cmd_count; + uschar * buffer; } transport_ctx; diff --git a/src/src/transport.c b/src/src/transport.c index 8c81e8a9e..e55e81f2f 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -423,7 +423,7 @@ for (ptr = start; ptr < end; ptr++) from previous SMTP commands. */ if (tctx && tctx->options & topt_use_bdat && tctx->chunk_cb) - if (tctx->chunk_cb(fd, tctx, (unsigned)len, FALSE) != OK) + if (tctx->chunk_cb(fd, tctx, (unsigned)len, tc_reap_prev|tc_reap_one) != OK) return FALSE; if (!transport_write_block(fd, deliver_out_buffer, len)) @@ -843,8 +843,6 @@ static BOOL internal_transport_write_message(int fd, transport_ctx * tctx, int size_limit) { int len; -off_t fsize; -int size; /* Initialize pointer in output buffer. */ @@ -935,27 +933,51 @@ last BDAT, consisting of the current write_chunk() output buffer fill (optimally, all of the headers - but it does not matter if we already had to flush that buffer with non-last BDAT prependix) plus the amount of body data (as expanded for CRLF lines). Then create and write the BDAT, and ensure -that further use of write_chunk() will not prepend BDATs. */ +that further use of write_chunk() will not prepend BDATs. +The first BDAT written will also first flush any outstanding MAIL and RCPT +commands which were buffered thans to PIPELINING. +Commands go out (using a send()) from a different buffer to data (using a +write()). They might not end up in the same TCP segment, which is +suboptimal. */ if (tctx->options & topt_use_bdat) { - if ((size = chunk_ptr - deliver_out_buffer) < 0) - size = 0; + off_t fsize; + int hsize, size; + + if ((hsize = chunk_ptr - deliver_out_buffer) < 0) + hsize = 0; if (!(tctx->options & topt_no_body)) { if ((fsize = lseek(deliver_datafile, 0, SEEK_END)) < 0) return FALSE; fsize -= SPOOL_DATA_START_OFFSET; if (size_limit > 0 && fsize > size_limit) fsize = size_limit; - size += fsize; + size = hsize + fsize; if (tctx->options & topt_use_crlf) size += body_linecount; /* account for CRLF-expansion */ } - /*XXX CHUNKING: - Emit a LAST datachunk command. */ + /* If the message is large, emit first a non-LAST chunk with just the + headers, and reap the command responses. This lets us error out early + on RCPT rejects rather than sending megabytes of data. Include headers + on the assumption they are cheap enough and some clever implementations + might errorcheck them too, on-the-fly, and reject that chunk. */ + + if (size > DELIVER_OUT_BUFFER_SIZE && hsize > 0) + { + if ( tctx->chunk_cb(fd, tctx, hsize, 0) != OK + || !transport_write_block(fd, deliver_out_buffer, hsize) + || tctx->chunk_cb(fd, tctx, 0, tc_reap_prev) != OK + ) + return FALSE; + chunk_ptr = deliver_out_buffer; + size -= hsize; + } + + /* Emit a LAST datachunk command. */ - if (tctx->chunk_cb(fd, tctx, size, TRUE) != OK) + if (tctx->chunk_cb(fd, tctx, size, tc_chunk_last) != OK) return FALSE; tctx->options &= ~topt_use_bdat; @@ -969,14 +991,19 @@ it, applying the size limit if required. */ if (!(tctx->options & topt_no_body)) { + int size = size_limit; + nl_check_length = abs(nl_check_length); nl_partial_match = 0; if (lseek(deliver_datafile, SPOOL_DATA_START_OFFSET, SEEK_SET) < 0) return FALSE; while ( (len = MAX(DELIVER_IN_BUFFER_SIZE, size)) > 0 && (len = read(deliver_datafile, deliver_in_buffer, len)) > 0) + { if (!write_chunk(fd, tctx, deliver_in_buffer, len)) return FALSE; + size -= len; + } /* A read error on the body will have left len == -1 and errno set. */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 58a59433d..00274656c 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -282,6 +282,7 @@ static uschar *rf_names[] = { US"NEVER", US"SUCCESS", US"FAILURE", US"DELAY" }; static uschar *smtp_command; /* Points to last cmd for error messages */ static uschar *mail_command; /* Points to MAIL cmd for error messages */ static BOOL update_waiting; /* TRUE to update the "wait" database */ +static BOOL pipelining_active; /* current transaction is in pipe mode */ /************************************************* @@ -510,13 +511,7 @@ static BOOL check_response(host_item *host, int *errno_value, int more_errno, uschar *buffer, int *yield, uschar **message, BOOL *pass_message) { -uschar *pl = US""; - -if (smtp_use_pipelining && - (Ustrcmp(smtp_command, "MAIL") == 0 || - Ustrcmp(smtp_command, "RCPT") == 0 || - Ustrcmp(smtp_command, "DATA") == 0)) - pl = US"pipelined "; +uschar * pl = pipelining_active ? US"pipelined " : US""; *yield = '4'; /* Default setting is to give a temporary error */ @@ -786,6 +781,7 @@ if (pending_MAIL) count--; if (!smtp_read_response(inblock, buffer, buffsize, '2', timeout)) { + DEBUG(D_transport) debug_printf("bad response for MAIL\n"); Ustrcpy(big_buffer, mail_command); /* Fits, because it came from there! */ if (errno == 0 && buffer[0] != 0) { @@ -1363,57 +1359,95 @@ return checks; /* Callback for emitting a BDAT data chunk header. -Flush any buffered SMTP commands first. -Reap SMTP command responses if not the BDAT LAST. -A nonlast request that is size zero is special-cased to only flush the -command buffer and reap all outstanding responses. +If given a nonzero size, first flush any buffered SMTP commands +then emit the command. + +Reap previous SMTP command responses if requested. +Reap one SMTP command response if requested. Returns: OK or ERROR */ static int smtp_chunk_cmd_callback(int fd, transport_ctx * tctx, - unsigned chunk_size, BOOL chunk_last) + unsigned chunk_size, unsigned flags) { smtp_transport_options_block * ob = (smtp_transport_options_block *)(tctx->tblock->options_block); -uschar buffer[128]; +int cmd_count = 0; +int prev_cmd_count; +uschar * buffer = tctx->buffer; -if ( (tctx->cmd_count = chunk_size == 0 && !chunk_last - /* Handle flush request */ - ? smtp_write_command(tctx->outblock, FALSE, NULL) +/* Write SMTP chunk header command */ - /* Write SMTP chunk header command */ - : smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n", - chunk_size, chunk_last ? " LAST" : "") - ) - < 0) - return ERROR; +if (chunk_size > 0) + if((cmd_count = smtp_write_command(tctx->outblock, FALSE, "BDAT %u%s\r\n", + chunk_size, + flags & tc_chunk_last ? " LAST" : "") + ) < 0) return ERROR; + +prev_cmd_count = cmd_count += tctx->cmd_count; -if (chunk_last) - return OK; +/* Reap responses for any previous, but not one we just emitted */ -/* Reap responses for this and any previous, and error out on failure */ -debug_printf("(look for %d responses)\n", tctx->cmd_count); +if (chunk_size > 0) + prev_cmd_count--; +if (tctx->pending_BDAT) + prev_cmd_count--; -switch(sync_responses(tctx->first_addr, tctx->tblock->rcpt_include_affixes, - tctx->sync_addr, tctx->host, tctx->cmd_count, - ob->address_retry_include_sender, - tctx->pending_MAIL, 0, - tctx->inblock, - ob->command_timeout, - buffer, sizeof(buffer))) +if (flags & tc_reap_prev && prev_cmd_count > 0) { - case 1: /* 2xx (only) => OK */ - case 3: /* 2xx & 5xx => OK & progress made */ - case 2: *tctx->completed_address = TRUE; /* 5xx (only) => progress made */ - case 0: return OK; /* No 2xx or 5xx, but no probs */ - case -1: /* Timeout on RCPT */ - default: return ERROR; /* I/O error, or any MAIL/DATA error */ + switch(sync_responses(tctx->first_addr, tctx->tblock->rcpt_include_affixes, + tctx->sync_addr, tctx->host, prev_cmd_count, + ob->address_retry_include_sender, + tctx->pending_MAIL, 0, + tctx->inblock, + ob->command_timeout, + buffer, 4096)) +/*XXX buffer size! */ + { + case 1: /* 2xx (only) => OK */ + case 3: tctx->good_RCPT = TRUE; /* 2xx & 5xx => OK & progress made */ + case 2: *tctx->completed_address = TRUE; /* 5xx (only) => progress made */ + case 0: break; /* No 2xx or 5xx, but no probs */ + + case -1: /* Timeout on RCPT */ + default: return ERROR; /* I/O error, or any MAIL/DATA error */ + } + cmd_count = 1; + if (!tctx->pending_BDAT) + pipelining_active = FALSE; } + +/* Reap response for the cmd we just emitted, or an outstanding BDAT */ + +if (flags & tc_reap_one || tctx->pending_BDAT) + { +/*XXX buffer size! */ + if (!smtp_read_response(tctx->inblock, buffer, 4096, '2', + ob->command_timeout)) + { + if (errno == 0 && buffer[0] == '4') + { + errno = ERRNO_DATA4XX; /*XXX does this actually get used? */ + tctx->first_addr->more_errno |= + ((buffer[1] - '0')*10 + buffer[2] - '0') << 8; + } + return ERROR; + } + cmd_count--; + tctx->pending_BDAT = FALSE; + pipelining_active = FALSE; + } +else if (chunk_size > 0) + tctx->pending_BDAT = TRUE; + + +tctx->cmd_count = cmd_count; +return OK; } @@ -2043,6 +2077,7 @@ if (continue_hostname == NULL case FAIL: goto RESPONSE_FAILED; } } +pipelining_active = smtp_use_pipelining; /* The setting up of the SMTP call is now complete. Any subsequent errors are message-specific. */ @@ -2399,6 +2434,7 @@ if ( !(peer_offered & PEER_OFFERED_CHUNKING) case -1: goto END_OFF; /* Timeout on RCPT */ default: goto RESPONSE_FAILED; /* I/O error, or any MAIL/DATA error */ } + pipelining_active = FALSE; } /* If there were no good recipients (but otherwise there have been no @@ -2445,7 +2481,11 @@ else tctx.first_addr = first_addr; tctx.sync_addr = &sync_addr; tctx.pending_MAIL = pending_MAIL; + tctx.pending_BDAT = FALSE; + tctx.good_RCPT = ok; tctx.completed_address = &completed_address; + tctx.cmd_count = 0; + tctx.buffer = buffer; } else tctx.options |= topt_end_dot; @@ -2453,6 +2493,11 @@ else /* Save the first address of the next batch. */ first_addr = addr; + /* Responses from CHUNKING commands go in buffer. Otherwise, + there has not been a response. */ + + buffer[0] = 0; + sigalrm_seen = FALSE; transport_write_timeout = ob->data_timeout; smtp_command = US"sending data block"; /* For error messages */ @@ -2477,13 +2522,11 @@ else transport_write_timeout = 0; /* for subsequent transports */ /* Failure can either be some kind of I/O disaster (including timeout), - or the failure of a transport filter or the expansion of added headers. */ + or the failure of a transport filter or the expansion of added headers. + Or, when CHUNKING, it can be a protocol-detected failure. */ if (!ok) - { - buffer[0] = 0; /* There hasn't been a response */ goto RESPONSE_FAILED; - } /* We used to send the terminating "." explicitly here, but because of buffering effects at both ends of TCP/IP connections, you don't gain @@ -2523,16 +2566,16 @@ else { ok = smtp_read_response(&inblock, buffer, sizeof(buffer), '3', ob->final_timeout); - if (!ok && errno == 0) - switch(buffer[0]) - { - case '2': prdr_active = FALSE; - ok = TRUE; - break; - case '4': errno = ERRNO_DATA4XX; - addrlist->more_errno |= ((buffer[1] - '0')*10 + buffer[2] - '0') << 8; - break; - } + if (!ok && errno == 0) switch(buffer[0]) + { + case '2': prdr_active = FALSE; + ok = TRUE; + break; + case '4': errno = ERRNO_DATA4XX; + addrlist->more_errno |= + ((buffer[1] - '0')*10 + buffer[2] - '0') << 8; + break; + } } else #endif @@ -2569,7 +2612,9 @@ else int delivery_time = (int)(time(NULL) - start_delivery_time); int len; uschar *conf = NULL; + send_rset = FALSE; + pipelining_active = FALSE; /* Set up confirmation if needed - applies only to SMTP */ diff --git a/test/confs/0900 b/test/confs/0900 index 4a014cee1..cdc6d84eb 100644 --- a/test/confs/0900 +++ b/test/confs/0900 @@ -1,4 +1,5 @@ # Exim test configuration 0900 +SERVER= exim_path = EXIM_PATH keep_environment = @@ -17,8 +18,6 @@ domainlist local_domains = @ acl_smtp_rcpt = check_recipient acl_smtp_data = check_data -message_id_header_domain = ${if eq{0}{0}{some.domain}} -message_id_header_text = ${if eq{0}{0}{a@b[c]}} trusted_users = CALLER queue_only smtp_receive_timeout = 2s @@ -42,6 +41,12 @@ check_data: begin routers +to_server: + driver = accept + condition = ${if !eq {SERVER}{server}} + transport = remote_smtp + errors_to = "" + fail_remote_domains: driver = redirect domains = ! +local_domains @@ -68,4 +73,16 @@ local_delivery: X-received-count: $received_count" return_path_add +remote_smtp: + driver = smtp + hosts = 127.0.0.1 + port = PORT_S + allow_localhost + command_timeout = 2s + final_timeout = 2s + +# ----- Retry ----- + +begin retry +* * F,30m,5m; # End diff --git a/test/confs/0901 b/test/confs/0901 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/0901 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/confs/0902 b/test/confs/0902 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/0902 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/log/0217 b/test/log/0217 index 1328a46db..b3cf93c4b 100644 --- a/test/log/0217 +++ b/test/log/0217 @@ -8,49 +8,49 @@ 1999-03-02 09:44:33 10HmaY-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmaZ-0005vi-00 == a@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO: -1999-03-02 09:44:33 10HmaZ-0005vi-00 == b@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO: -1999-03-02 09:44:33 10HmaZ-0005vi-00 == c@test.ex R=client T=send_to_server defer (dd): Connection timed out: SMTP timeout after RCPT TO: +1999-03-02 09:44:33 10HmaZ-0005vi-00 == e@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO: +1999-03-02 09:44:33 10HmaZ-0005vi-00 == f@test.ex R=client T=send_to_server defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after RCPT TO: +1999-03-02 09:44:33 10HmaZ-0005vi-00 == g@test.ex R=client T=send_to_server defer (dd): Connection timed out: SMTP timeout after RCPT TO: 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbA-0005vi-00 == a@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 451 Temp error -1999-03-02 09:44:33 10HmbA-0005vi-00 == b@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 451 Temp error +1999-03-02 09:44:33 10HmbA-0005vi-00 == h@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 451 Temp error +1999-03-02 09:44:33 10HmbA-0005vi-00 == i@test.ex R=client T=send_to_server defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 451 Temp error 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 Perm error -1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 Perm error +1999-03-02 09:44:33 10HmbB-0005vi-00 ** j@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 Perm error +1999-03-02 09:44:33 10HmbB-0005vi-00 ** k@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 Perm error 1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbC-0005vi-00 ** CALLER@test.ex R=bounce: just discard 1999-03-02 09:44:33 10HmbC-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbD-0005vi-00 == a@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 1 -1999-03-02 09:44:33 10HmbD-0005vi-00 == b@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 2 +1999-03-02 09:44:33 10HmbD-0005vi-00 == l@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 1 +1999-03-02 09:44:33 10HmbD-0005vi-00 == m@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 2 1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbE-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 1 -1999-03-02 09:44:33 10HmbE-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 2 +1999-03-02 09:44:33 10HmbE-0005vi-00 ** n@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 1 +1999-03-02 09:44:33 10HmbE-0005vi-00 ** o@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 2 1999-03-02 09:44:33 10HmbF-0005vi-00 <= <> R=10HmbE-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbF-0005vi-00 ** CALLER@test.ex R=bounce: just discard 1999-03-02 09:44:33 10HmbF-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmbF-0005vi-00 Completed 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed 1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbG-0005vi-00 == a@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 1 -1999-03-02 09:44:33 10HmbG-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 2 +1999-03-02 09:44:33 10HmbG-0005vi-00 == p@test.ex R=client T=send_to_server defer (-44) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 451 Temp error 1 +1999-03-02 09:44:33 10HmbG-0005vi-00 ** q@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 551 Perm error 2 1999-03-02 09:44:33 10HmbH-0005vi-00 <= <> R=10HmbG-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbH-0005vi-00 ** CALLER@test.ex R=bounce: just discard 1999-03-02 09:44:33 10HmbH-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmbH-0005vi-00 Completed 1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbI-0005vi-00 ** a@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error -1999-03-02 09:44:33 10HmbI-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error +1999-03-02 09:44:33 10HmbI-0005vi-00 ** r@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error +1999-03-02 09:44:33 10HmbI-0005vi-00 ** s@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 503 Sorry perm data error 1999-03-02 09:44:33 10HmbJ-0005vi-00 <= <> R=10HmbI-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbJ-0005vi-00 ** CALLER@test.ex R=bounce: just discard 1999-03-02 09:44:33 10HmbJ-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmbJ-0005vi-00 Completed 1999-03-02 09:44:33 10HmbI-0005vi-00 Completed 1999-03-02 09:44:33 10HmbK-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbK-0005vi-00 == a@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error -1999-03-02 09:44:33 10HmbK-0005vi-00 == b@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error +1999-03-02 09:44:33 10HmbK-0005vi-00 == t@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error +1999-03-02 09:44:33 10HmbK-0005vi-00 == u@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error 1999-03-02 09:44:33 10HmbL-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss 1999-03-02 09:44:33 10HmbL-0005vi-00 == yes@test.ex R=client T=send_to_server defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined DATA: 403 Sorry temp data error 1999-03-02 09:44:33 10HmbL-0005vi-00 ** n00@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 NO @@ -258,12 +258,12 @@ 1999-03-02 09:44:33 10HmbM-0005vi-00 CALLER@test.ex: error ignored 1999-03-02 09:44:33 10HmbM-0005vi-00 Completed 1999-03-02 09:44:33 10HmbN-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: -1999-03-02 09:44:33 10HmbN-0005vi-00 == a@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 == a@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: 1999-03-02 09:44:33 10HmbN-0005vi-00 ** b@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 NO -1999-03-02 09:44:33 10HmbN-0005vi-00 == c@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: -1999-03-02 09:44:33 10HmbN-0005vi-00 == d@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: -1999-03-02 09:44:33 10HmbN-0005vi-00 == e@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 == c@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 == d@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 == e@test.ex R=client T=send_to_server defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: 1999-03-02 09:44:33 10HmbO-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbO-0005vi-00 ** CALLER@test.ex R=bounce: just discard 1999-03-02 09:44:33 10HmbO-0005vi-00 CALLER@test.ex: error ignored diff --git a/test/log/0218 b/test/log/0218 index 4aac50dab..bdbd4141f 100644 --- a/test/log/0218 +++ b/test/log/0218 @@ -9,7 +9,7 @@ 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss 1999-03-02 09:44:33 Start queue run: pid=pppp -qq -1999-03-02 09:44:33 10HmaZ-0005vi-00 ** a@test.ex F= R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 NO +1999-03-02 09:44:33 10HmaZ-0005vi-00 ** a@test.ex F= R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 NO 1999-03-02 09:44:33 10HmbB-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed 1999-03-02 09:44:33 10HmbA-0005vi-00 H=127.0.0.1 [127.0.0.1] Connection refused diff --git a/test/log/0322 b/test/log/0322 index 0c45cc5d2..f76f0695b 100644 --- a/test/log/0322 +++ b/test/log/0322 @@ -7,26 +7,26 @@ 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed 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 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: -1999-03-02 09:44:33 10HmaZ-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: +1999-03-02 09:44:33 10HmaZ-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmaZ-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: 1999-03-02 09:44:33 10HmaZ-0005vi-00 ** x@test.ex: retry timeout exceeded 1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=null 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbB-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to MAIL FROM: -1999-03-02 09:44:33 10HmbB-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to MAIL FROM: +1999-03-02 09:44:33 10HmbB-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined MAIL FROM: +1999-03-02 09:44:33 10HmbB-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined MAIL FROM: 1999-03-02 09:44:33 10HmbB-0005vi-00 ** x@test.ex: retry timeout exceeded 1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: R=null 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbD-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: -1999-03-02 09:44:33 10HmbD-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: -1999-03-02 09:44:33 10HmbD-0005vi-00 == y@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: -1999-03-02 09:44:33 10HmbD-0005vi-00 == z@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to RCPT TO: +1999-03-02 09:44:33 10HmbD-0005vi-00 H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbD-0005vi-00 == x@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbD-0005vi-00 == y@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbD-0005vi-00 == z@test.ex R=remote T=smtp defer (-19) H=127.0.0.1 [127.0.0.1]: Malformed SMTP reply (an empty line) in response to pipelined RCPT TO: 1999-03-02 09:44:33 10HmbD-0005vi-00 ** z@test.ex: retry timeout exceeded 1999-03-02 09:44:33 10HmbD-0005vi-00 ** y@test.ex: retry timeout exceeded 1999-03-02 09:44:33 10HmbD-0005vi-00 ** x@test.ex: retry timeout exceeded diff --git a/test/log/0495 b/test/log/0495 index 17886a809..d55d67923 100644 --- a/test/log/0495 +++ b/test/log/0495 @@ -12,12 +12,12 @@ 1999-03-02 09:44:33 10HmbA-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 NOTOK 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 BAD MAIL -1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 BAD MAIL +1999-03-02 09:44:33 10HmbB-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 BAD MAIL +1999-03-02 09:44:33 10HmbB-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 BAD MAIL 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed 1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbC-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 450 TEMPORARY MAIL FAIL -1999-03-02 09:44:33 10HmbC-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 450 TEMPORARY MAIL FAIL +1999-03-02 09:44:33 10HmbC-0005vi-00 ** a@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 450 TEMPORARY MAIL FAIL +1999-03-02 09:44:33 10HmbC-0005vi-00 ** b@x.y R=r9 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 450 TEMPORARY MAIL FAIL 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss 1999-03-02 09:44:33 10HmbD-0005vi-00 => pm@p.q R=r9 T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK" diff --git a/test/log/0497 b/test/log/0497 index 9e55e5d29..8d47ac2b5 100644 --- a/test/log/0497 +++ b/test/log/0497 @@ -27,7 +27,7 @@ 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed 1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbF-0005vi-00 == userx@x.y R=r1 T=t1 defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 452 temporary error +1999-03-02 09:44:33 10HmbF-0005vi-00 == userx@x.y R=r1 T=t1 defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 452 temporary error 1999-03-02 09:44:33 10HmbF-0005vi-00 ** userx@x.y: retry timeout exceeded 1999-03-02 09:44:33 10HmbG-0005vi-00 <= <> R=10HmbF-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbG-0005vi-00 => :blackhole: R=r0 @@ -55,8 +55,8 @@ 1999-03-02 09:44:33 10HmbM-0005vi-00 Completed 1999-03-02 09:44:33 10HmbL-0005vi-00 Completed 1999-03-02 09:44:33 10HmbN-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss -1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: -1999-03-02 09:44:33 10HmbN-0005vi-00 == userx@x.y R=r1 T=t1 defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: +1999-03-02 09:44:33 10HmbN-0005vi-00 == userx@x.y R=r1 T=t1 defer (-18) H=127.0.0.1 [127.0.0.1]: Remote host closed connection in response to pipelined RCPT TO: 1999-03-02 09:44:33 10HmbN-0005vi-00 ** userx@x.y: retry timeout exceeded 1999-03-02 09:44:33 10HmbO-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss 1999-03-02 09:44:33 10HmbO-0005vi-00 => :blackhole: R=r0 diff --git a/test/log/0552 b/test/log/0552 index d070f9c8c..4ce57b114 100644 --- a/test/log/0552 +++ b/test/log/0552 @@ -1,9 +1,9 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 Accept non-SMTP 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 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM: SIZE=ssss -1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM: SIZE=ssss -1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after MAIL FROM: SIZE=ssss +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM: SIZE=ssss +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM: SIZE=ssss +1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined MAIL FROM: SIZE=ssss 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 => userx1@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmaY-0005vi-00" diff --git a/test/log/0901 b/test/log/0901 new file mode 100644 index 000000000..b2db284e3 --- /dev/null +++ b/test/log/0901 @@ -0,0 +1,38 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 == b@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after end of data (ddd bytes written) +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 => c@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 500 oops +1999-03-02 09:44:33 10HmbA-0005vi-00 d@test.ex: error ignored +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbB-0005vi-00 == e@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 400 not right now +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbC-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbC-0005vi-00 Completed +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 == q@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written) +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbE-0005vi-00 Completed +1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbF-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 550 unacceptable mail-from +1999-03-02 09:44:33 10HmbF-0005vi-00 s@test.ex: error ignored +1999-03-02 09:44:33 10HmbF-0005vi-00 Completed +1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbG-0005vi-00 == s1@test.ex R=to_server T=remote_smtp defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from +1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbH-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient +1999-03-02 09:44:33 10HmbH-0005vi-00 t@test.ex: error ignored +1999-03-02 09:44:33 10HmbH-0005vi-00 Completed +1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbI-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 500 oops bdat +1999-03-02 09:44:33 10HmbI-0005vi-00 u@test.ex: error ignored +1999-03-02 09:44:33 10HmbI-0005vi-00 Completed +1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbJ-0005vi-00 == v@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat diff --git a/test/log/0902 b/test/log/0902 new file mode 100644 index 000000000..31fb49eb0 --- /dev/null +++ b/test/log/0902 @@ -0,0 +1,31 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after sending data block: 500 oops bdat-nonlast +1999-03-02 09:44:33 10HmaY-0005vi-00 d@test.ex: error ignored +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined sending data block: 550 unacceptable mail-from +1999-03-02 09:44:33 10HmbA-0005vi-00 s@test.ex: error ignored +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbB-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient +1999-03-02 09:44:33 10HmbB-0005vi-00 t@test.ex: error ignored +1999-03-02 09:44:33 10HmbB-0005vi-00 Completed +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbC-0005vi-00 ** t1@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient +1999-03-02 09:44:33 10HmbC-0005vi-00 => t2@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbC-0005vi-00 t1@test.ex: error ignored +1999-03-02 09:44:33 10HmbC-0005vi-00 Completed +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined sending data block: 500 oops nonlast bdat +1999-03-02 09:44:33 10HmbD-0005vi-00 u@test.ex: error ignored +1999-03-02 09:44:33 10HmbD-0005vi-00 Completed +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 ** v@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 500 oops bdat +1999-03-02 09:44:33 10HmbE-0005vi-00 v@test.ex: error ignored +1999-03-02 09:44:33 10HmbE-0005vi-00 Completed diff --git a/test/log/2026 b/test/log/2026 index 90506c3cd..08255f8a1 100644 --- a/test/log/2026 +++ b/test/log/2026 @@ -1,6 +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 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT -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 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp K 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 CV=no S=sss id=E10HmaY-0005vi-00@myhost.test.ex +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 CV=no K 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/scripts/0000-Basic/0217 b/test/scripts/0000-Basic/0217 index c47ae5c9e..a74be606f 100644 --- a/test/scripts/0000-Basic/0217 +++ b/test/scripts/0000-Basic/0217 @@ -36,7 +36,7 @@ RCPT TO 250 OK *sleep 2 **** -exim -odi a b c +exim -odi e f g . **** # Temp error on MAIL @@ -56,7 +56,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi h i . **** # Perm error on MAIL @@ -76,7 +76,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi j k . **** # All get temp errors @@ -96,7 +96,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi l m . **** # All get perm errors @@ -116,7 +116,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi n o . **** # Mixed temp and perm @@ -136,7 +136,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi p q . **** # Perm error on DATA after good recipients @@ -156,7 +156,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi r s . **** # Temp error on DATA after good recipients @@ -176,7 +176,7 @@ DATA QUIT 250 OK **** -exim -odi a b +exim -odi t u . **** # Temp error on DATA after good recipients, but in first block of a diff --git a/test/scripts/0000-Basic/0901 b/test/scripts/0000-Basic/0901 new file mode 100644 index 000000000..7b0172a59 --- /dev/null +++ b/test/scripts/0000-Basic/0901 @@ -0,0 +1,309 @@ +# CHUNKING transmission, short messages +# +# Start with non-pipelined cases +# +# Basic short message +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 323 LAST +*data 323 +250 OK +QUIT +225 OK +*eof +**** +exim -odf a@test.ex +Subject: foo + +data +**** +# +# Error case: server wrongly expected more data, client gets timeout for data-ack +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 good mail cmd +RCPT TO +250 acceptable rcpt cmd +BDAT 323 LAST +*data 324 +250 OK got that data +QUIT +225 OK quitting +**** +exim -odf b@test.ex +Subject: foo + +data +**** +# +# Error case: server wrongly expected less data +# client get the data-ack, sends quit - but server +# sees a munged quit due to the outstanding data tail +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 323 LAST +*data 322 +250 OK +QUIT +225 OK +**** +exim -odf c@test.ex +Subject: foo + +data +**** +# +# server rejects BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 323 LAST +*data 323 +500 oops +QUIT +225 OK +**** +exim -odf d@test.ex +Subject: foo + +data +**** +# +# server tmp-rejects BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 323 LAST +*data 323 +400 not right now +QUIT +225 OK +**** +exim -odf e@test.ex +Subject: foo + +data +**** +# +# +################################################### +# +# Pipelined cases +# +# Basic short message +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 323 +250 OK mail +250 OK rcpt +250 OK bdat +QUIT +225 OK +*eof +**** +exim -odf p@test.ex +Subject: foo + +data +**** +# +# Error case: server wrongly expected more data, client gets timeout for data-ack +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 324 +250 good mail cmd +**** +exim -odf q@test.ex +Subject: foo + +data +**** +# +# Error case: server wrongly expected less data +# client get the data-ack, sends quit - but server +# sees a munged quit due to the outstanding data tail +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 322 +250 OK mail +250 OK rcpt +250 OK bdat +QUIT +225 OK +**** +exim -odf r@test.ex +Subject: foo + +data +**** +# +# server rejects MAIL cmd +# transport coding does not handle the possible RSET-and-another transaction, +# but always QUITs +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 323 +550 unacceptable mail-from +550 rcpt ungood lacking mail-from +500 bdat ungood lacking mail-from +QUIT +225 OK +**** +exim -odf s@test.ex +Subject: foo + +data +**** +# +# server tmp-rejects MAIL cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 324 LAST +*data 324 +450 greylisted mail-from +550 rcpt ungood lacking mail-from +500 bdat ungood lacking mail-from +QUIT +225 OK +**** +exim -odf s1@test.ex +Subject: foo + +data +**** +# +# server rejects RCPT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 323 +250 OK mail +550 no such recipient +500 oops bdat +QUIT +225 OK +**** +exim -odf t@test.ex +Subject: foo + +data +**** +# +# server rejects BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 323 +250 OK mail +250 OK rcpt +500 oops bdat +QUIT +225 OK +**** +exim -odf u@test.ex +Subject: foo + +data +**** +# +# server tmp-rejects BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 323 LAST +*data 323 +250 OK mail +250 OK rcpt +400 not right now bdat +QUIT +225 OK +**** +exim -odf v@test.ex +Subject: foo + +data +**** +# +# +no_msglog_check diff --git a/test/scripts/0000-Basic/0902 b/test/scripts/0000-Basic/0902 new file mode 100644 index 000000000..a1c4de4e1 --- /dev/null +++ b/test/scripts/0000-Basic/0902 @@ -0,0 +1,925 @@ +# CHUNKING transmission, long messages +# +# Start with non-pipelined cases +# +# Basic long message +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 317 +*data 317 +250 OK nonlast bdat +BDAT 8380 LAST +*data 8380 +250 OK bdat +QUIT +225 OK +*eof +**** +exim -odf a@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# +# server rejects BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250 CHUNKING +MAIL FROM +250 OK +RCPT TO +250 OK +BDAT 317 +*data 317 +500 oops bdat-nonlast +QUIT +225 OK +**** +exim -odf d@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# +################################################### +# +# Pipelined cases +# +# Basic long message +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 317 +250 OK mail +250 OK rcpt +*data 317 +250 OK nonlast bdat +BDAT 8380 LAST +*data 8380 +250 OK bdat +QUIT +225 OK +*eof +**** +exim -odf p@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# server rejects MAIL cmd +# transport coding does not handle the possible RSET-and-another transaction, +# but always QUITs +# +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 317 +*data 317 +550 unacceptable mail-from +550 rcpt ungood lacking mail-from +500 bdat (nonlast) ungood lacking mail-from +QUIT +225 OK +**** +exim -odf s@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# server rejects RCPT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 317 +*data 317 +250 OK mail +550 no such recipient +500 oops nonlast bdat - no rcpt +QUIT +225 OK +**** +exim -odf t@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# server rejects 1st RCPT cmd of two +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +RCPT TO +BDAT 301 +*data 301 +250 OK mail +550 no such recipient +250 good recipient +200 OK nonlast bdat +BDAT 8380 LAST +*data 8380 +250 OK bdat +QUIT +225 OK +**** +exim -odf t1@test.ex t2@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# server rejects initial BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 317 +*data 317 +250 OK mail +250 OK rcpt +500 oops nonlast bdat +QUIT +225 OK +**** +exim -odf u@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# server rejects final BDAT cmd +server PORT_S +220 Greetings +EHLO +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM +RCPT TO +BDAT 317 +*data 317 +250 OK mail +250 OK rcpt +250 OK nonlast bdat +BDAT 8380 LAST +*data 8380 +500 oops bdat +QUIT +225 OK +**** +exim -odf v@test.ex +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +**** +# +# +no_msglog_check diff --git a/test/src/server.c b/test/src/server.c index 4f2172376..1abd3f49a 100644 --- a/test/src/server.c +++ b/test/src/server.c @@ -640,6 +640,38 @@ for (count = 0; count < connection_count; count++) sleep(sleepfor); } + /* If the script line starts with "*data " we expect a numeric argument, + and we expect to read (and discard) that many data bytes from the input. */ + + else if (strncmp(ss, "*data ", 6) == 0) + { + int dlen = atoi(ss+6); + int n; + + alarm(timeout); + + if (!linebuf) + while (dlen > 0) + { + n = dlen < sizeof(buffer) ? dlen : sizeof(buffer); + if ((n = read(dup_accept_socket, CS buffer, n)) == 0) + { + printf("Unxpected EOF read from client\n"); + s = s->next; + goto END_OFF; + } + dlen -= n; + } + else + while (dlen-- > 0) + if (fgetc(in) == EOF) + { + printf("Unxpected EOF read from client\n"); + s = s->next; + goto END_OFF; + } + } + /* Otherwise the script line is the start of an input line we are expecting from the client, or "*eof" indicating we expect the client to close the connection. Read command line or data lines; the latter are indicated diff --git a/test/stderr/0218 b/test/stderr/0218 index fe4ee2df9..f9f1d6849 100644 --- a/test/stderr/0218 +++ b/test/stderr/0218 @@ -93,7 +93,7 @@ Connecting to 127.0.0.1 [127.0.0.1]:1224 ... connected SMTP>> QUIT SMTP(close)>> LOG: MAIN - ** a@test.ex F= R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 NO + ** a@test.ex F= R=client T=send_to_server H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 NO Exim version x.yz .... configuration file is TESTSUITE/test-config trusted user diff --git a/test/stderr/0495 b/test/stderr/0495 index b00cfd572..bfe9f6218 100644 --- a/test/stderr/0495 +++ b/test/stderr/0495 @@ -1,7 +1,7 @@ Delivery failed: Connection refused Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 NOTOK -Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 550 BAD MAIL -Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after MAIL FROM:: 450 TEMPORARY MAIL FAIL +Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 550 BAD MAIL +Delivery failed: H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined MAIL FROM:: 450 TEMPORARY MAIL FAIL routing file@x.y yielded a local delivery routing fail@x.y yielded a failed delivery: forcible fail message routing defer@x.y yielded a deferred delivery: forcible defer message diff --git a/test/stdout/0217 b/test/stdout/0217 index 8633a43ee..f08a3fab6 100644 --- a/test/stdout/0217 +++ b/test/stdout/0217 @@ -36,7 +36,7 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 250 OK *sleep 2 End of script @@ -48,9 +48,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 451 Temp error -RCPT TO: +RCPT TO: 503 No sender given -RCPT TO: +RCPT TO: 503 No sender given DATA 503 No envelope @@ -65,9 +65,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 550 Perm error -RCPT TO: +RCPT TO: 503 No sender given -RCPT TO: +RCPT TO: 503 No sender given DATA 503 No envelope @@ -82,9 +82,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 451 Temp error 1 -RCPT TO: +RCPT TO: 451 Temp error 2 DATA 503 No recipients @@ -99,9 +99,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 551 Perm error 1 -RCPT TO: +RCPT TO: 551 Perm error 2 DATA 503 No recipients @@ -116,9 +116,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 451 Temp error 1 -RCPT TO: +RCPT TO: 551 Perm error 2 DATA 503 No recipients @@ -133,9 +133,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 250 OK -RCPT TO: +RCPT TO: 250 OK DATA 503 Sorry perm data error @@ -150,9 +150,9 @@ EHLO myhost.test.ex 250 PIPELINING MAIL FROM: 250 OK -RCPT TO: +RCPT TO: 250 OK -RCPT TO: +RCPT TO: 250 OK DATA 403 Sorry temp data error diff --git a/test/stdout/0547 b/test/stdout/0547 index 7e931992c..418ddc4ba 100644 --- a/test/stdout/0547 +++ b/test/stdout/0547 @@ -61,31 +61,31 @@ End of script 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 221 myhost.test.ex closing connection 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 550 Administrative prohibition @@ -100,15 +100,15 @@ End of script 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 214-Commands supported: -214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP 250 Reset OK 250 OK 554 Too many nonmail commands diff --git a/test/stdout/0572 b/test/stdout/0572 index dbdf4b989..12cd05b78 100644 --- a/test/stdout/0572 +++ b/test/stdout/0572 @@ -57,6 +57,7 @@ no_hosts_override no_hosts_randomize hosts_require_auth = hosts_try_auth = +hosts_try_chunking = * hosts_try_prdr = * interface = ip4.ip4.ip4.ip4 keepalive diff --git a/test/stdout/0901 b/test/stdout/0901 new file mode 100644 index 000000000..12ed5ce0f --- /dev/null +++ b/test/stdout/0901 @@ -0,0 +1,199 @@ + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 323 LAST +250 OK +QUIT +225 OK +Expected EOF read from client +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 good mail cmd +RCPT TO: +250 acceptable rcpt cmd +BDAT 323 LAST +Unxpected EOF read from client +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 323 LAST +250 OK + +Comparison failed - bailing out +Expected: QUIT +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 323 LAST +500 oops +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 323 LAST +400 not right now +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +250 OK mail +250 OK rcpt +250 OK bdat +QUIT +225 OK +Expected EOF read from client +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +Unxpected EOF read from client +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +250 OK mail +250 OK rcpt +250 OK bdat + +Comparison failed - bailing out +Expected: QUIT +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +550 unacceptable mail-from +550 rcpt ungood lacking mail-from +500 bdat ungood lacking mail-from +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 324 LAST +450 greylisted mail-from +550 rcpt ungood lacking mail-from +500 bdat ungood lacking mail-from +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +250 OK mail +550 no such recipient +500 oops bdat +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +250 OK mail +250 OK rcpt +500 oops bdat +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 323 LAST +250 OK mail +250 OK rcpt +400 not right now bdat +QUIT +225 OK +End of script diff --git a/test/stdout/0902 b/test/stdout/0902 new file mode 100644 index 000000000..58dba6788 --- /dev/null +++ b/test/stdout/0902 @@ -0,0 +1,140 @@ + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 317 +250 OK nonlast bdat +BDAT 8380 LAST +250 OK bdat +QUIT +225 OK +Expected EOF read from client +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250 CHUNKING +MAIL FROM:<> +250 OK +RCPT TO: +250 OK +BDAT 317 +500 oops bdat-nonlast +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 317 +250 OK mail +250 OK rcpt +250 OK nonlast bdat +BDAT 8380 LAST +250 OK bdat +QUIT +225 OK +Expected EOF read from client +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 317 +550 unacceptable mail-from +550 rcpt ungood lacking mail-from +500 bdat (nonlast) ungood lacking mail-from +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 317 +250 OK mail +550 no such recipient +500 oops nonlast bdat - no rcpt +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +RCPT TO: +BDAT 301 +250 OK mail +550 no such recipient +250 good recipient +200 OK nonlast bdat +BDAT 8380 LAST +250 OK bdat +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 317 +250 OK mail +250 OK rcpt +500 oops nonlast bdat +QUIT +225 OK +End of script +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Greetings +EHLO the.local.host.name +250-Hello there +250-PIPELINING +250 CHUNKING +MAIL FROM:<> +RCPT TO: +BDAT 317 +250 OK mail +250 OK rcpt +250 OK nonlast bdat +BDAT 8380 LAST +500 oops bdat +QUIT +225 OK +End of script diff --git a/test/stdout/2022 b/test/stdout/2022 index c6124c698..3f280e0d5 100644 --- a/test/stdout/2022 +++ b/test/stdout/2022 @@ -23,7 +23,7 @@ Succeeded in starting TLS ??? 214- <<< 214-Commands supported: ??? 214 -<<< 214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +<<< 214 AUTH HELO EHLO MAIL RCPT DATA BDAT NOOP QUIT RSET HELP >>> quit ??? 221 <<< 221 myhost.test.ex closing connection -- cgit v1.2.3 From 48f1c8532119577336c1aa1c91a50b57ebecdaf8 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 1 Aug 2016 15:01:15 +0100 Subject: transmit with DKIM --- src/src/transport.c | 126 ++++++++++----------- src/src/transports/smtp.c | 10 ++ test/confs/0900 | 22 +++- test/confs/4509 | 1 + test/log/0900 | 6 +- test/log/0901 | 26 ++--- test/log/0902 | 16 +-- test/log/4509 | 13 +++ test/scripts/4500-Domain-Keys-Identified-Mail/4509 | 111 ++++++++++++++++++ 9 files changed, 240 insertions(+), 91 deletions(-) create mode 120000 test/confs/4509 create mode 100644 test/log/4509 create mode 100644 test/scripts/4500-Domain-Keys-Identified-Mail/4509 (limited to 'test') diff --git a/src/src/transport.c b/src/src/transport.c index e55e81f2f..3987fad3e 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -416,7 +416,6 @@ for (ptr = start; ptr < end; ptr++) room for the next uschar, plus a possible extra CR for an LF, plus the escape string. */ - /*XXX CHUNKING: probably want to increase DELIVER_OUT_BUFFER_SIZE */ if ((len = chunk_ptr - deliver_out_buffer) > mlen) { /* If CHUNKING, prefix with BDAT (size) NON-LAST. Also, reap responses @@ -1058,8 +1057,9 @@ uschar * dkim_spool_name; int sread = 0; int wwritten = 0; uschar *dkim_signature = NULL; -int siglen; +int siglen = 0; off_t k_file_size; +int options; /* If we can't sign, just call the original function. */ @@ -1079,8 +1079,10 @@ if ((dkim_fd = Uopen(dkim_spool_name, O_RDWR|O_CREAT|O_TRUNC, SPOOL_MODE)) < 0) /* Call original function to write the -K file; does the CRLF expansion */ +options = tctx->options; tctx->options &= ~topt_use_bdat; rc = transport_write_message(dkim_fd, tctx, 0); +tctx->options = options; /* Save error state. We must clean up before returning. */ if (!rc) @@ -1089,62 +1091,61 @@ if (!rc) goto CLEANUP; } -if (dkim->dkim_private_key && dkim->dkim_domain && dkim->dkim_selector) +/* Rewind file and feed it to the goats^W DKIM lib */ +lseek(dkim_fd, 0, SEEK_SET); +dkim_signature = dkim_exim_sign(dkim_fd, + dkim->dkim_private_key, + dkim->dkim_domain, + dkim->dkim_selector, + dkim->dkim_canon, + dkim->dkim_sign_headers); +if (dkim_signature) + siglen = Ustrlen(dkim_signature); +else if (dkim->dkim_strict) { - /* Rewind file and feed it to the goats^W DKIM lib */ - lseek(dkim_fd, 0, SEEK_SET); - dkim_signature = dkim_exim_sign(dkim_fd, - dkim->dkim_private_key, - dkim->dkim_domain, - dkim->dkim_selector, - dkim->dkim_canon, - dkim->dkim_sign_headers); - if (!dkim_signature) - { - if (dkim->dkim_strict) + uschar *dkim_strict_result = expand_string(dkim->dkim_strict); + if (dkim_strict_result) + if ( (strcmpic(dkim->dkim_strict,US"1") == 0) || + (strcmpic(dkim->dkim_strict,US"true") == 0) ) { - uschar *dkim_strict_result = expand_string(dkim->dkim_strict); - if (dkim_strict_result) - if ( (strcmpic(dkim->dkim_strict,US"1") == 0) || - (strcmpic(dkim->dkim_strict,US"true") == 0) ) - { - /* Set errno to something halfway meaningful */ - save_errno = EACCES; - log_write(0, LOG_MAIN, "DKIM: message could not be signed," - " and dkim_strict is set. Deferring message delivery."); - rc = FALSE; - goto CLEANUP; - } + /* Set errno to something halfway meaningful */ + save_errno = EACCES; + log_write(0, LOG_MAIN, "DKIM: message could not be signed," + " and dkim_strict is set. Deferring message delivery."); + rc = FALSE; + goto CLEANUP; } - } - - siglen = 0; } -if (dkim_signature) +#ifndef HAVE_LINUX_SENDFILE +if (options & topt_use_bdat) +#endif + k_file_size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */ + +if (options & topt_use_bdat) { - siglen = Ustrlen(dkim_signature); - while(siglen > 0) + + /* On big messages output a precursor chunk to get any pipelined + MAIL & RCPT commands flushed, then reap the responses so we can + error out on RCPT rejects before sending megabytes. */ + + if (siglen + k_file_size > DELIVER_OUT_BUFFER_SIZE && siglen > 0) { -#ifdef SUPPORT_TLS - wwritten = tls_out.active == out_fd - ? tls_write(FALSE, dkim_signature, siglen) - : write(out_fd, dkim_signature, siglen); -#else - wwritten = write(out_fd, dkim_signature, siglen); -#endif - if (wwritten == -1) - { - /* error, bail out */ - save_errno = errno; - rc = FALSE; - goto CLEANUP; - } - siglen -= wwritten; - dkim_signature += wwritten; + if ( tctx->chunk_cb(out_fd, tctx, siglen, 0) != OK + || !transport_write_block(out_fd, dkim_signature, siglen) + || tctx->chunk_cb(out_fd, tctx, 0, tc_reap_prev) != OK + ) + goto err; + siglen = 0; } + + if (tctx->chunk_cb(out_fd, tctx, siglen + k_file_size, tc_chunk_last) != OK) + goto err; } +if(siglen > 0 && !transport_write_block(out_fd, dkim_signature, siglen)) + goto err; + #ifdef HAVE_LINUX_SENDFILE /* We can use sendfile() to shove the file contents to the socket. However only if we don't use TLS, @@ -1155,18 +1156,13 @@ if (tls_out.active != out_fd) ssize_t copied = 0; off_t offset = 0; - k_file_size = lseek(dkim_fd, 0, SEEK_END); /* Fetch file size */ - /* Rewind file */ lseek(dkim_fd, 0, SEEK_SET); while(copied >= 0 && offset < k_file_size) copied = sendfile(out_fd, dkim_fd, &offset, k_file_size - offset); if (copied < 0) - { - save_errno = errno; - rc = FALSE; - } + goto err; } else @@ -1192,12 +1188,7 @@ else wwritten = write(out_fd, p, sread); #endif if (wwritten == -1) - { - /* error, bail out */ - save_errno = errno; - rc = FALSE; - goto CLEANUP; - } + goto err; p += wwritten; sread -= wwritten; } @@ -1211,11 +1202,16 @@ else } CLEANUP: -/* unlink -K file */ -(void)close(dkim_fd); -Uunlink(dkim_spool_name); -errno = save_errno; -return rc; + /* unlink -K file */ + (void)close(dkim_fd); + Uunlink(dkim_spool_name); + errno = save_errno; + return rc; + +err: + save_errno = errno; + rc = FALSE; + goto CLEANUP; } #endif diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 00274656c..a265e566e 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2123,6 +2123,16 @@ if (tblock->filter_command != NULL) yield = ERROR; goto SEND_QUIT; } + + if ( transport_filter_argv + && *transport_filter_argv + && **transport_filter_argv + && peer_offered & PEER_OFFERED_CHUNKING + ) + { + peer_offered &= ~PEER_OFFERED_CHUNKING; + DEBUG(D_transport) debug_printf("CHUNKING not usable due to transport filter\n"); + } } diff --git a/test/confs/0900 b/test/confs/0900 index cdc6d84eb..3235f1ee7 100644 --- a/test/confs/0900 +++ b/test/confs/0900 @@ -1,5 +1,7 @@ # Exim test configuration 0900 SERVER= +X= +OPT= exim_path = EXIM_PATH keep_environment = @@ -14,13 +16,14 @@ tls_advertise_hosts = # ----- Main settings ----- -domainlist local_domains = @ +domainlist local_domains = @ : test.ex acl_smtp_rcpt = check_recipient acl_smtp_data = check_data trusted_users = CALLER queue_only smtp_receive_timeout = 2s +log_selector = +received_recipients # ----- ACL ----- @@ -44,7 +47,7 @@ begin routers to_server: driver = accept condition = ${if !eq {SERVER}{server}} - transport = remote_smtp + transport = remote_smtp${if eq {X}{dkim} {_dkim}} errors_to = "" fail_remote_domains: @@ -81,6 +84,21 @@ remote_smtp: command_timeout = 2s final_timeout = 2s +remote_smtp_dkim: + driver = smtp + hosts = 127.0.0.1 + port = PORT_S + allow_localhost + command_timeout = 2s + final_timeout = 2s + + dkim_domain = test.ex + dkim_selector = sel + dkim_private_key = DIR/aux-fixed/dkim/dkim.private +.ifndef HEADERS_MAXSIZE + dkim_sign_headers = OPT +.endif + # ----- Retry ----- begin retry diff --git a/test/confs/4509 b/test/confs/4509 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/4509 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/log/0900 b/test/log/0900 index 37d70da7c..10e96f9a3 100644 --- a/test/log/0900 +++ b/test/log/0900 @@ -1,9 +1,9 @@ ******** SERVER ******** 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 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss -1999-03-02 09:44:33 10HmaY-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss -1999-03-02 09:44:33 10HmaZ-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@the.local.host.name +1999-03-02 09:44:33 10HmaY-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@the.local.host.name +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@the.local.host.name 1999-03-02 09:44:33 10HmbA-0005vi-00 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F= 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data diff --git a/test/log/0901 b/test/log/0901 index b2db284e3..58688cf28 100644 --- a/test/log/0901 +++ b/test/log/0901 @@ -1,38 +1,38 @@ -1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex 1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for b@test.ex 1999-03-02 09:44:33 10HmaY-0005vi-00 == b@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after end of data (ddd bytes written) -1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for c@test.ex 1999-03-02 09:44:33 10HmaZ-0005vi-00 => c@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed -1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for d@test.ex 1999-03-02 09:44:33 10HmbA-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 500 oops 1999-03-02 09:44:33 10HmbA-0005vi-00 d@test.ex: error ignored 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed -1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for e@test.ex 1999-03-02 09:44:33 10HmbB-0005vi-00 == e@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 400 not right now -1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for p@test.ex 1999-03-02 09:44:33 10HmbC-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed -1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for q@test.ex 1999-03-02 09:44:33 10HmbD-0005vi-00 == q@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written) -1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for r@test.ex 1999-03-02 09:44:33 10HmbE-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed -1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for s@test.ex 1999-03-02 09:44:33 10HmbF-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 550 unacceptable mail-from 1999-03-02 09:44:33 10HmbF-0005vi-00 s@test.ex: error ignored 1999-03-02 09:44:33 10HmbF-0005vi-00 Completed -1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbG-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for s1@test.ex 1999-03-02 09:44:33 10HmbG-0005vi-00 == s1@test.ex R=to_server T=remote_smtp defer (-45) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 450 greylisted mail-from -1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbH-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for t@test.ex 1999-03-02 09:44:33 10HmbH-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient 1999-03-02 09:44:33 10HmbH-0005vi-00 t@test.ex: error ignored 1999-03-02 09:44:33 10HmbH-0005vi-00 Completed -1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbI-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for u@test.ex 1999-03-02 09:44:33 10HmbI-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 500 oops bdat 1999-03-02 09:44:33 10HmbI-0005vi-00 u@test.ex: error ignored 1999-03-02 09:44:33 10HmbI-0005vi-00 Completed -1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbJ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for v@test.ex 1999-03-02 09:44:33 10HmbJ-0005vi-00 == v@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 400 not right now bdat diff --git a/test/log/0902 b/test/log/0902 index 31fb49eb0..330b472bd 100644 --- a/test/log/0902 +++ b/test/log/0902 @@ -1,31 +1,31 @@ -1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex 1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for d@test.ex 1999-03-02 09:44:33 10HmaY-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after sending data block: 500 oops bdat-nonlast 1999-03-02 09:44:33 10HmaY-0005vi-00 d@test.ex: error ignored 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed -1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for p@test.ex 1999-03-02 09:44:33 10HmaZ-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed -1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for s@test.ex 1999-03-02 09:44:33 10HmbA-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined sending data block: 550 unacceptable mail-from 1999-03-02 09:44:33 10HmbA-0005vi-00 s@test.ex: error ignored 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed -1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for t@test.ex 1999-03-02 09:44:33 10HmbB-0005vi-00 ** t@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient 1999-03-02 09:44:33 10HmbB-0005vi-00 t@test.ex: error ignored 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed -1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for t1@test.ex t2@test.ex 1999-03-02 09:44:33 10HmbC-0005vi-00 ** t1@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient 1999-03-02 09:44:33 10HmbC-0005vi-00 => t2@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" 1999-03-02 09:44:33 10HmbC-0005vi-00 t1@test.ex: error ignored 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed -1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for u@test.ex 1999-03-02 09:44:33 10HmbD-0005vi-00 ** u@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined sending data block: 500 oops nonlast bdat 1999-03-02 09:44:33 10HmbD-0005vi-00 u@test.ex: error ignored 1999-03-02 09:44:33 10HmbD-0005vi-00 Completed -1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for v@test.ex 1999-03-02 09:44:33 10HmbE-0005vi-00 ** v@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 500 oops bdat 1999-03-02 09:44:33 10HmbE-0005vi-00 v@test.ex: error ignored 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed diff --git a/test/log/4509 b/test/log/4509 new file mode 100644 index 000000000..6e62c5219 --- /dev/null +++ b/test/log/4509 @@ -0,0 +1,13 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] C="250- 973 byte chunk, total 973\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for b@test.ex +1999-03-02 09:44:33 10HmaZ-0005vi-00 => b@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] C="250- 8509 byte chunk, total 9160\\n250 OK id=10HmbA-0005vi-00" +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1224 +1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (the.local.host.name) [127.0.0.1] P=esmtp K S=sss id=E10HmaX-0005vi-00@the.local.host.name for a@test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (the.local.host.name) [127.0.0.1] P=esmtp K S=sss id=E10HmaZ-0005vi-00@the.local.host.name for b@test.ex diff --git a/test/scripts/4500-Domain-Keys-Identified-Mail/4509 b/test/scripts/4500-Domain-Keys-Identified-Mail/4509 new file mode 100644 index 000000000..9e4790172 --- /dev/null +++ b/test/scripts/4500-Domain-Keys-Identified-Mail/4509 @@ -0,0 +1,111 @@ +# DKIM signing, with CHUNKING +# +exim -bd -DSERVER=server -oX PORT_S +**** +# +# single header signed, short message +exim -DX=dkim -DOPT=From -odf a@test.ex +From: nobody@example.com +From: second@example.com + +content +**** +# +# single header signed, long message +exim -DX=dkim -DOPT=From -odf b@test.ex +From: nobody@example.com +From: second@example.com + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 +0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 + +The very last line +**** +millisleep 500 +killdaemon +no_msglog_check -- cgit v1.2.3 From 584e96c65f12aca9414450b656504af6e3f7a399 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 1 Aug 2016 18:38:22 +0100 Subject: receive with DKIM --- src/src/dkim.c | 3 +++ src/src/functions.h | 2 ++ src/src/globals.c | 1 + src/src/globals.h | 1 + src/src/smtp_in.c | 16 +++++++++++++++- src/src/tls-gnu.c | 13 +++++++++++++ src/src/tls-openssl.c | 12 ++++++++++++ test/stderr/0487 | 1 + 8 files changed, 48 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/src/src/dkim.c b/src/src/dkim.c index 24de2bc33..a09ec7eca 100644 --- a/src/src/dkim.c +++ b/src/src/dkim.c @@ -88,6 +88,9 @@ if (dkim_verify_ctx) dkim_verify_ctx = pdkim_init_verify(&dkim_exim_query_dns_txt); dkim_collect_input = !!dkim_verify_ctx; +/* Start feed up with any cached data */ +receive_get_cache(); + store_pool = dkim_verify_oldpool; } diff --git a/src/src/functions.h b/src/src/functions.h index 260b365df..8d47a0da1 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -56,6 +56,7 @@ extern int tls_feof(void); extern int tls_ferror(void); extern void tls_free_cert(void **); extern int tls_getc(void); +extern void tls_get_cache(void); extern int tls_import_cert(const uschar *, void **); extern int tls_read(BOOL, uschar *, size_t); extern int tls_server_start(const uschar *); @@ -390,6 +391,7 @@ extern BOOL smtp_get_interface(uschar *, int, address_item *, uschar **, uschar *); extern BOOL smtp_get_port(uschar *, address_item *, int *, uschar *); extern int smtp_getc(void); +extern void smtp_get_cache(void); extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); extern void smtp_log_no_mail(void); extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL); diff --git a/src/src/globals.c b/src/src/globals.c index 987c717fc..ba1336633 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -188,6 +188,7 @@ stand-alone tests. */ int (*lwr_receive_getc)(void) = stdin_getc; int (*lwr_receive_ungetc)(int) = stdin_ungetc; int (*receive_getc)(void) = stdin_getc; +void (*receive_get_cache)(void)= NULL; int (*receive_ungetc)(int) = stdin_ungetc; int (*receive_feof)(void) = stdin_feof; int (*receive_ferror)(void) = stdin_ferror; diff --git a/src/src/globals.h b/src/src/globals.h index 86ece2f30..f9af38ef5 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -141,6 +141,7 @@ incoming TCP/IP. */ extern int (*lwr_receive_getc)(void); extern int (*lwr_receive_ungetc)(int); extern int (*receive_getc)(void); +extern void (*receive_get_cache)(void); extern int (*receive_ungetc)(int); extern int (*receive_feof)(void); extern int (*receive_ferror)(void); diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 3144b39ad..8994c6edb 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -352,6 +352,15 @@ if (smtp_inptr >= smtp_inend) return *smtp_inptr++; } +#ifndef DISABLE_DKIM +void +smtp_get_cache(void) +{ +int n = smtp_inend - smtp_inptr; +if (n > 0) + dkim_exim_verify_feed(smtp_inptr, n); +} +#endif /* Get a byte from the smtp input, in CHUNKING mode. Handle ack of the @@ -386,10 +395,14 @@ for(;;) /* If not the last, ack the received chunk. The last response is delayed until after the data ACL decides on it */ - /*XXX find that "last response" and append the chunk size */ if (chunking_state == CHUNKING_LAST) + { +#ifndef DISABLE_DKIM + dkim_exim_verify_feed(".\r\n", 3); /* for consistency with .-term MAIL */ +#endif return EOD; + } chunking_state = CHUNKING_OFFERED; smtp_printf("250 %u byte chunk received\r\n", chunking_datasize); @@ -2051,6 +2064,7 @@ smtp_inbuffer = (uschar *)malloc(in_buffer_size); if (smtp_inbuffer == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malloc() failed for SMTP input buffer"); receive_getc = smtp_getc; +receive_get_cache = smtp_get_cache; receive_ungetc = smtp_ungetc; receive_feof = smtp_feof; receive_ferror = smtp_ferror; diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index c7c6b2674..0774850ca 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -1879,6 +1879,7 @@ and initialize appropriately. */ state->xfer_buffer = store_malloc(ssl_xfer_buffer_size); receive_getc = tls_getc; +receive_get_cache = tls_get_cache; receive_ungetc = tls_ungetc; receive_feof = tls_feof; receive_ferror = tls_ferror; @@ -2179,6 +2180,7 @@ if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm) DEBUG(D_tls) debug_printf("Got TLS_EOF\n"); receive_getc = smtp_getc; + receive_get_cache = smtp_get_cache; receive_ungetc = smtp_ungetc; receive_feof = smtp_feof; receive_ferror = smtp_ferror; @@ -2217,6 +2219,17 @@ if (state->xfer_buffer_lwm >= state->xfer_buffer_hwm) return state->xfer_buffer[state->xfer_buffer_lwm++]; } +#ifndef DISABLE_DKIM +void +tls_get_cache() +{ +exim_gnutls_state_st * state = &state_server; +int n = state->xfer_buffer_hwm - state->xfer_buffer_lwm; +if (n > 0) + dkim_exim_verify_feed(state->xfer_buffer+state->xfer_buffer_lwm, n); +} +#endif + diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index c24eb4544..242394f95 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1943,6 +1943,7 @@ ssl_xfer_buffer_lwm = ssl_xfer_buffer_hwm = 0; ssl_xfer_eof = ssl_xfer_error = 0; receive_getc = tls_getc; +receive_get_cache = tls_get_cache; receive_ungetc = tls_ungetc; receive_feof = tls_feof; receive_ferror = tls_ferror; @@ -2313,6 +2314,7 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm) DEBUG(D_tls) debug_printf("Got SSL_ERROR_ZERO_RETURN\n"); receive_getc = smtp_getc; + receive_get_cache = smtp_get_cache; receive_ungetc = smtp_ungetc; receive_feof = smtp_feof; receive_ferror = smtp_ferror; @@ -2358,6 +2360,16 @@ if (ssl_xfer_buffer_lwm >= ssl_xfer_buffer_hwm) return ssl_xfer_buffer[ssl_xfer_buffer_lwm++]; } +#ifndef DISABLE_DKIM +void +tls_get_cache() +{ +int n = ssl_xfer_buffer_hwm - ssl_xfer_buffer_lwm; +if (n > 0) + dkim_exim_verify_feed(ssl_xfer_buffer+ssl_xfer_buffer_lwm, n); +} +#endif + /************************************************* diff --git a/test/stderr/0487 b/test/stderr/0487 index b332f7f80..7f2ad5063 100644 --- a/test/stderr/0487 +++ b/test/stderr/0487 @@ -39,6 +39,7 @@ DSN: orcpt: NULL flags: 0 SMTP<< data SMTP>> 354 Enter message, ending with "." on a line by itself search_tidyup called +PDKIM >> Body data for hash, canonicalized >>>>>>>>>>>>>>>>>>>>>> >>Headers received: From: unqualified -- cgit v1.2.3 From e7621e8371917cc06d0abce0929c3166e29007fb Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 1 Aug 2016 22:39:20 +0100 Subject: testcases for TLS --- test/confs/0900 | 5 +- test/confs/2090 | 1 + test/confs/2091 | 1 + test/confs/2190 | 1 + test/confs/2191 | 1 + test/log/2090 | 5 ++ test/log/2091 | 7 +++ test/log/2190 | 5 ++ test/log/2191 | 9 +++ test/scripts/2000-GnuTLS/2090 | 78 +++++++++++++++++++++++ test/scripts/2000-GnuTLS/2091 | 9 +++ test/scripts/2100-OpenSSL/2190 | 77 +++++++++++++++++++++++ test/scripts/2100-OpenSSL/2191 | 1 + test/stdout/2090 | 110 ++++++++++++++++++++++++++++++++ test/stdout/2190 | 138 +++++++++++++++++++++++++++++++++++++++++ 15 files changed, 447 insertions(+), 1 deletion(-) create mode 120000 test/confs/2090 create mode 120000 test/confs/2091 create mode 120000 test/confs/2190 create mode 120000 test/confs/2191 create mode 100644 test/log/2090 create mode 100644 test/log/2091 create mode 100644 test/log/2190 create mode 100644 test/log/2191 create mode 100644 test/scripts/2000-GnuTLS/2090 create mode 100644 test/scripts/2000-GnuTLS/2091 create mode 100644 test/scripts/2100-OpenSSL/2190 create mode 120000 test/scripts/2100-OpenSSL/2191 create mode 100644 test/stdout/2090 create mode 100644 test/stdout/2190 (limited to 'test') diff --git a/test/confs/0900 b/test/confs/0900 index 3235f1ee7..245d9fa96 100644 --- a/test/confs/0900 +++ b/test/confs/0900 @@ -1,6 +1,7 @@ # Exim test configuration 0900 SERVER= X= +Y= OPT= exim_path = EXIM_PATH @@ -11,7 +12,7 @@ log_file_path = DIR/spool/log/SERVER%slog gecos_pattern = "" gecos_name = CALLER_NAME chunking_advertise_hosts = * -tls_advertise_hosts = +tls_advertise_hosts = ${if eq {Y}{tls} {*}} # ----- Main settings ----- @@ -25,6 +26,8 @@ queue_only smtp_receive_timeout = 2s log_selector = +received_recipients +tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} +tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} # ----- ACL ----- diff --git a/test/confs/2090 b/test/confs/2090 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/2090 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/confs/2091 b/test/confs/2091 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/2091 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/confs/2190 b/test/confs/2190 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/2190 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/confs/2191 b/test/confs/2191 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/2191 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/log/2090 b/test/log/2090 new file mode 100644 index 000000000..630d2c6a4 --- /dev/null +++ b/test/log/2090 @@ -0,0 +1,5 @@ + +******** SERVER ******** +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 <= someone@some.domain H=(rhu.barb) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no K S=sss for CALLER@the.local.host.name +1999-03-02 09:44:33 10HmaY-0005vi-00 <= someone@some.domain H=(rhu.barb) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no K S=sss for CALLER@the.local.host.name diff --git a/test/log/2091 b/test/log/2091 new file mode 100644 index 000000000..3c1be5c84 --- /dev/null +++ b/test/log/2091 @@ -0,0 +1,7 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for CALLER@test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1224 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (the.local.host.name) [127.0.0.1] P=esmtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no K S=sss id=E10HmaX-0005vi-00@the.local.host.name for CALLER@test.ex diff --git a/test/log/2190 b/test/log/2190 new file mode 100644 index 000000000..356a4ad92 --- /dev/null +++ b/test/log/2190 @@ -0,0 +1,5 @@ + +******** SERVER ******** +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 <= someone@some.domain H=(rhu.barb) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no K S=sss for CALLER@the.local.host.name +1999-03-02 09:44:33 10HmaY-0005vi-00 <= someone@some.domain H=(rhu.barb) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no K S=sss for CALLER@the.local.host.name diff --git a/test/log/2191 b/test/log/2191 new file mode 100644 index 000000000..4ff843230 --- /dev/null +++ b/test/log/2191 @@ -0,0 +1,9 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for CALLER@test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock +1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1224 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (the.local.host.name) [127.0.0.1] P=esmtps X=TLSv1:AES256-SHA:256 CV=no K S=sss id=E10HmaX-0005vi-00@the.local.host.name for CALLER@test.ex diff --git a/test/scripts/2000-GnuTLS/2090 b/test/scripts/2000-GnuTLS/2090 new file mode 100644 index 000000000..f799016f1 --- /dev/null +++ b/test/scripts/2000-GnuTLS/2090 @@ -0,0 +1,78 @@ +# TLS server, CHUNKING reception +gnutls +exim -DSERVER=server -DY=tls -bd -oX PORT_D +**** +# +# non-piplined +client-gnutls 127.0.0.1 PORT_D +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250-STARTTLS +??? 250 HELP +STARTTLS +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +BDAT 88 LAST +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250- +??? 250 +QUIT +??? 221 +**** +# +# pipelined +client-gnutls 127.0.0.1 PORT_D +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250-STARTTLS +??? 250 HELP +STARTTLS +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250 HELP +MAIL FROM: +RCPT TO: +BDAT 88 LAST +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250 +??? 250 +??? 250- +??? 250 +QUIT +??? 221 +**** +# +# +killdaemon +no_msglog_check diff --git a/test/scripts/2000-GnuTLS/2091 b/test/scripts/2000-GnuTLS/2091 new file mode 100644 index 000000000..aa7b26058 --- /dev/null +++ b/test/scripts/2000-GnuTLS/2091 @@ -0,0 +1,9 @@ +# TLS client, CHUNKING transmission +gnutls +exim -DSERVER=server -DY=tls -bd -oX PORT_S +**** +exim -odf CALLER@test.ex +Test message. Contains FF: ÿ +**** +killdaemon +no_msglog_check diff --git a/test/scripts/2100-OpenSSL/2190 b/test/scripts/2100-OpenSSL/2190 new file mode 100644 index 000000000..bacca676d --- /dev/null +++ b/test/scripts/2100-OpenSSL/2190 @@ -0,0 +1,77 @@ +# TLS server, CHUNKING reception +exim -DSERVER=server -DY=tls -bd -oX PORT_D +**** +# +# non-piplined +client-ssl 127.0.0.1 PORT_D +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250-STARTTLS +??? 250 HELP +STARTTLS +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250 HELP +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +BDAT 88 LAST +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250- +??? 250 +QUIT +??? 221 +**** +# +# pipelined +client-ssl 127.0.0.1 PORT_D +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250-STARTTLS +??? 250 HELP +STARTTLS +??? 220 +EHLO rhu.barb +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250 HELP +MAIL FROM: +RCPT TO: +BDAT 88 LAST +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyless test message + +??? 250 +??? 250 +??? 250- +??? 250 +QUIT +??? 221 +**** +# +# +killdaemon +no_msglog_check diff --git a/test/scripts/2100-OpenSSL/2191 b/test/scripts/2100-OpenSSL/2191 new file mode 120000 index 000000000..825b021c3 --- /dev/null +++ b/test/scripts/2100-OpenSSL/2191 @@ -0,0 +1 @@ +../2000-GnuTLS/2091 \ No newline at end of file diff --git a/test/stdout/2090 b/test/stdout/2090 new file mode 100644 index 000000000..e198f1279 --- /dev/null +++ b/test/stdout/2090 @@ -0,0 +1,110 @@ +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250-STARTTLS +<<< 250-STARTTLS +??? 250 HELP +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +Succeeded in starting TLS +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> BDAT 88 LAST +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> QUIT +??? 221 +<<< 221 the.local.host.name closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250-STARTTLS +<<< 250-STARTTLS +??? 250 HELP +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +Succeeded in starting TLS +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +>>> RCPT TO: +>>> BDAT 88 LAST +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250 +<<< 250 OK +??? 250 +<<< 250 Accepted +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaY-0005vi-00 +>>> QUIT +??? 221 +<<< 221 the.local.host.name closing connection +End of script diff --git a/test/stdout/2190 b/test/stdout/2190 new file mode 100644 index 000000000..7942a8ce5 --- /dev/null +++ b/test/stdout/2190 @@ -0,0 +1,138 @@ +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250-STARTTLS +<<< 250-STARTTLS +??? 250 HELP +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +SSL info: before/connect initialization +SSL info: before/connect initialization +SSL info: SSLv3 read server hello A +SSL info: SSLv3 read server certificate A +SSL info: SSLv3 read server done A +SSL info: SSLv3 write client key exchange A +SSL info: SSLv3 write change cipher spec A +SSL info: SSLv3 write finished A +SSL info: SSLv3 flush data +SSL info: SSLv3 read server session ticket A +SSL info: SSLv3 read finished A +SSL info: SSL negotiation finished successfully +SSL info: SSL negotiation finished successfully +SSL connection using AES256-SHA +Succeeded in starting TLS +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> BDAT 88 LAST +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> QUIT +??? 221 +<<< 221 the.local.host.name closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250-STARTTLS +<<< 250-STARTTLS +??? 250 HELP +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +SSL info: before/connect initialization +SSL info: before/connect initialization +SSL info: SSLv3 read server hello A +SSL info: SSLv3 read server certificate A +SSL info: SSLv3 read server done A +SSL info: SSLv3 write client key exchange A +SSL info: SSLv3 write change cipher spec A +SSL info: SSLv3 write finished A +SSL info: SSLv3 flush data +SSL info: SSLv3 read server session ticket A +SSL info: SSLv3 read finished A +SSL info: SSL negotiation finished successfully +SSL info: SSL negotiation finished successfully +SSL connection using AES256-SHA +Succeeded in starting TLS +>>> EHLO rhu.barb +??? 250- +<<< 250-the.local.host.name Hello rhu.barb [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM: +>>> RCPT TO: +>>> BDAT 88 LAST +>>> To: Susan@random.com +>>> From: Sam@random.com +>>> Subject: This is a bodyless test message +>>> +??? 250 +<<< 250 OK +??? 250 +<<< 250 Accepted +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmaY-0005vi-00 +>>> QUIT +??? 221 +<<< 221 the.local.host.name closing connection +End of script -- cgit v1.2.3 From 0b20855c02c44cb79a33824596e3ad8dc906131f Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 2 Aug 2016 00:24:00 +0100 Subject: testcases for PRDR --- test/confs/0900 | 8 ++++++++ test/confs/5590 | 1 + test/confs/5591 | 1 + test/log/5590 | 7 +++++++ test/log/5591 | 4 ++++ test/scripts/5500-PRDR/5590 | 40 ++++++++++++++++++++++++++++++++++++++++ test/scripts/5500-PRDR/5591 | 32 ++++++++++++++++++++++++++++++++ test/scripts/5500-PRDR/REQUIRES | 1 + test/stdout/5591 | 24 ++++++++++++++++++++++++ 9 files changed, 118 insertions(+) create mode 120000 test/confs/5590 create mode 120000 test/confs/5591 create mode 100644 test/log/5590 create mode 100644 test/log/5591 create mode 100644 test/scripts/5500-PRDR/5590 create mode 100644 test/scripts/5500-PRDR/5591 create mode 100644 test/stdout/5591 (limited to 'test') diff --git a/test/confs/0900 b/test/confs/0900 index 245d9fa96..427669c4b 100644 --- a/test/confs/0900 +++ b/test/confs/0900 @@ -3,6 +3,7 @@ SERVER= X= Y= OPT= +ALLOW= exim_path = EXIM_PATH keep_environment = @@ -20,6 +21,7 @@ tls_advertise_hosts = ${if eq {Y}{tls} {*}} domainlist local_domains = @ : test.ex acl_smtp_rcpt = check_recipient +acl_smtp_data_prdr = check_prdr acl_smtp_data = check_data trusted_users = CALLER queue_only @@ -29,6 +31,8 @@ log_selector = +received_recipients tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} +ALLOW + # ----- ACL ----- begin acl @@ -38,6 +42,10 @@ check_recipient: accept domains = +local_domains deny message = relay not permitted +check_prdr: + accept local_parts = good + deny + check_data: warn message = X-acl-message-linecount: $message_linecount accept diff --git a/test/confs/5590 b/test/confs/5590 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/5590 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/confs/5591 b/test/confs/5591 new file mode 120000 index 000000000..1bb987150 --- /dev/null +++ b/test/confs/5591 @@ -0,0 +1 @@ +0900 \ No newline at end of file diff --git a/test/log/5590 b/test/log/5590 new file mode 100644 index 000000000..1959dac0f --- /dev/null +++ b/test/log/5590 @@ -0,0 +1,7 @@ + +******** SERVER ******** +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 PRDR R= refusal +1999-03-02 09:44:33 10HmaX-0005vi-00 PRDR R= acceptance +1999-03-02 09:44:33 10HmaX-0005vi-00 PRDR R= refusal +1999-03-02 09:44:33 10HmaX-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp PRDR K S=sss for bad1@test.ex good@test.ex bad2@test.ex diff --git a/test/log/5591 b/test/log/5591 new file mode 100644 index 000000000..0b9bd84ef --- /dev/null +++ b/test/log/5591 @@ -0,0 +1,4 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= sender_gets_replaced@the.local.host.name U=CALLER P=local S=sss for usery userz +1999-03-02 09:44:33 10HmaX-0005vi-00 => usery@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR C="250 first rcpt was good" +1999-03-02 09:44:33 10HmaX-0005vi-00 -> userz@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR C="250 second rcpt was good" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed diff --git a/test/scripts/5500-PRDR/5590 b/test/scripts/5500-PRDR/5590 new file mode 100644 index 000000000..a9722ff81 --- /dev/null +++ b/test/scripts/5500-PRDR/5590 @@ -0,0 +1,40 @@ +# PRDR and CHUNKING reception +exim -DALLOW=prdr_enable -DSERVER=server -bd -oX PORT_D +**** +# +client 127.0.0.1 PORT_D +??? 220 +EHLO tester +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250-PRDR +??? 250 +MAIL FROM: PRDR +??? 250 +RCPT TO: +??? 250 +RCPT TO: +??? 250 +RCPT TO: +??? 250 +BDAT 100 last +To: Susan@random.com +From: Sam@random.com +Subject: This is a bodyfull test message + +1234567890 +??? 353 +??? 550 +??? 250 +??? 550 +??? 250 +QUIT +??? 221 +**** +# +# +killdaemon +no_msglog_check diff --git a/test/scripts/5500-PRDR/5591 b/test/scripts/5500-PRDR/5591 new file mode 100644 index 000000000..67b9de298 --- /dev/null +++ b/test/scripts/5500-PRDR/5591 @@ -0,0 +1,32 @@ +# PRDR and CHUNKING transmission +need_ipv4 +no_msglog_check +# +# Two recipients, accepted by full PRDR response sequence +server PORT_S +220 Server ready +EHLO +250-hiya matey +250-PRDR +250-CHUNKING +250 OK +MAIL FROM:<> PRDR +250 OK +RCPT TO +250 OK +RCPT TO +250 OK +BDAT 317 LAST +*data 317 +353 prdr responses coming up +250 first rcpt was good +250 second rcpt was good +250 OK, overall +QUIT +250 OK +**** +exim -odi -f sender_gets_replaced usery userz +Some message text. +**** +# +# diff --git a/test/scripts/5500-PRDR/REQUIRES b/test/scripts/5500-PRDR/REQUIRES index e69de29bb..bca921eaf 100644 --- a/test/scripts/5500-PRDR/REQUIRES +++ b/test/scripts/5500-PRDR/REQUIRES @@ -0,0 +1 @@ +support PRDR diff --git a/test/stdout/5591 b/test/stdout/5591 new file mode 100644 index 000000000..1a65e063d --- /dev/null +++ b/test/stdout/5591 @@ -0,0 +1,24 @@ + +******** SERVER ******** +Listening on port 1224 ... +Connection request from [127.0.0.1] +220 Server ready +EHLO the.local.host.name +250-hiya matey +250-PRDR +250-CHUNKING +250 OK +MAIL FROM:<> PRDR +250 OK +RCPT TO: +250 OK +RCPT TO: +250 OK +BDAT 317 LAST +353 prdr responses coming up +250 first rcpt was good +250 second rcpt was good +250 OK, overall +QUIT +250 OK +End of script -- cgit v1.2.3 From e0cc6cda55782d98187cdc2d11b7c3352e75c7d4 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 2 Aug 2016 10:53:06 +0100 Subject: transmit logging --- src/src/deliver.c | 14 ++++++++++++-- src/src/structs.h | 7 ++++--- src/src/transports/smtp.c | 1 + test/log/0901 | 8 ++++---- test/log/0902 | 6 +++--- test/log/2091 | 2 +- test/log/2191 | 2 +- test/log/4509 | 4 ++-- test/log/5591 | 4 ++-- 9 files changed, 30 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/src/src/deliver.c b/src/src/deliver.c index 419dee92c..a8d740cde 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -715,7 +715,7 @@ host_item * h = addr->host_used; s = string_append(s, sp, pp, 2, US" H=", h->name); if (LOGGING(dnssec) && h->dnssec == DS_YES) - s = string_cat(s, sp, pp, US" DS"); + s = string_catn(s, sp, pp, US" DS", 3); s = string_append(s, sp, pp, 3, US" [", h->address, US"]"); @@ -962,8 +962,11 @@ else #ifndef DISABLE_PRDR if (addr->flags & af_prdr_used) - s = string_append(s, &size, &ptr, 1, US" PRDR"); + s = string_catn(s, &size, &ptr, US" PRDR", 5); #endif + + if (addr->flags & af_chunking_used) + s = string_catn(s, &size, &ptr, US" K", 2); } /* confirmation message (SMTP (host_used) and LMTP (driver_name)) */ @@ -3289,6 +3292,10 @@ while (!done) break; #endif + case 'K': + addr->flags |= af_chunking_used; + break; + case 'D': if (!addr) goto ADDR_MISMATCH; memcpy(&(addr->dsn_aware), ptr, sizeof(addr->dsn_aware)); @@ -4527,6 +4534,9 @@ for (delivery_count = 0; addr_remote; delivery_count++) rmt_dlv_checked_write(fd, 'P', '0', NULL, 0); #endif + if (addr->flags & af_chunking_used) + rmt_dlv_checked_write(fd, 'K', '0', NULL, 0); + memcpy(big_buffer, &addr->dsn_aware, sizeof(addr->dsn_aware)); rmt_dlv_checked_write(fd, 'D', '0', big_buffer, sizeof(addr->dsn_aware)); DEBUG(D_deliver) debug_printf("DSN write: addr->dsn_aware = %d\n", addr->dsn_aware); diff --git a/src/src/structs.h b/src/src/structs.h index e378a16a2..ffbc899a5 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -546,12 +546,13 @@ typedef struct address_item_propagated { #ifndef DISABLE_PRDR # define af_prdr_used 0x08000000 /* delivery used SMTP PRDR */ #endif -#define af_force_command 0x10000000 /* force_command in pipe transport */ +#define af_chunking_used 0x10000000 /* delivery used SMTP CHUNKING */ +#define af_force_command 0x20000000 /* force_command in pipe transport */ #ifdef EXPERIMENTAL_DANE -# define af_dane_verified 0x20000000 /* TLS cert verify done with DANE */ +# define af_dane_verified 0x40000000 /* TLS cert verify done with DANE */ #endif #ifdef SUPPORT_I18N -# define af_utf8_downcvt 0x40000000 /* downconvert was done for delivery */ +# define af_utf8_downcvt 0x80000000 /* downconvert was done for delivery */ #endif /* These flags must be propagated when a child is created */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index a265e566e..110ced240 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2704,6 +2704,7 @@ else #ifndef DISABLE_PRDR if (prdr_active) addr->flags |= af_prdr_used; #endif + if (peer_offered & PEER_OFFERED_CHUNKING) addr->flags |= af_chunking_used; flag = '-'; #ifndef DISABLE_PRDR diff --git a/test/log/0901 b/test/log/0901 index 58688cf28..0239bac64 100644 --- a/test/log/0901 +++ b/test/log/0901 @@ -1,10 +1,10 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex -1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for b@test.ex 1999-03-02 09:44:33 10HmaY-0005vi-00 == b@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after end of data (ddd bytes written) 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for c@test.ex -1999-03-02 09:44:33 10HmaZ-0005vi-00 => c@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK" +1999-03-02 09:44:33 10HmaZ-0005vi-00 => c@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK" 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for d@test.ex 1999-03-02 09:44:33 10HmbA-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 500 oops @@ -13,12 +13,12 @@ 1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for e@test.ex 1999-03-02 09:44:33 10HmbB-0005vi-00 == e@test.ex R=to_server T=remote_smtp defer (-46) H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after end of data: 400 not right now 1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for p@test.ex -1999-03-02 09:44:33 10HmbC-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbC-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat" 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for q@test.ex 1999-03-02 09:44:33 10HmbD-0005vi-00 == q@test.ex R=to_server T=remote_smtp defer (dd): Connection timed out H=127.0.0.1 [127.0.0.1]: SMTP timeout after pipelined end of data (ddd bytes written) 1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for r@test.ex -1999-03-02 09:44:33 10HmbE-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbE-0005vi-00 => r@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat" 1999-03-02 09:44:33 10HmbE-0005vi-00 Completed 1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for s@test.ex 1999-03-02 09:44:33 10HmbF-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined end of data: 550 unacceptable mail-from diff --git a/test/log/0902 b/test/log/0902 index 330b472bd..63e180185 100644 --- a/test/log/0902 +++ b/test/log/0902 @@ -1,12 +1,12 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex -1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for d@test.ex 1999-03-02 09:44:33 10HmaY-0005vi-00 ** d@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after sending data block: 500 oops bdat-nonlast 1999-03-02 09:44:33 10HmaY-0005vi-00 d@test.ex: error ignored 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for p@test.ex -1999-03-02 09:44:33 10HmaZ-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmaZ-0005vi-00 => p@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat" 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed 1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for s@test.ex 1999-03-02 09:44:33 10HmbA-0005vi-00 ** s@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after pipelined sending data block: 550 unacceptable mail-from @@ -18,7 +18,7 @@ 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed 1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for t1@test.ex t2@test.ex 1999-03-02 09:44:33 10HmbC-0005vi-00 ** t1@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 no such recipient -1999-03-02 09:44:33 10HmbC-0005vi-00 => t2@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] C="250 OK bdat" +1999-03-02 09:44:33 10HmbC-0005vi-00 => t2@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250 OK bdat" 1999-03-02 09:44:33 10HmbC-0005vi-00 t1@test.ex: error ignored 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for u@test.ex diff --git a/test/log/2091 b/test/log/2091 index 3c1be5c84..62238f82a 100644 --- a/test/log/2091 +++ b/test/log/2091 @@ -1,5 +1,5 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for CALLER@test.ex -1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=no K C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed ******** SERVER ******** diff --git a/test/log/2191 b/test/log/2191 index 4ff843230..38418fb32 100644 --- a/test/log/2191 +++ b/test/log/2191 @@ -1,7 +1,7 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for CALLER@test.ex 1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: depth=0 error=self signed certificate cert=/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock 1999-03-02 09:44:33 10HmaX-0005vi-00 [127.0.0.1] SSL verify error: certificate name mismatch: "/C=UK/O=The Exim Maintainers/OU=Test Suite/CN=Phil Pennock" -1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 CV=no K C="250- 340 byte chunk, total 340\\n250 OK id=10HmaY-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed ******** SERVER ******** diff --git a/test/log/4509 b/test/log/4509 index 6e62c5219..e2d3bc714 100644 --- a/test/log/4509 +++ b/test/log/4509 @@ -1,8 +1,8 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for a@test.ex -1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] C="250- 973 byte chunk, total 973\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] K C="250- 973 byte chunk, total 973\\n250 OK id=10HmaY-0005vi-00" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss for b@test.ex -1999-03-02 09:44:33 10HmaZ-0005vi-00 => b@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] C="250- 8509 byte chunk, total 9160\\n250 OK id=10HmbA-0005vi-00" +1999-03-02 09:44:33 10HmaZ-0005vi-00 => b@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] K C="250- 8509 byte chunk, total 9160\\n250 OK id=10HmbA-0005vi-00" 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed ******** SERVER ******** diff --git a/test/log/5591 b/test/log/5591 index 0b9bd84ef..b216ad9ef 100644 --- a/test/log/5591 +++ b/test/log/5591 @@ -1,4 +1,4 @@ 1999-03-02 09:44:33 10HmaX-0005vi-00 <= sender_gets_replaced@the.local.host.name U=CALLER P=local S=sss for usery userz -1999-03-02 09:44:33 10HmaX-0005vi-00 => usery@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR C="250 first rcpt was good" -1999-03-02 09:44:33 10HmaX-0005vi-00 -> userz@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR C="250 second rcpt was good" +1999-03-02 09:44:33 10HmaX-0005vi-00 => usery@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR K C="250 first rcpt was good" +1999-03-02 09:44:33 10HmaX-0005vi-00 -> userz@the.local.host.name R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] PRDR K C="250 second rcpt was good" 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed -- cgit v1.2.3 From 2d14f39731e88a6d6bb9f1b5c56f497eb12198c4 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 2 Aug 2016 12:10:41 +0100 Subject: pass advertised facility to continued-transport process --- doc/doc-docbook/spec.xfpt | 2 +- src/src/exim.c | 67 +++++++++------------- src/src/globals.c | 6 +- src/src/globals.h | 6 +- src/src/transport.c | 24 ++++---- src/src/transports/smtp.c | 130 +++++++++++++++++++++++-------------------- src/src/verify.c | 2 +- test/log/0900 | 1 + test/scripts/0000-Basic/0900 | 31 ++++++++++- test/stdout/0900 | 35 +++++++++++- 10 files changed, 176 insertions(+), 128 deletions(-) (limited to 'test') diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 5edeee442..6302f5185 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -27767,7 +27767,7 @@ associated with the DATA command. .cindex "RFC 3030" CHUNKING If CHUNKING was advertised and a BDAT command sequence is received, the &%acl_smtp_predata%& ACL is not run. -.XXX why not? It should be possible, for the first BDAT. +. XXX why not? It should be possible, for the first BDAT. The &%acl_smtp_data%& is run after the last BDAT command and all of the data specified is received. .wen diff --git a/src/src/exim.c b/src/src/exim.c index 01770df73..14e0b9d67 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -2717,76 +2717,63 @@ for (i = 1; i < argc; i++) break; } + else if (*argrest == 'C' && argrest[1] && !argrest[2]) + { + switch(argrest[1]) + { /* -MCA: set the smtp_authenticated flag; this is useful only when it precedes -MC (see above). The flag indicates that the host to which Exim is connected has accepted an AUTH sequence. */ - else if (Ustrcmp(argrest, "CA") == 0) - { - smtp_authenticated = TRUE; - break; - } + case 'A': smtp_authenticated = TRUE; break; /* -MCD: set the smtp_use_dsn flag; this indicates that the host that exim is connected to supports the esmtp extension DSN */ - else if (Ustrcmp(argrest, "CD") == 0) - { - smtp_use_dsn = TRUE; - break; - } + case 'D': smtp_peer_options |= PEER_OFFERED_DSN; break; /* -MCG: set the queue name, to a non-default value */ - else if (Ustrcmp(argrest, "CG") == 0) - { - if (++i < argc) queue_name = string_copy(argv[i]); - else badarg = TRUE; - break; - } + case 'G': if (++i < argc) queue_name = string_copy(argv[i]); + else badarg = TRUE; + break; + + /* -MCK: the peer offered CHUNKING. Must precede -MC */ + + case 'K': smtp_peer_options |= PEER_OFFERED_CHUNKING; break; /* -MCP: set the smtp_use_pipelining flag; this is useful only when it preceded -MC (see above) */ - else if (Ustrcmp(argrest, "CP") == 0) - { - smtp_use_pipelining = TRUE; - break; - } + case 'P': smtp_peer_options |= PEER_OFFERED_PIPE; break; /* -MCQ: pass on the pid of the queue-running process that started this chain of deliveries and the fd of its synchronizing pipe; this is useful only when it precedes -MC (see above) */ - else if (Ustrcmp(argrest, "CQ") == 0) - { - if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); - else badarg = TRUE; - if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); - else badarg = TRUE; - break; - } + case 'Q': if (++i < argc) passed_qr_pid = (pid_t)(Uatol(argv[i])); + else badarg = TRUE; + if (++i < argc) passed_qr_pipe = (int)(Uatol(argv[i])); + else badarg = TRUE; + break; /* -MCS: set the smtp_use_size flag; this is useful only when it precedes -MC (see above) */ - else if (Ustrcmp(argrest, "CS") == 0) - { - smtp_use_size = TRUE; - break; - } + case 'S': smtp_peer_options |= PEER_OFFERED_SIZE; break; +#ifdef SUPPORT_TLS /* -MCT: set the tls_offered flag; this is useful only when it precedes -MC (see above). The flag indicates that the host to which Exim is connected has offered TLS support. */ - #ifdef SUPPORT_TLS - else if (Ustrcmp(argrest, "CT") == 0) - { - tls_offered = TRUE; - break; + case 'T': smtp_peer_options |= PEER_OFFERED_TLS; break; +#endif + + default: badarg = TRUE; break; + } + break; } - #endif /* -M[x]: various operations on the following list of message ids: -M deliver the messages, ignoring next retry times and thawing diff --git a/src/src/globals.c b/src/src/globals.c index ba1336633..9e6f9d347 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -138,7 +138,6 @@ tls_support tls_out = { uschar *dsn_envid = NULL; int dsn_ret = 0; const pcre *regex_DSN = NULL; -BOOL smtp_use_dsn = FALSE; uschar *dsn_advertise_hosts = NULL; #ifdef SUPPORT_TLS @@ -158,7 +157,6 @@ uschar *tls_eccurve = US"prime256v1"; # ifndef DISABLE_OCSP uschar *tls_ocsp_file = NULL; # endif -BOOL tls_offered = FALSE; uschar *tls_privatekey = NULL; BOOL tls_remember_esmtp = FALSE; uschar *tls_require_ciphers = NULL; @@ -1322,8 +1320,8 @@ int smtp_rlr_base = 0; double smtp_rlr_factor = 0.0; int smtp_rlr_limit = 0; int smtp_rlr_threshold = INT_MAX; -BOOL smtp_use_pipelining = FALSE; -BOOL smtp_use_size = FALSE; +unsigned smtp_peer_options = 0; +unsigned smtp_peer_options_wrap= 0; #ifdef SUPPORT_I18N uschar *smtputf8_advertise_hosts = US"*"; /* overridden under test-harness */ #endif diff --git a/src/src/globals.h b/src/src/globals.h index f9af38ef5..b2bfca64c 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -119,7 +119,6 @@ extern uschar *tls_eccurve; /* EC curve */ # ifndef DISABLE_OCSP extern uschar *tls_ocsp_file; /* OCSP stapling proof file */ # endif -extern BOOL tls_offered; /* Server offered TLS */ extern uschar *tls_privatekey; /* Private key file */ extern BOOL tls_remember_esmtp; /* For YAEB */ extern uschar *tls_require_ciphers; /* So some can be avoided */ @@ -132,7 +131,6 @@ extern uschar *tls_advertise_hosts; /* host for which TLS is advertised */ extern uschar *dsn_envid; /* DSN envid string */ extern int dsn_ret; /* DSN ret type*/ extern const pcre *regex_DSN; /* For recognizing DSN settings */ -extern BOOL smtp_use_dsn; /* Global for passed connections */ extern uschar *dsn_advertise_hosts; /* host for which TLS is advertised */ /* Input-reading functions for messages, so we can use special ones for @@ -838,8 +836,8 @@ extern int smtp_rlr_base; /* Base interval for RCPT rate limit */ extern double smtp_rlr_factor; /* Factor for RCPT rate limit */ extern int smtp_rlr_limit; /* Max delay */ extern int smtp_rlr_threshold; /* Threshold for RCPT rate limit */ -extern BOOL smtp_use_pipelining; /* Global for passed connections */ -extern BOOL smtp_use_size; /* Global for passed connections */ +extern unsigned smtp_peer_options; /* Global flags for passed connections */ +extern unsigned smtp_peer_options_wrap; /* stacked version hidden by TLS */ #ifdef SUPPORT_I18N extern uschar *smtputf8_advertise_hosts; /* ingress control */ #endif diff --git a/src/src/transport.c b/src/src/transport.c index 3987fad3e..88d925e39 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -826,12 +826,12 @@ Arguments: end_dot if TRUE, send a terminating "." line at the end no_headers if TRUE, omit the headers no_body if TRUE, omit the body - size_limit if > 0, this is a limit to the size of message written; + check_string a string to check for at the start of lines, or NULL + escape_string a string to insert in front of any check string + size_limit if > 0, this is a limit to the size of message written; it is used when returning messages to their senders, and is approximate rather than exact, owing to chunk buffering - check_string a string to check for at the start of lines, or NULL - escape_string a string to insert in front of any check string Returns: TRUE on success; FALSE (with errno) on failure. In addition, the global variable transport_count @@ -1228,7 +1228,6 @@ set up a filtering process, fork another process to call the internal function to write to the filter, and in this process just suck from the filter and write down the given fd. At the end, tidy up the pipes and the processes. -XXX Arguments: as for internal_transport_write_message() above Returns: TRUE on success; FALSE (with errno) for any failure @@ -1944,7 +1943,7 @@ DEBUG(D_transport) debug_printf("transport_pass_socket entered\n"); if ((pid = fork()) == 0) { - int i = 16; + int i = 17; const uschar **argv; /* Disconnect entirely from the parent process. If we are running in the @@ -1960,16 +1959,15 @@ if ((pid = fork()) == 0) argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, &i, FALSE, 0); - if (smtp_use_dsn) argv[i++] = US"-MCD"; - if (smtp_authenticated) argv[i++] = US"-MCA"; - #ifdef SUPPORT_TLS - if (tls_offered) argv[i++] = US"-MCT"; - #endif - - if (smtp_use_size) argv[i++] = US"-MCS"; - if (smtp_use_pipelining) argv[i++] = US"-MCP"; + if (smtp_peer_options & PEER_OFFERED_CHUNKING) argv[i++] = US"-MCK"; + if (smtp_peer_options & PEER_OFFERED_DSN) argv[i++] = US"-MCD"; + if (smtp_peer_options & PEER_OFFERED_PIPE) argv[i++] = US"-MCP"; + if (smtp_peer_options & PEER_OFFERED_SIZE) argv[i++] = US"-MCS"; +#ifdef SUPPORT_TLS + if (smtp_peer_options & PEER_OFFERED_TLS) argv[i++] = US"-MCT"; +#endif if (queue_run_pid != (pid_t)0) { diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 110ced240..25e493433 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -12,6 +12,8 @@ #define PENDING_DEFER (PENDING + DEFER) #define PENDING_OK (PENDING + OK) +#define DELIVER_BUFFER_SIZE 4096 + /* Options specific to the smtp transport. This transport also supports LMTP over TCP/IP. The options must be in alphabetic order (note that "_" comes @@ -1406,8 +1408,7 @@ if (flags & tc_reap_prev && prev_cmd_count > 0) tctx->pending_MAIL, 0, tctx->inblock, ob->command_timeout, - buffer, 4096)) -/*XXX buffer size! */ + buffer, DELIVER_BUFFER_SIZE)) { case 1: /* 2xx (only) => OK */ case 3: tctx->good_RCPT = TRUE; /* 2xx & 5xx => OK & progress made */ @@ -1426,8 +1427,7 @@ if (flags & tc_reap_prev && prev_cmd_count > 0) if (flags & tc_reap_one || tctx->pending_BDAT) { -/*XXX buffer size! */ - if (!smtp_read_response(tctx->inblock, buffer, 4096, '2', + if (!smtp_read_response(tctx->inblock, buffer, DELIVER_BUFFER_SIZE, '2', ob->command_timeout)) { if (errno == 0 && buffer[0] == '4') @@ -1521,7 +1521,7 @@ BOOL completed_address = FALSE; BOOL esmtp = TRUE; BOOL pending_MAIL; BOOL pass_message = FALSE; -uschar peer_offered = 0; /*XXX should this be handed on cf. tls_offered, smtp_use_dsn ? */ +uschar peer_offered = 0; #ifndef DISABLE_PRDR BOOL prdr_active; #endif @@ -1548,7 +1548,7 @@ uschar *helo_data = NULL; uschar *message = NULL; uschar new_message_id[MESSAGE_ID_LENGTH + 1]; uschar *p; -uschar buffer[4096]; +uschar buffer[DELIVER_BUFFER_SIZE]; uschar inbuffer[4096]; uschar outbuffer[4096]; @@ -1756,7 +1756,7 @@ goto SEND_QUIT; #ifdef SUPPORT_TLS if (smtps) { - tls_offered = TRUE; + smtp_peer_options |= PEER_OFFERED_TLS; suppress_tls = FALSE; ob->tls_tempfail_tryclear = FALSE; smtp_command = US"SSL-on-connect"; @@ -1805,7 +1805,10 @@ goto SEND_QUIT; if (!good_response) goto RESPONSE_FAILED; } + peer_offered = smtp_peer_options = 0; + if (esmtp || lmtp) + { peer_offered = ehlo_response(buffer, Ustrlen(buffer), PEER_OFFERED_TLS /* others checked later */ ); @@ -1813,14 +1816,15 @@ goto SEND_QUIT; /* Set tls_offered if the response to EHLO specifies support for STARTTLS. */ #ifdef SUPPORT_TLS - tls_offered = !!(peer_offered & PEER_OFFERED_TLS); + smtp_peer_options |= peer_offered & PEER_OFFERED_TLS; #endif + } } /* For continuing deliveries down the same channel, the socket is the standard input, and we don't need to redo EHLO here (but may need to do so for TLS - see below). Set up the pointer to where subsequent commands will be left, for -error messages. Note that smtp_use_size and smtp_use_pipelining will have been +error messages. Note that smtp_peer_options will have been set from the command line if they were set in the process that passed the connection on. */ @@ -1845,7 +1849,7 @@ the client not be required to use TLS. If the response is bad, copy the buffer for error analysis. */ #ifdef SUPPORT_TLS -if ( tls_offered +if ( smtp_peer_options & PEER_OFFERED_TLS && !suppress_tls && verify_check_given_host(&ob->hosts_avoid_tls, host) != OK) { @@ -1907,6 +1911,7 @@ if ( tls_offered /* TLS session is set up */ + smtp_peer_options_wrap = smtp_peer_options; for (addr = addrlist; addr; addr = addr->next) if (addr->transport_return == PENDING_DEFER) { @@ -1976,6 +1981,7 @@ if (tls_out.active >= 0) helo_response = string_copy(buffer); #endif if (!good_response) goto RESPONSE_FAILED; + smtp_peer_options = 0; } /* If the host is required to use a secure channel, ensure that we @@ -1990,8 +1996,8 @@ else if ( smtps { save_errno = ERRNO_TLSREQUIRED; message = string_sprintf("a TLS session is required, but %s", - tls_offered ? "an attempt to start TLS failed" - : "the server did not offer TLS support"); + smtp_peer_options & PEER_OFFERED_TLS + ? "an attempt to start TLS failed" : "the server did not offer TLS support"); goto TLS_FAILED; } #endif /*SUPPORT_TLS*/ @@ -2008,6 +2014,7 @@ if (continue_hostname == NULL ) { if (esmtp || lmtp) + { peer_offered = ehlo_response(buffer, Ustrlen(buffer), 0 /* no TLS */ | (lmtp && ob->lmtp_ignore_quota ? PEER_OFFERED_IGNQ : 0) @@ -2015,7 +2022,7 @@ if (continue_hostname == NULL | PEER_OFFERED_PRDR #ifdef SUPPORT_I18N | (addrlist->prop.utf8_msg ? PEER_OFFERED_UTF8 : 0) - /*XXX if we hand peercaps on to continued-conn processes, + /*XXX if we hand peercaps on to continued-conn processes, must not depend on this addr */ #endif | PEER_OFFERED_DSN @@ -2023,61 +2030,64 @@ if (continue_hostname == NULL | (ob->size_addition >= 0 ? PEER_OFFERED_SIZE : 0) ); - /* Set for IGNOREQUOTA if the response to LHLO specifies support and the - lmtp_ignore_quota option was set. */ + /* Set for IGNOREQUOTA if the response to LHLO specifies support and the + lmtp_ignore_quota option was set. */ - igquotstr = peer_offered & PEER_OFFERED_IGNQ ? US" IGNOREQUOTA" : US""; + igquotstr = peer_offered & PEER_OFFERED_IGNQ ? US" IGNOREQUOTA" : US""; - /* If the response to EHLO specified support for the SIZE parameter, note - this, provided size_addition is non-negative. */ + /* If the response to EHLO specified support for the SIZE parameter, note + this, provided size_addition is non-negative. */ - smtp_use_size = !!(peer_offered & PEER_OFFERED_SIZE); + smtp_peer_options |= peer_offered & PEER_OFFERED_SIZE; - /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched - the current host, esmtp will be false, so PIPELINING can never be used. If - the current host matches hosts_avoid_pipelining, don't do it. */ + /* Note whether the server supports PIPELINING. If hosts_avoid_esmtp matched + the current host, esmtp will be false, so PIPELINING can never be used. If + the current host matches hosts_avoid_pipelining, don't do it. */ - smtp_use_pipelining = peer_offered & PEER_OFFERED_PIPE - && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK; + if ( peer_offered & PEER_OFFERED_PIPE + && verify_check_given_host(&ob->hosts_avoid_pipelining, host) != OK) + smtp_peer_options |= PEER_OFFERED_PIPE; - DEBUG(D_transport) debug_printf("%susing PIPELINING\n", - smtp_use_pipelining ? "" : "not "); + DEBUG(D_transport) debug_printf("%susing PIPELINING\n", + smtp_peer_options & PEER_OFFERED_PIPE ? "" : "not "); - if ( peer_offered & PEER_OFFERED_CHUNKING - && verify_check_given_host(&ob->hosts_try_chunking, host) != OK) - peer_offered &= ~PEER_OFFERED_CHUNKING; + if ( peer_offered & PEER_OFFERED_CHUNKING + && verify_check_given_host(&ob->hosts_try_chunking, host) != OK) + peer_offered &= ~PEER_OFFERED_CHUNKING; - if (peer_offered & PEER_OFFERED_CHUNKING) - {DEBUG(D_transport) debug_printf("CHUNKING usable\n");} + if (peer_offered & PEER_OFFERED_CHUNKING) + {DEBUG(D_transport) debug_printf("CHUNKING usable\n");} #ifndef DISABLE_PRDR - if ( peer_offered & PEER_OFFERED_PRDR - && verify_check_given_host(&ob->hosts_try_prdr, host) != OK) - peer_offered &= ~PEER_OFFERED_PRDR; + if ( peer_offered & PEER_OFFERED_PRDR + && verify_check_given_host(&ob->hosts_try_prdr, host) != OK) + peer_offered &= ~PEER_OFFERED_PRDR; - if (peer_offered & PEER_OFFERED_PRDR) - {DEBUG(D_transport) debug_printf("PRDR usable\n");} + if (peer_offered & PEER_OFFERED_PRDR) + {DEBUG(D_transport) debug_printf("PRDR usable\n");} #endif - /* Note if the server supports DSN */ - smtp_use_dsn = !!(peer_offered & PEER_OFFERED_DSN); - DEBUG(D_transport) debug_printf("%susing DSN\n", smtp_use_dsn ? "" : "not "); + /* Note if the server supports DSN */ + smtp_peer_options |= peer_offered & PEER_OFFERED_DSN; + DEBUG(D_transport) debug_printf("%susing DSN\n", + peer_offered & PEER_OFFERED_DSN ? "" : "not "); - /* Note if the response to EHLO specifies support for the AUTH extension. - If it has, check that this host is one we want to authenticate to, and do - the business. The host name and address must be available when the - authenticator's client driver is running. */ + /* Note if the response to EHLO specifies support for the AUTH extension. + If it has, check that this host is one we want to authenticate to, and do + the business. The host name and address must be available when the + authenticator's client driver is running. */ - switch (yield = smtp_auth(buffer, sizeof(buffer), addrlist, host, - ob, esmtp, &inblock, &outblock)) - { - default: goto SEND_QUIT; - case OK: break; - case FAIL_SEND: goto SEND_FAILED; - case FAIL: goto RESPONSE_FAILED; + switch (yield = smtp_auth(buffer, sizeof(buffer), addrlist, host, + ob, esmtp, &inblock, &outblock)) + { + default: goto SEND_QUIT; + case OK: break; + case FAIL_SEND: goto SEND_FAILED; + case FAIL: goto RESPONSE_FAILED; + } } } -pipelining_active = smtp_use_pipelining; +pipelining_active = !!(smtp_peer_options & PEER_OFFERED_PIPE); /* The setting up of the SMTP call is now complete. Any subsequent errors are message-specific. */ @@ -2162,7 +2172,7 @@ included in the count.) */ p = buffer; *p = 0; -if (smtp_use_size) +if (peer_offered & PEER_OFFERED_SIZE) { sprintf(CS p, " SIZE=%d", message_size+message_linecount+ob->size_addition); while (*p) p++; @@ -2206,7 +2216,7 @@ for (dsn_all_lasthop = TRUE, addr = first_addr; /* Add any DSN flags to the mail command */ -if (smtp_use_dsn && !dsn_all_lasthop) +if (peer_offered & PEER_OFFERED_DSN && !dsn_all_lasthop) { if (dsn_ret == dsn_ret_hdrs) { Ustrcpy(p, " RET=HDRS"); p += 9; } @@ -2264,7 +2274,7 @@ pending_MAIL = TRUE; /* The block starts with MAIL */ } #endif - rc = smtp_write_command(&outblock, smtp_use_pipelining, + rc = smtp_write_command(&outblock, pipelining_active, "MAIL FROM:<%s>%s\r\n", s, buffer); } @@ -2311,21 +2321,22 @@ for (addr = first_addr; BOOL no_flush; uschar * rcpt_addr; - addr->dsn_aware = smtp_use_dsn ? dsn_support_yes : dsn_support_no; + addr->dsn_aware = peer_offered & PEER_OFFERED_DSN + ? dsn_support_yes : dsn_support_no; if (addr->transport_return != PENDING_DEFER) continue; address_count++; - no_flush = smtp_use_pipelining && (!mua_wrapper || addr->next); + no_flush = pipelining_active && (!mua_wrapper || addr->next); /* Add any DSN flags to the rcpt command and add to the sent string */ p = buffer; *p = 0; - if (smtp_use_dsn && !(addr->dsn_flags & rf_dsnlasthop)) + if (peer_offered & PEER_OFFERED_DSN && !(addr->dsn_flags & rf_dsnlasthop)) { - if ((addr->dsn_flags & rf_dsnflags) != 0) + if (addr->dsn_flags & rf_dsnflags) { int i; BOOL first = TRUE; @@ -2424,7 +2435,7 @@ If using CHUNKING, do not send a BDAT until we know how big a chunk we want to send is. */ if ( !(peer_offered & PEER_OFFERED_CHUNKING) - && (ok || (smtp_use_pipelining && !mua_wrapper))) + && (ok || (pipelining_active && !mua_wrapper))) { int count = smtp_write_command(&outblock, FALSE, "DATA\r\n"); @@ -3031,6 +3042,7 @@ if (completed_address && ok && send_quit) if (tls_out.active >= 0) { tls_close(FALSE, TRUE); + smtp_peer_options = smtp_peer_options_wrap; if (smtps) ok = FALSE; else diff --git a/src/src/verify.c b/src/src/verify.c index 4c4dfc599..d890f5fc6 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -759,7 +759,7 @@ can do it there for the non-rcpt-verify case. For this we keep an addresscount. ? string_sprintf(" SIZE=%d", message_size + ob->size_addition) : US""; #ifdef SUPPORT_TLS - tls_offered = !!(peer_offered & PEER_OFFERED_TLS); + smtp_peer_options |= peer_offered & PEER_OFFERED_TLS; #endif /* If TLS is available on this connection attempt to diff --git a/test/log/0900 b/test/log/0900 index 10e96f9a3..63072b9a9 100644 --- a/test/log/0900 +++ b/test/log/0900 @@ -7,3 +7,4 @@ 1999-03-02 09:44:33 10HmbA-0005vi-00 SMTP data timeout (message abandoned) on connection from (tester) [127.0.0.1] F= 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data 1999-03-02 09:44:33 SMTP connection from (tester) [127.0.0.1] lost while reading message data +1999-03-02 09:44:33 10HmbB-0005vi-00 <= someone@some.domain H=(tester) [127.0.0.1] P=esmtp K S=sss for CALLER@the.local.host.name diff --git a/test/scripts/0000-Basic/0900 b/test/scripts/0000-Basic/0900 index cb8cf63e3..435906d60 100644 --- a/test/scripts/0000-Basic/0900 +++ b/test/scripts/0000-Basic/0900 @@ -2,13 +2,14 @@ exim -DSERVER=server -bd -oX PORT_D **** # +# plain, small message (no body) client 127.0.0.1 PORT_D ??? 220 ehlo tester ??? 250- -??? 250- -??? 250- -??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING ??? 250-CHUNKING ??? 250 HELP mail from:someone@some.domain @@ -26,6 +27,9 @@ quit ??? 221 **** # +# plain, small message (with body) +# nonlast 1st bdat, noop, last-bdat(0) +# immediate followon 2nd message client 127.0.0.1 PORT_D ??? 220 ehlo tester @@ -118,6 +122,7 @@ quit ??? 221 **** # +# followon EHLO and another message client 127.0.0.1 PORT_D ??? 220 ehlo tester @@ -166,5 +171,25 @@ quit ??? 221 **** # +# plain, small message (no body) +# pipelined +client 127.0.0.1 PORT_D +??? 220 +EHLO tester +??? 250- +??? 250-SIZE +??? 250-8BITMIME +??? 250-PIPELINING +??? 250-CHUNKING +??? 250 HELP +MAIL FROM:\r\nRCPT TO:\r\nBDAT 88 LAST\r\nTo: Susan@random.com\r\nFrom: Sam@random.com\r\nSubject: This is a bodyless test message\r\n +??? 250 +??? 250 +??? 250- +??? 250 +quit +??? 221 +**** +# killdaemon no_msglog_check diff --git a/test/stdout/0900 b/test/stdout/0900 index 24c591617..28f479c22 100644 --- a/test/stdout/0900 +++ b/test/stdout/0900 @@ -4,11 +4,11 @@ Connecting to 127.0.0.1 port 1225 ... connected >>> ehlo tester ??? 250- <<< 250-the.local.host.name Hello tester [127.0.0.1] -??? 250- +??? 250-SIZE <<< 250-SIZE 52428800 -??? 250- +??? 250-8BITMIME <<< 250-8BITMIME -??? 250- +??? 250-PIPELINING <<< 250-PIPELINING ??? 250-CHUNKING <<< 250-CHUNKING @@ -230,3 +230,32 @@ Connecting to 127.0.0.1 port 1225 ... connected ??? 221 <<< 221 the.local.host.name closing connection End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO tester +??? 250- +<<< 250-the.local.host.name Hello tester [127.0.0.1] +??? 250-SIZE +<<< 250-SIZE 52428800 +??? 250-8BITMIME +<<< 250-8BITMIME +??? 250-PIPELINING +<<< 250-PIPELINING +??? 250-CHUNKING +<<< 250-CHUNKING +??? 250 HELP +<<< 250 HELP +>>> MAIL FROM:\r\nRCPT TO:\r\nBDAT 88 LAST\r\nTo: Susan@random.com\r\nFrom: Sam@random.com\r\nSubject: This is a bodyless test message\r\n +??? 250 +<<< 250 OK +??? 250 +<<< 250 Accepted +??? 250- +<<< 250- 88 byte chunk, total 88 +??? 250 +<<< 250 OK id=10HmbB-0005vi-00 +>>> quit +??? 221 +<<< 221 the.local.host.name closing connection +End of script -- cgit v1.2.3