--- qmail-smtpd.c.orig 2006-12-31 02:11:02.000000000 +0100 +++ qmail-smtpd.c 2006-12-31 02:35:31.000000000 +0100 @@ -44,6 +44,8 @@ #define MAXHOPS 100 unsigned int databytes = 0; unsigned int mfchk = 0; +unsigned int greetdelay = 0; +unsigned int drop_pre_greet = 0; int timeout = 1200; const char *protocol = "SMTP"; @@ -134,6 +136,7 @@ out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); eflush(); _exit(1); } +void die_pre_greet() { out("554 SMTP protocol violation\r\n"); flush(); _exit(1); } void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); } @@ -282,6 +285,11 @@ if (x) { scan_ulong(x,&u); databytes = u; } if (!(databytes + 1)) --databytes; + x = env_get("GREETDELAY"); + if (x) { scan_ulong(x, &u); greetdelay = u; } + x = env_get("DROP_PRE_GREET"); + if (x) { scan_ulong(x, &u); drop_pre_greet = u; } + remoteip = env_get("TCPREMOTEIP"); if (!remoteip) remoteip = "unknown"; local = env_get("TCPLOCALHOST"); @@ -1308,12 +1316,40 @@ int argc; char **argv; { + int n, m; childargs = argv + 1; sig_pipeignore(); if (chdir(auto_qmail) == -1) die_control(); setup(); if (ipme_init() != 1) die_ipme(); if (spp_connect()) { + if (!relayclient && greetdelay) { + if (drop_pre_greet) { + n = timeoutread(greetdelay ? greetdelay : 1, 0, ssinbuf, sizeof(ssinbuf)); + if(n == -1) { + if (errno != error_timeout) + strerr_die3sys(1, "GREETDELAY from ", remoteip, ": "); + } else if (n == 0) { + strerr_die3x(1, "GREETDELAY from ", remoteip, ": client disconnected"); + } else { + strerr_warn3("GREETDELAY from ", remoteip, ": client sent data before greeting", 0); + die_pre_greet(); + } + } + else { + sleep(greetdelay); + m = 0; + for (;;) { + n = timeoutread(0, 0, ssinbuf, sizeof(ssinbuf)); + if (n <= 0) + break; + if (n > 0 && m == 0) { + strerr_warn3("GREETDELAY from ", remoteip, ": client sent data before greeting. ignoring", 0); + m = 1; + } + } + } + } smtp_greet("220 "); out(" ESMTP\r\n"); }