From f98442df114d9dda7efdc34a3ddfde088021299f Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 20 Jul 2016 16:49:24 +0100 Subject: [PATCH] transmit peer capability recognition --- src/src/deliver.c | 3 +++ src/src/globals.c | 1 + src/src/globals.h | 1 + src/src/macros.h | 1 + src/src/transports/smtp.c | 17 ++++++++++++++++- src/src/transports/smtp.h | 1 + 6 files changed, 23 insertions(+), 1 deletion(-) 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; -- 2.25.1