ietf-clear
[Top] [All Lists]

Re: [clear] BATV with Postfix, examples?

2006-05-25 07:16:57
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

<Prev in Thread] Current Thread [Next in Thread>