diff -ur --new-file qmail-1.03.orig/README.relaymxlookup qmail-1.03/README.relaymxlookup --- qmail-1.03.orig/README.relaymxlookup 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03/README.relaymxlookup 2004-12-15 20:39:47.955639059 +0100 @@ -0,0 +1,38 @@ +relaymxlookup, version 0.3 +Written by Michael Hanselmann, http://hansmi.ch/contact + +Description +----------- + +This is a patch to look up MX-records before relaying. + +This patch, relaymxlookup, integrates itself into the rcpthosts-function. When +an email arrives, it queries the Domain Name Server (DNS) of the receivers +(taken from the SMTP "RCPT TO") domain. If it is listed itself as an MX for the +domain, relaying is allowed, otherwise not. The patch does not modify the +original way using control/rcpthosts and checks control/rcpthosts before DNS. + +Diagram +------- + +sender -> qmail + | + control/rcpthosts -- ok --> relay + | + +---> DNS --- not ok --> deny relaying + | + ok ("control/me is in mx-list") + | + +--------- ok --> relay + +How to enable/disable +--------------------- + +The check is only performed, if control/relaymxlookup exists. After creating or +deleting this file, qmail-smtpd has to be restarted. + +Questions? +---------- + +Please contact me for questions or suggestions: http://hansmi.ch/contact + diff -ur --new-file qmail-1.03.orig/qmail-smtpd.c qmail-1.03/qmail-smtpd.c --- qmail-1.03.orig/qmail-smtpd.c 2004-12-15 20:18:50.000000000 +0100 +++ qmail-1.03/qmail-smtpd.c 2004-12-15 20:39:30.688768170 +0100 @@ -153,6 +153,7 @@ void err_brt() { out("550 sorry, this message is not deliverable (#5.7.1)\r\n"); } void err_bmt() { out("533 sorry, your envelope recipient has been denied (#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_dns() { out("453 temporary problem with dns\r\n"); } void err_badbounce() { out("550 sorry, bounce messages should have a single envelope recipient (#5.7.1)\r\n"); } #ifdef TLS void err_nogwcert() { out("553 no valid cert for gatewaying (#5.7.1)\r\n"); } @@ -447,6 +448,7 @@ int r; r = rcpthosts(addr.s,str_len(addr.s)); if (r == -1) die_control(); + if (r == -2) err_dns(); return r; } diff -ur --new-file qmail-1.03.orig/rcpthosts.c qmail-1.03/rcpthosts.c --- qmail-1.03.orig/rcpthosts.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03/rcpthosts.c 2004-12-15 20:39:30.739761882 +0100 @@ -6,11 +6,16 @@ #include "constmap.h" #include "stralloc.h" #include "rcpthosts.h" +#include "dns.h" +#include "ipalloc.h" +#include "ipme.h" static int flagrh = 0; static stralloc rh = {0}; static struct constmap maprh; static int fdmrh; +static int flagrmxl = 0; +static stralloc rmxl = {0}; int rcpthosts_init() { @@ -19,6 +24,8 @@ if (!constmap_init(&maprh,rh.s,rh.len,0)) return flagrh = -1; fdmrh = open_read("control/morercpthosts.cdb"); if (fdmrh == -1) if (errno != error_noent) return flagrh = -1; + flagrmxl = control_readfile(&rmxl, "control/relaymxlookup", 0); + if (flagrmxl == -1) if (errno != error_noent) return flagrh = -1; return 0; } @@ -29,6 +36,8 @@ int len; { int j; + static ipalloc ip = {0}; + unsigned long random; if (flagrh != 1) return 1; @@ -56,5 +65,27 @@ } } + if (flagrmxl == 1) { + random = now() + (getpid() << 16); + switch (dns_mxip(&ip,&host,random)) { + case DNS_MEM: + case DNS_SOFT: + return -2; + case DNS_HARD: + return 0; + case 1: + if (ip.len <= 0) return 0; + default: + break; + } + + if(ip.len >= 1) { + int i; + for (i = 0;i < ip.len;++i) + if (ipme_is(&ip.ix[i].ip)) + return 1; + } + } + return 0; }