nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e9fae4301c8ba31e901f1de3901bb8f133c1b04f
parent 7026ed6493da9c906e69b027da805edd3b0b44d6
Author: Fabio Busatto <fabio.busatto@sikurezza.org>
Date:   Mon, 13 Sep 2021 23:28:29 -0700

qmail-dnsbl-20060130.patch
Signed-off-by: Ellenor Bjornsdottir <ellenor@umbrellix.net>

Diffstat:
M.gitignore | 2++
MMakefile | 6+++---
Mdoc/man/qmail-control.9 | 1+
Mdoc/man/qmail-smtpd.8 | 21+++++++++++++++++++++
Msrc/qmail-showctl.c | 2++
Msrc/qmail-smtpd.c | 78+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
6 files changed, 94 insertions(+), 16 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -375,3 +375,5 @@ doc/man/forgeries.0 setup include/qtmp.h qmail-send.service +*.orig +*.rej diff --git a/Makefile b/Makefile @@ -1454,13 +1454,13 @@ load src/qmail-smtpd.o src/rcpthosts.o src/commands.o src/timeoutread.o \ src/timeoutwrite.o src/ip.o src/ipme.o src/ipalloc.o src/control.o src/constmap.o src/received.o \ src/date822fmt.o src/qmail.o src/cdb.a src/fd.a src/wait.a src/datetime.a src/getln.a \ src/open.a src/sig.a src/case.a src/env.a src/stralloc.a src/substdio.a src/error.a src/str.a \ -src/fs.a src/auto_qmail.o socket.lib +src/fs.a src/auto_qmail.o socket.lib src/dns.o ./load qmail-smtpd src/rcpthosts.o src/commands.o src/timeoutread.o \ src/timeoutwrite.o src/ip.o src/ipme.o src/ipalloc.o src/control.o src/constmap.o \ src/received.o src/date822fmt.o src/qmail.o src/cdb.a src/fd.a src/wait.a \ src/datetime.a src/getln.a src/open.a src/sig.a src/case.a src/env.a src/stralloc.a \ src/substdio.a src/error.a src/str.a src/fs.a src/auto_qmail.o `cat \ - socket.lib` + socket.lib` src/dns.o doc/man/qmail-smtpd.0: \ doc/man/qmail-smtpd.8 @@ -1470,7 +1470,7 @@ compile src/qmail-smtpd.c include/sig.h include/readwrite.h include/stralloc.h i include/substdio.h include/alloc.h include/auto_qmail.h include/control.h include/received.h include/constmap.h \ include/error.h include/ipme.h include/ip.h include/ipalloc.h include/ip.h include/gen_alloc.h include/ip.h include/qmail.h \ include/substdio.h include/str.h include/fmt.h include/scan.h include/byte.h include/case.h include/env.h include/now.h include/datetime.h \ -include/exit.h include/rcpthosts.h include/timeoutread.h include/timeoutwrite.h include/commands.h +include/exit.h include/rcpthosts.h include/timeoutread.h include/timeoutwrite.h include/commands.h include/dns.h ./compile src/qmail-smtpd.c qmail-start: \ diff --git a/doc/man/qmail-control.9 b/doc/man/qmail-control.9 @@ -48,6 +48,7 @@ control default used by .I defaultdomain \fIme \fRqmail-inject .I defaulthost \fIme \fRqmail-inject .I databytes \fR0 \fRqmail-smtpd +.I dnsbllist \fR(none) \fRqmail-smtpd .I doublebouncehost \fIme \fRqmail-send .I doublebounceto \fRpostmaster \fRqmail-send .I envnoathost \fIme \fRqmail-send diff --git a/doc/man/qmail-smtpd.8 b/doc/man/qmail-smtpd.8 @@ -76,6 +76,27 @@ If the environment variable .B DATABYTES is set, it overrides .IR databytes . + +.TP 5 +.I dnsbllist +A list of dnsbl providers that +.B qmail-smtpd +checks to identify blacklisted ip addresses. + +Exception: +If the environment variable +.B DNSBLSKIP +is set, +.B qmail-smtpd +ignores +.IR dnsbllist , +and the dnsbl check is not performed. +The check is skipped even if some other authentication method succedeed +and authorized the client to relay (smtp-auth or tls client certificate), +or if +.B RELAYCLIENT +enviromnent variable is set. + .TP 5 .I localiphost Replacement host name for local IP addresses. diff --git a/src/qmail-showctl.c b/src/qmail-showctl.c @@ -248,6 +248,7 @@ int main(void) do_int("databytes","0","SMTP DATA limit is "," bytes"); do_str("defaultdomain",1,"defaultdomain","Default domain name is "); do_str("defaulthost",1,"defaulthost","Default host name is "); + do_lst("dnsbllist","No dnsbl list configured.","List at "," configured for dnsbl check."); do_str("doublebouncehost",1,"doublebouncehost","2B recipient host: "); do_str("doublebounceto",0,"postmaster","2B recipient user: "); do_str("envnoathost",1,"envnoathost","Presumed domain name is "); @@ -301,6 +302,7 @@ int main(void) if (str_equal(d->d_name,"databytes")) continue; if (str_equal(d->d_name,"defaultdomain")) continue; if (str_equal(d->d_name,"defaulthost")) continue; + if (str_equal(d->d_name,"dnsbllist")) continue; if (str_equal(d->d_name,"doublebouncehost")) continue; if (str_equal(d->d_name,"doublebounceto")) continue; if (str_equal(d->d_name,"envnoathost")) continue; diff --git a/src/qmail-smtpd.c b/src/qmail-smtpd.c @@ -24,6 +24,7 @@ #include "timeoutread.h" #include "timeoutwrite.h" #include "commands.h" +#include "dns.h" #define MAXHOPS 100 unsigned int databytes = 0; @@ -46,14 +47,19 @@ void straynewline() { out("451 See https://cr.yp.to/docs/smtplf.html.\r\n"); flu 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_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); } +void err_unimpl(char *arg) { 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"); } void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } -void err_noop(arg) char *arg; { out("250 ok\r\n"); } -void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); } +void err_noop(char *arg) { out("250 ok\r\n"); } +void err_vrfy(char *arg) { out("252 send some mail, i'll try my best\r\n"); } void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } - +void die_dnsbl(char *arg) +{ + out("421 your ip is currently blacklisted, try to auth first ("); out(arg); out(")\r\n"); + flush(); + _exit(1); +} stralloc greeting = {0}; @@ -62,11 +68,11 @@ void smtp_greet(code) char *code; substdio_puts(&ssout,code); substdio_put(&ssout,greeting.s,greeting.len); } -void smtp_help(arg) char *arg; +void smtp_help(char *arg) { out("214 NightmareMail home page: <https://github.com./SystemLeningrad/mxf> MXF is based on notqmail. notqmail home page: <https://notqmail.org>\r\n"); } -void smtp_quit(arg) char *arg; +void smtp_quit(char *arg) { smtp_greet("221 "); out("\r\n"); flush(); _exit(0); } @@ -76,11 +82,12 @@ char *remotehost; char *remoteinfo; char *local; char *relayclient; +char *dnsblskip; stralloc helohost = {0}; char *fakehelo; /* pointer into helohost, or 0 */ -void dohelo(arg) char *arg; { +void dohelo(char *arg) { if (!stralloc_copys(&helohost,arg)) die_nomem(); if (!stralloc_0(&helohost)) die_nomem(); fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0; @@ -126,6 +133,7 @@ void setup() if (!remotehost) remotehost = "unknown"; remoteinfo = env_get("TCPREMOTEINFO"); relayclient = env_get("RELAYCLIENT"); + dnsblskip = env_get("DNSBLSKIP"); dohelo(remotehost); } @@ -211,28 +219,70 @@ int addrallowed() return r; } +int flagdnsbl = 0; +stralloc dnsblhost = {0}; + +int dnsblcheck() +{ + char *ch; + static stralloc dnsblbyte = {0}; + static stralloc dnsblrev = {0}; + static ipalloc dnsblip = {0}; + static stralloc dnsbllist = {0}; + + ch = remoteip; + if(control_readfile(&dnsbllist,"control/dnsbllist",0) != 1) return 0; + + if (!stralloc_copys(&dnsblrev,"")) return 0; + for (;;) { + if (!stralloc_copys(&dnsblbyte,"")) return 0; + while (ch[0] && (ch[0] != '.')) { + if (!stralloc_append(&dnsblbyte,ch)) return 0; + ch++; + } + if (!stralloc_append(&dnsblbyte,".")) return 0; + if (!stralloc_cat(&dnsblbyte,&dnsblrev)) return 0; + if (!stralloc_copy(&dnsblrev,&dnsblbyte)) return 0; + + if (!ch[0]) break; + ch++; + } + + flagdnsbl = 1; + ch = dnsbllist.s; + while (ch < (dnsbllist.s + dnsbllist.len)) { + if (!stralloc_copy(&dnsblhost,&dnsblrev)) return 0; + if (!stralloc_cats(&dnsblhost,ch)) return 0; + if (!stralloc_0(&dnsblhost)) return 0; + + if (!dns_ip(&dnsblip,&dnsblhost)) return 1; + while (*ch++); + } + + return 0; +} int seenmail = 0; int flagbarf; /* defined if seenmail */ stralloc mailfrom = {0}; stralloc rcptto = {0}; -void smtp_helo(arg) char *arg; +void smtp_helo(char *arg) { smtp_greet("250 "); out("\r\n"); seenmail = 0; dohelo(arg); } -void smtp_ehlo(arg) char *arg; +void smtp_ehlo(char *arg) { smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); seenmail = 0; dohelo(arg); } -void smtp_rset(arg) char *arg; +void smtp_rset(char *arg) { seenmail = 0; out("250 flushed\r\n"); } -void smtp_mail(arg) char *arg; +void smtp_mail(char *arg) { if (!addrparse(arg)) { err_syntax(); return; } flagbarf = bmfcheck(); @@ -242,7 +292,7 @@ void smtp_mail(arg) char *arg; if (!stralloc_0(&mailfrom)) die_nomem(); out("250 ok\r\n"); } -void smtp_rcpt(arg) char *arg; { +void smtp_rcpt(char *arg) { if (!seenmail) { err_wantmail(); return; } if (!addrparse(arg)) { err_syntax(); return; } if (flagbarf) { err_bmf(); return; } @@ -253,6 +303,8 @@ void smtp_rcpt(arg) char *arg; { } else if (!addrallowed()) { err_nogateway(); return; } + if (!(relayclient || dnsblskip || flagdnsbl)) + if (dnsblcheck()) die_dnsbl(dnsblhost.s); if (!stralloc_cats(&rcptto,"T")) die_nomem(); if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); if (!stralloc_0(&rcptto)) die_nomem(); @@ -360,7 +412,7 @@ void acceptmessage(qp) unsigned long qp; out("\r\n"); } -void smtp_data(arg) char *arg; { +void smtp_data(char *arg) { int hops; unsigned long qp; char *qqx;