#include "now.h"
#include "exit.h"
#include "rcpthosts.h"
+#include "addrcheck.h"
#include "timeoutread.h"
#include "timeoutwrite.h"
#include "commands.h"
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("553 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"); }
int liphostok = 0;
stralloc liphost = {0};
+int relayhostsok = 0;
+stralloc relayhosts = {0};
+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()
{
if (bmfok == -1) die_control();
if (bmfok)
if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
+
+ switch (control_readfile(&relayhosts, "control/relayhosts", 0)) {
+ case -1:
+ die_control();
+ case 1:
+ relayhostsok = 1;
+ if (!constmap_init(&maprelayhosts, relayhosts.s, relayhosts.len, 1))
+ 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");
if (!remotehost) remotehost = "unknown";
remoteinfo = env_get("TCPREMOTEINFO");
relayclient = env_get("RELAYCLIENT");
+ if (!relayclient && relayhostsok) {
+ int j;
+ int l = str_len(remotehost);
+ relayclient = constmap(&maprelayhosts, remotehost, l);
+ if (!relayclient) for (j = 0; j < l; ++j) {
+ if (remotehost[j] == '.' &&
+ (relayclient = constmap(&maprelayhosts,
+ remotehost + j,
+ l - j)) != 0)
+ break;
+ }
+ }
dohelo(remotehost);
}
}
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();