From fd404641357a4a3bc0a55cb31deb3d4bad4ec2ee Mon Sep 17 00:00:00 2001 From: manuel Date: Mon, 4 Feb 2013 02:55:38 +0100 Subject: [PATCH] badrcptto support qmail-gentoo-1.03-r16-badrcptto-morebadrcptto-accdias --- qmail-smtpd.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 11 deletions(-) (limited to 'qmail-smtpd.c') diff --git a/qmail-smtpd.c b/qmail-smtpd.c index 86c5bd9..4466168 100644 --- a/qmail-smtpd.c +++ b/qmail-smtpd.c @@ -26,6 +26,7 @@ #include "wait.h" #include "qregex.h" #include "strerr.h" +#include "cdb.h" #define BMCHECK_BMF 0 #define BMCHECK_BMFNR 1 @@ -42,6 +43,12 @@ int timeout = 1200; const char *protocol = "SMTP"; +char *remoteip; +char *remotehost; +char *remoteinfo; +char *local; +char *relayclient; + #ifdef TLS #include #include "tls.h" @@ -69,19 +76,52 @@ int safewrite(fd,buf,len) int fd; char *buf; int len; char ssoutbuf[512]; substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); +/* write errors to stderr */ +char erroutbuf[512]; +substdio errout = SUBSTDIO_FDBUF(safewrite,2,erroutbuf,sizeof erroutbuf); + void flush() { substdio_flush(&ssout); } void out(s) char *s; { substdio_puts(&ssout,s); } +void eflush() { substdio_flush(&errout); } +void eout(s) char *s; { substdio_puts(&errout,s); } +void enew() { substdio_puts(&errout,"qmail-smtpd: "); } + void die_read() { _exit(1); } -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 straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } + +void die_alarm() +{ + enew(); eout("Connection to "); eout(remoteip); eout(" timed out.\n"); + out("451 timeout (#4.4.2)\r\n"); flush(); eflush(); _exit(1); +} +void die_nomem() +{ + enew(); eout("Out of memory while connected to "); eout(remoteip); eout("!\n"); + out("421 out of memory (#4.3.0)\r\n"); flush(); eflush(); _exit(1); +} +void die_control() +{ + enew(); eout("Unable to read controls!\n"); + out("421 unable to read controls (#4.3.0)\r\n"); flush(); eflush(); + _exit(1); +} +void die_ipme() +{ + enew(); eout("Unable to figure out my IP addresses!\n"); + out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); + eflush(); _exit(1); +} +void straynewline() +{ + enew(); eout("Stray newline from "); eout(remoteip); eout(".\n"); + out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); + eflush(); _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 has been denied (#5.7.1)\r\n"); } void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); } +void err_brt() { out("550 sorry, this message is not deliverable (#5.7.1)\r\n"); } void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); } #ifndef TLS void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } @@ -129,12 +169,6 @@ void smtp_quit() smtp_greet("221 "); out("\r\n"); flush(); _exit(0); } -char *remoteip; -char *remotehost; -char *remoteinfo; -char *local; -char *relayclient; - stralloc helohost = {0}; char *fakehelo; /* pointer into helohost, or 0 */ @@ -159,6 +193,11 @@ stralloc bmt = {0}; int bmtnrok = 0; stralloc bmtnr = {0}; +int brtok = 0; +stralloc brt = {0}; +struct constmap mapbrt; +int fdmbrt; + int bhelook = 0; stralloc bhelo = {0}; @@ -197,6 +236,17 @@ void setup() if (env_get("LOGREGEX")) logregex = 1; + + brtok = control_readfile(&brt,"control/badrcptto",0); + if (brtok == -1) die_control(); + if (brtok) + if (!constmap_init(&mapbrt,brt.s,brt.len,0)) die_nomem(); + + fdmbrt = open_read("control/morebadrcptto.cdb"); + if (fdmbrt == -1) if (errno != error_noent) die_control(); + + + if (control_readint(&databytes,"control/databytes") == -1) die_control(); x = env_get("DATABYTES"); if (x) { scan_ulong(x,&u); databytes = u; } @@ -282,6 +332,14 @@ char *arg; return 1; } +static void log_deny(m,f,t) char *m,*f,*t; +{ + enew(); eout(m); eout(" check failed ("); eout(f); eout(") -> ("); + eout(t); eout(") ["); eout(remoteip); eout("] (HELO "); + eout(helohost.s); eout(")\n"); + eflush(); +} + int bmcheck(which) int which; { int i = 0; @@ -335,6 +393,19 @@ int bmcheck(which) int which; return 0; } +int brtcheck() +{ + int j; + if (brtok) if (constmap(&mapbrt,addr.s,addr.len - 1)) return 1; + if (fdmbrt != -1) { + uint32 dlen; + j = cdb_seek(fdmbrt, addr.s, addr.len - 1, &dlen); + if (j == -1) die_control(); + if (j) return j; + } + return 0; +} + int addrallowed() { int r; @@ -364,6 +435,7 @@ int addrrelay() int seenmail = 0; int flagbarfbmf; /* defined if seenmail */ int flagbarfbmt; +int flagbrt; /* defined if any bad rcpts */ int flagbarfbhelo; int flagsize; stralloc mailfrom = {0}; @@ -523,6 +595,10 @@ void smtp_rcpt(arg) char *arg; { } else if (!addrallowed()) { err_nogateway(); return; } + if (!env_get("RELAYCLIENT") && brtcheck()) { + flagbrt = 1; + log_deny("BAD RCPT TO", mailfrom.s,addr.s); + } if (!stralloc_cats(&rcptto,"T")) die_nomem(); if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); if (!stralloc_0(&rcptto)) die_nomem(); @@ -642,6 +718,7 @@ void smtp_data() { if (!seenmail) { err_wantmail(); return; } if (!rcptto.len) { err_wantrcpt(); return; } + if (flagbrt) { err_brt(); return; } seenmail = 0; if (databytes) bytestooverflow = databytes + 1; if (qmail_open(&qqt) == -1) { err_qqt(); return; } -- cgit v1.2.3