summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2016-07-20 16:49:24 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2016-08-02 16:46:31 +0100
commitf98442df114d9dda7efdc34a3ddfde088021299f (patch)
tree5a6025d3fb614942ff50caa1a3dbff8556c0d419
parent7e3ce68e68ab9b8906a637d352993abf361554e2 (diff)
transmit peer capability recognition
-rw-r--r--src/src/deliver.c3
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/macros.h1
-rw-r--r--src/src/transports/smtp.c17
-rw-r--r--src/src/transports/smtp.h1
6 files changed, 23 insertions, 1 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index f99aa1819..450b58098 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -8073,6 +8073,9 @@ if (!regex_STARTTLS) regex_STARTTLS =
regex_must_compile(US"\\n250[\\s\\-]STARTTLS(\\s|\\n|$)", FALSE, TRUE);
#endif
+if (!regex_CHUNKING) regex_CHUNKING =
+ regex_must_compile(US"\\n250[\\s\\-]CHUNKING(\\s|\\n|$)", FALSE, TRUE);
+
#ifndef DISABLE_PRDR
if (!regex_PRDR) regex_PRDR =
regex_must_compile(US"\\n250[\\s\\-]PRDR(\\s|\\n|$)", FALSE, TRUE);
diff --git a/src/src/globals.c b/src/src/globals.c
index c86b9478d..987c717fc 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -500,6 +500,7 @@ unsigned chunking_datasize = 0;
unsigned chunking_data_left = 0;
BOOL chunking_offered = FALSE;
chunking_state_t chunking_state= CHUNKING_NOT_OFFERED;
+const pcre *regex_CHUNKING = NULL;
uschar *client_authenticator = NULL;
uschar *client_authenticated_id = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index c5767d73a..86ece2f30 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -718,6 +718,7 @@ extern int recipients_max_reject; /* If TRUE, reject whole message */
extern const pcre *regex_AUTH; /* For recognizing AUTH settings */
extern const pcre *regex_check_dns_names; /* For DNS name checking */
extern const pcre *regex_From; /* For recognizing "From_" lines */
+extern const pcre *regex_CHUNKING; /* For recognizing CHUNKING (RFC 3030) */
extern const pcre *regex_IGNOREQUOTA; /* For recognizing IGNOREQUOTA (LMTP) */
extern const pcre *regex_PIPELINING; /* For recognizing PIPELINING */
extern const pcre *regex_SIZE; /* For recognizing SIZE settings */
diff --git a/src/src/macros.h b/src/src/macros.h
index f567c7ec2..9b52fb775 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -960,6 +960,7 @@ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE };
#define PEER_OFFERED_DSN BIT(4)
#define PEER_OFFERED_PIPE BIT(5)
#define PEER_OFFERED_SIZE BIT(6)
+#define PEER_OFFERED_CHUNKING BIT(7)
/* End of macros.h */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 757a837db..cd9ac04e2 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -116,6 +116,8 @@ optionlist smtp_transport_options[] = {
#endif
{ "hosts_try_auth", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_auth) },
+ { "hosts_try_chunking", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, hosts_try_chunking) },
#if defined(SUPPORT_TLS) && defined(EXPERIMENTAL_DANE)
{ "hosts_try_dane", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, hosts_try_dane) },
@@ -200,12 +202,13 @@ smtp_transport_options_block smtp_transport_option_defaults = {
NULL, /* serialize_hosts */
NULL, /* hosts_try_auth */
NULL, /* hosts_require_auth */
+ US"*", /* hosts_try_chunking */
#ifdef EXPERIMENTAL_DANE
NULL, /* hosts_try_dane */
NULL, /* hosts_require_dane */
#endif
#ifndef DISABLE_PRDR
- US"*", /* hosts_try_prdr */
+ US"*", /* hosts_try_prdr */
#endif
#ifndef DISABLE_OCSP
US"*", /* hosts_request_ocsp (except under DANE; tls_client_start()) */
@@ -1325,6 +1328,10 @@ if ( checks & PEER_OFFERED_IGNQ
PCRE_EOPT, NULL, 0) < 0)
checks &= ~PEER_OFFERED_IGNQ;
+if ( checks & PEER_OFFERED_CHUNKING
+ && pcre_exec(regex_CHUNKING, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
+ checks &= ~PEER_OFFERED_CHUNKING;
+
#ifndef DISABLE_PRDR
if ( checks & PEER_OFFERED_PRDR
&& pcre_exec(regex_PRDR, NULL, CS buf, bsize, 0, PCRE_EOPT, NULL, 0) < 0)
@@ -1913,6 +1920,7 @@ if (continue_hostname == NULL
peer_offered = ehlo_response(buffer, Ustrlen(buffer),
0 /* no TLS */
| (lmtp && ob->lmtp_ignore_quota ? PEER_OFFERED_IGNQ : 0)
+ | PEER_OFFERED_CHUNKING
| PEER_OFFERED_PRDR
#ifdef SUPPORT_I18N
| (addrlist->prop.utf8_msg ? PEER_OFFERED_UTF8 : 0)
@@ -1944,6 +1952,13 @@ if (continue_hostname == NULL
DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
smtp_use_pipelining ? "" : "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)
+ {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)
diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h
index 804b9942f..d3666ae78 100644
--- a/src/src/transports/smtp.h
+++ b/src/src/transports/smtp.h
@@ -21,6 +21,7 @@ typedef struct {
uschar *serialize_hosts;
uschar *hosts_try_auth;
uschar *hosts_require_auth;
+ uschar *hosts_try_chunking;
#ifdef EXPERIMENTAL_DANE
uschar *hosts_try_dane;
uschar *hosts_require_dane;