Download | Plain Text | Line Numbers


diff -Naur ucspi-tcp6-1.00.orig/package/commands-base ucspi-tcp6-1.00/package/commands-base
--- ucspi-tcp6-1.00.orig/package/commands-base	2014-05-18 21:32:58.424457097 +0200
+++ ucspi-tcp6-1.00/package/commands-base	2014-05-18 22:23:35.808824900 +0200
@@ -15,3 +15,4 @@
 finger@
 http@
 who@
+rblspp
diff -Naur ucspi-tcp6-1.00.orig/src/it-base=d ucspi-tcp6-1.00/src/it-base=d
--- ucspi-tcp6-1.00.orig/src/it-base=d	2014-05-18 21:32:58.428457166 +0200
+++ ucspi-tcp6-1.00/src/it-base=d	2014-05-18 21:33:29.085965413 +0200
@@ -20,3 +20,4 @@
 http@4
 who@
 who@4
+rblspp
diff -Naur ucspi-tcp6-1.00.orig/src/Makefile ucspi-tcp6-1.00/src/Makefile
--- ucspi-tcp6-1.00.orig/src/Makefile	2014-05-18 21:32:58.425457118 +0200
+++ ucspi-tcp6-1.00/src/Makefile	2014-05-18 22:04:19.670646890 +0200
@@ -405,7 +405,7 @@
 
 it-base: \
 tcpserver tcprules tcprulescheck argv0 recordio tcpclient who@ date@ \
-finger@ http@ tcpcat mconnect mconnect-io addcr delcr fixcrio rblsmtpd \
+finger@ http@ tcpcat mconnect mconnect-io addcr delcr fixcrio rblsmtpd rblspp \
 sysdeps
 
 load: \
@@ -503,6 +503,17 @@
 str.h stralloc.h strerr.h subgetopt.h tai.h taia.h uint64.h
 	./compile rblsmtpd.c
 
+rblspp: \
+load rblspp.o byte.a dns.a socket.lib time.a unix.a
+	./load rblspp dns.a time.a unix.a byte.a  \
+	`cat socket.lib`
+
+rblspp.o: \
+compile rblspp.c buffer.h byte.h dns.h env.h exit.h \
+fmt.h gen_alloc.h iopause.h ip6.h readwrite.h scan.h sgetopt.h \
+str.h stralloc.h strerr.h subgetopt.h tai.h taia.h uint64.h
+	./compile rblspp.c
+
 readclose.o: \
 compile readclose.c error.h gen_alloc.h readclose.h readwrite.h stralloc.h
 	./compile readclose.c
@@ -934,4 +945,4 @@
 	| sed s}HOME}"`head -1 home`"}g \
 	> who@
 	chmod 755 who@
-	
\ No newline at end of file
+	
diff -Naur ucspi-tcp6-1.00.orig/src/rblspp.c ucspi-tcp6-1.00/src/rblspp.c
--- ucspi-tcp6-1.00.orig/src/rblspp.c	1970-01-01 01:00:00.000000000 +0100
+++ ucspi-tcp6-1.00/src/rblspp.c	2014-05-18 23:21:26.462421956 +0200
@@ -0,0 +1,275 @@
+#include "byte.h"
+#include "str.h"
+#include "scan.h"
+#include "fmt.h"
+#include "env.h"
+#include "exit.h"
+#include "buffer.h"
+#include "readwrite.h"
+#include "sgetopt.h"
+#include "strerr.h"
+#include "stralloc.h"
+#include "dns.h"
+#include "ip6.h"
+
+#define FATAL "rblspp: fatal: "
+
+void nomem(void)
+{
+  strerr_die2x(111,FATAL,"out of memory");
+}
+void usage(void)
+{
+  strerr_die1x(100,"rblspp: usage: rblspp [ -B ] [ -b ] [ -C ] [ -c ] [ -i ] [ -r base ] [ -a base ]");
+}
+
+char *tcp_proto;
+char *ip_env;
+static stralloc ip_reverse;
+int flagip6 = 0;
+
+static inline char tohex(char c) { return c>=10?c-10+'a':c+'0'; }
+
+void ip_init(void)
+{
+  unsigned int i;
+  unsigned int j;
+  char hexval;
+  char remoteip[16];
+
+  tcp_proto = env_get("PROTO");
+  if (!tcp_proto) tcp_proto = "";
+  ip_env = env_get("TCPREMOTEIP");
+  if (!ip_env) ip_env = "";
+  if (str_diff(tcp_proto,"TCP6") == 0) {
+    if (byte_equal(ip_env,7,V4MAPPREFIX)) 
+      ip_env = ip_env + 7;
+     else
+      flagip6 = 1;
+  }
+ 
+  if (!stralloc_copys(&ip_reverse,"")) nomem();
+
+  if (flagip6) { 
+    if ((ip6_scan(ip_env,remoteip)) == 0) return;
+
+    for (j = 16; j > 0; j--) {
+      hexval = tohex(remoteip[j - 1] & 15);
+      if (!stralloc_catb(&ip_reverse,&hexval,1)) nomem();
+      if (!stralloc_cats(&ip_reverse,".")) nomem();
+
+      hexval = tohex(remoteip[j - 1] >> 4);
+      if (!stralloc_catb(&ip_reverse,&hexval,1)) nomem();
+      if (!stralloc_cats(&ip_reverse,".")) nomem(); 
+    }
+  } else {
+    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)) nomem();
+      if (!stralloc_cats(&ip_reverse,".")) nomem();
+      if (!j) break;
+      i = j - 1;
+    }
+  }
+}
+
+int flagrblbounce = 0;
+int flagfailclosed = 0;
+int flagmustnotbounce = 0;
+int flagrblinfo = 0;
+
+int decision = 0; /* 0 undecided, 1 accept, 2 direct refuse, 3 direct bounce, 4 rbl refuse, 5 rbl bounce */
+static stralloc text; /* defined if decision is > 2 */
+
+static stralloc tmp;
+
+void rbl(char *base)
+{
+  int i;
+  char *altreply = 0;
+  if (decision) return;
+  if (!stralloc_copy(&tmp,&ip_reverse)) nomem();
+  i = str_chr(base, ':');
+  if (base[i]) {
+    base[i] = 0;
+    altreply = base+i+1;
+  }
+  if (!stralloc_cats(&tmp,base)) nomem();
+  if (altreply) {
+    if (dns_ip4(&text,&tmp) == -1) {
+      flagmustnotbounce = 1;
+      if (flagfailclosed) {
+        if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem();
+        decision = 4;
+      }
+      return;
+    }
+    if (text.len) {
+      if(!stralloc_copys(&text, "")) nomem();
+      while(*altreply) {
+        char *x;
+        i = str_chr(altreply, '%');
+        if(!stralloc_catb(&text, altreply, i)) nomem();
+        if(altreply[i] &&
+           altreply[i+1]=='I' &&
+           altreply[i+2]=='P' &&
+           altreply[i+3]=='%') {
+          if(!stralloc_catb(&text, ip_env, str_len(ip_env))) nomem();
+          altreply+=i+4;
+        } else if(altreply[i]) {
+          if(!stralloc_cats(&text, "%")) nomem();
+          altreply+=i+1;
+        } else {
+          altreply+=i;
+        }
+      }
+    }
+  } else {
+    if (dns_txt(&text,&tmp) == -1) {
+      flagmustnotbounce = 1;
+      if (flagfailclosed) {
+        if (!stralloc_copys(&text,"temporary RBL lookup error")) nomem();
+        decision = 4;
+      }
+      return;
+    }
+  }
+  if (text.len)
+    if (flagrblbounce)
+      decision = 5;
+    else
+      decision = 4;
+}
+
+void antirbl(char *base)
+{
+  if (decision) return;
+  int flagip;
+
+  if (!stralloc_copy(&tmp,&ip_reverse)) nomem();
+  if (!stralloc_cats(&tmp,base)) nomem();
+   
+  if (flagip6) 
+    flagip = dns_ip6(&text,&tmp);
+  else
+    flagip = dns_ip4(&text,&tmp);
+ 
+  if (flagip == -1) {
+    flagmustnotbounce = 1;
+    if (!flagfailclosed)
+      decision = 1;
+    return;
+  }
+  if (text.len)
+    decision = 1;
+}
+
+char strnum[FMT_ULONG];
+static stralloc message;
+
+char outspace[1]; buffer out = BUFFER_INIT(write,1,outspace,sizeof outspace);
+
+void rblinfo(void)
+{
+  int i; 
+ 
+  if (!stralloc_copys(&message,"[RBL info] ")) nomem();
+
+  if (text.len > 200) text.len = 200;
+  if (!stralloc_cat(&message,&text)) nomem();
+
+  for (i = 0;i < message.len;++i)
+    if ((message.s[i] < 32) || (message.s[i] > 126))
+      message.s[i] = '?';
+
+  buffer_puts(buffer_2,"rblspp: ");
+  buffer_puts(buffer_2,ip_env);
+  buffer_puts(buffer_2," pid ");
+  buffer_put(buffer_2,strnum,fmt_ulong(strnum,getpid()));
+  buffer_puts(buffer_2,": ");
+  buffer_put(buffer_2,message.s,message.len);
+  buffer_puts(buffer_2,"\n");
+  buffer_flush(buffer_2);
+}
+
+void rblspp(void)
+{
+  int i;
+
+  if (flagmustnotbounce || (decision == 2) || (decision == 4)) {
+    if (!stralloc_copys(&message,"E451 ")) nomem();
+  }
+  else
+    if (!stralloc_copys(&message,"E553 ")) nomem();
+
+  if (text.len > 200) text.len = 200;
+  if (!stralloc_cat(&message,&text)) nomem();
+  for (i = 0;i < message.len;++i)
+    if ((message.s[i] < 32) || (message.s[i] > 126))
+      message.s[i] = '?';
+
+  buffer_puts(buffer_2,"rblspp: ");
+  buffer_puts(buffer_2,ip_env);
+  buffer_puts(buffer_2," pid ");
+  buffer_put(buffer_2,strnum,fmt_ulong(strnum,getppid()));
+  buffer_puts(buffer_2,": ");
+  buffer_put(buffer_2,message.s,message.len);
+  buffer_puts(buffer_2,"\n");
+  buffer_flush(buffer_2);
+
+  if (!stralloc_cats(&message,"\r\n")) nomem();
+
+  buffer_putflush(&out,message.s,message.len);
+
+  _exit(0);
+}
+
+int main(int argc,char **argv,char **envp)
+{
+  char *x;
+  int opt;
+  int rcount;
+
+  x = env_get("SMTPRCPTCOUNT");
+  if (x) {
+    rcount = atoi(x);
+    if (rcount > 0)
+      return 0;
+  }
+
+  ip_init();
+
+  x = env_get("RBLSPP");
+  if (x) {
+    if (!*x)
+      decision = 1;
+    else if (*x == '-') {
+      if (!stralloc_copys(&text,x + 1)) nomem();
+      decision = 3;
+    }
+    else {
+      if (!stralloc_copys(&text,x)) nomem();
+      decision = 2;
+    }
+  }
+
+  while ((opt = getopt(argc,argv,"bBcCir:a:")) != opteof)
+    switch(opt) {
+      case 'b': flagrblbounce = 1; break;
+      case 'B': flagrblbounce = 0; break;
+      case 'c': flagfailclosed = 1; break;
+      case 'C': flagfailclosed = 0; break;
+      case 'i': flagrblinfo = 1; break;
+      case 'r': rbl(optarg); break;
+      case 'a': antirbl(optarg); break;
+      default: usage();
+    }
+
+  if (flagrblinfo && decision >= 4)
+    rblinfo(); 
+  else if (decision >= 2)
+    rblspp();
+
+  return 0;
+}