debian/rules: Use `git' potty wrapper.
[qmail] / qmail-smtpd.c
index 6f453ce..88f4ea6 100644 (file)
@@ -20,6 +20,7 @@
 #include "now.h"
 #include "exit.h"
 #include "rcpthosts.h"
+#include "addrcheck.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
@@ -47,10 +48,12 @@ void die_alarm() { out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1); }
 void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); }
 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 die_badaddr() { out("553 too many bad recipients: sulking (#5.5.1)\r\n"); flush(); _exit(1); }
 void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
 
 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
+void err_badaddr() { out("550 unknown mailbox (#5.1.1)\r\n"); }
 void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
 void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); }
@@ -99,6 +102,11 @@ struct constmap maprelayhosts;
 int bmfok = 0;
 stralloc bmf = {0};
 struct constmap mapbmf;
+static int ac_slow = 5;
+static int ac_limit = 50;
+static int ac_delay = 2;
+static int ac_count = 0;
+static int ac_fd = -1;
 
 void setup()
 {
@@ -129,6 +137,13 @@ void setup()
        die_nomem();
   }
 
+  if (control_readint(&ac_slow, "control/addrcheck-slow") == -1 ||
+      control_readint(&ac_slow, "control/addrcheck-limit") == -1 ||
+      control_readint(&ac_slow, "control/addrcheck-delay") == -1)
+    die_control();
+
+  if ((ac_fd = open_read("control/addrcheck.cdb")) < 0 && errno != error_noent)
+    die_control();
  
   if (control_readint(&databytes,"control/databytes") == -1) die_control();
   x = env_get("DATABYTES");
@@ -283,6 +298,22 @@ void smtp_rcpt(arg) char *arg; {
   }
   else
     if (!addrallowed()) { err_nogateway(); return; }
+  if (ac_fd != -1) {
+    int rc;
+    if (addrcheck(ac_fd, addr.s, mailfrom.s, &rc) < 0) {
+      if (errno == error_nomem)
+       die_nomem();
+      else
+       die_control();
+    }
+    if (!rc) {
+      ac_count++;
+      if (ac_limit && ac_count >= ac_limit) die_badaddr();
+      if (ac_delay && ac_count >= ac_slow) sleep(ac_delay);
+      err_badaddr();
+      return;
+    }
+  }
   if (!stralloc_cats(&rcptto,"T")) die_nomem();
   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
   if (!stralloc_0(&rcptto)) die_nomem();