diff -Nur qmail-1.03/error.h qmail-1.03.tap/error.h --- qmail-1.03/error.h 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/error.h 2005-06-06 13:02:38.000000000 -0500 @@ -1,5 +1,6 @@ #ifndef ERROR_H #define ERROR_H +#include extern int errno; diff -Nur qmail-1.03/Makefile qmail-1.03.tap/Makefile --- qmail-1.03/Makefile 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/Makefile 2005-02-15 12:50:37.000000000 -0600 @@ -1419,13 +1419,14 @@ nroff -man qmail-qstat.8 > qmail-qstat.0 qmail-queue: \ -load qmail-queue.o triggerpull.o fmtqfn.o now.o date822fmt.o \ -datetime.a seek.a ndelay.a open.a sig.a alloc.a substdio.a error.a \ -str.a fs.a auto_qmail.o auto_split.o auto_uids.o +load qmail-queue.o triggerpull.o fmtqfn.o now.o date822fmt.o qregex.o \ +datetime.a seek.a case.a ndelay.a open.a sig.a getln.a stralloc.a alloc.a \ +substdio.a error.a control.o constmap.o str.a fs.a auto_qmail.o \ +auto_split.o auto_uids.o ./load qmail-queue triggerpull.o fmtqfn.o now.o \ - date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \ - alloc.a substdio.a error.a str.a fs.a auto_qmail.o \ - auto_split.o auto_uids.o + date822fmt.o qregex.o control.o constmap.o datetime.a case.a seek.a \ + ndelay.a open.a sig.a getln.a stralloc.a alloc.a substdio.a error.a \ + str.a fs.a auto_qmail.o auto_split.o auto_uids.o qmail-queue.0: \ qmail-queue.8 @@ -1681,6 +1682,10 @@ constmap.h stralloc.h gen_alloc.h rcpthosts.h ./compile rcpthosts.c +qregex.o: \ +compile qregex.c qregex.h + ./compile qregex.c + readsubdir.o: \ compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \ auto_split.h diff -Nur qmail-1.03/qmail-control.9 qmail-1.03.tap/qmail-control.9 --- qmail-1.03/qmail-control.9 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/qmail-control.9 2005-06-06 13:10:03.000000000 -0500 @@ -63,6 +63,7 @@ .I rcpthosts \fR(none) \fRqmail-smtpd .I smtpgreeting \fIme \fRqmail-smtpd .I smtproutes \fR(none) \fRqmail-remote +.I taps \fR(none) \fRqmail-queue .I timeoutconnect \fR60 \fRqmail-remote .I timeoutremote \fR1200 \fRqmail-remote .I timeoutsmtpd \fR1200 \fRqmail-smtpd @@ -72,6 +73,7 @@ .SH "SEE ALSO" qmail-inject(8), qmail-qmqpc(8), +qmail-queue(8), qmail-remote(8), qmail-send(8), qmail-showctl(8), diff -Nur qmail-1.03/qmail-queue.8 qmail-1.03.tap/qmail-queue.8 --- qmail-1.03/qmail-queue.8 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/qmail-queue.8 2005-06-06 13:11:01.000000000 -0500 @@ -40,6 +40,12 @@ However, the recipients probably expect to see a proper header, as described in .BR qmail-header(5) . +.SH "CONTROL FILES" +.TP 5 +.I taps +Should contain regex syntax of email addresses to tap and +the associated email address to send the copy to. The two +fields should be separated by a colon. .SH "FILESYSTEM RESTRICTIONS" .B qmail-queue imposes two constraints on the queue structure: diff -Nur qmail-1.03/qmail-queue.c qmail-1.03.tap/qmail-queue.c --- qmail-1.03/qmail-queue.c 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/qmail-queue.c 2005-05-17 14:59:00.000000000 -0500 @@ -16,6 +16,8 @@ #include "auto_uids.h" #include "date822fmt.h" #include "fmtqfn.h" +#include "stralloc.h" +#include "constmap.h" #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */ #define ADDR 1003 @@ -25,6 +27,14 @@ char outbuf[256]; struct substdio ssout; +int tapok = 0; +stralloc tap = {0}; +struct constmap maptap; +stralloc chkaddr = {0}; +int tapped; +stralloc tapaddr = {0}; +stralloc controlfile = {0}; + datetime_sec starttime; struct datetime dt; unsigned long mypid; @@ -175,6 +185,13 @@ alarm(DEATH); + stralloc_copys( &controlfile, auto_qmail); + stralloc_cats( &controlfile, "/control/taps"); + stralloc_0( &controlfile); + tapok = control_readfile(&tap,controlfile.s,0); + if (tapok == -1) die(65); + if (!constmap_init(&maptap,tap.s,tap.len,0)) die(65); + pidopen(); if (fstat(messfd,&pidst) == -1) die(63); @@ -219,14 +236,28 @@ if (substdio_get(&ssin,&ch,1) < 1) die_read(); if (ch != 'F') die(91); if (substdio_bput(&ssout,&ch,1) == -1) die_write(); + stralloc_0(&chkaddr); for (len = 0;len < ADDR;++len) { + if ( len == 1 ) stralloc_copyb(&chkaddr, &ch,1); + else if ( len > 1 ) stralloc_catb(&chkaddr, &ch,1); if (substdio_get(&ssin,&ch,1) < 1) die_read(); if (substdio_put(&ssout,&ch,1) == -1) die_write(); if (!ch) break; } if (len >= ADDR) die(11); + /* check the from address */ + stralloc_0(&chkaddr); + if (tapped == 0 && tapcheck()==1 ) { + tapped = 1; + if ( tapaddr.len > 0 ) { + if (substdio_bput(&ssout,"T",1) == -1) die_write(); + if (substdio_bput(&ssout,tapaddr.s,tapaddr.len) == -1) die_write(); + if (substdio_bput(&ssout,"",1) == -1) die_write(); + } + } + if (substdio_bput(&ssout,QUEUE_EXTRA,QUEUE_EXTRALEN) == -1) die_write(); for (;;) @@ -237,10 +268,24 @@ if (substdio_bput(&ssout,&ch,1) == -1) die_write(); for (len = 0;len < ADDR;++len) { + if ( len == 1 ) stralloc_copyb(&chkaddr, &ch,1); + else if ( len > 1 ) stralloc_catb(&chkaddr, &ch,1); if (substdio_get(&ssin,&ch,1) < 1) die_read(); if (substdio_bput(&ssout,&ch,1) == -1) die_write(); if (!ch) break; } + + /* check the to address */ + stralloc_0(&chkaddr); + if (tapped == 0 && tapcheck()==1 ) { + tapped = 1; + if ( tapaddr.len > 0 ) { + if (substdio_bput(&ssout,"T",1) == -1) die_write(); + if (substdio_bput(&ssout,tapaddr.s,tapaddr.len) == -1) die_write(); + if (substdio_bput(&ssout,"",1) == -1) die_write(); + } + } + if (len >= ADDR) die(11); } @@ -252,3 +297,42 @@ triggerpull(); die(0); } + +int tapcheck() +{ + int i = 0; + int j = 0; + int x = 0; + int negate = 0; + stralloc curregex = {0}; + char tmpbuf[200]; + + while (j < tap.len) { + i = j; + while ((tap.s[i] != ':') && (i < tap.len)) i++; + if (tap.s[j] == '!') { + negate = 1; + j++; + } + stralloc_copys(&tapaddr, &tap.s[i+1]); + + stralloc_copyb(&curregex,tap.s + j,(i - j)); + stralloc_0(&curregex); + x = matchregex(chkaddr.s, curregex.s, tmpbuf); + + while ((tap.s[i] != '\0') && (i < tap.len)) i++; + + if ((negate) && (x == 0)) { + return 1; + } + if (!(negate) && (x > 0)) { + return 1; + } + j = i + 1; + negate = 0; + + + } + return 0; +} + diff -Nur qmail-1.03/qregex.c qmail-1.03.tap/qregex.c --- qmail-1.03/qregex.c 1969-12-31 18:00:00.000000000 -0600 +++ qmail-1.03.tap/qregex.c 2005-02-15 12:48:58.000000000 -0600 @@ -0,0 +1,57 @@ +/* + * qregex (v2) + * $Id: qregex.c,v 2.1 2001/12/28 07:05:21 evan Exp $ + * + * Author : Evan Borgstrom (evan at unixpimps dot org) + * Created : 2001/12/14 23:08:16 + * Modified: $Date: 2001/12/28 07:05:21 $ + * Revision: $Revision: 2.1 $ + * + * Do POSIX regex matching on addresses for anti-relay / spam control. + * It logs to the maillog + * See the qregex-readme file included with this tarball. + * If you didn't get this file in a tarball please see the following URL: + * http://www.unixpimps.org/software/qregex + * + * qregex.c is released under a BSD style copyright. + * See http://www.unixpimps.org/software/qregex/copyright.html + * + * Note: this revision follows the coding guidelines set forth by the rest of + * the qmail code and that described at the following URL. + * http://cr.yp.to/qmail/guarantee.html + * + */ + +#include +#include +#include "qregex.h" + +#define REGCOMP(X,Y) regcomp(&X, Y, REG_EXTENDED|REG_ICASE) +#define REGEXEC(X,Y) regexec(&X, Y, (size_t)0, (regmatch_t *)0, (int)0) + +int matchregex(char *text, char *regex) { + regex_t qreg; + int retval = 0; + + + /* build the regex */ + if ((retval = REGCOMP(qreg, regex)) != 0) { + regfree(&qreg); + return(-retval); + } + + /* execute the regex */ + if ((retval = REGEXEC(qreg, text)) != 0) { + /* did we just not match anything? */ + if (retval == REG_NOMATCH) { + regfree(&qreg); + return(0); + } + regfree(&qreg); + return(-retval); + } + + /* signal the match */ + regfree(&qreg); + return(1); +} diff -Nur qmail-1.03/qregex.h qmail-1.03.tap/qregex.h --- qmail-1.03/qregex.h 1969-12-31 18:00:00.000000000 -0600 +++ qmail-1.03.tap/qregex.h 2005-02-15 12:48:58.000000000 -0600 @@ -0,0 +1,5 @@ +/* simple header file for the matchregex prototype */ +#ifndef _QREGEX_H_ +#define _QREGEX_H_ +int matchregex(char *text, char *regex); +#endif diff -Nur qmail-1.03/README.tap qmail-1.03.tap/README.tap --- qmail-1.03/README.tap 1969-12-31 18:00:00.000000000 -0600 +++ qmail-1.03.tap/README.tap 2005-06-07 09:48:41.000000000 -0500 @@ -0,0 +1,28 @@ +qmail provides the ability to make a copy of each email that flows through the system. +This is done using the QUEUE_EXTRA code. See qmail FAQ #8.2 + +The qmail tap patch adds additional functionality: +1) Specify which email addresses to tap using a regex style control file. With the + regex function, you can specify full domains or individual email addresses. + +2) Specify which email address to send the emails to. + +3) Qmail does not need to be restated to when the taps control file is changed. + +The regex match is applied to both the to and from email addresses. So email +sent to or from the addresses will be copied. Matching is case insensitive. +If there are multiple matches, the first match is used. + +The queue tap patch adds a new control file: + +/var/qmail/control/taps +Contains a regex style list of addresses to tap and the email +address of where you want the copy sent to. + +Examples: +a) To tap a whole domain add a line like: +.*@domain.com:joe@example.com + + +b) To tap an individual email address add a line like: +user@domain.com:other@example.com diff -Nur qmail-1.03/TARGETS qmail-1.03.tap/TARGETS --- qmail-1.03/TARGETS 1998-06-15 05:53:16.000000000 -0500 +++ qmail-1.03.tap/TARGETS 2005-02-15 12:48:21.000000000 -0600 @@ -385,3 +385,4 @@ man setup check +qregex.o