From b9f56e82da9a0821011e1e0924acd1d781643070 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Sep 2016 13:16:33 +0200 Subject: [PATCH] sendmail: make it possible to pause after connection helper is started If a non-starttls helper is in use, initial 220 response is processed by us, not by helper. Some servers consider us to be a spammer if we don't wait for it. It is not in protocol, but it is a real-life problem. The workaround in this patch is a magic envvar, $SMTP_ANTISPAM_DELAY: ... -H 'PROG ARGS' Run connection helper. Examples: openssl s_client -quiet -tls1 -starttls smtp -connect smtp.gmail.com:25 openssl s_client -quiet -tls1 -connect smtp.gmail.com:465 $SMTP_ANTISPAM_DELAY: seconds to wait after helper connect ... By using it, people can tweak sendmail behavior even if sendmail invocation is buried in some scripts. function old new delta packed_usage 30464 30497 +33 sendmail_main 1185 1206 +21 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 54/0) Total: 54 bytes Signed-off-by: Denys Vlasenko --- mailutils/sendmail.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index cd27d676e..1242795b8 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -27,6 +27,7 @@ //usage: "\n -H 'PROG ARGS' Run connection helper. Examples:" //usage: "\n openssl s_client -quiet -tls1 -starttls smtp -connect smtp.gmail.com:25" //usage: "\n openssl s_client -quiet -tls1 -connect smtp.gmail.com:465" +//usage: "\n $SMTP_ANTISPAM_DELAY: seconds to wait after helper connect" //usage: "\n -S HOST[:PORT] Server (default $SMTPHOST or 127.0.0.1)" //usage: "\n -amLOGIN Log in using AUTH LOGIN (-amCRAM-MD5 not supported)" //usage: "\n -auUSER Username for AUTH" @@ -207,7 +208,7 @@ static void rcptto_list(const char *list) int sendmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int sendmail_main(int argc UNUSED_PARAM, char **argv) { - char *opt_connect = opt_connect; + char *opt_connect; char *opt_from = NULL; char *s; llist_t *list = NULL; @@ -239,6 +240,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // init global variables INIT_G(); + // default HOST[:PORT] is $SMTPHOST, or localhost + opt_connect = getenv("SMTPHOST"); + if (!opt_connect) + opt_connect = (char *)"127.0.0.1"; + // save initial stdin since body is piped! xdup2(STDIN_FILENO, 3); G.fp0 = xfdopen_for_read(3); @@ -274,6 +280,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // connection helper ordered? -> if (opts & OPT_H) { + const char *delay; const char *args[] = { "sh", "-c", opt_connect, NULL }; // plug it in launch_helper(args); @@ -292,7 +299,12 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // before 220 reached it. The code below is unsafe in this regard: // in non-STARTTLSed case, we potentially send NOOP before 220 // is sent by server. - // Ideas? (--delay SECS opt? --assume-starttls-helper opt?) + // + // If $SMTP_ANTISPAM_DELAY is set, we pause before sending NOOP. + // + delay = getenv("SMTP_ANTISPAM_DELAY"); + if (delay) + sleep(atoi(delay)); code = smtp_check("NOOP", -1); if (code == 220) // we got 220 - this is not STARTTLSed connection, @@ -304,14 +316,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) } else { // vanilla connection int fd; - // host[:port] not explicitly specified? -> use $SMTPHOST - // no $SMTPHOST? -> use localhost - if (!(opts & OPT_S)) { - opt_connect = getenv("SMTPHOST"); - if (!opt_connect) - opt_connect = (char *)"127.0.0.1"; - } - // do connect fd = create_and_connect_stream_or_die(opt_connect, 25); // and make ourselves a simple IO filter xmove_fd(fd, STDIN_FILENO); -- 2.25.1