From 1cf47989a0376c3f7156c214c1d509d372e4262b Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 19 Mar 2021 20:42:25 +0000 Subject: [PATCH] Make smtp_accept_max_per_connection expanded --- doc/doc-docbook/spec.xfpt | 7 ++++++- doc/doc-txt/NewStuff | 2 ++ src/src/globals.c | 2 +- src/src/globals.h | 2 +- src/src/readconf.c | 2 +- src/src/smtp_in.c | 31 ++++++++++++++++++++++--------- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index d971bbf60..e6135eb52 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -17575,7 +17575,7 @@ live with. . searchable. NM changed this occurrence for bug 1197 to no longer allow . the option name to split. -.option "smtp_accept_max_per_connection" main integer 1000 &&& +.option "smtp_accept_max_per_connection" main integer&!! 1000 &&& smtp_accept_max_per_connection .cindex "SMTP" "limiting incoming message count" .cindex "limit" "messages per SMTP connection" @@ -17585,6 +17585,11 @@ results in the transfer of a message. After the limit is reached, a 421 response is given to subsequent MAIL commands. This limit is a safety precaution against a client that goes mad (incidents of this type have been seen). +.new +The option is expanded after the HELO or EHLO is received +and may depend on values available at that time. +An empty or zero value after expansion removes the limit. +.wen .option smtp_accept_max_per_host main string&!! unset diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index cd1699dc6..50f7b4357 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -46,6 +46,8 @@ Version 4.95 12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout" main config option. +13. Option "smtp_accept_msx_per_connection" is now expanded. + Version 4.94 ------------ diff --git a/src/src/globals.c b/src/src/globals.c index b7e117868..04e47050e 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1450,7 +1450,7 @@ int smtp_accept_count = 0; int smtp_accept_max = 20; int smtp_accept_max_nonmail= 10; uschar *smtp_accept_max_nonmail_hosts = US"*"; -int smtp_accept_max_per_connection = 1000; +uschar *smtp_accept_max_per_connection = US"1000"; uschar *smtp_accept_max_per_host = NULL; int smtp_accept_queue = 0; int smtp_accept_queue_per_connection = 10; diff --git a/src/src/globals.h b/src/src/globals.h index 41705fb4b..652518ade 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -926,7 +926,7 @@ extern BOOL smtp_accept_keepalive; /* Set keepalive on incoming */ extern int smtp_accept_max; /* Max SMTP connections */ extern int smtp_accept_max_nonmail;/* Max non-mail commands in one con */ extern uschar *smtp_accept_max_nonmail_hosts; /* Limit non-mail cmds from these hosts */ -extern int smtp_accept_max_per_connection; /* Max msgs per connection */ +extern uschar *smtp_accept_max_per_connection; /* Max msgs per connection */ extern uschar *smtp_accept_max_per_host; /* Max SMTP cons from one IP addr */ extern int smtp_accept_queue; /* Queue after so many connections */ extern int smtp_accept_queue_per_connection; /* Queue after so many msgs */ diff --git a/src/src/readconf.c b/src/src/readconf.c index fb9164c9d..0ae3166c3 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -300,7 +300,7 @@ static optionlist optionlist_config[] = { { "smtp_accept_max", opt_int, {&smtp_accept_max} }, { "smtp_accept_max_nonmail", opt_int, {&smtp_accept_max_nonmail} }, { "smtp_accept_max_nonmail_hosts", opt_stringptr, {&smtp_accept_max_nonmail_hosts} }, - { "smtp_accept_max_per_connection", opt_int, {&smtp_accept_max_per_connection} }, + { "smtp_accept_max_per_connection", opt_stringptr, {&smtp_accept_max_per_connection} }, { "smtp_accept_max_per_host", opt_stringptr, {&smtp_accept_max_per_host} }, { "smtp_accept_queue", opt_int, {&smtp_accept_queue} }, { "smtp_accept_queue_per_connection", opt_int, {&smtp_accept_queue_per_connection} }, diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 6d6370ffd..5888b8037 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -3879,6 +3879,13 @@ cmd_list[CMD_LIST_RSET].is_mail_cmd = FALSE; } +static int +expand_mailmax(const uschar * s) +{ +if (!(s = expand_cstring(s))) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand smtp_accept_max_per_connection"); +return *s ? Uatoi(s) : 0; +} /************************************************* * Initialize for SMTP incoming message * @@ -3909,6 +3916,7 @@ int smtp_setup_msg(void) { int done = 0; +int mailmax = -1; BOOL toomany = FALSE; BOOL discarded = FALSE; BOOL last_was_rej_mail = FALSE; @@ -4266,6 +4274,9 @@ while (done <= 0) fl.smtputf8_advertised = FALSE; #endif + /* Expand the per-connection message count limit option */ + mailmax = expand_mailmax(smtp_accept_max_per_connection); + smtp_code = US"250 "; /* Default response code plus space*/ if (!user_msg) { @@ -4541,13 +4552,16 @@ while (done <= 0) was_rej_mail = TRUE; /* Reset if accepted */ env_mail_type_t * mail_args; /* Sanity check & validate args */ - if (fl.helo_required && !fl.helo_seen) - { - smtp_printf("503 HELO or EHLO required\r\n", FALSE); - log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no " - "HELO/EHLO given", host_and_ident(FALSE)); - break; - } + if (!fl.helo_seen) + if (fl.helo_required) + { + smtp_printf("503 HELO or EHLO required\r\n", FALSE); + log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no " + "HELO/EHLO given", host_and_ident(FALSE)); + break; + } + else if (mailmax < 0) + mailmax = expand_mailmax(smtp_accept_max_per_connection); if (sender_address) { @@ -4566,8 +4580,7 @@ while (done <= 0) /* Check to see if the limit for messages per connection would be exceeded by accepting further messages. */ - if (smtp_accept_max_per_connection > 0 && - smtp_mailcmd_count > smtp_accept_max_per_connection) + if (mailmax > 0 && smtp_mailcmd_count > mailmax) { smtp_printf("421 too many messages in this connection\r\n", FALSE); log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many " -- 2.30.2