In article
<20060525131510(_dot_)22679(_dot_)qmail(_at_)web32907(_dot_)mail(_dot_)mud(_dot_)yahoo(_dot_)com>
you write:
John,
Thanks for the reply. Can you please send me the code
for the Qmail patch?
Here you go. Good luck.
R's,
John
diff -C3 netqmail-1.05-dist/netqmail-1.05/qmail-remote.c
netqmail-1.05/netqmail-1.05/qmail-remote.c
*** netqmail-1.05-dist/netqmail-1.05/qmail-remote.c Mon Jun 15 06:53:16 1998
--- netqmail-1.05/netqmail-1.05/qmail-remote.c Fri Jan 6 12:24:47 2006
***************
*** 48,53 ****
--- 48,74 ----
+ #ifdef BATV
+ #define BATVLEN 3 /* number of bytes */
+ #include <openssl/md5.h>
+ stralloc signkey = {0};
+ stralloc nosign = {0};
+ struct constmap mapnosign;
+ stralloc nosigndoms = {0};
+ struct constmap mapnosigndoms;
+ #endif
+
void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); }
void zero() { if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); }
void zerodie() { zero(); substdio_flush(subfdoutsmall); _exit(0); }
***************
*** 324,331 ****
--- 659,742 ----
case 1:
if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem();
break;
}
+ #ifdef BATV
+ if(control_readline(&signkey, "control/signenv") == -1) temp_control();
+ switch(control_readfile(&nosign,"control/nosign",0)) {
+ case -1:
+ temp_control();
+ case 0:
+ if (!constmap_init(&mapnosign,"",0,1)) temp_nomem(); break;
+ case 1:
+ if (!constmap_init(&mapnosign,nosign.s,nosign.len,0)) temp_nomem();
break;
+ }
+ switch(control_readfile(&nosigndoms,"control/nosigndoms",0)) {
+ case -1:
+ temp_control();
+ case 0:
+ if (!constmap_init(&mapnosigndoms,"",0,1)) temp_nomem(); break;
+ case 1:
+ if (!constmap_init(&mapnosigndoms,nosigndoms.s,nosigndoms.len,0))
temp_nomem(); break;
+ }
+ #endif
}
+
+ #if BATV
+ stralloc newsender = {0};
+
+ signenv()
+ {
+ int daynumber = (now() / 86400) % 1000;
+ int i, atpos;
+ char kdate[] = "0000";
+ static char hex[] = "0123456789abcdef";
+ MD5_CTX md5;
+ unsigned char md5digest[MD5_DIGEST_LENGTH];
+
+ if(stralloc_starts(&sender, "prvs=")) return; /* already signed */
+ if(stralloc_starts(&sender, "sb*-")) { /* don't sign this */
+ sender.len -= 4;
+ byte_copy(sender.s, sender.len, sender.s+4);
+ return;
+ }
+
+ if(!stralloc_ready(&newsender, sender.len+(2*BATVLEN+10))) temp_nomem();
+ if(!stralloc_copyb(&newsender, "prvs=", 5)) temp_nomem();
+
+ /* copy in the mailbox */
+ if(!stralloc_0(&sender)) temp_nomem();
+ sender.len--; /* null isn't part of of the sender */
+ atpos = str_rchr(sender.s, '@');
+ if(!stralloc_catb(&newsender, sender.s, atpos)) temp_nomem();
+ if(!stralloc_catb(&newsender, "=", 1)) temp_nomem();
+
+ /* only one key so far */
+ kdate[1] = '0' + daynumber/100;
+ kdate[2] = '0' + (daynumber/10)%10;
+ kdate[3] = '0' + daynumber%10;
+
+ if(!stralloc_catb(&newsender, kdate, 4)) temp_nomem();
+
+ MD5_Init(&md5);
+ MD5_Update(&md5, kdate, 4);
+ MD5_Update(&md5, sender.s, sender.len);
+ MD5_Update(&md5, signkey.s, signkey.len);
+ MD5_Final(md5digest, &md5);
+
+ for(i = 0; i < BATVLEN; i++) {
+ char md5hex[2];
+
+ md5hex[0] = hex[md5digest[i]>>4];
+ md5hex[1] = hex[md5digest[i]&15];
+ if(!stralloc_catb(&newsender, md5hex, 2)) temp_nomem();
+ }
+
+ if(!stralloc_catb(&newsender, sender.s+atpos, sender.len-atpos))
temp_nomem();
+ if(!stralloc_copy(&sender, &newsender)) temp_nomem();
+ if(!stralloc_copys(&newsender, "")) temp_nomem();
+ }
+ #endif
+
void main(argc,argv)
int argc;
char **argv;
***************
*** 366,371 ****
--- 777,794 ----
addrmangle(&sender,argv[2],&flagalias,0);
+ #if BATV
+ if (sender.len && signkey.len) {
+ int j;
+ if (!stralloc_catb(&sender,"", 1)) temp_nomem(); /* null terminate */
+ sender.len--;
+
+ i = str_rchr(argv[3],'@'); /* should check all recips, not just
the first */
+ j = str_rchr(sender.s,'@');
+ if(!constmap(&mapnosign, argv[3]+i+1, str_len(argv[3]+i+1))
+ && !constmap(&mapnosigndoms, sender.s+j+1, sender.len-(j+1)))
signenv();
+ }
+ #endif
if (!saa_readyplus(&reciplist,0)) temp_nomem();
if (ipme_init() != 1) temp_oserr();
*** netqmail-1.05-dist/netqmail-1.05/qmail-send.c Mon Jun 15 06:53:16 1998
--- netqmail-1.05/netqmail-1.05/qmail-send.c Sun Nov 21 22:20:04 2004
***************
*** 672,677 ****
--- 672,685 ----
sender.s[sender.len - 1] = 0;
}
+ /* sb*-foo -> foo */
+ if (sender.len >= 5)
+ if (!str_diffn(sender.s,"sb*-", 4))
+ {
+ sender.len -= 4;
+ byte_copy(sender.s, sender.len, sender.s+4);
+ }
+
fnmake2_bounce(id);
fnmake_mess(id);
if (stat(fn2.s,&st) == -1)
diff -C3 netqmail-1.05-dist/netqmail-1.05/qmail-smtpd.c
netqmail-1.05/netqmail-1.05/qmail-smtpd.c
*** netqmail-1.05-dist/netqmail-1.05/qmail-smtpd.c Wed Jan 25 16:07:58 2006
--- netqmail-1.05/netqmail-1.05/qmail-smtpd.c Thu Aug 18 22:18:37 2005
***************
*** 1,3 ****
--- 1,4 ----
+ /* $Id: qmail-smtpd.c,v 1.1 2004/08/11 21:47:51 johnl Exp johnl $ */
#include "sig.h"
#include "readwrite.h"
#include "stralloc.h"
***************
*** 23,36 ****
--- 24,76 ----
#include "timeoutread.h"
#include "timeoutwrite.h"
#include "commands.h"
+ #include "cdb.h"
+ #include "wait.h"
+
+ #ifdef BATV
+ #define BATVLEN 3 /* number of bytes */
+ #define BATVSTALE 7 /* accept for a week */
+ #include <openssl/md5.h>
+ stralloc signkey = {0};
+ stralloc nosign = {0};
+ struct constmap mapnosign;
+ int isbounce;
+ #endif
#define MAXHOPS 100
unsigned int databytes = 0;
int timeout = 1200;
***************
*** 131,136 ****
--- 266,288 ----
if (!remotehost) remotehost = "unknown";
remoteinfo = env_get("TCPREMOTEINFO");
relayclient = env_get("RELAYCLIENT");
+
+ #ifdef BATV
+ if(control_readline(&signkey, "control/signenv") == -1) die_control();
+ switch(control_readfile(&nosign,"control/nosign",0)) {
+ case -1:
+ die_control();
+ case 0:
+ if (!constmap_init(&mapnosign,"",0,1)) die_nomem(); break;
+ case 1:
+ if (!constmap_init(&mapnosign,nosign.s,nosign.len,0)) die_nomem();
break;
+ }
+ #endif
dohelo(remotehost);
}
***************
*** 237,255 ****
--- 465,573 ----
seenmail = 0;
out("250 flushed\r\n");
}
+
+ #ifdef BATV
+ int check_env_sig()
+ {
+ int daynumber = (now() / 86400) % 1000;
+ int i;
+ int md5pos;
+ int atpos, slpos;
+ char kdate[] = "0000";
+ MD5_CTX md5;
+ unsigned char md5digest[MD5_DIGEST_LENGTH];
+ unsigned long signday;
+
+ if(addr.len >= (11+2*BATVLEN) && stralloc_starts(&addr, "prvs=")) {
+ atpos = str_rchr(addr.s, '@');
+ addr.s[atpos] = 0; /* just for a moment */
+ slpos = str_rchr(addr.s, '='); /* prefer an = sign */
+ if(slpos < 5) slpos = str_rchr(addr.s, '/');
+ addr.s[atpos] = '@';
+ if((slpos+5+2*BATVLEN) != atpos) return 0; /* no slash in the right
place, not a batv address */
+ byte_copy(kdate, 4, addr.s+slpos+1);
+ md5pos = slpos+5;
+ }
+ else return 0; /* no BATV */
+
+ if(kdate[0] != '0') return 0; /* not known format 0 */
+ if(scan_ulong(kdate+1, &signday) != 3) return 0;
+ if((unsigned)(daynumber-signday) > BATVSTALE) return 0; /* stale bounce
*/
+
+ MD5_Init(&md5);
+ MD5_Update(&md5, kdate, 4);
+ MD5_Update(&md5, addr.s+5, slpos-5);
+ MD5_Update(&md5, addr.s+atpos, str_len(addr.s+atpos));
+ MD5_Update(&md5, signkey.s, signkey.len);
+ MD5_Final(md5digest, &md5);
+
+ for(i = 0; i < BATVLEN; i++) {
+ int c, x;
+
+ c = addr.s[md5pos+2*i];
+
+ if(isdigit(c)) x = c-'0';
+ else if(c >= 'a' && c <= 'f') x = 10+c-'a';
+ else if(c >= 'A' && c <= 'F') x = 10+c-'A';
+ else return 0;
+
+ c = addr.s[md5pos+1+2*i];
+ x <<= 4;
+
+ if(isdigit(c)) x += c-'0';
+ else if(c >= 'a' && c <= 'f') x += 10+c-'a';
+ else if(c >= 'A' && c <= 'F') x += 10+c-'A';
+ else return 0;
+
+ if(x != md5digest[i]) return 0;
+ }
+
+ /* peel off the signature, we know byte_copy works a char at a time */
+ addr.len -= (10+2*BATVLEN);
+ byte_copy(addr.s, slpos-5, addr.s+5);
+ byte_copy(addr.s+slpos-5, 1+str_len(addr.s+atpos), addr.s+atpos);
+
+ return 1;
+ }
+ #endif
+
void smtp_mail(arg) char *arg;
{
+ int i;
+
if (!addrparse(arg)) { err_syntax(); return; }
+ #if BATV
+ (void)check_env_sig(); /* unwrap in case it's ours */
+ #endif
flagbarf = bmfcheck();
seenmail = 1;
if (!stralloc_copys(&rcptto,"")) die_nomem();
if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
if (!stralloc_0(&mailfrom)) die_nomem();
out("250 ok\r\n");
+ #if BATV
+ isbounce = 0;
+ if(addr.len <= 1 /* null term */
+ || stralloc_starts(&addr, "mailer-daemon@")
+ || stralloc_starts(&addr, "Mailer-Daemon@")
+ || stralloc_starts(&addr, "MAILER-DAEMON@")) {
+ i = str_rchr(addr.s,'@');
+ if(!i || !constmap(&mapnosign, addr.s+i+1, addr.len-i-2)) isbounce = 1;
+ }
+ #endif BATV
}
+
void smtp_rcpt(arg) char *arg; {
+ char *bba = env_get("SBADDR");
+ #if BATV
+ int ws;
+ #endif
+
if (!seenmail) { err_wantmail(); return; }
if (!addrparse(arg)) { err_syntax(); return; }
+ #if BATV
+ ws = check_env_sig(); /* always strip sig, even if it's not a
bounce */
+ #endif
if (flagbarf) { err_bmf(); return; }
if (relayclient) {
--addr.len;
***************
*** 258,263 ****
--- 576,606 ----
}
else
if (!addrallowed()) { err_nogateway(); return; }
+ #if BATV
+ /* if wasn't signed and was bounce, sideline it */
+ if(!relayclient && !ws && bba && *bba && isbounce) {
+ if(*bba == '#') { /* reject it */
+ flagbrt = 1;
+ log_deny("BAD BOUNCE", mailfrom.s,addr.s);
+ out("553 Not our message (#5.7.1)\r\n");
+ return;
+ }
+ --addr.len;
+ if (!stralloc_cats(&addr,bba)) die_nomem();
+ if (!stralloc_0(&addr)) die_nomem();
+ }
+ #endif
if (!stralloc_cats(&rcptto,"T")) die_nomem();
if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
if (!stralloc_0(&rcptto)) die_nomem();
_______________________________________________
ietf-clear mailing list
ietf-clear(_at_)mipassoc(_dot_)org
http://mipassoc.org/mailman/listinfo/ietf-clear