Download | Plain Text | Line Numbers


--- 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);
+}