--- Makefile.orig Tue Jan 2 04:45:17 2007 +++ Makefile Tue Jan 2 04:49:30 2007 @@ -1611,14 +1611,14 @@ timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o constmap.o \ received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a fd.a wait.a \ datetime.a getln.a open.a sig.a case.a env.a stralloc.a alloc.a substdio.a \ -error.a str.a fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.lib $(SMTPD_CHKUSER_OBJ) +error.a strerr.a str.a fs.a auto_qmail.o base64.o qmail-spp.o socket.lib dns.lib $(SMTPD_CHKUSER_OBJ) ./load qmail-smtpd $(SMTPD_CHKUSER_OBJ) rcpthosts.o commands.o timeoutread.o \ timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o \ tls.o ssl_timeoutio.o ndelay.a -L/usr/lib -lssl -lcrypto \ constmap.o received.o date822fmt.o now.o qmail.o spf.o dns.o cdb.a \ fd.a wait.a datetime.a getln.a open.a sig.a case.a qmail-spp.o env.a stralloc.a \ alloc.a substdio.a error.a fs.a auto_qmail.o base64.o \ - str.a `cat socket.lib` $(VPOPMAIL_LIBS) `cat dns.lib` + strerr.a str.a `cat socket.lib` $(VPOPMAIL_LIBS) `cat dns.lib` qmail-smtpd.0: \ qmail-smtpd.8 @@ -1628,7 +1628,7 @@ compile qmail-smtpd.c chkuser.h sig.h readwrite.h stralloc.h gen_alloc.h \ substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \ error.h ipme.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ip.h qmail.h qmail-spp.h \ -substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ +substdio.h strerr.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h spf.h ./compile qmail-smtpd.c --- qmail-smtpd.c.orig 2006-12-31 02:11:02.000000000 +0100 +++ qmail-smtpd.c 2006-12-31 02:35:31.000000000 +0100 @@ -12,6 +12,7 @@ #include "ip.h" #include "qmail.h" #include "str.h" +#include "strerr.h" #include "fmt.h" #include "scan.h" #include "byte.h" @@ -44,6 +44,8 @@ #define MAXHOPS 100 unsigned int databytes = 0; +unsigned int greetdelay = 0; +unsigned int drop_pre_greet = 0; int timeout = 1200; unsigned int spfbehavior = 0; @@ -134,6 +136,7 @@ void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); } void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); } void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _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 is in my badmailfrom list (#5.7.1)\r\n"); } @@ -282,6 +285,11 @@ die_control(); if (!stralloc_0(&spfexp)) die_nomem(); + 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"); }