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; +}