diff -u orig/Makefile rbltag/Makefile --- orig/Makefile Thu Aug 2 16:30:02 2001 +++ rbltag/Makefile Fri Aug 3 15:20:44 2001 @@ -7,6 +7,7 @@ # to use cleartext passwords (a bad idea on production systems) add # -DCLEARTEXTPASSWD to the LDAPFLAGS #LDAPFLAGS=-DQLDAP_CLUSTER +RBLTAGON=-DRBLTAG # Perhaps you have different ldap libraries, change them here LDAPLIBS=-L/usr/local/lib -lldap -llber @@ -1584,11 +1585,12 @@ load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a open.a \ getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \ -str.a fs.a auto_qmail.o +str.a fs.a auto_qmail.o dns.o ipalloc.o ./load qmail-qmtpd rcpthosts.o control.o constmap.o \ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ datetime.a open.a getln.a sig.a case.a env.a stralloc.a \ - alloc.a substdio.a error.a str.a fs.a auto_qmail.o + alloc.a substdio.a error.a str.a fs.a auto_qmail.o \ + dns.o ipalloc.o ip.o `cat dns.lib` qmail-qmtpd.0: \ qmail-qmtpd.8 @@ -1598,7 +1600,7 @@ compile qmail-qmtpd.c stralloc.h gen_alloc.h substdio.h qmail.h \ substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h \ auto_qmail.h readwrite.h control.h received.h - ./compile qmail-qmtpd.c + ./compile ${RBLTAGON} qmail-qmtpd.c qmail-qread: \ load qmail-qread.o fmtqfn.o readsubdir.o date822fmt.o datetime.a \ @@ -1796,7 +1798,7 @@ error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \ substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h - ./compile ${TLSON} ${TLSINCLUDES} qmail-smtpd.c + ./compile ${RBLTAGON} ${TLSON} ${TLSINCLUDES} qmail-smtpd.c qmail-start: \ load qmail-start.o prot.o fd.a auto_uids.o diff -u orig/Makefile.orig rbltag/Makefile.orig diff -u orig/qmail-qmtpd.c rbltag/qmail-qmtpd.c --- orig/qmail-qmtpd.c Thu Aug 2 16:30:03 2001 +++ rbltag/qmail-qmtpd.c Fri Aug 3 15:19:52 2001 @@ -12,6 +12,11 @@ #include "control.h" #include "received.h" +#ifdef RBLTAG + #include "ipalloc.h" + #include "dns.h" +#endif + void badproto() { _exit(100); } void resources() { _exit(111); } @@ -73,6 +78,129 @@ char *relayclient; int relayclientlen; +#ifdef RBLTAG +char *rbltagenabled; +int rbltagok = 0; +stralloc rbltag = {0}; +#endif + +/* RBL */ + +stralloc ip_reverse; +#ifdef RBLTAG +stralloc tagrblid; + +void rbl_init() +{ + unsigned int i; + unsigned int j; + char *ip_env; + + ip_env = remoteip; + if (!ip_env) ip_env = ""; + + if (!stralloc_copys(&ip_reverse,"")) resources(); + + i = str_len(ip_env); + while (i) { + for (j = i;j > 0;--j) if (ip_env[j - 1] == '.') break; + if (!stralloc_catb(&ip_reverse,ip_env + j,i - j)) resources(); + if (!stralloc_cats(&ip_reverse,".")) resources(); + if (!j) break; + i = j - 1; + } +} + +stralloc rbl_tmp; + +int rbl_lookup(char *base) +{ + ipalloc rblsa = {0}; + + if (!*base) return 2; + + if (!stralloc_copys(&rbl_tmp,"")) resources(); + + if (!stralloc_copy(&rbl_tmp,&ip_reverse)) resources(); + if (!stralloc_cats(&rbl_tmp,base)) resources(); + + switch (dns_ip(&rblsa,&rbl_tmp)) + { + case DNS_MEM: + case DNS_SOFT: + return 2; /* soft error */ + break; + + case DNS_HARD: + return 0; /* found no match */ + break; + + default: + return 1; /* found match */ + break; + } +} + +int rblcheck_tag() +{ + int r; + char *p; + rbl_init(); + + p = &rbltag.s[0]; + while(p < &rbltag.s[0]+rbltag.len) + { + r = rbl_lookup(p); + switch(r) { + case 2: + break; + case 1: + if ( 0 != tagrblid.len ) if (!stralloc_cats(&tagrblid," ")) resources(); + if (!stralloc_cats(&tagrblid,p)) resources(); + break; + default: + break; + } + /* continue */ + p = p+strlen(p); + p++; + } + if ( 0 != tagrblid.len ) tagrblid.s[tagrblid.len]='\0'; + return r; +} + +void rblcheckfmt(qqt, rblid) +struct qmail *qqt; +char *rblid; +{ + unsigned int j,k; + + if (!rblid) return; + + j=0; + while ('\0'!=rblid[j] && ' '==rblid[j]) j++; /* eat up whitespace */ + k=j; + while ('\0' != rblid[j]) { + if (' ' == rblid[j]) { + rblid[j] = '\0'; + qmail_puts(qqt,"X-RBL-Check: "); + qmail_puts(qqt,rblid+k); + qmail_puts(qqt,"\n"); + rblid[j] = ' '; + while (' ' == rblid[++j]); /* eat up whitespace */ + k=j; + } else j++; + } + if (j!=k) { + qmail_puts(qqt,"X-RBL-Check: "); + qmail_puts(qqt,rblid+k); + qmail_puts(qqt,"\n"); + } +} +#endif +/* RBL */ + + main() { @@ -112,6 +240,14 @@ local = env_get("TCPLOCALHOST"); if (!local) local = env_get("TCPLOCALIP"); if (!local) local = "unknown"; +#ifdef RBLTAG + rbltagok = control_readfile(&rbltag,"control/rbltags",0); + if (rbltagok == -1) resources(); + if (rbltagok) + { + rblcheck_tag(); + } +#endif for (;;) { if (!stralloc_copys(&failure,"")) resources(); @@ -131,6 +267,9 @@ else badproto(); received(&qq,"QMTP",local,remoteip,remotehost,remoteinfo,(char *) 0,(char *) 0,(char *) 0); +#ifdef RBLTAG + rblcheckfmt(&qq, tagrblid.s); +#endif /* XXX: check for loops? only if len is big? */ diff -u orig/qmail-showctl.c rbltag/qmail-showctl.c --- orig/qmail-showctl.c Thu Aug 2 16:30:03 2001 +++ rbltag/qmail-showctl.c Fri Aug 3 15:19:51 2001 @@ -300,6 +300,7 @@ do_lst("badrcptto","Any RCPT TO is allowed.",""," not accepted in RCPT TO"); do_lst("relaymailfrom","Relaymailfrom not enabled.","Envelope senders allowed to relay: ","."); do_lst("rbllist","No RBL listed.","RBL to check: ","."); + do_lst("rbltags","No RBL listed.","RBL to check: ","."); substdio_puts(subfdout,"\n"); diff -u orig/qmail-smtpd.c rbltag/qmail-smtpd.c --- orig/qmail-smtpd.c Thu Aug 2 16:30:04 2001 +++ rbltag/qmail-smtpd.c Fri Aug 3 15:28:05 2001 @@ -186,6 +186,9 @@ char *relayok; char *denymail; char *rblenabled; +#ifdef RBLTAG +char *rbltagenabled; +#endif char *rblonlyheader; int spamflag = 0; @@ -210,6 +213,10 @@ int rblohok = 0; stralloc rbl = {0}; stralloc rblmessage = {0}; +#ifdef RBLTAG +int rbltagok = 0; +stralloc rbltag = {0}; +#endif int tarpitcount = 0; int tarpitdelay = 5; int maxrcptcount = 0; @@ -273,6 +280,13 @@ if (rblonlyheader) logline(2,"Log RBL match only in header, do not reject message"); } +#ifdef RBLTAG + rbltagok = control_readfile(&rbltag,"control/rbltags",0); + if (rbltagok == -1) die_control(); + if (rbltagok) + rbltagenabled = env_get("RBLTAG"); +#endif + if (control_readint(&databytes,"control/databytes") == -1) die_control(); x = env_get("DATABYTES"); if (x) { scan_ulong(x,&u); databytes = u; } @@ -397,6 +411,9 @@ /* RBL */ stralloc ip_reverse; +#ifdef RBLTAG +stralloc tagrblid; +#endif void rbl_init() { @@ -482,6 +499,41 @@ return r; } +#ifdef RBLTAG +int rblcheck_tag() +{ + int r; + char *p; + rbl_init(); + + p = &rbltag.s[0]; + while(p < &rbltag.s[0]+rbltag.len) + { + logpid(2); logstring(2,"RBL check with '"); logstring(2,p); logstring(2,"':"); + r = rbl_lookup(p); + switch(r) { + case 2: + logstring(2,"temporary DNS error"); + break; + case 1: + logstring(2,"found match"); + if ( 0 != tagrblid.len ) if (!stralloc_cats(&tagrblid," ")) die_nomem(); + if (!stralloc_cats(&tagrblid,p)) die_nomem(); + break; + default: + logstring(2, "no match"); + break; + } + /* continue */ + logflush(); + p = p+strlen(p); + p++; + } + if ( 0 != tagrblid.len ) tagrblid.s[tagrblid.len]='\0'; + return r; +} +#endif + /* RBL */ int sizelimit(arg) @@ -657,6 +709,14 @@ } } +#ifdef RBLTAG + if (rbltagenabled && !relayclient) + { + logline(3,"RBL TAGGING enabled, going through list of RBLs"); + rblcheck_tag(); + } +#endif + /* DENYMAIL is set for this session from this client, so heavy checking * of mailfrom is done. If one of the following is set: * SPAM -> refuse all mail @@ -883,6 +943,37 @@ return r; } +#ifdef RBLTAG +void rblcheckfmt(qqt, rblid) +struct qmail *qqt; +char *rblid; +{ + unsigned int j,k; + + if (!rblid) return; + + j=0; + while ('\0'!=rblid[j] && ' '==rblid[j]) j++; /* eat up whitespace */ + k=j; + while ('\0' != rblid[j]) { + if (' ' == rblid[j]) { + rblid[j] = '\0'; + qmail_puts(qqt,"X-RBL-Check: "); + qmail_puts(qqt,rblid+k); + qmail_puts(qqt,"\n"); + rblid[j] = ' '; + while (' ' == rblid[++j]); /* eat up whitespace */ + k=j; + } else j++; + } + if (j!=k) { + qmail_puts(qqt,"X-RBL-Check: "); + qmail_puts(qqt,rblid+k); + qmail_puts(qqt,"\n"); + } +} +#endif + char ssinbuf[1024]; substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); @@ -1009,6 +1100,9 @@ #else received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo,mailfrom.s,&rcptto.s[1]); #endif +#ifdef RBLTAG + rblcheckfmt(&qqt, tagrblid.s); +#endif blast(&hops); receivedbytes[fmt_ulong(receivedbytes,(unsigned long) bytesreceived)] = 0;