--- Makefile.orig Fri Dec 29 02:54:34 2006 +++ Makefile Fri Dec 29 02:54:43 2006 @@ -657,6 +657,16 @@ compile gfrom.c str.h gfrom.h ./compile gfrom.c +greetdelay: \ +load greetdelay.o scan_ulong.o timeoutread.o timeoutwrite.o strerr.a \ +substdio.a env.a error.a str.a + ./load greetdelay scan_ulong.o timeoutread.o timeoutwrite.o strerr.a \ + substdio.a env.a error.a str.a + +greetdelay.o: \ +compile greetdelay.c substdio.h env.h timeoutread.h error.h strerr.h + ./compile greetdelay.c + hasflock.h: \ tryflock.c compile load ( ( ./compile tryflock.c && ./load tryflock ) >/dev/null \ @@ -832,3 +842,3 @@ forward preline condredirect bouncesaying except maildirmake \ -maildir2mbox maildirwatch qail elq pinq idedit install-big install \ +maildir2mbox maildirwatch qail elq greetdelay pinq idedit install-big install \ instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ --- TARGETS.orig Fri Dec 29 15:01:04 2006 +++ TARGETS Fri Dec 29 15:03:39 2006 @@ -303,6 +303,8 @@ qsmhook qbiff.o qbiff +greetdelay.o +greetdelay forward.o forward preline.o --- FILES.orig Fri Dec 29 15:06:09 2006 +++ FILES Fri Dec 29 15:05:52 2006 @@ -144,6 +144,7 @@ qreceipt.c qsmhook.c qbiff.c +greetdelay.c forward.c preline.c predate.c --- /dev/null Fri Dec 29 02:56:54 2006 +++ /root/greetdelay.c Fri Dec 29 02:43:04 2006 @@ -0,0 +1,70 @@ +#include "substdio.h" +#include "env.h" +#include "timeoutread.h" +#include "error.h" +#include "strerr.h" + +unsigned int greetdelay = 0; +unsigned int drop_pre_greet = 0; +int timeout = 1200; + +int safewrite(fd,buf,len) int fd; char *buf; int len; +{ + int r; + r = timeoutwrite(timeout,fd,buf,len); + if (r <= 0) _exit(1); + return r; +} + +char ssoutbuf[512]; +char ssinbuf[1024]; +substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); +void die_pre_greet() { substdio_puts(&ssout, "554 SMTP protocol violation\r\n"); substdio_flush(&ssout); exit(1); } + +void main(argc,argv) +int argc; +char **argv; +{ + char *remoteip; + char *x; + unsigned long u; + int n, m; + + 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"; + + if (!env_get("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; + } + } + } + } + if (argv[1]) + execvp(argv[1], argv + 1); + _exit(0); +}