diff -urN qmail-1.03/alloc.c qmail-1.03-md/alloc.c --- qmail-1.03/alloc.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/alloc.c 2011-03-11 10:56:43.120082406 +0100 @@ -1,7 +1,7 @@ #include "alloc.h" #include "error.h" -extern char *malloc(); -extern void free(); + +#include #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ #define SPACE 4096 /* must be multiple of ALIGNMENT */ diff -urN qmail-1.03/auto-gid.c qmail-1.03-md/auto-gid.c --- qmail-1.03/auto-gid.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/auto-gid.c 2011-03-11 10:56:43.120082406 +0100 @@ -16,7 +16,7 @@ if (substdio_puts(&ss1,s) == -1) _exit(111); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -47,5 +47,5 @@ outs(strnum); outs(";\n"); if (substdio_flush(&ss1) == -1) _exit(111); - _exit(0); + return 0; } diff -urN qmail-1.03/auto-int8.c qmail-1.03-md/auto-int8.c --- qmail-1.03/auto-int8.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/auto-int8.c 2011-03-11 10:56:43.123415951 +0100 @@ -7,13 +7,13 @@ char buf1[256]; substdio ss1 = SUBSTDIO_FDBUF(write,1,buf1,sizeof(buf1)); -void puts(s) +void out(s) char *s; { if (substdio_puts(&ss1,s) == -1) _exit(111); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -30,11 +30,11 @@ scan_8long(value,&num); strnum[fmt_ulong(strnum,num)] = 0; - puts("int "); - puts(name); - puts(" = "); - puts(strnum); - puts(";\n"); + out("int "); + out(name); + out(" = "); + out(strnum); + out(";\n"); if (substdio_flush(&ss1) == -1) _exit(111); - _exit(0); + return 0; } diff -urN qmail-1.03/auto-int.c qmail-1.03-md/auto-int.c --- qmail-1.03/auto-int.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/auto-int.c 2011-03-11 10:56:43.123415951 +0100 @@ -7,13 +7,13 @@ char buf1[256]; substdio ss1 = SUBSTDIO_FDBUF(write,1,buf1,sizeof(buf1)); -void puts(s) +void out(s) char *s; { if (substdio_puts(&ss1,s) == -1) _exit(111); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -30,11 +30,11 @@ scan_ulong(value,&num); strnum[fmt_ulong(strnum,num)] = 0; - puts("int "); - puts(name); - puts(" = "); - puts(strnum); - puts(";\n"); + out("int "); + out(name); + out(" = "); + out(strnum); + out(";\n"); if (substdio_flush(&ss1) == -1) _exit(111); - _exit(0); + return 0; } diff -urN qmail-1.03/auto-str.c qmail-1.03-md/auto-str.c --- qmail-1.03/auto-str.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/auto-str.c 2011-03-11 10:56:43.123415951 +0100 @@ -5,13 +5,13 @@ char buf1[256]; substdio ss1 = SUBSTDIO_FDBUF(write,1,buf1,sizeof(buf1)); -void puts(s) +void out(s) char *s; { if (substdio_puts(&ss1,s) == -1) _exit(111); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -25,20 +25,20 @@ value = argv[2]; if (!value) _exit(100); - puts("char "); - puts(name); - puts("[] = \"\\\n"); + out("char "); + out(name); + out("[] = \"\\\n"); - while (ch = *value++) { - puts("\\"); + while ((ch = *value++)) { + out("\\"); octal[3] = 0; octal[2] = '0' + (ch & 7); ch >>= 3; octal[1] = '0' + (ch & 7); ch >>= 3; octal[0] = '0' + (ch & 7); - puts(octal); + out(octal); } - puts("\\\n\";\n"); + out("\\\n\";\n"); if (substdio_flush(&ss1) == -1) _exit(111); - _exit(0); + return 0; } diff -urN qmail-1.03/auto-uid.c qmail-1.03-md/auto-uid.c --- qmail-1.03/auto-uid.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/auto-uid.c 2011-03-11 10:56:43.123415951 +0100 @@ -16,7 +16,7 @@ if (substdio_puts(&ss1,s) == -1) _exit(111); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/base64.c qmail-1.03-md/base64.c --- qmail-1.03/base64.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/base64.c 2011-03-11 10:56:43.123415951 +0100 @@ -0,0 +1,79 @@ +#include "base64.h" +#include "stralloc.h" +#include "str.h" + +const char base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +static inline int dec(unsigned char x) { + if (x>='A' && x<='Z') return x-'A'; + if (x>='a' && x<='z') return x-'a'+26; + if (x>='0' && x<='9') return x-'0'+26+26; + switch (x) { + case '+': return 62; + case '/': return 63; + default: return -1; + } +} + +unsigned long scan_base64(const char *src,char *dest,unsigned long *destlen) { + unsigned short tmp=0,bits=0; + register const unsigned char* s=(const unsigned char*) src; + const char* orig=dest; + for (;;) { + int a=dec(*s); + if (a<0) { + while (*s=='=') ++s; + break; + } + tmp=(tmp<<6)|a; bits+=6; + ++s; + if (bits>=8) { + *dest=(tmp>>(bits-=8)); + ++dest; + } + } + *destlen=dest-orig; + return (const char*)s-src; +} + +unsigned long fmt_base64(char* dest,const char* src,unsigned long len) { + register const unsigned char* s=(const unsigned char*) src; + unsigned short bits=0,temp=0; + unsigned long written=0,i; + if (!dest) return ((len+2)/3)*4; + for (i=0; i6) { + dest[written]=base64[((temp>>(bits-6))&63)]; + ++written; bits-=6; + } + } + if (bits) { + temp<<=(6-bits); + dest[written]=base64[temp&63]; + ++written; + } + while (written&3) { dest[written]='='; ++written; } + return written; +} + +/* returns 0 ok, 1 illegal */ +int b64decode(stralloc *out, const char *in, int l) +{ + if (!stralloc_readyplus(out, str_len(in))) return 1; + scan_base64(in, out->s, &out->len); + + return 0; +} + + +/* returns 0 ok, 1 illegal */ +int b64encode(stralloc *out, stralloc *in) +{ + if (stralloc_readyplus(out, fmt_base64(0,in->s,in->len))) { + out->len+=fmt_base64(out->s+out->len,in->s,in->len); + return 0; + } + + return 1; +} diff -urN qmail-1.03/base64.h qmail-1.03-md/base64.h --- qmail-1.03/base64.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/base64.h 2011-03-11 10:56:43.123415951 +0100 @@ -0,0 +1,12 @@ +#ifndef BASE64_H +#define BASE64_H + +#include "stralloc.h" + +extern unsigned long scan_base64(const char *src,char *dest,unsigned long *destlen); +extern unsigned long fmt_base64(char* dest,const char* src,unsigned long len); + +extern int b64decode(stralloc *out, const char *in, int l); +extern int b64encode(stralloc *out, stralloc *in); + +#endif diff -urN qmail-1.03/bouncesaying.c qmail-1.03-md/bouncesaying.c --- qmail-1.03/bouncesaying.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/bouncesaying.c 2011-03-11 10:56:43.123415951 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "fork.h" #include "strerr.h" #include "error.h" @@ -7,7 +9,7 @@ #define FATAL "bouncesaying: fatal: " -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -38,4 +40,5 @@ } strerr_die1x(100,argv[1]); + return 0; } diff -urN qmail-1.03/byte_cspn.c qmail-1.03-md/byte_cspn.c --- qmail-1.03/byte_cspn.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/byte_cspn.c 2011-03-11 10:56:43.123415951 +0100 @@ -0,0 +1,11 @@ +#include "byte.h" + +unsigned int byte_cspn(s,n,c) +register char *s; +register unsigned int n; +register char *c; +{ + while(*c) + n = byte_chr(s,n,*c++); + return n; +} diff -urN qmail-1.03/byte.h qmail-1.03-md/byte.h --- qmail-1.03/byte.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/byte.h 2011-03-11 10:56:43.123415951 +0100 @@ -3,9 +3,12 @@ extern unsigned int byte_chr(); extern unsigned int byte_rchr(); +extern unsigned int byte_cspn(); +extern unsigned int byte_rcspn(); + +extern int byte_diff(); extern void byte_copy(); extern void byte_copyr(); -extern int byte_diff(); extern void byte_zero(); #define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) diff -urN qmail-1.03/byte_rcspn.c qmail-1.03-md/byte_rcspn.c --- qmail-1.03/byte_rcspn.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/byte_rcspn.c 2011-03-11 10:56:43.123415951 +0100 @@ -0,0 +1,17 @@ +#include "byte.h" + +unsigned int byte_rcspn(s,n,c) +register char *s; +register unsigned int n; +register char *c; +{ + unsigned int ret,pos,i; + + for(ret = n,pos = 0;*c;++c) { + i = byte_rchr(s + pos,n - pos,*c) + pos; + if (i < n) ret = pos = i; + } + + return ret; +} + diff -urN qmail-1.03/case_lowers.c qmail-1.03-md/case_lowers.c --- qmail-1.03/case_lowers.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/case_lowers.c 2011-03-11 10:56:43.123415951 +0100 @@ -4,7 +4,7 @@ char *s; { unsigned char x; - while (x = *s) { + while ((x = *s)) { x -= 'A'; if (x <= 'Z' - 'A') *s = x + 'a'; ++s; diff -urN qmail-1.03/cdb.h qmail-1.03-md/cdb.h --- qmail-1.03/cdb.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/cdb.h 2011-03-11 10:56:43.123415951 +0100 @@ -1,6 +1,8 @@ #ifndef CDB_H #define CDB_H +#include +#include #include "uint32.h" extern uint32 cdb_hash(); diff -urN qmail-1.03/cdbmss.h qmail-1.03-md/cdbmss.h --- qmail-1.03/cdbmss.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/cdbmss.h 2011-03-11 10:56:43.123415951 +0100 @@ -4,6 +4,10 @@ #include "cdbmake.h" #include "substdio.h" +extern int cdbmss_start(); +extern int cdbmss_add(); +extern int cdbmss_finish(); + struct cdbmss { char ssbuf[1024]; struct cdbmake cdbm; @@ -11,6 +15,8 @@ char packbuf[8]; uint32 pos; int fd; -} ; +}; #endif + + diff -urN qmail-1.03/cdb_seek.c qmail-1.03-md/cdb_seek.c --- qmail-1.03/cdb_seek.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/cdb_seek.c 2011-03-11 10:56:43.123415951 +0100 @@ -1,7 +1,5 @@ -#include -#include -extern int errno; #include "cdb.h" +#include "error.h" #ifndef SEEK_SET #define SEEK_SET 0 diff -urN qmail-1.03/chkshsgr.c qmail-1.03-md/chkshsgr.c --- qmail-1.03/chkshsgr.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/chkshsgr.c 2011-03-11 10:56:43.123415951 +0100 @@ -1,5 +1,9 @@ +#include +#include +#include + #include "exit.h" -void main() +int main() { short x[4]; diff -urN qmail-1.03/chkspawn.c qmail-1.03-md/chkspawn.c --- qmail-1.03/chkspawn.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/chkspawn.c 2011-03-11 10:56:43.123415951 +0100 @@ -8,7 +8,7 @@ char num[FMT_ULONG]; fd_set fds; -void main() +int main() { unsigned long hiddenlimit; unsigned long maxnumd; @@ -22,8 +22,8 @@ _exit(1); } - if (auto_spawn > 255) { - substdio_puts(subfderr,"Oops. You have set conf-spawn higher than 255.\n"); + if (auto_spawn > 65000) { + substdio_puts(subfderr,"Oops. You have set conf-spawn higher than 65000.\n"); substdio_flush(subfderr); _exit(1); } diff -urN qmail-1.03/commands.c qmail-1.03-md/commands.c --- qmail-1.03/commands.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/commands.c 2011-03-11 10:56:43.123415951 +0100 @@ -1,13 +1,33 @@ +#include +#include #include "commands.h" #include "substdio.h" #include "stralloc.h" #include "str.h" +#include "fmt.h" #include "case.h" static stralloc cmd = {0}; -int commands(ss,c) +static void logit(substdio *ll, char *str) +{ + static int pid=0; + char pidstr[FMT_ULONG]; + + if (!pid) { pid=getpid(); } + pidstr[fmt_ulong(pidstr,pid)] = 0; + substdio_puts(ll,name); + substdio_puts(ll,": pid "); + substdio_puts(ll,pidstr); + substdio_puts(ll," C: "); + substdio_puts(ll,str); + substdio_puts(ll,"\n"); + substdio_flush(ll); +} + +int commands(ss,ll,c) substdio *ss; +substdio *ll; struct commands *c; { int i; @@ -22,12 +42,21 @@ if (i != 1) return i; if (cmd.s[cmd.len] == '\n') break; ++cmd.len; + + if (ctl_maxcmdlen) + if (cmd.len > ctl_maxcmdlen) { + die_lcmd(); /* long command detected! ... + we also don't log such things! */ + } } if (cmd.len > 0) if (cmd.s[cmd.len - 1] == '\r') --cmd.len; - cmd.s[cmd.len] = 0; + if (ctl_log_in > 0) + if (ll->fd>0) + logit(ll,cmd.s); + i = str_chr(cmd.s,' '); arg = cmd.s + i; while (*arg == ' ') ++arg; @@ -35,6 +64,7 @@ for (i = 0;c[i].text;++i) if (case_equals(c[i].text,cmd.s)) break; c[i].fun(arg); + if (c[i].flush) c[i].flush(); } } diff -urN qmail-1.03/commands.h qmail-1.03-md/commands.h --- qmail-1.03/commands.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/commands.h 2011-03-11 10:56:43.123415951 +0100 @@ -4,9 +4,14 @@ struct commands { char *text; void (*fun)(); - void (*flush)(); -} ; + int (*flush)(); +}; + +extern char *name; /* the name of the prog, which uses commands() */ +extern int ctl_log_in; +extern int ctl_maxcmdlen; /* max length a smtp command may have */ extern int commands(); +extern void die_lcmd(); /* we call this function, when the command is too long */ #endif diff -urN qmail-1.03/condredirect.c qmail-1.03-md/condredirect.c --- qmail-1.03/condredirect.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/condredirect.c 2011-03-11 10:56:43.123415951 +0100 @@ -28,7 +28,7 @@ char num[FMT_ULONG]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -82,4 +82,5 @@ qqx = qmail_close(&qqt); if (*qqx) strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1); strerr_die2x(99,"condredirect: qp ",num); + return 0; } diff -urN qmail-1.03/control.c qmail-1.03-md/control.c --- qmail-1.03/control.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/control.c 2011-03-11 10:56:43.123415951 +0100 @@ -1,17 +1,9 @@ -#include "readwrite.h" -#include "open.h" -#include "getln.h" -#include "stralloc.h" -#include "substdio.h" -#include "error.h" #include "control.h" -#include "alloc.h" -#include "scan.h" static char inbuf[64]; static stralloc line = {0}; -static stralloc me = {0}; -static int meok = 0; +stralloc me = {0}; +int meok = 0; static void striptrailingwhitespace(sa) stralloc *sa; @@ -74,7 +66,7 @@ char *fn; { unsigned long u; - switch(control_readline(&line,fn)) + switch (control_readline(&line,fn)) { case 0: return 0; case -1: return -1; diff -urN qmail-1.03/control.h qmail-1.03-md/control.h --- qmail-1.03/control.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/control.h 2011-03-11 10:56:43.123415951 +0100 @@ -1,6 +1,20 @@ #ifndef CONTROL_H #define CONTROL_H +#include +#include +#include "readwrite.h" +#include "open.h" +#include "getln.h" +#include "stralloc.h" +#include "substdio.h" +#include "error.h" +#include "alloc.h" +#include "scan.h" + +extern int meok; +extern stralloc me; + extern int control_init(); extern int control_readline(); extern int control_rldef(); diff -urN qmail-1.03/dns.c qmail-1.03-md/dns.c --- qmail-1.03/dns.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dns.c 2011-03-11 10:56:43.126749620 +0100 @@ -4,13 +4,15 @@ #include #include #include -#include + extern int res_query(); extern int res_search(); -extern int errno; extern int h_errno; + +#include "error.h" #include "ip.h" #include "ipalloc.h" +#include "strsalloc.h" #include "fmt.h" #include "alloc.h" #include "str.h" @@ -18,17 +20,22 @@ #include "dns.h" #include "case.h" +#define MAXTXT 256 + static unsigned short getshort(c) unsigned char *c; { unsigned short u; u = c[0]; return (u << 8) + c[1]; } -static union { HEADER hdr; unsigned char buf[PACKETSZ]; } response; +static struct { unsigned char *buf; } response; +static int responsebuflen = 0; static int responselen; static unsigned char *responseend; static unsigned char *responsepos; +static unsigned long saveresoptions; static int numanswers; static char name[MAXDNAME]; static struct ip_address ip; +static char txt[MAXTXT]; unsigned short pref; static stralloc glue = {0}; @@ -45,18 +52,32 @@ errno = 0; if (!stralloc_copy(&glue,domain)) return DNS_MEM; if (!stralloc_0(&glue)) return DNS_MEM; - responselen = lookup(glue.s,C_IN,type,response.buf,sizeof(response)); + if (!responsebuflen) response.buf = (unsigned char *)alloc(PACKETSZ+1); + if (response.buf) responsebuflen = PACKETSZ+1; + else return DNS_MEM; + + responselen = lookup(glue.s,C_IN,type,response.buf,responsebuflen); + if ((responselen >= responsebuflen) || + (responselen > 0 && (((HEADER *)response.buf)->tc))) + { + if (responsebuflen < 65536) { + if (alloc_re(&response.buf, responsebuflen, 65536)) + responsebuflen = 65536; + } else return DNS_MEM; + saveresoptions = _res.options; + _res.options |= RES_USEVC; + responselen = lookup(glue.s,C_IN,type,response.buf,responsebuflen); + _res.options = saveresoptions; + } if (responselen <= 0) { if (errno == ECONNREFUSED) return DNS_SOFT; if (h_errno == TRY_AGAIN) return DNS_SOFT; return DNS_HARD; } - if (responselen >= sizeof(response)) - responselen = sizeof(response); responseend = response.buf + responselen; responsepos = response.buf + sizeof(HEADER); - n = ntohs(response.hdr.qdcount); + n = ntohs(((HEADER *)response.buf)->qdcount); while (n-- > 0) { i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); @@ -66,7 +87,7 @@ if (i < QFIXEDSZ) return DNS_SOFT; responsepos += QFIXEDSZ; } - numanswers = ntohs(response.hdr.ancount); + numanswers = ntohs(((HEADER *)response.buf)->ancount); return 0; } @@ -179,6 +200,38 @@ return 0; } +static int findtxt(wanttype) +int wanttype; +{ + unsigned short rrtype; + unsigned short rrdlen; + int i; + + if (numanswers <= 0) return 2; + --numanswers; + if (responsepos == responseend) return DNS_SOFT; + + i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME); + if (i < 0) return DNS_SOFT; + responsepos += i; + + i = responseend - responsepos; + if (i < 4 + 3 * 2) return DNS_SOFT; + + rrtype = getshort(responsepos); + rrdlen = getshort(responsepos + 8); + responsepos += 10; + + if (rrtype == wanttype) { + str_copyb(txt, responsepos, rrdlen); + responsepos += rrdlen; + return 1; + } + + responsepos += rrdlen; + return 0; +} + void dns_init(flagsearch) int flagsearch; { @@ -237,15 +290,18 @@ return len; } -int dns_ptr(sa,ip) -stralloc *sa; +static int dns_ptrplus(ssa,ip) +strsalloc *ssa; struct ip_address *ip; { + stralloc sa = {0}; int r; - if (!stralloc_ready(sa,iaafmt((char *) 0,ip))) return DNS_MEM; - sa->len = iaafmt(sa->s,ip); - switch(resolve(sa,T_PTR)) + if (!stralloc_ready(&sa,iaafmt((char *) 0,ip))) return DNS_MEM; + sa.len = iaafmt(sa.s,ip); + r = resolve(&sa,T_PTR); + alloc_free(sa.s); + switch(r) { case DNS_MEM: return DNS_MEM; case DNS_SOFT: return DNS_SOFT; @@ -256,25 +312,46 @@ if (r == DNS_SOFT) return DNS_SOFT; if (r == 1) { - if (!stralloc_copys(sa,name)) return DNS_MEM; - return 0; + stralloc sa2 = {0}; + if (!stralloc_copys(&sa2,name)) return DNS_MEM; + if (!strsalloc_append(ssa,&sa2)) return DNS_MEM; } } + if (ssa->len) return 0; return DNS_HARD; } +int dns_ptr(ssa,ip) +strsalloc *ssa; +struct ip_address *ip; +{ + int r; + int j; + + if (!strsalloc_readyplus(ssa,0)) return DNS_MEM; + ssa->len = 0; + r = dns_ptrplus(ssa,ip); + if (r < 0) + { + for (j = 0;j < ssa->len;++j) + alloc_free(ssa->sa[j].s); + ssa->len = 0; + } + return r; +} + + static int dns_ipplus(ia,sa,pref) ipalloc *ia; stralloc *sa; int pref; { int r; - struct ip_mx ix; + struct ip_mx ix = {0}; if (!stralloc_copy(&glue,sa)) return DNS_MEM; if (!stralloc_0(&glue)) return DNS_MEM; if (glue.s[0]) { - ix.pref = 0; if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) { if (!ipalloc_append(ia,&ix)) return DNS_MEM; @@ -293,9 +370,12 @@ ix.ip = ip; ix.pref = pref; if (r == DNS_SOFT) return DNS_SOFT; - if (r == 1) + if (r == 1) { + ix.fqdn = glue.s; if (!ipalloc_append(ia,&ix)) return DNS_MEM; } + } + glue.s = 0; return 0; } @@ -315,7 +395,7 @@ { int r; struct mx { stralloc sa; unsigned short p; } *mx; - struct ip_mx ix; + struct ip_mx ix = {0}; int nummx; int i; int j; @@ -327,7 +407,6 @@ if (!stralloc_copy(&glue,sa)) return DNS_MEM; if (!stralloc_0(&glue)) return DNS_MEM; if (glue.s[0]) { - ix.pref = 0; if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)]) { if (!ipalloc_append(ia,&ix)) return DNS_MEM; @@ -398,3 +477,49 @@ alloc_free(mx); return flagsoft; } + + +static int dns_txtplus(ssa,sa) +strsalloc *ssa; +stralloc *sa; +{ + int r; + + switch(resolve(sa,T_TXT)) + { + case DNS_MEM: return DNS_MEM; + case DNS_SOFT: return DNS_SOFT; + case DNS_HARD: return DNS_HARD; + } + while ((r = findtxt(T_TXT)) != 2) + { + if (r == DNS_SOFT) return DNS_SOFT; + if (r == 1) + { + stralloc sa = {0}; + if (!stralloc_copyb(&sa,txt+1,(unsigned char)txt[0])) return DNS_MEM; + if (!strsalloc_append(ssa,&sa)) return DNS_MEM; + } + } + if (ssa->len) return 0; + return DNS_HARD; +} + +int dns_txt(ssa,sa) +strsalloc *ssa; +stralloc *sa; +{ + int r; + int j; + + if (!strsalloc_readyplus(ssa,0)) return DNS_MEM; + ssa->len = 0; + r = dns_txtplus(ssa,sa); + if (r < 0) + { + for (j = 0;j < ssa->len;++j) + alloc_free(ssa->sa[j].s); + ssa->len = 0; + } + return r; +} diff -urN qmail-1.03/dnscname.c qmail-1.03-md/dnscname.c --- qmail-1.03/dnscname.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dnscname.c 2011-03-11 10:56:43.126749620 +0100 @@ -8,7 +8,7 @@ stralloc sa = {0}; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/dnsfq.c qmail-1.03-md/dnsfq.c --- qmail-1.03/dnsfq.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dnsfq.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,6 +1,7 @@ #include "substdio.h" #include "subfd.h" #include "stralloc.h" +#include "strsalloc.h" #include "dns.h" #include "dnsdoe.h" #include "ip.h" @@ -8,12 +9,15 @@ #include "exit.h" stralloc sa = {0}; +strsalloc ssa = {0}; ipalloc ia = {0}; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { + int j; + if (!argv[1]) _exit(100); if (!stralloc_copys(&sa,argv[1])) @@ -25,8 +29,11 @@ { substdio_putsflush(subfderr,"no IP addresses\n"); _exit(100); } - dnsdoe(dns_ptr(&sa,&ia.ix[0].ip)); - substdio_putflush(subfdout,sa.s,sa.len); - substdio_putsflush(subfdout,"\n"); + dnsdoe(dns_ptr(&ssa,&ia.ix[0].ip)); + for(j = 0;j < ssa.len;++j) + { + substdio_putflush(subfdout,ssa.sa[j].s,ssa.sa[j].len); + substdio_putsflush(subfdout,"\n"); + } _exit(0); } diff -urN qmail-1.03/dns.h qmail-1.03-md/dns.h --- qmail-1.03/dns.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dns.h 2011-03-11 10:56:43.126749620 +0100 @@ -3,12 +3,13 @@ #define DNS_SOFT -1 #define DNS_HARD -2 -#define DNS_MEM -3 +#define DNS_MEM -3 void dns_init(); int dns_cname(); int dns_mxip(); int dns_ip(); int dns_ptr(); +int dns_txt(); #endif diff -urN qmail-1.03/dnsip.c qmail-1.03-md/dnsip.c --- qmail-1.03/dnsip.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dnsip.c 2011-03-11 10:56:43.126749620 +0100 @@ -12,7 +12,7 @@ stralloc sa = {0}; ipalloc ia = {0}; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/dnsmxip.c qmail-1.03-md/dnsmxip.c --- qmail-1.03/dnsmxip.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dnsmxip.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "substdio.h" #include "subfd.h" #include "stralloc.h" @@ -14,7 +16,7 @@ stralloc sa = {0}; ipalloc ia = {0}; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/dnsptr.c qmail-1.03-md/dnsptr.c --- qmail-1.03/dnsptr.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/dnsptr.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,6 +1,7 @@ #include "substdio.h" #include "subfd.h" #include "stralloc.h" +#include "strsalloc.h" #include "str.h" #include "scan.h" #include "dns.h" @@ -8,20 +9,25 @@ #include "ip.h" #include "exit.h" -stralloc sa = {0}; +strsalloc ssa = {0}; struct ip_address ip; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { + int j; + if (!argv[1]) _exit(100); ip_scan(argv[1],&ip); dns_init(0); - dnsdoe(dns_ptr(&sa,&ip)); - substdio_putflush(subfdout,sa.s,sa.len); - substdio_putsflush(subfdout,"\n"); + dnsdoe(dns_ptr(&ssa,&ip)); + for(j = 0;j < ssa.len;++j) + { + substdio_putflush(subfdout,ssa.sa[j].s,ssa.sa[j].len); + substdio_putsflush(subfdout,"\n"); + } _exit(0); } diff -urN qmail-1.03/dnstxt.c qmail-1.03-md/dnstxt.c --- qmail-1.03/dnstxt.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/dnstxt.c 2011-03-11 10:56:43.126749620 +0100 @@ -0,0 +1,32 @@ +#include "substdio.h" +#include "subfd.h" +#include "stralloc.h" +#include "str.h" +#include "scan.h" +#include "dns.h" +#include "dnsdoe.h" +#include "strsalloc.h" +#include "exit.h" + +strsalloc ssa = {0}; +stralloc sa = {0}; + +int main(argc,argv) +int argc; +char **argv; +{ + int j; + + if (!argv[1]) _exit(100); + + if (!stralloc_copys(&sa, argv[1])) + { substdio_putsflush(subfderr,"out of memory\n"); _exit(111); } + dns_init(0); + dnsdoe(dns_txt(&ssa,&sa)); + for (j = 0;j < ssa.len;++j) + { + substdio_put(subfdout,ssa.sa[j].s,ssa.sa[j].len); + substdio_putsflush(subfdout,"\n"); + } + _exit(0); +} diff -urN qmail-1.03/envread.c qmail-1.03-md/envread.c --- qmail-1.03/envread.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/envread.c 2011-03-11 10:56:43.126749620 +0100 @@ -9,7 +9,7 @@ char *envi; slen = str_len(s); - for (i = 0;envi = environ[i];++i) + for (i = 0; (envi = environ[i]); ++i) if ((!str_diffn(s,envi,slen)) && (envi[slen] == '=')) return envi + slen + 1; return 0; diff -urN qmail-1.03/error.c qmail-1.03-md/error.c --- qmail-1.03/error.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/error.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,4 +1,3 @@ -#include #include "error.h" /* warning: as coverage improves here, should update error_{str,temp} */ @@ -93,3 +92,10 @@ #else -13; #endif + +int error_dquot = +#ifdef EDQUOT +EDQUOT; +#else +-14; +#endif diff -urN qmail-1.03/error.h qmail-1.03-md/error.h --- qmail-1.03/error.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/error.h 2011-03-11 10:56:43.126749620 +0100 @@ -1,7 +1,9 @@ #ifndef ERROR_H #define ERROR_H -extern int errno; +#include "errno.h" + +#include extern int error_intr; extern int error_nomem; @@ -16,6 +18,7 @@ extern int error_pipe; extern int error_perm; extern int error_acces; +extern int error_dquot; extern char *error_str(); extern int error_temp(); diff -urN qmail-1.03/error.h.orig qmail-1.03-md/error.h.orig --- qmail-1.03/error.h.orig 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/error.h.orig 2011-03-11 10:56:43.126749620 +0100 @@ -0,0 +1,25 @@ +#ifndef ERROR_H +#define ERROR_H + +#include "errno.h" + +extern int errno; + +extern int error_intr; +extern int error_nomem; +extern int error_noent; +extern int error_txtbsy; +extern int error_io; +extern int error_exist; +extern int error_timeout; +extern int error_inprogress; +extern int error_wouldblock; +extern int error_again; +extern int error_pipe; +extern int error_perm; +extern int error_acces; + +extern char *error_str(); +extern int error_temp(); + +#endif diff -urN qmail-1.03/error_str.c qmail-1.03-md/error_str.c --- qmail-1.03/error_str.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/error_str.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,4 +1,3 @@ -#include #include "error.h" #define X(e,s) if (i == e) return s; diff -urN qmail-1.03/error_temp.c qmail-1.03-md/error_temp.c --- qmail-1.03/error_temp.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/error_temp.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,4 +1,3 @@ -#include #include "error.h" #define X(n) if (e == n) return 1; diff -urN qmail-1.03/except.c qmail-1.03-md/except.c --- qmail-1.03/except.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/except.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "fork.h" #include "strerr.h" #include "wait.h" @@ -6,7 +8,7 @@ #define FATAL "except: fatal: " -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/fd_copy.c qmail-1.03-md/fd_copy.c --- qmail-1.03/fd_copy.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/fd_copy.c 2011-03-11 10:56:43.126749620 +0100 @@ -1,5 +1,5 @@ -#include #include "fd.h" +#include int fd_copy(to,from) int to; diff -urN qmail-1.03/fd.h qmail-1.03-md/fd.h --- qmail-1.03/fd.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/fd.h 2011-03-11 10:56:43.126749620 +0100 @@ -1,6 +1,9 @@ #ifndef FD_H #define FD_H +#include +#include + extern int fd_copy(); extern int fd_move(); diff -urN qmail-1.03/FILES qmail-1.03-md/FILES --- qmail-1.03/FILES 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/FILES 2011-03-11 10:56:43.130083196 +0100 @@ -1,9 +1,12 @@ +BIN.Makefile +BIN.README BLURB BLURB2 BLURB3 BLURB4 -README +CHANGES FAQ +FILES INSTALL INSTALL.alias INSTALL.ctl @@ -11,18 +14,8 @@ INSTALL.maildir INSTALL.mbox INSTALL.vsm -REMOVE.sendmail -REMOVE.binmail -TEST.deliver -TEST.receive -UPGRADE -THOUGHTS -TODO -THANKS -CHANGES -SECURITY INTERNALS -SENDMAIL +Makefile PIC.local2alias PIC.local2ext PIC.local2local @@ -32,402 +25,444 @@ PIC.relaybad PIC.relaygood PIC.rem2local -FILES -VERSION +README +REMOVE.binmail +REMOVE.sendmail +SECURITY +SENDMAIL SYSDEPS TARGETS -Makefile -BIN.README -BIN.Makefile -idedit.c -conf-break +TEST.deliver +TEST.receive +THANKS +THOUGHTS +TODO +UPGRADE +VERSION +addresses.5 +alloc.3 +alloc.c +alloc.h +alloc_re.c +auto-gid.c +auto-int.c +auto-int8.c +auto-str.c +auto-uid.c auto_break.h -conf-spawn +auto_patrn.h +auto_qmail.h auto_spawn.h -chkspawn.c -conf-split auto_split.h -conf-patrn -auto_patrn.h -conf-users -conf-groups auto_uids.h auto_usera.h -extra.h -addresses.5 -except.1 +base64.c +base64.h +binm1+df.sh +binm1.sh +binm2+df.sh +binm2.sh +binm3+df.sh +binm3.sh bouncesaying.1 +bouncesaying.c +byte.h +byte_chr.c +byte_copy.c +byte_cr.c +byte_cspn.c +byte_diff.c +byte_rchr.c +byte_rcspn.c +byte_zero.c +case.3 +case.h +case_diffb.c +case_diffs.c +case_lowerb.c +case_lowers.c +case_starts.c +cdb.3 +cdb.h +cdb_hash.c +cdb_seek.c +cdb_unpack.c +cdbmake.h +cdbmake_add.c +cdbmake_hash.c +cdbmake_pack.c +cdbmss.c +cdbmss.h +chkshsgr.c +chkspawn.c +coe.3 +coe.c +coe.h +commands.c +commands.h condredirect.1 +condredirect.c +conf-break +conf-cc +conf-groups +conf-ld +conf-patrn +conf-qmail +conf-spawn +conf-split +conf-users +config-fast.sh +config.sh +constmap.c +constmap.h +control.c +control.h +date822fmt.c +date822fmt.h +datemail.sh +datetime.3 +datetime.c +datetime.h +datetime_un.c +direntry.3 +direntry.h1 +direntry.h2 +dns.c +dns.h +dnscname.c +dnsdoe.c +dnsdoe.h +dnsfq.c +dnsip.c +dnsmxip.c +dnsptr.c +dnstxt.c dot-qmail.9 +elq.sh +env.3 +env.c +env.h envelopes.5 +envread.c +error.3 +error.c +error.h +error_str.3 +error_str.c +error_temp.3 +error_temp.c +except.1 +except.c +exit.h +extra.h +fd.h +fd_copy.3 +fd_copy.c +fd_move.3 +fd_move.c +fifo.c +fifo.h +fifo_make.3 +find-systype.sh +fmt.h +fmt_str.c +fmt_strn.c +fmt_uint.c +fmt_uint0.c +fmt_ulong.c +fmtqfn.c +fmtqfn.h forgeries.7 +fork.h1 +fork.h2 forward.1 +forward.c +gen_alloc.h +gen_allocdefs.h +getln.3 +getln.c +getln.h +getln2.3 +getln2.c +gfrom.c +gfrom.h +headerbody.c +headerbody.h +hfield.c +hfield.h +hier.c +hmac.h +hmac_md5.c +hmac_md5.o +hmac_ripemd.c +hmac_ripemd.o +hmac_sha1.c +hmac_sha1.h +home+df.sh +home.sh +hostname.c +idedit.c +install-big.c +install.c +install.h +instcheck.c +ip.c +ip.h +ipalloc.c +ipalloc.h +ipme.c +ipme.h +ipmeprint.c +lock.h +lock_ex.c +lock_exnb.c +lock_un.c +maildir.5 +maildir.c +maildir.h maildir2mbox.1 +maildir2mbox.c maildirmake.1 +maildirmake.c maildirwatch.1 +maildirwatch.c mailsubj.1 +mailsubj.sh +make-compile.sh +make-load.sh +make-makelib.sh mbox.5 +md5.c +md5.h +md5.o +myctime.c +myctime.h +ndelay.c +ndelay.h +ndelay_off.c +newfield.c +newfield.h +now.3 +now.c +now.h +open.h +open_append.c +open_excl.c +open_read.c +open_trunc.c +open_write.c +out_log.c +out_log.h +pinq.sh +predate.c preline.1 +preline.c +prioq.c +prioq.h +proc+df.sh +proc.sh +prot.c +prot.h +qail.sh qbiff.1 +qbiff.c +qlx.h qmail-clean.8 +qmail-clean.c qmail-command.8 qmail-control.9 qmail-getpw.9 +qmail-getpw.c qmail-header.5 qmail-inject.8 +qmail-inject.c qmail-limits.9 qmail-local.8 +qmail-local.c qmail-log.5 qmail-lspawn.8 +qmail-lspawn.c qmail-newmrh.9 +qmail-newmrh.c qmail-newu.9 +qmail-newu.c +qmail-p0f.c +qmail-p0f.h +qmail-p0f.o qmail-pop3d.8 +qmail-pop3d.c qmail-popup.8 +qmail-popup.c qmail-pw2u.9 +qmail-pw2u.c qmail-qmqpc.8 +qmail-qmqpc.c qmail-qmqpd.8 +qmail-qmqpd.c qmail-qmtpd.8 +qmail-qmtpd.c qmail-qread.8 +qmail-qread.c qmail-qstat.8 +qmail-qstat.sh qmail-queue.8 +qmail-queue.c qmail-remote.8 +qmail-remote.c qmail-rspawn.8 +qmail-rspawn.c +qmail-sasl.c +qmail-sasl.h qmail-send.9 +qmail-send.c qmail-showctl.8 +qmail-showctl.c qmail-smtpd.8 +qmail-smtpd.c qmail-start.9 +qmail-start.c qmail-tcpok.8 +qmail-tcpok.c qmail-tcpto.8 +qmail-tcpto.c +qmail-upq.sh qmail-users.9 qmail.7 +qmail.c +qmail.h qreceipt.1 -splogger.8 -tcp-env.1 -config.sh -config-fast.sh -qmail-clean.c -qmail-getpw.c -qmail-inject.c -qmail-local.c -qmail-lspawn.c -qmail-newmrh.c -qmail-newu.c -qmail-pop3d.c -qmail-popup.c -qmail-pw2u.c -qmail-qmqpc.c -qmail-qmqpd.c -qmail-qmtpd.c -qmail-qread.c -qmail-qstat.sh -qmail-queue.c -qmail-remote.c -qmail-rspawn.c -qmail-send.c -qmail-showctl.c -qmail-smtpd.c -qmail-start.c -qmail-tcpok.c -qmail-tcpto.c -spawn.c -dnscname.c -dnsfq.c -dnsip.c -dnsmxip.c -dnsptr.c -hostname.c -ipmeprint.c -tcp-env.c -sendmail.c qreceipt.c qsmhook.c -qbiff.c -forward.c -preline.c -predate.c -except.c -bouncesaying.c -condredirect.c -maildirmake.c -maildir2mbox.c -maildirwatch.c -splogger.c -qail.sh -elq.sh -pinq.sh -qmail-upq.sh -datemail.sh -mailsubj.sh -qlx.h -rcpthosts.h -rcpthosts.c -commands.h -commands.c -dnsdoe.h -dnsdoe.c -fmtqfn.h -fmtqfn.c -gfrom.h -gfrom.c -myctime.h -myctime.c -newfield.h -newfield.c -qsutil.h qsutil.c -readsubdir.h +qsutil.h +quote.c +quote.h +rcpthosts.c +rcpthosts.h readsubdir.c -received.h +readsubdir.h +readwrite.h +realrcptto.c +realrcptto.o received.c -tcpto.h -tcpto.c -tcpto_clean.c -trigger.h -trigger.c -triggerpull.h -triggerpull.c -trynpbg1.c -trysyslog.c -conf-cc -conf-ld -home.sh -home+df.sh -proc.sh -proc+df.sh -binm1.sh -binm2.sh -binm3.sh -binm1+df.sh -binm2+df.sh -binm3+df.sh -find-systype.sh -make-compile.sh -make-load.sh -make-makelib.sh -trycpp.c -warn-auto.sh -auto-str.c -auto-int.c -auto-int8.c -auto-gid.c -auto-uid.c -hier.c -install.c -instcheck.c -install-big.c -alloc.3 -alloc.h -alloc.c -alloc_re.c -case.3 -case.h -case_diffb.c -case_diffs.c -case_lowerb.c -case_lowers.c -case_starts.c -cdb.3 -cdb.h -cdb_hash.c -cdb_seek.c -cdb_unpack.c -cdbmake.h -cdbmake_add.c -cdbmake_hash.c -cdbmake_pack.c -cdbmss.h -cdbmss.c -coe.3 -coe.h -coe.c -fd.h -fd_copy.3 -fd_copy.c -fd_move.3 -fd_move.c -fifo_make.3 -fifo.h -fifo.c -trymkffo.c -fork.h1 -fork.h2 -tryvfork.c -now.3 -now.h -now.c -open.h -open_append.c -open_excl.c -open_read.c -open_trunc.c -open_write.c +received.h +remoteinfo.c +remoteinfo.h +ripemd.c +ripemd.h +ripemd.o +scan.h +scan_8long.c +scan_ulong.c seek.h seek_cur.c seek_end.c seek_set.c seek_trunc.c -conf-qmail -auto_qmail.h -qmail.h -qmail.c -gen_alloc.h -gen_allocdefs.h -stralloc.3 -stralloc.h -stralloc_eady.c -stralloc_pend.c -stralloc_copy.c -stralloc_opyb.c -stralloc_opys.c -stralloc_cat.c -stralloc_catb.c -stralloc_cats.c -stralloc_arts.c -strerr.h -strerr_sys.c -strerr_die.c -substdio.h -substdio.c -substdi.c -substdo.c -substdio_copy.c -subfd.h -subfderr.c -subfdouts.c -subfdout.c -subfdins.c -subfdin.c -readwrite.h -exit.h -timeoutconn.h -timeoutconn.c -timeoutread.h -timeoutread.c -timeoutwrite.h -timeoutwrite.c -remoteinfo.h -remoteinfo.c -uint32.h1 -uint32.h2 -tryulong32.c -wait.3 -wait.h -wait_pid.c -wait_nohang.c -trywaitp.c +select.h1 +select.h2 +sendmail.c +sgetopt.3 +sgetopt.c +sgetopt.h +sha1.c +sha1.h +sha1.o sig.h sig_alarm.c sig_block.c +sig_bug.c sig_catch.c -sig_pause.c -sig_pipe.c sig_child.c -sig_term.c sig_hup.c sig_misc.c -sig_bug.c -trysgact.c -trysgprm.c -env.3 -env.h -env.c -envread.c -byte.h -byte_chr.c -byte_copy.c -byte_cr.c -byte_diff.c -byte_rchr.c -byte_zero.c +sig_pause.c +sig_pipe.c +sig_term.c +slurpclose.c +slurpclose.h +spawn.c +splogger.8 +splogger.c str.h str_chr.c str_cpy.c +str_cpyb.c str_diff.c str_diffn.c str_len.c str_rchr.c str_start.c -lock.h -lock_ex.c -lock_exnb.c -lock_un.c -tryflock.c -getln.3 -getln.h -getln.c -getln2.3 -getln2.c -sgetopt.3 -sgetopt.h -sgetopt.c +stralloc.3 +stralloc.h +stralloc_arts.c +stralloc_cat.c +stralloc_catb.c +stralloc_cats.c +stralloc_copy.c +stralloc_eady.c +stralloc_opyb.c +stralloc_opys.c +stralloc_pend.c +strerr.h +strerr_die.c +strerr_sys.c +strsalloc.c +strsalloc.h +subfd.h +subfderr.c +subfdin.c +subfdins.c +subfdout.c +subfdouts.c subgetopt.3 -subgetopt.h subgetopt.c -error.3 -error_str.3 -error_temp.3 -error.h -error.c -error_str.c -error_temp.c -fmt.h -fmt_str.c -fmt_strn.c -fmt_uint.c -fmt_uint0.c -fmt_ulong.c -scan.h -scan_ulong.c -scan_8long.c -slurpclose.h -slurpclose.c -quote.h -quote.c -hfield.h -hfield.c -headerbody.h -headerbody.c -token822.h +subgetopt.h +substdi.c +substdio.c +substdio.h +substdio_copy.c +substdo.c +tcp-env.1 +tcp-env.c +tcp-environ.5 +tcpto.c +tcpto.h +tcpto_clean.c +timeoutconn.c +timeoutconn.h +timeoutread.c +timeoutread.h +timeoutwrite.c +timeoutwrite.h token822.c -control.h -control.c -datetime.3 -datetime.h -datetime.c -datetime_un.c -prioq.h -prioq.c -date822fmt.h -date822fmt.c -dns.h -dns.c +token822.h +trigger.c +trigger.h +triggerpull.c +triggerpull.h +trycpp.c +trydrent.c +tryflock.c trylsock.c +trymkffo.c +trynpbg1.c tryrsolv.c -ip.h -ip.c -ipalloc.h -ipalloc.c -select.h1 -select.h2 +trysalen.c +trysgact.c +trysgprm.c +tryshsgr.c trysysel.c -ndelay.h -ndelay.c -ndelay_off.c -direntry.3 -direntry.h1 -direntry.h2 -trydrent.c -prot.h -prot.c -chkshsgr.c +trysyslog.c +tryulong32.c +tryvfork.c +trywaitp.c +typesx.h +uint32.h1 +uint32.h2 +wait.3 +wait.h +wait_nohang.c +wait_pid.c +warn-auto.sh warn-shsgr -tryshsgr.c -ipme.h -ipme.c -trysalen.c -maildir.5 -maildir.h -maildir.c -tcp-environ.5 -constmap.h -constmap.c diff -urN qmail-1.03/fmt_str.c qmail-1.03-md/fmt_str.c --- qmail-1.03/fmt_str.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/fmt_str.c 2011-03-11 10:56:43.130083196 +0100 @@ -6,7 +6,7 @@ register unsigned int len; char ch; len = 0; - if (s) { while (ch = t[len]) s[len++] = ch; } + if (s) { while ((ch = t[len])) s[len++] = ch; } else while (t[len]) len++; return len; } diff -urN qmail-1.03/forward.c qmail-1.03-md/forward.c --- qmail-1.03/forward.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/forward.c 2011-03-11 10:56:43.130083196 +0100 @@ -26,7 +26,7 @@ char num[FMT_ULONG]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -57,4 +57,5 @@ qqx = qmail_close(&qqt); if (*qqx) strerr_die2x(*qqx == 'D' ? 100 : 111,FATAL,qqx + 1); strerr_die2x(0,"forward: qp ",num); + return 0; } diff -urN qmail-1.03/hfield.c qmail-1.03-md/hfield.c --- qmail-1.03/hfield.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/hfield.c 2011-03-11 10:56:43.130083196 +0100 @@ -41,7 +41,7 @@ int i; char ch; - for (i = 0;ch = t[i];++i) + for (i = 0;(ch = t[i]);++i) { if (i >= len) return 0; if (ch != s[i]) @@ -67,7 +67,7 @@ int i; char *t; - for (i = 1;t = hname[i];++i) + for (i = 1;(t = hname[i]);++i) if (hmatch(s,len,t)) return i; return 0; diff -urN qmail-1.03/hier.c qmail-1.03-md/hier.c --- qmail-1.03/hier.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/hier.c 2011-03-11 10:56:43.130083196 +0100 @@ -1,3 +1,4 @@ +#include "install.h" #include "auto_qmail.h" #include "auto_split.h" #include "auto_uids.h" @@ -55,6 +56,8 @@ d(auto_qmail,"queue/bounce",auto_uids,auto_gidq,0700); dsplit("queue/mess",auto_uidq,0750); + dsplit("queue/todo",auto_uidq,0750); + dsplit("queue/intd",auto_uidq,0700); dsplit("queue/info",auto_uids,0700); dsplit("queue/local",auto_uids,0700); dsplit("queue/remote",auto_uids,0700); @@ -145,108 +148,57 @@ c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","envelopes.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","envelopes.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","maildir.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","maildir.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","mbox.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","mbox.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","dot-qmail.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","dot-qmail.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-control.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-control.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-header.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-header.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-log.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-log.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-users.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-users.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","tcp-environ.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","tcp-environ.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","forgeries.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","forgeries.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","qmail-limits.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","qmail-limits.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","qmail.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","qmail.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","forward.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","forward.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","condredirect.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","condredirect.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","bouncesaying.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","bouncesaying.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","except.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","except.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildirmake.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildirmake.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildir2mbox.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildir2mbox.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildirwatch.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildirwatch.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","mailsubj.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","mailsubj.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","qreceipt.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","qreceipt.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","qbiff.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","qbiff.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","preline.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","preline.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","tcp-env.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","tcp-env.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-local.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-local.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-lspawn.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-lspawn.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-getpw.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-getpw.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-remote.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-remote.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-rspawn.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-rspawn.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-clean.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-clean.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-send.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-send.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-start.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-start.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","splogger.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","splogger.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-queue.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-queue.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-inject.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-newu.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-pw2u.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-pw2u.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qread.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qread.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qstat.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qstat.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-tcpok.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-tcpok.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-tcpto.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-tcpto.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-pop3d.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-pop3d.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-popup.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-popup.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmqpc.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmqpc.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmqpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmqpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmtpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmtpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-smtpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-smtpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-command.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-command.0",auto_uido,auto_gidq,0644); } diff -urN qmail-1.03/hmac.h qmail-1.03-md/hmac.h --- qmail-1.03/hmac.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/hmac.h 2011-03-11 10:56:43.130083196 +0100 @@ -0,0 +1,4 @@ + +extern void hmac_md5(); +extern void hmac_ripemd(); +extern void hmac_sha1(); diff -urN qmail-1.03/hmac_md5.c qmail-1.03-md/hmac_md5.c --- qmail-1.03/hmac_md5.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/hmac_md5.c 2011-03-11 10:56:43.130083196 +0100 @@ -0,0 +1,56 @@ +#include +#include +#include + +#include "typesx.h" +#include "md5.h" + +#define PAD 64 +#define TK 16 + +void hmac_md5(text, key, digest) + u8 *text; /* pointer to data stream */ + u8 *key; /* pointer to authentication key */ + u8 *digest; /* caller digest to be filled in */ +{ + MD5_CTX ctx; + u8 k_ipad[PAD+1]; /* inner padding - key XORd with ipad */ + u8 k_opad[PAD+1]; /* outer padding - key XORd with opad */ + u8 tk[TK]; + size_t text_len=strlen(text); + size_t key_len=strlen(key); + int i; + + if (key_len > PAD) { + MD5_CTX tctx; + MD5_Init(&tctx); + MD5_Update(&tctx, key, key_len); + MD5_Final(tk, &tctx); + key = tk; + key_len = TK; + } + + /* start out by storing key in pads */ + memset(k_ipad, 0, PAD); + memcpy(k_ipad, key, key_len); + memset(k_opad, 0, PAD); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i +#include +#include + +#include "typesx.h" +#include "ripemd.h" + +#define PAD 64 +#define TK 20 + +void hmac_ripemd(text, key, digest) + u8 *text; /* pointer to data stream */ + u8 *key; /* pointer to authentication key */ + u8 *digest; /* caller digest to be filled in */ +{ + RIPEMD160_CTX ctx; + u8 k_ipad[PAD+1]; /* inner padding - key XORd with ipad */ + u8 k_opad[PAD+1]; /* outer padding - key XORd with opad */ + u8 tk[TK]; + size_t text_len=strlen(text); + size_t key_len=strlen(key); + int i; + + if (key_len > PAD) { + RIPEMD160_CTX tctx; + RIPEMD160_Init(&tctx); + RIPEMD160_Update(&tctx, key, key_len); + RIPEMD160_Final(tk, &tctx); + key = tk; + key_len = TK; + } + + /* start out by storing key in pads */ + memset(k_ipad, 0, PAD); + memcpy(k_ipad, key, key_len); + memset(k_opad, 0, PAD); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i +#include +#include + +#include "typesx.h" +#include "sha1.h" + +#define PAD 64 +#define TK 20 + +void hmac_sha1(text, key, digest) + u8 *text; /* pointer to data stream */ + u8 *key; /* pointer to authentication key */ + u8 *digest; /* caller digest to be filled in */ +{ + SHA1_CTX ctx; + u8 k_ipad[PAD+1]; /* inner padding - key XORd with ipad */ + u8 k_opad[PAD+1]; /* outer padding - key XORd with opad */ + u8 tk[TK]; + size_t text_len=strlen(text); + size_t key_len=strlen(key); + int i; + + if (key_len > PAD) { + SHA1_CTX tctx; + SHA1_Init(&tctx); + SHA1_Update(&tctx, key, key_len); + SHA1_Final(tk, &tctx); + key = tk; + key_len = TK; + } + + /* start out by storing key in pads */ + memset(k_ipad, 0, PAD); + memcpy(k_ipad, key, key_len); + memset(k_opad, 0, PAD); + memcpy(k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i +#include #include "substdio.h" #include "subfd.h" #include "readwrite.h" @@ -5,7 +7,7 @@ char host[256]; -void main() +int main() { host[0] = 0; /* sigh */ gethostname(host,sizeof(host)); diff -urN qmail-1.03/idedit.c qmail-1.03-md/idedit.c --- qmail-1.03/idedit.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/idedit.c 2011-03-11 10:56:43.130083196 +0100 @@ -1,4 +1,5 @@ #include +#include #include #include #include "readwrite.h" @@ -9,6 +10,7 @@ #include "open.h" #include "seek.h" #include "fork.h" +#include "wait.h" #define FATAL "idedit: fatal: " #define WARNING "idedit: warning: " @@ -120,7 +122,7 @@ strerr_die3x(111,FATAL,"excessively large gid for ",group); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/install-big.c qmail-1.03-md/install-big.c --- qmail-1.03/install-big.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/install-big.c 2011-03-11 10:56:43.130083196 +0100 @@ -1,3 +1,4 @@ +#include "install.h" #include "auto_qmail.h" #include "auto_split.h" #include "auto_uids.h" @@ -145,115 +146,63 @@ c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","envelopes.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","envelopes.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","maildir.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","maildir.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","mbox.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","mbox.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","dot-qmail.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","dot-qmail.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-control.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-control.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-header.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-header.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-log.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-log.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","qmail-users.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","qmail-users.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man5","tcp-environ.5",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat5","tcp-environ.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","forgeries.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","forgeries.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","qmail-limits.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","qmail-limits.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man7","qmail.7",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat7","qmail.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","forward.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","forward.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","condredirect.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","condredirect.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","bouncesaying.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","bouncesaying.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","except.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","except.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildirmake.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildirmake.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildir2mbox.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildir2mbox.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","maildirwatch.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","maildirwatch.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","mailsubj.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","mailsubj.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","qreceipt.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","qreceipt.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","qbiff.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","qbiff.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","preline.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","preline.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","tcp-env.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","tcp-env.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-local.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-local.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-lspawn.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-lspawn.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-getpw.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-getpw.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-remote.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-remote.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-rspawn.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-rspawn.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-clean.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-clean.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-send.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-send.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-start.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-start.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","splogger.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","splogger.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-queue.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-queue.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-inject.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-newu.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-pw2u.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-pw2u.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qread.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qread.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qstat.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qstat.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-tcpok.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-tcpok.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-tcpto.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-tcpto.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-pop3d.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-pop3d.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-popup.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-popup.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmqpc.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmqpc.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmqpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmqpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-qmtpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-qmtpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-smtpd.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-smtpd.0",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man8","qmail-command.8",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat8","qmail-command.0",auto_uido,auto_gidq,0644); c(auto_qmail,"bin","dot-forward",auto_uido,auto_gidq,0755); c(auto_qmail,"man/man1","dot-forward.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","dot-forward.0",auto_uido,auto_gidq,0644); d(auto_qmail,"doc/fastforward",auto_uido,auto_gidq,0755); @@ -275,11 +224,4 @@ c(auto_qmail,"man/man1","setmaillist.1",auto_uido,auto_gidq,0644); c(auto_qmail,"man/man1","newinclude.1",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","fastforward.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","printforward.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","setforward.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","newaliases.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","printmaillist.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","setmaillist.0",auto_uido,auto_gidq,0644); - c(auto_qmail,"man/cat1","newinclude.0",auto_uido,auto_gidq,0644); } diff -urN qmail-1.03/install.c qmail-1.03-md/install.c --- qmail-1.03/install.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/install.c 2011-03-11 10:56:43.130083196 +0100 @@ -1,9 +1,11 @@ +#include "install.h" #include "substdio.h" #include "strerr.h" #include "error.h" #include "open.h" #include "readwrite.h" #include "exit.h" +#include "fifo.h" extern void hier(); @@ -152,7 +154,7 @@ strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); } -void main() +int main() { fdsourcedir = open_read("."); if (fdsourcedir == -1) diff -urN qmail-1.03/install.h qmail-1.03-md/install.h --- qmail-1.03/install.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/install.h 2011-03-11 10:56:43.130083196 +0100 @@ -0,0 +1,11 @@ +#include +#include +#include + +extern void hier(); +extern void perm(); +extern void h(); +extern void d(); +extern void p(); +extern void c(); +extern void z(); diff -urN qmail-1.03/instcheck.c qmail-1.03-md/instcheck.c --- qmail-1.03/instcheck.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/instcheck.c 2011-03-11 10:56:43.130083196 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include "strerr.h" #include "error.h" #include "readwrite.h" @@ -101,7 +102,7 @@ perm("",home,"/",file,S_IFREG,uid,gid,mode); } -void main() +int main() { hier(); _exit(0); diff -urN qmail-1.03/ipalloc.h qmail-1.03-md/ipalloc.h --- qmail-1.03/ipalloc.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/ipalloc.h 2011-03-11 10:56:43.130083196 +0100 @@ -2,8 +2,7 @@ #define IPALLOC_H #include "ip.h" - -struct ip_mx { struct ip_address ip; int pref; } ; +struct ip_mx { struct ip_address ip; int pref; char *fqdn; } ; #include "gen_alloc.h" diff -urN qmail-1.03/ip.c qmail-1.03-md/ip.c --- qmail-1.03/ip.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/ip.c 2011-03-11 10:56:43.133416638 +0100 @@ -8,7 +8,7 @@ { unsigned int len; unsigned int i; - + len = 0; i = fmt_ulong(s,(unsigned long) ip->d[0]); len += i; if (s) s += i; i = fmt_str(s,"."); len += i; if (s) s += i; @@ -27,7 +27,7 @@ unsigned int i; unsigned int len; unsigned long u; - + len = 0; i = scan_ulong(s,&u); if (!i) return 0; ip->d[0] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; @@ -44,7 +44,7 @@ struct ip_address *ip; { unsigned int len; - + if (*s != '[') return 0; len = ip_scan(s + 1,ip); if (!len) return 0; diff -urN qmail-1.03/ipme.c qmail-1.03-md/ipme.c --- qmail-1.03/ipme.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/ipme.c 2011-03-11 10:56:43.133416638 +0100 @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifndef SIOCGIFCONF /* whatever works */ #include @@ -46,6 +47,11 @@ ipme.len = 0; ix.pref = 0; + /* 0.0.0.0 is a special address which always refers to + * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a. + */ + byte_copy(&ix.ip,4,"\0\0\0\0"); + if (!ipalloc_append(&ipme,&ix)) { return 0; } if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1; len = 256; diff -urN qmail-1.03/ipmeprint.c qmail-1.03-md/ipmeprint.c --- qmail-1.03/ipmeprint.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/ipmeprint.c 2011-03-11 10:56:43.133416638 +0100 @@ -6,7 +6,7 @@ char temp[IPFMT]; -void main() +int main() { int j; switch(ipme_init()) diff -urN qmail-1.03/maildir2mbox.c qmail-1.03-md/maildir2mbox.c --- qmail-1.03/maildir2mbox.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/maildir2mbox.c 2011-03-11 10:56:43.133416638 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "readwrite.h" #include "prioq.h" #include "env.h" @@ -33,7 +35,7 @@ void die_nomem() { strerr_die2x(111,FATAL,"out of memory"); } -void main() +int main() { substdio ssin; substdio ssout; diff -urN qmail-1.03/maildir.c qmail-1.03-md/maildir.c --- qmail-1.03/maildir.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/maildir.c 2011-03-11 10:56:43.133416638 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include "prioq.h" #include "env.h" #include "stralloc.h" @@ -36,8 +37,7 @@ dir = opendir("tmp"); if (!dir) return; - while (d = readdir(dir)) - { + while ((d = readdir(dir))) { if (d->d_name[0] == '.') continue; if (!stralloc_copys(tmpname,"tmp/")) break; if (!stralloc_cats(tmpname,d->d_name)) break; @@ -45,7 +45,7 @@ if (stat(tmpname->s,&st) == 0) if (time > st.st_atime + 129600) unlink(tmpname->s); - } + } closedir(dir); } @@ -65,8 +65,7 @@ if (!dir) STRERR_SYS3(-1,maildir_scan_err,"unable to scan $MAILDIR/",subdir,": ") - while (d = readdir(dir)) - { + while ((d = readdir(dir))) { if (d->d_name[0] == '.') continue; pos = filenames->len; if (!stralloc_cats(filenames,subdir)) break; @@ -80,7 +79,7 @@ pe.id = pos; if (!prioq_insert(pq,&pe)) break; } - } + } closedir(dir); if (d) STRERR_SYS3(-1,maildir_scan_err,"unable to read $MAILDIR/",subdir,": ") @@ -95,7 +94,6 @@ { struct prioq_elt pe; datetime_sec time; - int r; if (!stralloc_copys(filenames,"")) return 0; while (prioq_min(pq,&pe)) prioq_delmin(pq); diff -urN qmail-1.03/maildirmake.c qmail-1.03-md/maildirmake.c --- qmail-1.03/maildirmake.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/maildirmake.c 2011-03-11 10:56:43.133416638 +0100 @@ -1,9 +1,11 @@ +#include +#include #include "strerr.h" #include "exit.h" #define FATAL "maildirmake: fatal: " -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/maildirwatch.c qmail-1.03-md/maildirwatch.c --- qmail-1.03/maildirwatch.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/maildirwatch.c 2011-03-11 10:56:43.133416638 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "getln.h" #include "substdio.h" #include "subfd.h" @@ -58,7 +60,7 @@ char inbuf[SUBSTDIO_INSIZE]; substdio ssin; -void main() +int main() { struct prioq_elt pe; int fd; diff -urN qmail-1.03/Makefile qmail-1.03-md/Makefile --- qmail-1.03/Makefile 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/Makefile 2011-03-11 10:56:43.133416638 +0100 @@ -399,6 +399,8 @@ ipalloc.o ip.o stralloc.a alloc.a error.a fs.a str.a \ -lresolv `cat socket.lib` ) >/dev/null 2>&1 \ && echo -lresolv || exit 0 ) > dns.lib + # use it allways! + echo "-lresolv" > dns.lib rm -f tryrsolv.o tryrsolv dns.o: \ @@ -408,10 +410,10 @@ dnscname: \ load dnscname.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \ -substdio.a error.a str.a fs.a dns.lib socket.lib +substdio.a error.a str.a fs.a strsalloc.o dns.lib socket.lib ./load dnscname dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \ - alloc.a substdio.a error.a str.a fs.a `cat dns.lib` `cat \ - socket.lib` + alloc.a substdio.a error.a str.a fs.a strsalloc.o \ + `cat dns.lib` `cat socket.lib` dnscname.o: \ compile dnscname.c substdio.h subfd.h substdio.h stralloc.h \ @@ -424,10 +426,10 @@ dnsfq: \ load dnsfq.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \ -substdio.a error.a str.a fs.a dns.lib socket.lib +substdio.a error.a str.a fs.a strsalloc.o dns.lib socket.lib ./load dnsfq dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \ - alloc.a substdio.a error.a str.a fs.a `cat dns.lib` `cat \ - socket.lib` + alloc.a substdio.a error.a str.a fs.a strsalloc.o `cat dns.lib` \ + `cat socket.lib` dnsfq.o: \ compile dnsfq.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ @@ -436,10 +438,10 @@ dnsip: \ load dnsip.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \ -substdio.a error.a str.a fs.a dns.lib socket.lib +substdio.a error.a str.a fs.a strsalloc.o dns.lib socket.lib ./load dnsip dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \ - alloc.a substdio.a error.a str.a fs.a `cat dns.lib` `cat \ - socket.lib` + alloc.a substdio.a error.a str.a fs.a strsalloc.o \ + `cat dns.lib` `cat socket.lib` dnsip.o: \ compile dnsip.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ @@ -448,10 +450,10 @@ dnsmxip: \ load dnsmxip.o dns.o dnsdoe.o ip.o ipalloc.o now.o stralloc.a alloc.a \ -substdio.a error.a str.a fs.a dns.lib socket.lib +substdio.a error.a str.a fs.a strsalloc.o dns.lib socket.lib ./load dnsmxip dns.o dnsdoe.o ip.o ipalloc.o now.o \ - stralloc.a alloc.a substdio.a error.a str.a fs.a `cat \ - dns.lib` `cat socket.lib` + stralloc.a alloc.a substdio.a error.a str.a fs.a strsalloc.o \ + `cat dns.lib` `cat socket.lib` dnsmxip.o: \ compile dnsmxip.c substdio.h subfd.h substdio.h stralloc.h \ @@ -461,10 +463,10 @@ dnsptr: \ load dnsptr.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \ -substdio.a error.a str.a fs.a dns.lib socket.lib +substdio.a error.a str.a fs.a strsalloc.o dns.lib socket.lib ./load dnsptr dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \ - alloc.a substdio.a error.a str.a fs.a `cat dns.lib` `cat \ - socket.lib` + alloc.a substdio.a error.a str.a fs.a strsalloc.o \ + `cat dns.lib` `cat socket.lib` dnsptr.o: \ compile dnsptr.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ @@ -1269,9 +1271,11 @@ qmail-pop3d: \ load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \ maildir.o prioq.o now.o env.a strerr.a sig.a open.a getln.a \ +out_log.o control.o base64.o auto_qmail.o \ stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib ./load qmail-pop3d commands.o case.a timeoutread.o \ timeoutwrite.o maildir.o prioq.o now.o env.a strerr.a sig.a \ + out_log.o control.o base64.o auto_qmail.o \ open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \ fs.a `cat socket.lib` @@ -1288,11 +1292,13 @@ qmail-popup: \ load qmail-popup.o commands.o timeoutread.o timeoutwrite.o now.o \ +control.o out_log.o qmail-sasl.o base64.o env.a getln.a open.a \ case.a fd.a sig.a wait.a stralloc.a alloc.a substdio.a error.a str.a \ -fs.a socket.lib - ./load qmail-popup commands.o timeoutread.o timeoutwrite.o \ - now.o case.a fd.a sig.a wait.a stralloc.a alloc.a \ - substdio.a error.a str.a fs.a `cat socket.lib` +fs.a socket.lib auto_qmail.o sha1.o hmac_sha1.o ucspitls.o + ./load qmail-popup commands.o timeoutread.o timeoutwrite.o ucspitls.o \ + control.o out_log.o qmail-sasl.o base64.o env.a getln.a open.a \ + now.o case.a fd.a sig.a wait.a stralloc.a alloc.a auto_qmail.o \ + substdio.a error.a str.a fs.a sha1.o hmac_sha1.o `cat socket.lib` qmail-popup.0: \ qmail-popup.8 @@ -1368,13 +1374,15 @@ qmail-qmtpd: \ load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \ +realrcptto.o auto_break.o auto_usera.o \ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a open.a \ getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \ -str.a fs.a auto_qmail.o +str.a fs.a auto_qmail.o ./load qmail-qmtpd rcpthosts.o control.o constmap.o \ + realrcptto.o auto_break.o auto_usera.o \ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ datetime.a open.a getln.a sig.a case.a env.a stralloc.a \ - alloc.a substdio.a error.a str.a fs.a auto_qmail.o + alloc.a substdio.a error.a str.a fs.a auto_qmail.o qmail-qmtpd.0: \ qmail-qmtpd.8 @@ -1421,11 +1429,13 @@ 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 triggerpull.o fmtqfn.o now.o \ +str.a fs.a auto_qmail.o auto_split.o auto_uids.o control.o stralloc.a \ +constmap.o open.a getln.a case.a alloc.a + ./load qmail-queue triggerpull.o fmtqfn.o now.o scan_ulong.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 + auto_split.o auto_uids.o control.o stralloc.a constmap.o \ + open.a getln.a case.a alloc.a qmail-queue.0: \ qmail-queue.8 @@ -1439,35 +1449,38 @@ qmail-remote: \ load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \ -timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \ +timeoutconn.o tcpto.o now.o dns.o ip.o strsalloc.o ipalloc.o ipme.o quote.o \ ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \ +md5.o sha1.o ripemd.o hmac_ripemd.o hmac_md5.o hmac_sha1.o base64.o \ substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib ./load qmail-remote control.o constmap.o timeoutread.o \ - timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \ - ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \ + timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o strsalloc.o \ + md5.o sha1.o ripemd.o hmac_ripemd.o hmac_md5.o hmac_sha1.o \ + ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a base64.o \ lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \ - str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib` + str.a fs.a auto_qmail.o `cat dns.lib` `cat socket.lib` qmail-remote.0: \ qmail-remote.8 nroff -man qmail-remote.8 > qmail-remote.0 qmail-remote.o: \ -compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \ +compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h control.h \ subfd.h substdio.h scan.h case.h error.h auto_qmail.h control.h dns.h \ -alloc.h quote.h ip.h ipalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h \ -gen_alloc.h gen_allocdefs.h str.h now.h datetime.h exit.h constmap.h \ -tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h +alloc.h quote.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ipme.h ip.h \ +ipalloc.h strsalloc.h gen_alloc.h gen_allocdefs.h str.h now.h datetime.h \ +exit.h constmap.h tcpto.h readwrite.h timeoutconn.h timeoutread.h \ +timeoutwrite.h ./compile qmail-remote.c qmail-rspawn: \ load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \ seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a str.a \ -auto_qmail.o auto_uids.o auto_spawn.o +auto_qmail.o auto_uids.o auto_spawn.o fmt_ulong.o ./load qmail-rspawn spawn.o tcpto_clean.o now.o coe.o \ sig.a open.a seek.a lock.a wait.a fd.a stralloc.a alloc.a \ substdio.a error.a str.a auto_qmail.o auto_uids.o \ - auto_spawn.o + auto_spawn.o fmt_ulong.o qmail-rspawn.0: \ qmail-rspawn.8 @@ -1483,12 +1496,12 @@ trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \ datetime.a case.a ndelay.a getln.a wait.a seek.a fd.a sig.a open.a \ lock.a stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o \ -auto_split.o +auto_split.o env.a ./load qmail-send qsutil.o control.o constmap.o newfield.o \ prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \ qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \ wait.a seek.a fd.a sig.a open.a lock.a stralloc.a alloc.a \ - substdio.a error.a str.a fs.a auto_qmail.o auto_split.o + substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a qmail-send.0: \ qmail-send.8 @@ -1533,15 +1546,21 @@ qmail-smtpd: \ load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \ +out_log.o timeoutconn.o qmail-p0f.o qmail-sasl.o base64.o dns.o \ +realrcptto.o strsalloc.o ndelay.a auto_break.o auto_usera.o \ +sha1.o hmac_sha1.o ucspitls.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \ date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \ open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \ fs.a auto_qmail.o socket.lib ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ + out_log.o timeoutconn.o qmail-p0f.o qmail-sasl.o base64.o \ + dns.o realrcptto.o strsalloc.o ndelay.a auto_break.o \ + auto_usera.o sha1.o hmac_sha1.o ucspitls.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \ datetime.a getln.a open.a sig.a case.a env.a stralloc.a \ - alloc.a substdio.a error.a str.a fs.a auto_qmail.o `cat \ + alloc.a substdio.a error.a str.a fs.a auto_qmail.o `cat \ socket.lib` qmail-smtpd.0: \ @@ -1888,6 +1907,8 @@ ( ( ./compile trylsock.c && \ ./load trylsock -lsocket -lnsl ) >/dev/null 2>&1 \ && echo -lsocket -lnsl || exit 0 ) > socket.lib + # use it allways! + echo "-lresolv" > socket.lib rm -f trylsock.o trylsock spawn.o: \ @@ -1914,10 +1935,10 @@ str.a: \ makelib str_len.o str_diff.o str_diffn.o str_cpy.o str_chr.o \ str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o \ -byte_cr.o byte_zero.o +byte_cr.o byte_zero.o str_cpyb.o ./makelib str.a str_len.o str_diff.o str_diffn.o str_cpy.o \ str_chr.o str_rchr.o str_start.o byte_chr.o byte_rchr.o \ - byte_diff.o byte_copy.o byte_cr.o byte_zero.o + byte_diff.o byte_copy.o byte_cr.o byte_zero.o str_cpyb.o str_chr.o: \ compile str_chr.c str.h @@ -2066,9 +2087,10 @@ tcp-env: \ load tcp-env.o dns.o remoteinfo.o timeoutread.o timeoutwrite.o \ +strsalloc.o \ timeoutconn.o ip.o ipalloc.o case.a ndelay.a sig.a env.a getopt.a \ stralloc.a alloc.a substdio.a error.a str.a fs.a dns.lib socket.lib - ./load tcp-env dns.o remoteinfo.o timeoutread.o \ + ./load tcp-env dns.o remoteinfo.o timeoutread.o strsalloc.o \ timeoutwrite.o timeoutconn.o ip.o ipalloc.o case.a ndelay.a \ sig.a env.a getopt.a stralloc.a alloc.a substdio.a error.a \ str.a fs.a `cat dns.lib` `cat socket.lib` @@ -2139,3 +2161,60 @@ wait_pid.o: \ compile wait_pid.c error.h haswaitp.h ./compile wait_pid.c + +# new targets +strsalloc.o: \ +compile strsalloc.c + ./compile strsalloc.c + +str_cpyb.o: \ +compile str_cpyb.c + ./compile str_cpyb.c + +md5.o: \ +compile md5.c md5.h + ./compile md5.c + +sha1.o: \ +compile sha1.c sha1.h + ./compile sha1.c + +ripemd.o: \ +compile ripemd.c ripemd.h + ./compile ripemd.c + +hmac_ripemd.o: \ +compile hmac_ripemd.c hmac.h + ./compile hmac_ripemd.c + +hmac_md5.o: \ +compile hmac_md5.c hmac.h + ./compile hmac_md5.c + +hmac_sha1.o: \ +compile hmac_sha1.c hmac.h + ./compile hmac_sha1.c + +base64.o: \ +compile base64.c base64.h + ./compile base64.c + +out_log.o: \ +compile out_log.c out_log.h + ./compile out_log.c + +qmail-sasl.o: \ +compile qmail-sasl.c qmail-sasl.h + ./compile qmail-sasl.c + +realrcptto.o: \ +compile realrcptto.c + ./compile realrcptto.c + +qmail-p0f.o: \ +compile qmail-p0f.c qmail-p0f.h + ./compile qmail-p0f.c + +ucspitls.o: \ +compile ucspitls.c ucspitls.h + ./compile ucspitls.c diff -urN qmail-1.03/md5.c qmail-1.03-md/md5.c --- qmail-1.03/md5.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/md5.c 2011-03-11 10:56:43.133416638 +0100 @@ -0,0 +1,259 @@ + +/** + * Copyright (C) 2005-2006 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Written by Solar Designer in 2001 and placed in the public domain. + * There's absolutely no warranty. + */ + +#include "md5.h" + +/** + * MD5 Message-Digest Algorithm - rfc 1321 + */ + +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures which tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__vax__) +#define SET(n) (*(u32 *)&ptr[(n) * 4]) +#define GET(n) SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (u32)ptr[(n) * 4] | \ + ((u32)ptr[(n) * 4 + 1] << 8) | \ + ((u32)ptr[(n) * 4 + 2] << 16) | \ + ((u32)ptr[(n) * 4 + 3] << 24)) +#define GET(n) (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There're no alignment requirements. + */ +static void *body(MD5_CTX *ctx, void *data, u32 size) +{ + u8 *ptr=data; + u32 a,b,c,d; + u32 saved_a, saved_b, saved_c, saved_d; + + ptr = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; ctx->b = b; ctx->c = c; ctx->d = d; + + return ptr; +} + +void MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; ctx->hi = 0; +} + +void MD5_Update(MD5_CTX *ctx, void *data, u32 size) +{ + u32 saved_lo, used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (u8 *)data + free; + size -= free; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(u32)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +void MD5_Final(u8 *result, MD5_CTX *ctx) +{ + u32 used, free; + + used = ctx->lo & 0x3f; + ctx->buffer[used++] = 0x80; + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + + memset(ctx, 0, sizeof(ctx)); +} +#undef F +#undef G +#undef H +#undef I +#undef SET +#undef GET +#undef STEP diff -urN qmail-1.03/md5.h qmail-1.03-md/md5.h --- qmail-1.03/md5.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/md5.h 2011-03-11 10:56:43.143416651 +0100 @@ -0,0 +1,38 @@ +#ifndef SW_MD5_H +#define SW_MD5_H + +/** + * Copyright (C) 2005-2006 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Written by Solar Designer in 2001 and placed in the public domain. + * There's absolutely no warranty. + */ + +#include "typesx.h" +#include + +typedef struct { + u32 lo, hi; + u32 a,b,c,d; + u32 block[16]; + u8 buffer[64]; +} MD5_CTX; + +extern void MD5_Init(MD5_CTX *ctx); +extern void MD5_Update(MD5_CTX *ctx, void *data, u32 size); +extern void MD5_Final(u8 *result, MD5_CTX *ctx); + +#endif diff -urN qmail-1.03/newfield.c qmail-1.03-md/newfield.c --- qmail-1.03/newfield.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/newfield.c 2011-03-11 10:56:43.143416651 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "fmt.h" #include "datetime.h" #include "stralloc.h" diff -urN qmail-1.03/out_log.c qmail-1.03-md/out_log.c --- qmail-1.03/out_log.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/out_log.c 2011-03-11 10:56:43.143416651 +0100 @@ -0,0 +1,72 @@ +#include +#include + +#include "substdio.h" +#include "now.h" +#include "fmt.h" +#include "out_log.h" + +void Out(char *s) +{ substdio_puts(&ssout,s); return;} + +void Outn(char *s, int len) +{ substdio_put(&ssout,s,len); return; } + +void Log(char *s) +{ if (ctl_log_out > 0) if (sserr.fd>0) substdio_puts(&sserr,s); return; } + +void Logn(char *s, int len) +{ if (ctl_log_out > 0) if (sserr.fd>0) substdio_put(&sserr,s,len); return; } + +void out(char *s) { Out(s); Log(s); return; } +void outn(char *s, int len) { Outn(s,len); Logn(s,len); return; } + +int flush(void) +{ + int r1,r2; + r1=substdio_flush(&ssout); + r2=substdio_flush(&sserr); + if (r1 == -1 || r2 == -1) return -1; + return 0; +} + +void doname(void) +{ + static int pid=0; + char pidstr[FMT_ULONG]; + + if (!pid) { pid=getpid(); } + pidstr[fmt_ulong(pidstr,pid)] = 0; + Log(name);Log(": pid ");Log(pidstr);Log(" "); + return; +} + +void doserv(void) +{ + doname(); Log("S: "); + return; +} + +void doeol(void) +{ + Out("\r"); out("\n"); + return; +} + +void out_err(char *s) +{ + doserv(); out(s); doeol(); flush(); + return; +} + +void dounique(void) +{ + char *s=unique; + + s += fmt_uint(s,getpid()); + s += fmt_str(s,"."); + s += fmt_ulong(s,(unsigned long) now()); + s += fmt_str(s,"@"); + s = 0; + return; +} diff -urN qmail-1.03/out_log.h qmail-1.03-md/out_log.h --- qmail-1.03/out_log.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/out_log.h 2011-03-11 10:56:43.146749923 +0100 @@ -0,0 +1,37 @@ +#include "substdio.h" +#include "fmt.h" + +#define VERSION "md25" + +/* have to be provided by qmail-smtpd, qmail-popup and qmail-remote */ +extern char *name; +extern char unique[]; +extern char ssinbuf[]; +extern char ssoutbuf[]; +extern char sserrbuf[]; + +extern int ctl_log_out; + +extern substdio ssin; +extern substdio ssout; +extern substdio sserr; + +/* overview: + * Log() = append to logfile + * Out() = append to server output + * out() = append to logfile+server output + * flush() = flush logfile+server buffers + */ +extern void Log(char *s); +extern void Out(char *s); +extern void out(char *s); +extern void Logn(char *s, int len); +extern void Outn(char *s, int len); +extern void outn(char *s, int len); + +extern int flush(void); +extern void doname(void); /* logs 'name of prog' */ +extern void doserv(void); /* logs 'name: S: ' */ +extern void doeol(void); /* logs a , but write to stdout */ +extern void dounique(void); /* fill unique */ +extern void out_err(char *s); /* name: S: *s EOL + flush() */ diff -urN qmail-1.03/predate.c qmail-1.03-md/predate.c --- qmail-1.03/predate.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/predate.c 2011-03-11 10:57:03.780477740 +0100 @@ -10,6 +10,7 @@ #include "subfd.h" #include "readwrite.h" #include "exit.h" +#include "sig.h" #define FATAL "predate: fatal: " @@ -20,7 +21,7 @@ char num[FMT_ULONG]; char outbuf[1024]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/preline.1 qmail-1.03-md/preline.1 --- qmail-1.03/preline.1 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/preline.1 2011-03-11 10:56:43.146749923 +0100 @@ -52,6 +52,9 @@ Do not include the .B Return-Path line. +.TP +.B \-p +Ignore a possible errno = EPIPE! .SH "SEE ALSO" mbox(5), qmail-command(8) diff -urN qmail-1.03/preline.c qmail-1.03-md/preline.c --- qmail-1.03/preline.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/preline.c 2011-03-11 10:56:43.146749923 +0100 @@ -20,13 +20,14 @@ int flagufline = 1; char *ufline; int flagrpline = 1; char *rpline; int flagdtline = 1; char *dtline; +int flagpipe = 0; char outbuf[SUBSTDIO_OUTSIZE]; char inbuf[SUBSTDIO_INSIZE]; substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof outbuf); substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -41,7 +42,7 @@ if (!(rpline = env_get("RPLINE"))) die_usage(); if (!(dtline = env_get("DTLINE"))) die_usage(); - while ((opt = getopt(argc,argv,"frdFRD")) != opteof) + while ((opt = getopt(argc,argv,"frdFRDp")) != opteof) switch(opt) { case 'f': flagufline = 0; break; case 'r': flagrpline = 0; break; @@ -49,6 +50,7 @@ case 'F': flagufline = 1; break; case 'R': flagrpline = 1; break; case 'D': flagdtline = 1; break; + case 'p': flagpipe = 1; break; default: die_usage(); } argc -= optind; @@ -77,8 +79,10 @@ if (flagufline) substdio_bputs(&ssout,ufline); if (flagrpline) substdio_bputs(&ssout,rpline); if (flagdtline) substdio_bputs(&ssout,dtline); - if (substdio_copy(&ssout,&ssin) != 0) - strerr_die2sys(111,FATAL,"unable to copy input: "); + if (substdio_copy(&ssout,&ssin) != 0) { + if (errno!=error_pipe || !flagpipe) + strerr_die2sys(111,FATAL,"unable to copy input: "); + } substdio_flush(&ssout); close(1); diff -urN qmail-1.03/prot.c qmail-1.03-md/prot.c --- qmail-1.03/prot.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/prot.c 2011-03-11 10:56:43.146749923 +0100 @@ -1,16 +1,20 @@ +#include +#include +#include #include "hasshsgr.h" #include "prot.h" /* XXX: there are more portability problems here waiting to leap out at me */ -int prot_gid(gid) int gid; +int prot_gid(int gid) { #ifdef HASSHORTSETGROUPS short x[2]; x[0] = gid; x[1] = 73; /* catch errors */ if (setgroups(1,x) == -1) return -1; #else - if (setgroups(1,&gid) == -1) return -1; + const gid_t G=gid; /* fix warning of gcc */ + if (setgroups(1,&G) == -1) return -1; #endif return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ } diff -urN qmail-1.03/qbiff.c qmail-1.03-md/qbiff.c --- qmail-1.03/qbiff.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qbiff.c 2011-03-11 10:56:43.146749923 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include #ifndef UTMP_FILE #ifdef _PATH_UTMP @@ -50,7 +51,7 @@ } void finishheader() { ; } -void main() +int main() { char *user; char *sender; diff -urN qmail-1.03/qmail.c qmail-1.03-md/qmail.c --- qmail-1.03/qmail.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail.c 2011-03-11 10:56:43.146749923 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "substdio.h" #include "readwrite.h" #include "wait.h" @@ -6,8 +8,17 @@ #include "fd.h" #include "qmail.h" #include "auto_qmail.h" +#include "env.h" -static char *binqqargs[2] = { "bin/qmail-queue", 0 } ; +static char *binqqargs[2] = { 0, 0 } ; + +static void setup_qqargs() +{ + if(!binqqargs[0]) + binqqargs[0] = env_get("QMAILQUEUE"); + if(!binqqargs[0]) + binqqargs[0] = "bin/qmail-queue"; +} int qmail_open(qq) struct qmail *qq; @@ -15,6 +26,8 @@ int pim[2]; int pie[2]; + setup_qqargs(); + if (pipe(pim) == -1) return -1; if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; } @@ -88,38 +101,38 @@ close(qq->fde); if (wait_pid(&wstat,qq->pid) != qq->pid) - return "Zqq waitpid surprise (#4.3.0)"; + return "Z4.3.0 qq waitpid surprise"; if (wait_crashed(wstat)) - return "Zqq crashed (#4.3.0)"; + return "Z4.3.0 qq crashed"; exitcode = wait_exitcode(wstat); switch(exitcode) { case 115: /* compatibility */ - case 11: return "Denvelope address too long for qq (#5.1.3)"; - case 31: return "Dmail server permanently rejected message (#5.3.0)"; - case 51: return "Zqq out of memory (#4.3.0)"; - case 52: return "Zqq timeout (#4.3.0)"; - case 53: return "Zqq write error or disk full (#4.3.0)"; + case 11: return "D5.1.3 envelope address too long for qq"; + case 31: return "D5.3.0 mail server permanently rejected message"; + case 51: return "Z4.3.0 qq out of memory"; + case 52: return "Z4.3.0 qq timeout"; + case 53: return "Z4.3.0 qq write error or disk full"; case 0: if (!qq->flagerr) return ""; /* fall through */ - case 54: return "Zqq read error (#4.3.0)"; - case 55: return "Zqq unable to read configuration (#4.3.0)"; - case 56: return "Zqq trouble making network connection (#4.3.0)"; - case 61: return "Zqq trouble in home directory (#4.3.0)"; + case 54: return "Z4.3.0 qq read error"; + case 55: return "Z4.3.0 qq unable to read configuration"; + case 56: return "Z4.3.0 qq trouble making network connection"; + case 61: return "Z4.3.0 qq trouble in home directory"; case 63: case 64: case 65: case 66: - case 62: return "Zqq trouble creating files in queue (#4.3.0)"; - case 71: return "Zmail server temporarily rejected message (#4.3.0)"; - case 72: return "Zconnection to mail server timed out (#4.4.1)"; - case 73: return "Zconnection to mail server rejected (#4.4.1)"; - case 74: return "Zcommunication with mail server failed (#4.4.2)"; + case 62: return "Z4.3.0 qq trouble creating files in queue"; + case 71: return "Z4.3.0 mail server temporarily rejected message"; + case 72: return "Z4.4.1 connection to mail server timed out"; + case 73: return "Z4.4.1 connection to mail server rejected"; + case 74: return "Z4.4.2 communication with mail server failed"; case 91: /* fall through */ - case 81: return "Zqq internal bug (#4.3.0)"; - case 120: return "Zunable to exec qq (#4.3.0)"; + case 81: return "Z4.3.0 qq internal bug"; + case 120:return "Z4.3.0 unable to exec qq"; default: if ((exitcode >= 11) && (exitcode <= 40)) - return "Dqq permanent problem (#5.3.0)"; - return "Zqq temporary problem (#4.3.0)"; + return "D5.3.0 qq permanent problem"; + return "Z4.3.0 qq temporary problem"; } } diff -urN qmail-1.03/qmail-clean.c qmail-1.03-md/qmail-clean.c --- qmail-1.03/qmail-clean.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-clean.c 2011-03-11 10:56:43.146749923 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include "readwrite.h" #include "sig.h" #include "now.h" @@ -31,7 +32,7 @@ time = now(); dir = opendir("pid"); if (!dir) return; - while (d = readdir(dir)) + while ((d = readdir(dir))) { if (str_equal(d->d_name,".")) continue; if (str_equal(d->d_name,"..")) continue; @@ -49,7 +50,7 @@ void respond(s) char *s; { if (substdio_putflush(subfdoutsmall,s,1) == -1) _exit(100); } -void main() +int main() { int i; int match; @@ -73,22 +74,26 @@ if (line.len < 7) { respond("x"); continue; } if (line.len > 100) { respond("x"); continue; } if (line.s[line.len - 1]) { respond("x"); continue; } /* impossible */ - for (i = 5;i < line.len - 1;++i) + for (i = line.len - 2;i > 4;--i) + { + if (line.s[i] == '/') break; if ((unsigned char) (line.s[i] - '0') > 9) { respond("x"); continue; } - if (!scan_ulong(line.s + 5,&id)) { respond("x"); continue; } + } + if (line.s[i] == '/') + if (!scan_ulong(line.s + i + 1,&id)) { respond("x"); continue; } if (byte_equal(line.s,5,"foop/")) { #define U(prefix,flag) fmtqfn(fnbuf,prefix,id,flag); \ if (unlink(fnbuf) == -1) if (errno != error_noent) { respond("!"); continue; } - U("intd/",0) + U("intd/",1) U("mess/",1) respond("+"); } else if (byte_equal(line.s,4,"todo/")) { - U("intd/",0) - U("todo/",0) + U("intd/",1) + U("todo/",1) respond("+"); } else diff -urN qmail-1.03/qmail-control.9 qmail-1.03-md/qmail-control.9 --- qmail-1.03/qmail-control.9 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-control.9 2011-03-11 10:56:43.146749923 +0100 @@ -21,6 +21,7 @@ Comments are allowed in .IR badmailfrom , +.IR badmailto , .IR locals , .IR percenthack , .IR qmqpservers , @@ -30,6 +31,13 @@ .IR virtualdomains . Trailing spaces and tabs are allowed in any control file. +Regular expressions are allowed in +.IR badmailfrom +and +.IR badmailto . +This can be used for filtering out some spam, see +QMAIL/doc/README.qregex for more details! + The following table lists all control files other than .IR me . @@ -40,7 +48,9 @@ .ta 5c 10c control default used by -.I badmailfrom \fR(none) \fRqmail-smtpd +.I badmailfrom \fR(none) \fRqmail-smtpd ($BADMAILFROM) +.I badmailto \fR(none) \fRqmail-smtpd ($BADMAILTO) +.I badhelo \fR(none) \fRqmail-smtpd ($BADHELO) .I bouncefrom \fRMAILER-DAEMON \fRqmail-send .I bouncehost \fIme \fRqmail-send .I concurrencylocal \fR10 \fRqmail-send @@ -55,7 +65,9 @@ .I idhost \fIme \fRqmail-inject .I localiphost \fIme \fRqmail-smtpd .I locals \fIme \fRqmail-send +.I mfcheck \fR(none) \fRqmail-smtpd ($MFCHECK) .I morercpthosts \fR(none) \fRqmail-smtpd +.I outgoingip \fR0.0.0.0 \fRqmail-remote .I percenthack \fR(none) \fRqmail-send .I plusdomain \fIme \fRqmail-inject .I qmqpservers \fR(none) \fRqmail-qmqpc @@ -63,10 +75,25 @@ .I rcpthosts \fR(none) \fRqmail-smtpd .I smtpgreeting \fIme \fRqmail-smtpd .I smtproutes \fR(none) \fRqmail-remote +.I spfbehavior \fR0 \fRqmail-smtpd +.I spfexp \fR(default) \fRqmail-smtpd +.I spfguess \fR(none) \fRqmail-smtpd +.I spfrules \fR(none) \fRqmail-smtpd .I timeoutconnect \fR60 \fRqmail-remote .I timeoutremote \fR1200 \fRqmail-remote .I timeoutsmtpd \fR1200 \fRqmail-smtpd +.I tarpitcount \fR(none) \fRqmail-smtpd ($TARPITCOUNT) +.I tarpitdelay \fR(none) \fRqmail-smtpd ($TARPITDELAY) .I virtualdomains \fR(none) \fRqmail-send + +.I clientcert.pem \fR(none) \fRqmail-remote +.I tlsclientciphers \fR(none) \fRqmail-remote +.I tlshosts/FQDN.pem \fR(none) \fRqmail-remote +.I clientca.pem \fR(none) \fRqmail-smtpd +.I rsa512.pem \fR(none) \fRqmail-smtpd +.I servercert.pem \fR(none) \fRqmail-smtpd +.I tlsclients \fR(none) \fRqmail-smtpd +.I tlsserverciphers \fR(none) \fRqmail-smtpd .fi .RE .SH "SEE ALSO" diff -urN qmail-1.03/qmail-getpw.c qmail-1.03-md/qmail-getpw.c --- qmail-1.03/qmail-getpw.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-getpw.c 2011-03-11 10:56:43.146749923 +0100 @@ -36,17 +36,19 @@ errno = 0; pw = getpwnam(username); if (errno == error_txtbsy) _exit(QLX_SYS); - if (pw) - if (pw->pw_uid) + if (pw) { + if (pw->pw_uid) { if (stat(pw->pw_dir,&st) == 0) { if (st.st_uid == pw->pw_uid) { dash = ""; if (*extension) { ++extension; dash = "-"; } return 1; } - } - else + } else { if (error_temp(errno)) _exit(QLX_NFS); + } + } + } } if (extension == local) return 0; --extension; @@ -55,7 +57,7 @@ char num[FMT_ULONG]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/qmail-inject.c qmail-1.03-md/qmail-inject.c --- qmail-1.03/qmail-inject.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-inject.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "sig.h" #include "substdio.h" #include "stralloc.h" @@ -55,7 +57,7 @@ void put(s,len) char *s; int len; { if (flagqueue) qmail_put(&qqt,s,len); else substdio_put(subfdout,s,len); } -void puts(s) char *s; { put(s,str_len(s)); } +void out(s) char *s; { put(s,str_len(s)); } void perm() { _exit(100); } void temp() { _exit(111); } @@ -94,8 +96,7 @@ if (!flagqueue) substdio_flush(subfdout); - if (flagqueue) - { + if (flagqueue) { int i; if (!stralloc_0(&sender)) die_nomem(); @@ -106,7 +107,7 @@ if (!stralloc_0(&reciplist.sa[i])) die_nomem(); qmail_to(&qqt,reciplist.sa[i].s); } - if (flagrh) + if (flagrh) { if (flagresent) for (i = 0;i < hrrlist.len;++i) { @@ -119,23 +120,24 @@ if (!stralloc_0(&hrlist.sa[i])) die_nomem(); qmail_to(&qqt,hrlist.sa[i].s); } + } qqx = qmail_close(&qqt); - if (*qqx) + if (*qqx) { if (*qqx == 'D') { substdio_puts(subfderr,"qmail-inject: fatal: "); substdio_puts(subfderr,qqx + 1); substdio_puts(subfderr,"\n"); substdio_flush(subfderr); perm(); - } - else { + } else { substdio_puts(subfderr,"qmail-inject: fatal: "); substdio_puts(subfderr,qqx + 1); substdio_puts(subfderr,"\n"); substdio_flush(subfderr); temp(); } + } } _exit(0); @@ -477,12 +479,11 @@ void dodefaultreturnpath() { if (!stralloc_copys(&hackedruser,mailruser)) die_nomem(); - if (flaghackmess) - { + if (flaghackmess) { if (!stralloc_cats(&hackedruser,"-")) die_nomem(); - if (!stralloc_catb(&hackedruser,strnum,fmt_ulong(strnum,(unsigned long) starttime))) die_nomem(); + if (!stralloc_catb(&hackedruser,strnum,fmt_ulong(strnum,(unsigned long)starttime))) die_nomem(); if (!stralloc_cats(&hackedruser,".")) die_nomem(); - if (!stralloc_catb(&hackedruser,strnum,fmt_ulong(strnum,(unsigned long) getpid()))) die_nomem(); + if (!stralloc_catb(&hackedruser,strnum,fmt_ulong(strnum,(unsigned long)getpid()))) die_nomem(); } if (flaghackrecip) if (!stralloc_cats(&hackedruser,"-")) die_nomem(); @@ -549,16 +550,16 @@ if (i == tocclist.len) return; - puts("Mail-Followup-To: "); + out("Mail-Followup-To: "); i = tocclist.len; while (i--) { if (!stralloc_copy(&sa,&tocclist.sa[i])) die_nomem(); if (!stralloc_0(&sa)) die_nomem(); if (!quote2(&sa2,sa.s)) die_nomem(); put(sa2.s,sa2.len); - if (i) puts(",\n "); + if (i) out(",\n "); } - puts("\n"); + out("\n"); } void finishheader() @@ -580,9 +581,9 @@ if (!stralloc_0(&sa)) die_nomem(); if (!quote2(&sa2,sa.s)) die_nomem(); - puts("Return-Path: <"); + out("Return-Path: <"); put(sa2.s,sa2.len); - puts(">\n"); + out(">\n"); } /* could check at this point whether there are any recipients */ @@ -594,23 +595,23 @@ if (!htypeseen[H_R_DATE]) { if (!newfield_datemake(starttime)) die_nomem(); - puts("Resent-"); + out("Resent-"); put(newfield_date.s,newfield_date.len); } if (!htypeseen[H_R_MESSAGEID]) { if (!newfield_msgidmake(control_idhost.s,control_idhost.len,starttime)) die_nomem(); - puts("Resent-"); + out("Resent-"); put(newfield_msgid.s,newfield_msgid.len); } if (!htypeseen[H_R_FROM]) { defaultfrommake(); - puts("Resent-"); + out("Resent-"); put(defaultfrom.s,defaultfrom.len); } if (!htypeseen[H_R_TO] && !htypeseen[H_R_CC]) - puts("Resent-Cc: recipient list not shown: ;\n"); + out("Resent-Cc: recipient list not shown: ;\n"); } else { @@ -630,7 +631,7 @@ put(defaultfrom.s,defaultfrom.len); } if (!htypeseen[H_TO] && !htypeseen[H_CC]) - puts("Cc: recipient list not shown: ;\n"); + out("Cc: recipient list not shown: ;\n"); finishmft(); } @@ -682,7 +683,7 @@ #define RECIP_HEADER 3 #define RECIP_AH 4 -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -770,4 +771,5 @@ if (headerbody(subfdin,doheaderfield,finishheader,dobody) == -1) die_read(); exitnicely(); + return 0; /* gcc happyness */ } diff -urN qmail-1.03/qmail-local.c qmail-1.03-md/qmail-local.c --- qmail-1.03/qmail-local.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-local.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,5 +1,7 @@ #include #include +#include +#include #include "readwrite.h" #include "sig.h" #include "env.h" @@ -29,17 +31,18 @@ #include "gfrom.h" #include "auto_patrn.h" -void usage() { strerr_die1x(100,"qmail-local: usage: qmail-local [ -nN ] user homedir local dash ext domain sender aliasempty"); } +char *overquota = "5.2.2 Recipient's mailbox is full, message returned to sender."; -void temp_nomem() { strerr_die1x(111,"Out of memory. (#4.3.0)"); } -void temp_rewind() { strerr_die1x(111,"Unable to rewind message. (#4.3.0)"); } -void temp_childcrashed() { strerr_die1x(111,"Aack, child crashed. (#4.3.0)"); } -void temp_fork() { strerr_die3x(111,"Unable to fork: ",error_str(errno),". (#4.3.0)"); } -void temp_read() { strerr_die3x(111,"Unable to read message: ",error_str(errno),". (#4.3.0)"); } -void temp_slowlock() -{ strerr_die1x(111,"File has been locked for 30 seconds straight. (#4.3.0)"); } -void temp_qmail(fn) char *fn; -{ strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.3.0)"); } +void usage() +{ strerr_die1x(100,"qmail-local: usage: qmail-local [ -nN ] user homedir local dash ext domain sender aliasempty"); } + +void temp_nomem() { strerr_die1x(111,"4.3.0 out of memory"); } +void temp_rewind() { strerr_die1x(111,"4.3.0 unable to rewind message"); } +void temp_childcrashed() { strerr_die1x(111,"4.3.0 aack, child crashed"); } +void temp_fork() { strerr_die2x(111,"4.3.0 unable to fork: ",error_str(errno)); } +void temp_read() { strerr_die2x(111,"4.3.0 unable to read message: ",error_str(errno)); } +void temp_slowlock() { strerr_die1x(111,"4.3.0 file has been locked for 30 seconds straight"); } +void temp_qmail(fn) char *fn; { strerr_die4x(111,"4.3.0 unable to open ",fn,": ",error_str(errno)); } int flagdoit; int flag99; @@ -110,7 +113,10 @@ alarm(86400); fd = open_excl(fntmptph); - if (fd == -1) _exit(1); + if (fd == -1) { + if (errno == error_dquot) _exit(5); + else _exit(1); + } substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); @@ -128,10 +134,17 @@ if (close(fd) == -1) goto fail; /* NFS dorks */ if (link(fntmptph,fnnewtph) == -1) goto fail; + if ((fd = open(fnnewtph, O_RDONLY)) < 0 || fsync(fd) < 0 || close(fd) < 0) + goto fail; /* if it was error_exist, almost certainly successful; i hate NFS */ tryunlinktmp(); _exit(0); - fail: tryunlinktmp(); _exit(1); + fail: + if (errno == error_dquot) { + tryunlinktmp(); _exit(5); + } else { + tryunlinktmp(); _exit(1); + } } /* end child process */ @@ -159,10 +172,11 @@ switch(wait_exitcode(wstat)) { case 0: break; - case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)"); - case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)"); - case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)"); - default: strerr_die1x(111,"Temporary error on maildir delivery. (#4.3.0)"); + case 2: strerr_die1x(111,"4.2.1 unable to chdir to maildir"); + case 3: strerr_die1x(111,"4.3.0 timeout on maildir delivery"); + case 4: strerr_die1x(111,"4.3.0 unable to read message"); + case 5: strerr_die1x(100,overquota); + default: strerr_die1x(111,"4.3.0 temporary error on maildir delivery"); } } @@ -180,7 +194,7 @@ fd = open_append(fn); if (fd == -1) - strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.2.1)"); + strerr_die4x(111,"4.2.1 unable to open ",fn,": ",error_str(errno)); sig_alarmcatch(temp_slowlock); alarm(30); @@ -200,7 +214,7 @@ { if (getln(&ss,&messline,&match,'\n') != 0) { - strerr_warn3("Unable to read message: ",error_str(errno),". (#4.3.0)",0); + strerr_warn2("4.3.0 unable to read message: ",error_str(errno),0); if (flaglocked) seek_trunc(fd,pos); close(fd); _exit(111); } @@ -221,7 +235,12 @@ return; writeerrs: - strerr_warn5("Unable to write ",fn,": ",error_str(errno),". (#4.3.0)",0); + if (errno == error_dquot) { + if (flaglocked) seek_trunc(fd,pos); + close(fd); + strerr_die1x(100,overquota); + } else + strerr_warn4("4.3.0 unable to write ",fn,": ",error_str(errno),0); if (flaglocked) seek_trunc(fd,pos); close(fd); _exit(111); @@ -244,7 +263,7 @@ args[0] = "/bin/sh"; args[1] = "-c"; args[2] = prog; args[3] = 0; sig_pipedefault(); execv(*args,args); - strerr_die3x(111,"Unable to run /bin/sh: ",error_str(errno),". (#4.3.0)"); + strerr_die2x(111,"4.3.0 unable to run /bin/sh: ",error_str(errno)); } wait_pid(&wstat,child); @@ -304,7 +323,7 @@ break; if (messline.len == dtline.len) if (!str_diffn(messline.s,dtline.s,dtline.len)) - strerr_die1x(100,"This message is looping: it already has my Delivered-To line. (#5.4.6)"); + strerr_die1x(100,"5.4.6 this message is looping: it already has my Delivered-To line"); } } @@ -313,14 +332,16 @@ struct stat st; if (stat(".",&st) == -1) - strerr_die3x(111,"Unable to stat home directory: ",error_str(errno),". (#4.3.0)"); + strerr_die2x(111,"4.3.0 unable to stat home directory: ",error_str(errno)); if (st.st_mode & auto_patrn) - strerr_die1x(111,"Uh-oh: home directory is writable. (#4.7.0)"); - if (st.st_mode & 01000) - if (flagdoit) - strerr_die1x(111,"Home directory is sticky: user is editing his .qmail file. (#4.2.1)"); - else + strerr_die1x(111,"4.7.0 uh-oh: home directory is writable"); + if (st.st_mode & 01000) { + if (flagdoit) { + strerr_die1x(111,"4.2.1 home directory is sticky: user is editing his .qmail file"); + } else { strerr_warn1("Warning: home directory is sticky.",0); + } + } } int qmeox(dashowner) @@ -360,7 +381,7 @@ if (fstat(*fd,&st) == -1) temp_qmail(qme.s); if ((st.st_mode & S_IFMT) == S_IFREG) { if (st.st_mode & auto_patrn) - strerr_die1x(111,"Uh-oh: .qmail file is writable. (#4.7.0)"); + strerr_die1x(111,"4.7.0 uh-oh: .qmail file is writable"); *cutable = !!(st.st_mode & 0100); return 1; } @@ -444,7 +465,7 @@ substdio_putsflush(subfdoutsmall,"\n"); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -488,7 +509,7 @@ if (homedir[0] != '/') usage(); if (chdir(homedir) == -1) - strerr_die5x(111,"Unable to switch to ",homedir,": ",error_str(errno),". (#4.3.0)"); + strerr_die4x(111,"4.3.0 unable to switch to ",homedir,": ",error_str(errno)); checkhome(); if (!env_put2("HOST",host)) temp_nomem(); @@ -586,7 +607,7 @@ qmesearch(&fd,&flagforwardonly); if (fd == -1) if (*dash) - strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)"); + strerr_die1x(100,"5.1.1 sorry, no mailbox here by that name"); if (!stralloc_copys(&ueo,sender)) temp_nomem(); if (str_diff(sender,"")) @@ -645,19 +666,20 @@ { cmds.s[j] = 0; k = j; - while ((k > i) && (cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t')) + while ((k > i) && ((cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t'))) cmds.s[--k] = 0; switch(cmds.s[i]) { case 0: /* k == i */ if (i) break; - strerr_die1x(111,"Uh-oh: first line of .qmail file is blank. (#4.2.1)"); + strerr_die1x(111,"4.2.1 uh-oh: first line of .qmail file is blank"); case '#': + case ':': break; case '.': case '/': ++count_file; - if (flagforwardonly) strerr_die1x(111,"Uh-oh: .qmail has file delivery but has x bit set. (#4.7.0)"); + if (flagforwardonly) strerr_die1x(111,"4.7.0 uh-oh: .qmail has file delivery but has x bit set"); if (cmds.s[k - 1] == '/') if (flagdoit) maildir(cmds.s + i); else sayit("maildir ",cmds.s + i,k - i); @@ -667,10 +689,50 @@ break; case '|': ++count_program; - if (flagforwardonly) strerr_die1x(111,"Uh-oh: .qmail has prog delivery but has x bit set. (#4.7.0)"); + if (flagforwardonly) strerr_die1x(111,"4.7.0 uh-oh: .qmail has prog delivery but has x bit set"); if (flagdoit) mailprogram(cmds.s + i + 1); else sayit("program ",cmds.s + i + 1,k - i - 1); break; + case '?': + ++i; + { + int l; + for (l = i;l < k;++l) + if (cmds.s[l] == ' ' || cmds.s[l] == '\t') { + cmds.s[l] = 0; + for (++l;l < k;++l) + if (cmds.s[l] != ' ' && cmds.s[l] != '\t') { + ++count_program; + if (flagforwardonly) strerr_die1x(111,"Uh-oh: .qmail has prog delivery but has x bit set. (#4.7.0)"); + if (flagdoit) mailprogram(cmds.s + l); + else sayit("program ",cmds.s + l,k - l); + break; + } + break; + } + if (l == k || flag99) { + flag99 = 0; + cmds.s[j] = '\n'; + for (;j + 1 < cmds.len;++j) + if (cmds.s[j] == '\n' && cmds.s[j + 1] == ':') { + j += 2; + l = j; + for (; j < cmds.len;++j) { + if (cmds.s[j] == 0) break; + if (cmds.s[j] == '\t') break; + if (cmds.s[j] == '\n') break; + if (cmds.s[j] == ' ') break; + } + if (!str_diffn(cmds.s + i,cmds.s + l,j - l)) { + for (; j < cmds.len;++j) + if (cmds.s[j] == '\n') break; + break; + } + --j; + } + } + } + break; case '+': if (str_equal(cmds.s + i + 1,"list")) flagforwardonly = 1; diff -urN qmail-1.03/qmail-lspawn.c qmail-1.03-md/qmail-lspawn.c --- qmail-1.03/qmail-lspawn.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-lspawn.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "fd.h" #include "wait.h" #include "prot.h" @@ -13,6 +15,8 @@ #include "auto_qmail.h" #include "auto_uids.h" #include "qlx.h" +#include "byte.h" +#include "open.h" char *aliasempty; @@ -165,9 +169,8 @@ } } -int spawn(fdmess,fdout,s,r,at) -int fdmess; int fdout; -char *s; char *r; int at; +int +spawn(int fdmess, int fdout, unsigned long msgsize, char *s, char *r, int at) { int f; diff -urN qmail-1.03/qmail-newmrh.c qmail-1.03-md/qmail-newmrh.c --- qmail-1.03/qmail-newmrh.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-newmrh.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,6 +1,9 @@ +#include +#include #include "strerr.h" #include "stralloc.h" #include "substdio.h" +#include "case.h" #include "getln.h" #include "exit.h" #include "readwrite.h" @@ -29,7 +32,7 @@ stralloc line = {0}; int match; -void main() +int main() { umask(033); if (chdir(auto_qmail) == -1) diff -urN qmail-1.03/qmail-newu.c qmail-1.03-md/qmail-newu.c --- qmail-1.03/qmail-newu.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-newu.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,9 +1,12 @@ +#include +#include #include "stralloc.h" #include "subfd.h" #include "getln.h" #include "substdio.h" #include "cdbmss.h" #include "exit.h" +#include "byte.h" #include "readwrite.h" #include "open.h" #include "error.h" @@ -68,7 +71,7 @@ stralloc wildchars = {0}; -void main() +int main() { int i; int numcolons; diff -urN qmail-1.03/qmail-p0f.c qmail-1.03-md/qmail-p0f.c --- qmail-1.03/qmail-p0f.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/qmail-p0f.c 2011-03-11 10:56:43.150083241 +0100 @@ -0,0 +1,90 @@ +#include "qmail-p0f.h" + +char *p0fos, *p0fdetails, *p0flink; +char p0fdistance; +signed int p0fuptime; +char p0ffw,p0fnat; + +void p0f_received(struct qmail *qqt, char *remoteip) +{ + char buf[FMT_ULONG]; + if (!p0fos) return; + qmail_puts(qqt,"X-P0F-Info: "); + safeput(qqt,remoteip?remoteip:"unknown"); + qmail_puts(qqt," is-a "); + if (p0ffw) qmail_puts(qqt,"firewalled "); + if (p0fnat) qmail_puts(qqt,"NATted "); + safeput(qqt,p0fos); + qmail_puts(qqt," ["); + if (p0fdetails) { + int i; + for (i=0; p0fdetails[i]; ++i) { + if (p0fdetails[i]<' ') p0fdetails[i]='?'; + if (p0fdetails[i]=='[') p0fdetails[i]='('; + if (p0fdetails[i]==']') p0fdetails[i]=')'; + } + } else p0fdetails="unknown"; + qmail_puts(qqt,p0fdetails); + qmail_puts(qqt,"]"); + if (p0flink) { + qmail_puts(qqt,", link \""); + qmail_puts(qqt,p0flink); + qmail_puts(qqt,"\""); + } + if (p0fdistance) { + qmail_puts(qqt,", "); + qmail_put(qqt,buf,fmt_ulong(buf,p0fdistance)); + qmail_puts(qqt," hops away"); + } + if (p0fuptime>-1) { + qmail_puts(qqt,", uptime "); + qmail_put(qqt,buf,fmt_ulong(buf,p0fuptime)); + } + qmail_puts(qqt,"\n"); +} + +/* xxx: prove this */ +void p0f_query(void) +{ + int sock; + struct sockaddr_un x; + struct p0f_query p; + struct p0f_response r; + char* tmp; + + if (!ctl_p0fsock) return; + + p0fos=p0fdetails=0; + p0fdistance=p0ffw=p0fnat=0; + p0fuptime=0; + + if (strlen(ctl_p0fsock)+1>sizeof(x.sun_path)) return; + + p.magic=QUERY_MAGIC; + p.id=getpid(); + p.src_ad=(tmp=env_get("TCPREMOTEIP"))?inet_addr(tmp):-1; + p.dst_ad=(tmp=env_get("TCPLOCALIP"))?inet_addr(tmp):-1; + p.src_port=atoi((tmp=env_get("TCPREMOTEPORT"))?tmp:"0"); + p.dst_port=atoi((tmp=env_get("TCPLOCALPORT"))?tmp:"0"); + if (p.src_ad==-1 || p.dst_ad==-1 || !p.src_port || !p.dst_port) return; + + sock=socket(PF_UNIX,SOCK_STREAM,0); + if (sock == -1) return; + x.sun_family=AF_UNIX; + str_copy(x.sun_path, ctl_p0fsock); + if (connect(sock,(struct sockaddr*)&x,sizeof(x))) {close(sock);return;} + if (write(sock,&p,sizeof(p)) != sizeof(p)) {close(sock);return;} + if (read(sock,&r,sizeof(r)) != sizeof(r)) {close(sock);return;} + close(sock); + if (r.magic != QUERY_MAGIC) return; + if (r.type == RESP_BADQUERY || r.type == RESP_NOMATCH) return; + if (!r.genre[0]) { p0fos="unknown"; return; } + + p0fos=strdup(r.genre); + p0fdetails=strdup(r.detail); + p0flink=strdup(r.link); + p0fdistance=r.dist; + p0fuptime=r.uptime; + p0fnat=r.nat; + p0ffw=r.fw; +} diff -urN qmail-1.03/qmail-p0f.h qmail-1.03-md/qmail-p0f.h --- qmail-1.03/qmail-p0f.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/qmail-p0f.h 2011-03-11 10:56:43.150083241 +0100 @@ -0,0 +1,75 @@ +#ifndef P0F_H +#define P0F_H + +#include +#include +#include +#include +#include +#include + +#include "received.h" +#include "uint32.h" +#include "qmail.h" +#include "fmt.h" +#include "env.h" +#include "str.h" + +/* from p0f-query.h */ +#define QUERY_MAGIC 0x0defaced +#define NO_SCORE -100 + +/* Masquerade detection flags: */ +#define D_GENRE 0x0001 +#define D_DETAIL 0x0002 +#define D_LINK 0x0004 +#define D_DIST 0x0008 +#define D_NAT 0x0010 +#define D_FW 0x0020 +#define D_NAT2_1 0x0040 +#define D_FW2_1 0x0080 +#define D_NAT2_2 0x0100 +#define D_FW2_2 0x0200 +#define D_FAST 0x0400 +#define D_TNEG 0x0800 + +#define D_TIME 0x4000 +#define D_FAR 0x8000 + +struct p0f_query { + uint32 magic; /* must be set to QUERY_MAGIC */ + uint32 id; /* Unique query ID */ + uint32 src_ad,dst_ad; /* src address, local dst addr */ + unsigned short src_port,dst_port; /* src and dst ports */ +}; + +#define RESP_OK 0 /* Response OK */ +#define RESP_BADQUERY 1 /* Query malformed */ +#define RESP_NOMATCH 2 /* No match for src-dst data */ + +struct p0f_response { + uint32 magic; /* QUERY_MAGIC */ + uint32 id; /* Query ID (copied from p0f_query) */ + unsigned char type; /* RESP_* */ + unsigned char genre[20]; /* OS genre (empty if no match) */ + unsigned char detail[40]; /* OS version (empty if no match) */ + char dist; /* Distance (-1 if unknown ) */ + unsigned char link[30]; /* Link type (empty if unknown) */ + unsigned char tos[30]; /* Traffic type (empty if unknown) */ + unsigned char fw,nat; /* firewall and NAT flags flags */ + unsigned char real; /* A real operating system? */ + signed short score; /* Masquerade score (or NO_SCORE) */ + unsigned short mflags; /* Masquerade flags (D_*) */ + signed int uptime; /* Uptime in hours (-1 = unknown) */ +}; + +extern char *ctl_p0fsock; /* from qmail-smtpd */ +extern char *p0fos, *p0fdetails, *p0flink; +extern char p0fdistance; +extern signed int p0fuptime; +extern char p0ffw,p0fnat; + +extern void p0f_received(struct qmail *qqt, char *remoteip); +extern void p0f_query(void); + +#endif /* P0F_H */ diff -urN qmail-1.03/qmail-pop3d.c qmail-1.03-md/qmail-pop3d.c --- qmail-1.03/qmail-pop3d.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-pop3d.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,6 +1,8 @@ #include #include -#include "commands.h" +#include +#include +#include "auto_qmail.h" #include "sig.h" #include "getln.h" #include "stralloc.h" @@ -9,6 +11,7 @@ #include "open.h" #include "prioq.h" #include "scan.h" +#include "base64.h" #include "fmt.h" #include "str.h" #include "exit.h" @@ -16,8 +19,26 @@ #include "readwrite.h" #include "timeoutread.h" #include "timeoutwrite.h" +#include "out_log.h" +#include "case.h" +#include "env.h" +#include "commands.h" +#include "control.h" +#include "scan.h" +#include "fd.h" +#include "wait.h" +#include "byte.h" +#include "now.h" + +char *name="qmail-pop3d"; +char unique[FMT_ULONG + FMT_ULONG + 3]; + +int ctl_log_in=0; +int ctl_log_out=0; +int ctl_log_fd=2; +int ctl_maxcmdlen; -void die() { _exit(0); } +void die() { _exit(1); } int saferead(fd,buf,len) int fd; char *buf; int len; { @@ -35,78 +56,65 @@ return r; } +char ssinbuf[1024]; char ssoutbuf[1024]; -substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); - -char ssinbuf[128]; +char sserrbuf[1024]; +char strnum[FMT_ULONG]; +stralloc line = {0}; substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); +substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); +substdio sserr = SUBSTDIO_FDBUF(safewrite,-1,sserrbuf,sizeof sserrbuf); -void put(buf,len) char *buf; int len; -{ - substdio_put(&ssout,buf,len); -} -void puts(s) char *s; -{ - substdio_puts(&ssout,s); -} -void flush() +void err(char *s) { - substdio_flush(&ssout); + doserv(); + out("-ERR"); + if (s) { out(" "); out(s); } + doeol(); flush(); } -void err(s) char *s; -{ - puts("-ERR "); - puts(s); - puts("\r\n"); - flush(); -} - -void die_nomem() { err("out of memory"); die(); } -void die_nomaildir() { err("this user has no $HOME/Maildir"); die(); } -void die_scan() { err("unable to scan $HOME/Maildir"); die(); } - -void err_syntax() { err("syntax error"); } -void err_unimpl() { err("unimplemented"); } -void err_deleted() { err("already deleted"); } -void err_nozero() { err("messages are counted from 1"); } -void err_toobig() { err("not that many messages"); } -void err_nosuch() { err("unable to open that message"); } -void err_nounlink() { err("unable to unlink all deleted messages"); } -void okay() { puts("+OK \r\n"); flush(); } - -void printfn(fn) char *fn; +void err_die(char *s) { - fn += 4; - put(fn,str_chr(fn,':')); + err(s);die(); } -char strnum[FMT_ULONG]; -stralloc line = {0}; +void die_nomaildir() { err_die("[SYS/TEMP] this user has no $HOME/Maildir"); } +void die_nomem() { err_die("[SYS/TEMP] out of memory"); } +void die_scan() { err_die("[SYS/TEMP] unable to scan $HOME/Maildir"); } +void die_control() { err_die("[SYS/TEMP] unable to read controls"); } +void die_lcmd() { err_die("[SYS/TEMP] the given command is too long!"); } + +void err_noargs() { err("don't need any arguments"); } +void err_syntax() { err("syntax error"); } +void err_unimpl() { err("unimplemented"); } +void err_deleted() { err("already deleted"); } +void err_nozero() { err("messages are counted from 1"); } +void err_toobig() { err("not that many messages"); } +void err_nosuch() { err("unable to open that message"); } +void err_nounlink() { err("unable to unlink all deleted messages"); } void blast(ssfrom,limit) -substdio *ssfrom; -unsigned long limit; + substdio *ssfrom; + unsigned long limit; { int match; int inheaders = 1; - + for (;;) { if (getln(ssfrom,&line,&match,'\n') != 0) die(); if (!match && !line.len) break; if (match) --line.len; /* no way to pass this info over POP */ if (limit) if (!inheaders) if (!--limit) break; - if (!line.len) + if (!line.len) { inheaders = 0; - else - if (line.s[0] == '.') - put(".",1); - put(line.s,line.len); - put("\r\n",2); + } else if (line.s[0] == '.') { + Out("."); + } + Outn(line.s,line.len);Out("\r\n"); if (!match) break; } - put("\r\n.\r\n",5); - flush(); + doserv(); Log("[...]"); Out("."); + doeol(); flush(); } stralloc filenames = {0}; @@ -114,89 +122,127 @@ struct message { int flagdeleted; + int read; unsigned long size; char *fn; } *m; int numm; -int last = 0; +int last=0; void getlist() { struct prioq_elt pe; struct stat st; int i; - + maildir_clean(&line); if (maildir_scan(&pq,&filenames,1,1) == -1) die_scan(); - + numm = pq.p ? pq.len : 0; m = (struct message *) alloc(numm * sizeof(struct message)); if (!m) die_nomem(); - - for (i = 0;i < numm;++i) { + + for (i=0; i last) last = i + 1; - okay(); + out_err("+OK"); } -void list(i,flaguidl) -int i; -int flaguidl; +void printfn(char *fn, int log) { - put(strnum,fmt_uint(strnum,i + 1)); - puts(" "); - if (flaguidl) printfn(m[i].fn); - else put(strnum,fmt_ulong(strnum,m[i].size)); - puts("\r\n"); + fn += 4; + if (log) outn(fn,str_chr(fn,':')); + else Outn(fn,str_chr(fn,':')); } -void dolisting(arg,flaguidl) char *arg; int flaguidl; +void list(int i, int flaguidl, int log) +{ + if (log) { + outn(strnum,fmt_uint(strnum,i + 1)); out(" "); + if (flaguidl) printfn(m[i].fn, log); + else outn(strnum,fmt_ulong(strnum,m[i].size)); + doeol(); + } else { + /* big listings are not logged! */ + Outn(strnum,fmt_uint(strnum,i + 1)); Out(" "); + if (flaguidl) printfn(m[i].fn, log); + else Outn(strnum,fmt_ulong(strnum,m[i].size)); + Out("\r\n"); + } + flush(); +} + +/* +OK 2 messages (320 octets) */ +void dolisting(char *arg, int flaguidl) { unsigned int i; + if (*arg) { i = msgno(arg); if (i == -1) return; - puts("+OK "); - list(i,flaguidl); - } - else { - okay(); - for (i = 0;i < numm;++i) - if (!m[i].flagdeleted) - list(i,flaguidl); - puts(".\r\n"); + doserv(); out("+OK "); list(i,flaguidl,1); + } else { + unsigned long total=0,n=0; + for (i=0; i 0) if (temp.s[temp.len - 1] == '\r') --temp.len; + temp.s[temp.len] = 0; + doname();out("C: ");out(temp.s);Log("\n"); + out_err("+OK digest auth was good!"); + } + commands(&ssin,&sserr,pop3commands); - okay(); - commands(&ssin,pop3commands); die(); + return 0; /* gcc happyness */ } diff -urN qmail-1.03/qmail-popup.c qmail-1.03-md/qmail-popup.c --- qmail-1.03/qmail-popup.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-popup.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,4 +1,20 @@ +/* + * mtime: TR 2007-07-28 + * + * control/log/pop3_fd -> the logging file desciptor + * control/log/pop3_in -> enable/disable logging of incoming cmd's from client + * control/log/pop3_out -> enable/disable logging of outgoing server resonses + * + * + sasl authentication (rfc1734) + * - methods: plain, login, cram-md5, cram-sha1, cram-ripemd, digest-md5 + */ +#include +#include +#include +#include "auto_qmail.h" #include "commands.h" +#include "control.h" +#include "scan.h" #include "fd.h" #include "sig.h" #include "stralloc.h" @@ -13,93 +29,127 @@ #include "readwrite.h" #include "timeoutread.h" #include "timeoutwrite.h" +#include "stralloc.h" +#include "case.h" +#include "env.h" +#include "out_log.h" +#include "qmail-sasl.h" +#include "ucspitls.h" + +char ssinbuf[1024]; +char ssoutbuf[1024]; +char sserrbuf[1024]; + +substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); +substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); +substdio sserr = SUBSTDIO_FDBUF(safewrite,-1,sserrbuf,sizeof sserrbuf); + +stralloc username = {0}; +char **childargs; +char *hostname; +char *name="qmail-popup"; + +int ctl_log_in=0; +int ctl_log_out=0; +int ctl_log_fd=2; +int ctl_logindelay=0; /* how can we do this ? */ +int ctl_expire=0; +int ctl_auth_delay=5; +int ctl_auth_secure=(1|2|4|8|16); /* sasl methods in TLS mode */ +int ctl_auth_insecure=(4|8|16); /* sasl methods in NON-TLS mode */ +int *ctl_auth_current = &ctl_auth_insecure; +int ctl_maxcmdlen; + +int tls_available = 0; +int tls_started = 0; + +char logindelay[FMT_ULONG+22]; +char expire[FMT_ULONG+22]; + +int seenuser = 0; +char upbuf[128]; +substdio ssup; + +void die() { flush(); _exit(1); } + +void err(char *s) +{ + doserv(); + if (s) { + out("-ERR "); out(s); + } else { + out("-ERR"); + } + doeol(); + flush(); +} -void die() { _exit(1); } +void ok(char *s) +{ + doserv(); out("+OK"); + if (s) out(s); + doeol(); flush(); +} + +void err_die(char *s) { err(s);die(); } + +/* rfc: [SYS/PERM] [SYS/TEMP] [AUTH] [IN-USE] */ +void die_read() { doname();Log("client exited\n");_exit(0); } +void die_usage() { err_die("[SYS/TEMP] usage: popup hostname checkprogram subprogram"); } +void die_nomem() { err_die("[SYS/TEMP] out of memory"); } +void die_pipe() { err_die("[SYS/TEMP] unable to open pipe"); } +void die_write() { err_die("[SYS/TEMP] unable to write pipe"); } +void die_fork() { err_die("[SYS/TEMP] unable to fork"); } +void die_child() { err_die("[SYS/TEMP] aack, child crashed"); } +void die_control() { err_die("[SYS/TEMP] unable to read controls"); } +void die_lcmd() { err_die("[SYS/TEMP] the given command is too long!"); } +void die_tls() { err_die("[SYS/TEMP] TLS startup failed"); } + +void err_wantauth() { err("[SYS/PERM] authorization first"); } +void err_authfail() { err("[AUTH] authorization failed"); } +void err_authin() { err("[AUTH] invalid authorization input"); } +int err_noauth() { err("auth type unimplemented"); return -1; } +int err_authabrt() { err("auth exchange cancelled"); return -1; } +void err_wantuser() { err("USER first"); } +void err_syntax() { err("syntax error"); } +void err_unimpl() { err("unimplemented"); } -int saferead(fd,buf,len) int fd; char *buf; int len; +int saferead(int fd, char *buf, int len) { int r; r = timeoutread(1200,fd,buf,len); - if (r <= 0) die(); + if (r <= 0) die_read(); return r; } -int safewrite(fd,buf,len) int fd; char *buf; int len; +int safewrite(int fd, char *buf, int len) { int r; r = timeoutwrite(1200,fd,buf,len); - if (r <= 0) die(); + if (r <= 0) die_write(); return r; } -char ssoutbuf[128]; -substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); - -char ssinbuf[128]; -substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); - -void puts(s) char *s; -{ - substdio_puts(&ssout,s); -} -void flush() -{ - substdio_flush(&ssout); -} -void err(s) char *s; -{ - puts("-ERR "); - puts(s); - puts("\r\n"); - flush(); -} - -void die_usage() { err("usage: popup hostname subprogram"); die(); } -void die_nomem() { err("out of memory"); die(); } -void die_pipe() { err("unable to open pipe"); die(); } -void die_write() { err("unable to write pipe"); die(); } -void die_fork() { err("unable to fork"); die(); } -void die_childcrashed() { err("aack, child crashed"); } -void die_badauth() { err("authorization failed"); } - -void err_syntax() { err("syntax error"); } -void err_wantuser() { err("USER first"); } -void err_authoriz() { err("authorization first"); } - -void okay() { puts("+OK \r\n"); flush(); } -void pop3_quit() { okay(); die(); } - - -char unique[FMT_ULONG + FMT_ULONG + 3]; -char *hostname; -stralloc username = {0}; -int seenuser = 0; -char **childargs; -substdio ssup; -char upbuf[128]; - - void doanddie(user,userlen,pass) -char *user; -unsigned int userlen; /* including 0 byte */ -char *pass; + char *user; + unsigned int userlen; /* including 0 byte */ + char *pass; { int child; int wstat; int pi[2]; - + if (fd_copy(2,1) == -1) die_pipe(); close(3); if (pipe(pi) == -1) die_pipe(); if (pi[0] != 3) die_pipe(); switch(child = fork()) { - case -1: - die_fork(); + case -1: die_fork(); break; case 0: close(pi[1]); sig_pipedefault(); execvp(*childargs,childargs); - _exit(1); + _exit(0); } close(pi[0]); substdio_fdbuf(&ssup,write,pi[1],upbuf,sizeof upbuf); @@ -113,71 +163,275 @@ close(pi[1]); byte_zero(pass,str_len(pass)); byte_zero(upbuf,sizeof upbuf); - if (wait_pid(&wstat,child) == -1) die(); - if (wait_crashed(wstat)) die_childcrashed(); - if (wait_exitcode(wstat)) die_badauth(); + if (wait_pid(&wstat,child) == -1) die_child(); + if (wait_crashed(wstat)) die_child(); + if (wait_exitcode(wstat)) { err_authfail(); return; } die(); } + +void pop3_okay() { ok(0); } +void pop3_quit() { ok(0);_exit(0); } + void pop3_greet() { - char *s; - s = unique; - s += fmt_uint(s,getpid()); - *s++ = '.'; - s += fmt_ulong(s,(unsigned long) now()); - *s++ = '@'; - *s++ = 0; - puts("+OK <"); - puts(unique); - puts(hostname); - puts(">\r\n"); - flush(); + dounique(); + doserv(); out("+OK "); out("<"); out(unique); out(hostname); out(">"); + doeol(); flush(); } + void pop3_user(arg) char *arg; { if (!*arg) { err_syntax(); return; } - okay(); seenuser = 1; - if (!stralloc_copys(&username,arg)) die_nomem(); - if (!stralloc_0(&username)) die_nomem(); + if (!stralloc_copys(&username,arg)) die_nomem(); + if (!stralloc_0(&username)) die_nomem(); + ok(0); } + void pop3_pass(arg) char *arg; { if (!seenuser) { err_wantuser(); return; } if (!*arg) { err_syntax(); return; } + if (!env_put2("AUTH", "POP3")) die_nomem(); doanddie(username.s,username.len,arg); } + void pop3_apop(arg) char *arg; { char *space; space = arg + str_chr(arg,' '); if (!*space) { err_syntax(); return; } *space++ = 0; + if (!env_put2("AUTH", "APOP")) die_nomem(); doanddie(arg,space - arg,space); } -struct commands pop3commands[] = { +void dosasl() { + int i=0,space=0; + while (i #include +#include #include "substdio.h" #include "readwrite.h" #include "subfd.h" @@ -11,6 +12,7 @@ #include "str.h" #include "scan.h" #include "open.h" +#include "byte.h" #include "error.h" #include "getln.h" #include "auto_break.h" @@ -228,7 +230,7 @@ substdio ss; char ssbuf[SUBSTDIO_INSIZE]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/qmail-qmqpc.c qmail-1.03-md/qmail-qmqpc.c --- qmail-1.03/qmail-qmqpc.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-qmqpc.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -102,14 +103,16 @@ char *server; { struct ip_address ip; + struct ip_address outip; char ch; + outip.d[0]=outip.d[1]=outip.d[2]=outip.d[3]=(unsigned long)0; if (!ip_scan(server,&ip)) return; qmqpfd = socket(AF_INET,SOCK_STREAM,0); if (qmqpfd == -1) die_socket(); - if (timeoutconn(qmqpfd,&ip,PORT_QMQP,10) != 0) { + if (timeoutconn(qmqpfd,&ip,&outip,PORT_QMQP,10) != 0) { lasterror = 73; if (errno == error_timeout) lasterror = 72; close(qmqpfd); @@ -135,10 +138,9 @@ stralloc servers = {0}; -main() +int main(int argc, char **argv) { - int i; - int j; + int i,j; sig_pipeignore(); diff -urN qmail-1.03/qmail-qmqpd.c qmail-1.03-md/qmail-qmqpd.c --- qmail-1.03/qmail-qmqpd.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-qmqpd.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "auto_qmail.h" #include "qmail.h" #include "received.h" @@ -8,6 +10,9 @@ #include "now.h" #include "fmt.h" #include "env.h" +#include "str.h" +#include "byte.h" +#include "scan.h" void resources() { _exit(111); } @@ -48,7 +53,7 @@ for (;;) { getbyte(&ch); if (ch == ':') return len; - if (len > 200000000) resources(); + if (len > 200000000 || ch < '0' || ch > '9') resources(); len = 10 * len + (ch - '0'); } } @@ -105,7 +110,7 @@ int flagok = 1; -main() +int main() { char *result; unsigned long qp; @@ -163,7 +168,7 @@ } if (!flagok) - result = "Dsorry, I can't accept addresses like that (#5.1.3)"; + result = "D5.1.3 sorry, I can't accept addresses like that"; substdio_put(&ssout,strnum,fmt_ulong(strnum,(unsigned long) str_len(result))); substdio_puts(&ssout,":"); diff -urN qmail-1.03/qmail-qmtpd.c qmail-1.03-md/qmail-qmtpd.c --- qmail-1.03/qmail-qmtpd.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-qmtpd.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,7 +1,10 @@ +#include +#include #include "stralloc.h" #include "substdio.h" #include "qmail.h" #include "now.h" +#include "scan.h" #include "str.h" #include "fmt.h" #include "env.h" @@ -14,6 +17,13 @@ void badproto() { _exit(100); } void resources() { _exit(111); } +void die_nomem() { resources(); } +void die_control() { resources(); } +void die_cdb() { resources(); } +void die_sys() { resources(); } + +extern void realrcptto_init(); +extern int realrcptto(); int safewrite(fd,buf,len) int fd; char *buf; int len; { @@ -74,36 +84,38 @@ char *relayclient; int relayclientlen; -main() +int main() { char ch; int i; unsigned long biglen; unsigned long len; - int flagdos; + int flagdos=0; int flagsenderok; int flagbother; unsigned long qp; char *result; char *x; unsigned long u; - + sig_pipeignore(); sig_alarmcatch(resources); alarm(3600); - + if (chdir(auto_qmail) == -1) resources(); - + if (control_init() == -1) resources(); if (rcpthosts_init() == -1) resources(); relayclient = env_get("RELAYCLIENT"); relayclientlen = relayclient ? str_len(relayclient) : 0; - + + realrcptto_init(); + if (control_readint(&databytes,"control/databytes") == -1) resources(); x = env_get("DATABYTES"); if (x) { scan_ulong(x,&u); databytes = u; } if (!(databytes + 1)) --databytes; - + remotehost = env_get("TCPREMOTEHOST"); if (!remotehost) remotehost = "unknown"; remoteinfo = env_get("TCPREMOTEINFO"); @@ -112,28 +124,28 @@ local = env_get("TCPLOCALHOST"); if (!local) local = env_get("TCPLOCALIP"); if (!local) local = "unknown"; - + for (;;) { if (!stralloc_copys(&failure,"")) resources(); flagsenderok = 1; - + len = getlen(); if (len == 0) badproto(); - + if (databytes) bytestooverflow = databytes + 1; if (qmail_open(&qq) == -1) resources(); qp = qmail_qp(&qq); - + substdio_get(&ssin,&ch,1); --len; if (ch == 10) flagdos = 0; else if (ch == 13) flagdos = 1; else badproto(); - + received(&qq,"QMTP",local,remoteip,remotehost,remoteinfo,(char *) 0); - + /* XXX: check for loops? only if len is big? */ - + if (flagdos) while (len > 0) { substdio_get(&ssin,&ch,1); @@ -161,9 +173,9 @@ } } getcomma(); - + len = getlen(); - + if (len >= 1000) { buf[0] = 0; flagsenderok = 0; @@ -178,15 +190,15 @@ buf[len] = 0; } getcomma(); - + flagbother = 0; qmail_from(&qq,buf); if (!flagsenderok) qmail_fail(&qq); - + biglen = getlen(); while (biglen > 0) { if (!stralloc_append(&failure,"")) resources(); - + len = 0; for (;;) { if (!biglen) badproto(); @@ -208,15 +220,20 @@ if (!buf[i]) failure.s[failure.len - 1] = 'N'; } buf[len] = 0; - - if (relayclient) + + if (relayclient) { str_copy(buf + len,relayclient); - else + } else { switch(rcpthosts(buf,len)) { case -1: resources(); case 0: failure.s[failure.len - 1] = 'D'; } - + } + + if (!failure.s[failure.len - 1]) + if (!realrcptto(buf)) + failure.s[failure.len - 1] = 'D'; + if (!failure.s[failure.len - 1]) { qmail_to(&qq,buf); flagbother = 1; @@ -226,12 +243,12 @@ biglen -= (len + 1); } getcomma(); - + if (!flagbother) qmail_fail(&qq); result = qmail_close(&qq); - if (!flagsenderok) result = "Dunacceptable sender (#5.1.7)"; - if (databytes) if (!bytestooverflow) result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)"; - + if (!flagsenderok) result = "D5.1.7 unacceptable sender"; + if (databytes) if (!bytestooverflow) result = "D5.3.4 sorry, that message size exceeds my databytes limit"; + if (*result) len = str_len(result); else { @@ -244,25 +261,26 @@ buf2[len] = 0; result = buf2; } - + len = fmt_ulong(buf,len); buf[len++] = ':'; len += fmt_str(buf + len,result); buf[len++] = ','; - + for (i = 0;i < failure.len;++i) switch(failure.s[i]) { case 0: substdio_put(&ssout,buf,len); break; case 'D': - substdio_puts(&ssout,"66:Dsorry, that domain isn't in my list of allowed rcpthosts (#5.7.1),"); + substdio_puts(&ssout,"66:D5.7.1 sorry, that domain isn't in my list of allowed rcpthosts,"); break; default: - substdio_puts(&ssout,"46:Dsorry, I can't handle that recipient (#5.1.3),"); + substdio_puts(&ssout,"46:D5.1.3 sorry, I can't handle that recipient,"); break; } - + /* ssout will be flushed when we read from the network again */ } + return 0; /* gcc happyness */ } diff -urN qmail-1.03/qmail-qread.c qmail-1.03-md/qmail-qread.c --- qmail-1.03/qmail-qread.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-qread.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include "stralloc.h" #include "substdio.h" #include "subfd.h" @@ -105,7 +106,7 @@ stralloc line = {0}; -void main() +int main() { int channel; int match; @@ -118,7 +119,7 @@ if (chdir("queue") == -1) die_chdir(); readsubdir_init(&rs,"info",die_opendir); - while (x = readsubdir_next(&rs,&id)) + while ((x = readsubdir_next(&rs,&id))) if (x > 0) { fmtqfn(fnmess,"mess/",id,1); @@ -172,4 +173,5 @@ } die(0); + return 0; } diff -urN qmail-1.03/qmail-qstat.sh qmail-1.03-md/qmail-qstat.sh --- qmail-1.03/qmail-qstat.sh 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-qstat.sh 2011-03-11 10:56:43.150083241 +0100 @@ -1,7 +1,7 @@ cd QMAIL messdirs=`echo queue/mess/* | wc -w` messfiles=`find queue/mess/* -print | wc -w` -tododirs=`echo queue/todo | wc -w` -todofiles=`find queue/todo -print | wc -w` +tododirs=`echo queue/todo/* | wc -w` +todofiles=`find queue/todo/* -print | wc -w` echo messages in queue: `expr $messfiles - $messdirs` echo messages in queue but not yet preprocessed: `expr $todofiles - $tododirs` diff -urN qmail-1.03/qmail-queue.c qmail-1.03-md/qmail-queue.c --- qmail-1.03/qmail-queue.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-queue.c 2011-03-11 10:56:43.150083241 +0100 @@ -1,5 +1,7 @@ #include #include +#include +#include #include "readwrite.h" #include "sig.h" #include "exit.h" @@ -16,6 +18,10 @@ #include "auto_uids.h" #include "date822fmt.h" #include "fmtqfn.h" +#include "byte.h" +#include "constmap.h" +#include "control.h" +#include "stralloc.h" #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */ #define ADDR 1003 @@ -40,6 +46,11 @@ int flagmademess = 0; int flagmadeintd = 0; +int bbon = 0; +stralloc bbs = {0}; /* control/bigbrother */ +stralloc bba = {0}; /* from/to addr */ +struct constmap mapbb; + void cleanup() { if (flagmadeintd) @@ -57,6 +68,7 @@ void die(e) int e; { _exit(e); } void die_write() { cleanup(); die(53); } void die_read() { cleanup(); die(54); } +void die_bb() { cleanup(); die(51); } void sigalrm() { /* thou shalt not clean up here */ die(52); } void sigbug() { die(81); } @@ -151,14 +163,31 @@ char tmp[FMT_ULONG]; -void main() +int main() { - unsigned int len; - char ch; + unsigned int len, xlen, n; + const char *b; + char ch, *x; + int fd; sig_blocknone(); umask(033); if (chdir(auto_qmail) == -1) die(61); + + if (control_init() == -1) die(55); + switch (control_readfile(&bbs,"control/bigbrother",0)) { + case -1: + die(55); + case 0: + bbon = 0; + if (!constmap_init(&mapbb,"",0,1)) die(51); + break; + case 1: + bbon = 1; + if (!constmap_init(&mapbb,bbs.s,bbs.len,1)) die(51); + break; + } + if (chdir("queue") == -1) die(62); mypid = getpid(); @@ -180,10 +209,11 @@ messnum = pidst.st_ino; messfn = fnnum("mess/",1); - todofn = fnnum("todo/",0); - intdfn = fnnum("intd/",0); + todofn = fnnum("todo/",1); + intdfn = fnnum("intd/",1); if (link(pidfn,messfn) == -1) die(64); + if ((fd = open(messfn, O_RDONLY)) < 0 || fsync(fd) < 0 || close(fd) < 0) die(64); if (unlink(pidfn) == -1) die(63); flagmademess = 1; @@ -223,6 +253,7 @@ { if (substdio_get(&ssin,&ch,1) < 1) die_read(); if (substdio_put(&ssout,&ch,1) == -1) die_write(); + if (bbon) if (!stralloc_catb(&bba, &ch, 1)) die_bb(); if (!ch) break; } if (len >= ADDR) die(11); @@ -235,20 +266,38 @@ if (!ch) break; if (ch != 'T') die(91); if (substdio_bput(&ssout,&ch,1) == -1) die_write(); - for (len = 0;len < ADDR;++len) - { + for (len = 0;len < ADDR;++len) { if (substdio_get(&ssin,&ch,1) < 1) die_read(); if (substdio_bput(&ssout,&ch,1) == -1) die_write(); + if (bbon) if (!stralloc_catb(&bba, &ch, 1)) die_bb(); if (!ch) break; - } + } if (len >= ADDR) die(11); } + if (bbon) { + x = bba.s; + xlen = bba.len; + do { + n = byte_chr(x,xlen,0); + if ((b = constmap(&mapbb, x, n))) { + if (*b) { + if (substdio_bput(&ssout,"T", 1) == -1) die_write(); + if (substdio_bputs(&ssout,b) == -1) die_write(); + if (substdio_bput(&ssout,"",1) == -1) die_write(); + } + } + if (n++ >= xlen) break; + x += n; xlen -= n; + } while (xlen > 0); + } + if (substdio_flush(&ssout) == -1) die_write(); if (fsync(intdfd) == -1) die_write(); if (link(intdfn,todofn) == -1) die(66); + if ((fd = open(todofn, O_RDONLY)) < 0 || fsync(fd) < 0 || close(fd) < 0) die(66); triggerpull(); - die(0); + return 0; } diff -urN qmail-1.03/qmail-remote.8 qmail-1.03-md/qmail-remote.8 --- qmail-1.03/qmail-remote.8 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-remote.8 2011-03-11 10:56:43.153416606 +0100 @@ -1,10 +1,11 @@ .TH qmail-remote 8 .SH NAME -qmail-remote \- send mail via SMTP +qmail-remote \- send mail via SMTP / ESMTP .SH SYNOPSIS .B qmail-remote .I host .I sender +.I size .I recip [ .I recip ... @@ -26,7 +27,7 @@ or to a mail exchanger for .I host listed in the Domain Name System, -via the Simple Mail Transfer Protocol (SMTP). +via the Simple Mail Transfer Protocol (SMTP / ESMTP). .I host can be either a fully-qualified domain name: @@ -124,10 +125,23 @@ .B qmail-remote refuses to run. .TP 5 +.I outgoingip +IP address to be used on outgoing connections. +Default: system-defined. +The value +.IR 0.0.0.0 +is equivalent to the system default. + +.TP 5 +.I smtprelays +Can be used for auth ... XXX == TODO!!! +PLAIN / LOGIN / CRAM-MD5 / CRAM-SHA1 / CRAM-RIPEMD mechanism + +.TP 5 .I smtproutes Artificial SMTP routes. Each route has the form -.IR domain\fB:\fIrelay , +.IR domain relay , without any extra spaces. If .I domain @@ -156,6 +170,8 @@ this tells .B qmail-remote to look up MX records as usual. +.I port +value of 465 (deprecated smtps port) causes TLS session to be started. .I smtproutes may include wildcards: @@ -195,6 +211,32 @@ .B qmail-remote will wait for each response from the remote SMTP server. Default: 1200. + +.SH "ESMTP TLS CLIENT OPTIONS" +.TP 5 +.I clientcert.pem +SSL certificate that is used to authenticate with the remote server +during a TLS session. + +.TP 5 +.I tlsclientciphers +A set of OpenSSL client cipher strings. Multiple ciphers +contained in a string should be separated by a colon. + +.TP 5 +.I tlshosts/.pem +.B qmail-remote +requires authentication from servers for which this certificate exists +.RB ( +is the fully-qualified domain name of the server). One of the +.I dNSName +or the +.I CommonName +attributes have to match. + +.B WARNING: +this option may cause mail to be delayed, bounced, doublebounced, or lost. + .SH "SEE ALSO" addresses(5), envelopes(5), diff -urN qmail-1.03/qmail-remote.c qmail-1.03-md/qmail-remote.c --- qmail-1.03/qmail-remote.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-remote.c 2011-03-11 10:56:43.153416606 +0100 @@ -1,7 +1,16 @@ +/* + * - esmtp size + auth + logging by me: http://www.mcmilk.de/qmail/ + * - many other improvements + */ + #include #include +#include #include #include +#include +#include + #include "sig.h" #include "stralloc.h" #include "substdio.h" @@ -11,6 +20,7 @@ #include "error.h" #include "auto_qmail.h" #include "control.h" +#include "base64.h" #include "dns.h" #include "alloc.h" #include "quote.h" @@ -19,7 +29,9 @@ #include "ipme.h" #include "gen_alloc.h" #include "gen_allocdefs.h" +#include "fmt.h" #include "str.h" +#include "hmac.h" #include "now.h" #include "exit.h" #include "constmap.h" @@ -30,61 +42,155 @@ #include "timeoutwrite.h" #define HUGESMTPTEXT 5000 +unsigned long smtp_port = 25; +unsigned long qmtp_port = 209; -#define PORT_SMTP 25 /* silly rabbit, /etc/services is for users */ -unsigned long port = PORT_SMTP; +char *name="qmail-remote"; +int ctl_log_fd=25; /* logging fd if >0 */ GEN_ALLOC_typedef(saa,stralloc,sa,len,a) GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus) static stralloc sauninit = {0}; +substdio ssin; +substdio smtpto; +substdio smtpfrom; + +struct constmap maproutes; +struct constmap maprelays; +struct constmap mapqroutes; + +stralloc outgoingip = {0}; stralloc helohost = {0}; +stralloc qroutes = {0}; stralloc routes = {0}; -struct constmap maproutes; -stralloc host = {0}; +stralloc relays = {0}; stralloc sender = {0}; +stralloc host = {0}; -saa reciplist = {0}; +stralloc authuser = {0}; +stralloc authpass = {0}; +stralloc authtype = {0}; +stralloc slop = {0}; +stralloc resp = {0}; +stralloc temp = {0}; + +saa reciplist = {0}; /* list of recipients */ +saa ehlokw = {0}; /* list of EHLO keywords and parameters */ struct ip_address partner; +struct ip_address outip; + +/* auth stuff */ +unsigned char digest[21], encrypted[41]; +char hextab[]="0123456789abcdef"; +char *sasl[] = { "LOGIN","PLAIN","CRAM-MD5","CRAM-SHA1","CRAM-RIPEMD","DIGEST-MD5" }; +#define SASL_MAX 6 +int ehloflags = 0; /* */ +int authflags = 0; /* possible auth types, which are suported by client+server */ +int needauth = 0; /* is set, when we have to authenticate */ + +int client_auth_login(char *arg); +int client_auth_plain(char *arg); +int client_auth_cram_md5(char *arg); +int client_auth_cram_rmd(char *arg); +int client_auth_cram_sha1(char *arg); +int client_auth_digest_md5(char *arg); +int client_auth_notsupported(char *arg); + +typedef struct { + char *text; + int (*fun)(); +} authcmd_t; + +authcmd_t authcmds[] = { + { "login", client_auth_login } +, { "plain", client_auth_plain } +, { "cram-md5", client_auth_cram_md5 } +, { "cram-ripemd", client_auth_cram_rmd } +, { "cram-sha1", client_auth_cram_sha1 } +/* , { "digest-md5", client_auth_digest_md5 } */ +, { 0, client_auth_notsupported } +}; + +void quit(char *prepend, char *append); + +/* flush all buffers */ +void flush(void) +{ + substdio_flush(&smtpto); + substdio_flush(subfdoutsmall); + if (ctl_log_fd) substdio_flush(subfderr); +} -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); } -void outsafe(sa) stralloc *sa; { int i; char ch; -for (i = 0;i < sa->len;++i) { -ch = sa->s[i]; if (ch < 33) ch = '?'; if (ch > 126) ch = '?'; -if (substdio_put(subfdoutsmall,&ch,1) == -1) _exit(0); } } - -void temp_nomem() { out("ZOut of memory. (#4.3.0)\n"); zerodie(); } -void temp_oserr() { out("Z\ -System resources temporarily unavailable. (#4.3.0)\n"); zerodie(); } -void temp_noconn() { out("Z\ -Sorry, I wasn't able to establish an SMTP connection. (#4.4.1)\n"); zerodie(); } -void temp_read() { out("ZUnable to read message. (#4.3.0)\n"); zerodie(); } -void temp_dnscanon() { out("Z\ -CNAME lookup failed temporarily. (#4.4.3)\n"); zerodie(); } -void temp_dns() { out("Z\ -Sorry, I couldn't find any host by that name. (#4.1.2)\n"); zerodie(); } -void temp_chdir() { out("Z\ -Unable to switch to home directory. (#4.3.0)\n"); zerodie(); } -void temp_control() { out("Z\ -Unable to read control files. (#4.3.0)\n"); zerodie(); } -void perm_partialline() { out("D\ -SMTP cannot transfer messages with partial final lines. (#5.6.2)\n"); zerodie(); } -void perm_usage() { out("D\ -I (qmail-remote) was invoked improperly. (#5.3.5)\n"); zerodie(); } -void perm_dns() { out("D\ -Sorry, I couldn't find any host named "); -outsafe(&host); -out(". (#5.1.2)\n"); zerodie(); } -void perm_nomx() { out("D\ -Sorry, I couldn't find a mail exchanger or IP address. (#5.4.4)\n"); -zerodie(); } -void perm_ambigmx() { out("D\ -Sorry. Although I'm listed as a best-preference MX or A for that host,\n\ -it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n"); -zerodie(); } +void Logn(char *s, int n) +{ + if (ctl_log_fd) + if (substdio_put(subfderr,s,n) == -1) _exit(0); + + return; +} + +void Log(char *s) +{ + if (ctl_log_fd) + if (substdio_puts(subfderr,s) == -1) _exit(0); + + return; +} + +void smtp_to(char *s) +{ if (substdio_puts(&smtpto,s) == -1) _exit(0); Log(s); } + +void smtp_nto(char *s, int n) +{ if (substdio_put(&smtpto,s,n) == -1) _exit(0); Logn(s,n); } + +void smtp_eol(void) +{ + if (substdio_puts(subfderr, "\n") == -1) _exit(0); + if (substdio_puts(&smtpto, "\r\n") == -1) _exit(0); + flush(); +} + +void out(char *s) +{ + if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); +} + +void zero() +{ + if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); +} + +void zerodie() { zero(); flush(); _exit(0); } + +void outsafe(stralloc *sa) +{ + int i; char ch; + for (i = 0;i < sa->len;++i) { + ch = sa->s[i]; if (ch < 33) ch = '?'; + if (ch > 126) ch = '?'; + if (substdio_put(subfdoutsmall,&ch,1) == -1) _exit(0); + } +} + +void temp_noip() { out("Z4.3.0 invalid ipaddr in control/outgoingip\n"); zerodie(); } +void temp_nomem() { out("Z4.3.0 Out of memory.\n"); zerodie(); } +void temp_oserr() { out("Z4.3.0 System resources temporarily unavailable.\n"); zerodie(); } +void temp_noconn() { out("Z4.4.1 Sorry, I wasn't able to establish an SMTP connection.\n"); zerodie(); } +void temp_read() { out("Z4.3.0 Unable to read message.\n"); zerodie(); } +void temp_dnscanon(){ out("Z4.4.3 CNAME lookup failed temporarily.\n"); zerodie(); } +void temp_dns() { out("Z4.1.2 Sorry, I couldn't find any host by that name.\n"); zerodie(); } +void temp_chdir() { out("Z4.3.0 Unable to switch to home directory.\n"); zerodie(); } +void temp_control() { out("Z4.3.0 Unable to read control files.\n"); zerodie(); } +void temp_proto() { out("Z4.3.0 recipient did not talk proper QMTP\n"); zerodie(); } + +void perm_pl() { out("D5.6.2 SMTP cannot transfer messages with partial final lines.\n"); zerodie(); } +void perm_usage() { out("D5.3.5 I (qmail-remote) was invoked improperly.\n"); zerodie(); } +void perm_dns() { out("D5.1.2 Sorry, I couldn't find any host named ");outsafe(&host);out(".\n"); zerodie(); } +void perm_nomx() { out("D5.4.4 Sorry, I couldn't find a mail exchanger or IP address.\n"); zerodie(); } +void perm_ambigmx() { out("D5.4.6 Sorry. Although I'm listed as a best-preference MX or A for that host,\n" + "it isn't in my control/locals file, so I don't treat it as local.\n"); zerodie(); } void outhost() { @@ -93,20 +199,17 @@ } int flagcritical = 0; +int timeoutconnect = 60; +int smtpfd; +int timeout = 1200; void dropped() { - out("ZConnected to "); - outhost(); - out(" but connection died. "); + out("Z4.4.2 Connected to "); outhost(); out(" but connection died. "); if (flagcritical) out("Possible duplicate! "); - out("(#4.4.2)\n"); + out("\n"); zerodie(); } -int timeoutconnect = 60; -int smtpfd; -int timeout = 1200; - int saferead(fd,buf,len) int fd; char *buf; int len; { int r; @@ -114,6 +217,7 @@ if (r <= 0) dropped(); return r; } + int safewrite(fd,buf,len) int fd; char *buf; int len; { int r; @@ -122,24 +226,44 @@ return r; } -char inbuf[1024]; -substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); -char smtptobuf[1024]; -substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf); -char smtpfrombuf[128]; +char inbuf[1624]; +char smtptobuf[1624]; /* out */ +char smtpfrombuf[1624]; /* in */ + +substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf); +substdio smtpto = SUBSTDIO_FDBUF(safewrite,-1,smtptobuf,sizeof smtptobuf); substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); stralloc smtptext = {0}; -void get(ch) -char *ch; +void get(char *ch) { substdio_get(&smtpfrom,ch,1); - if (*ch != '\r') - if (smtptext.len < HUGESMTPTEXT) - if (!stralloc_append(&smtptext,ch)) temp_nomem(); + if (*ch != '\r') { + if (smtptext.len < HUGESMTPTEXT) { + if (!stralloc_append(&smtptext,ch)) temp_nomem(); + Logn(ch, 1); + } + } + + return; } +void doname(void) +{ + static int pid=0; + char pidstr[FMT_ULONG]; + + if (!pid) { pid=getpid(); } + pidstr[fmt_ulong(pidstr,pid)] = 0; + Log(name);Log(": pid ");Log(pidstr);Log(" "); + + return; +} + +void client(void) { doname(); Log("S: "); } +void doserv(void) { doname(); Log("C: "); } + unsigned long smtpcode() { unsigned char ch; @@ -147,6 +271,7 @@ if (!stralloc_copys(&smtptext,"")) temp_nomem(); + client(); get(&ch); code = ch - '0'; get(&ch); code = code * 10 + (ch - '0'); get(&ch); code = code * 10 + (ch - '0'); @@ -154,18 +279,189 @@ get(&ch); if (ch != '-') break; while (ch != '\n') get(&ch); - get(&ch); - get(&ch); - get(&ch); + client(); + get(&ch); get(&ch); get(&ch); } while (ch != '\n') get(&ch); + flush(); return code; } +#define ERR_AUTH_FAILED 1 +#define ERR_AUTH_INPUT 2 +#define ERR_AUTH_ABORT 3 + +/* AUTH LOGIN with long form */ +int client_auth_login(char *arg) +{ + doserv(); smtp_to("AUTH LOGIN"); smtp_eol(); + if (smtpcode() != 334) return ERR_AUTH_FAILED; + + if (!stralloc_copy(&slop, &authuser)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + doserv(); smtp_nto(temp.s, temp.len); smtp_eol(); + if (smtpcode() != 334) return ERR_AUTH_FAILED; + + if (!stralloc_copy(&slop, &authpass)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + doserv(); smtp_nto(temp.s, temp.len); smtp_eol(); + if (smtpcode() != 235) return ERR_AUTH_FAILED; + + return 0; +} + +/* AUTH PLAIN in short form */ +int client_auth_plain(char *arg) +{ + if (!stralloc_0(&slop)) temp_nomem(); + if (!stralloc_cat(&slop, &authuser)) temp_nomem(); + if (!stralloc_0(&slop)) temp_nomem(); + if (!stralloc_cat(&slop, &authpass)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + + doserv(); smtp_to("AUTH PLAIN "); smtp_nto(temp.s, temp.len); smtp_eol(); + if (smtpcode() != 235) return ERR_AUTH_FAILED; + + return 0; +} + +int client_auth_cram_md5(char *arg) +{ + unsigned int code; + unsigned char *e=encrypted; + int i; + + doserv(); smtp_to("AUTH CRAM-MD5"); smtp_eol(); + code = smtpcode(); + if (code != 334) return ERR_AUTH_FAILED; + if (b64decode(&resp, smtptext.s+4, smtptext.len-5) != 0) + return ERR_AUTH_INPUT; + resp.s[resp.len]=0; + + hmac_md5(resp.s, authpass.s, digest); + for (i=0; i<16; i++) { + *e = hextab[digest[i]/16]; ++e; + *e = hextab[digest[i]%16]; ++e; + } *e=0; + + if (!stralloc_copy(&slop, &authuser)) temp_nomem(); + if (!stralloc_cats(&slop, " ")) temp_nomem(); + if (!stralloc_cats(&slop, encrypted)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + + doserv(); smtp_nto(temp.s, temp.len); smtp_eol(); + code = smtpcode(); + if (code != 235) return ERR_AUTH_FAILED; + + return 0; +} + +int client_auth_cram_sha1(char *arg) +{ + unsigned int code; + unsigned char *e=encrypted; + int i; + + doserv(); smtp_to("AUTH CRAM-SHA1"); smtp_eol(); + code = smtpcode(); + if (code != 334) return ERR_AUTH_FAILED; + if (b64decode(&resp, smtptext.s+4, smtptext.len-5) != 0) + return ERR_AUTH_INPUT; + resp.s[resp.len]=0; + + hmac_sha1(resp.s, authpass.s, digest); + for (i=0; i<20; i++) { + *e = hextab[digest[i]/16]; ++e; + *e = hextab[digest[i]%16]; ++e; + } *e=0; + + if (!stralloc_copy(&slop, &authuser)) temp_nomem(); + if (!stralloc_cats(&slop, " ")) temp_nomem(); + if (!stralloc_cats(&slop, encrypted)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + + doserv(); smtp_nto(temp.s, temp.len); smtp_eol(); + code = smtpcode(); + if (code != 235) return ERR_AUTH_FAILED; + + return 0; +} + +int client_auth_cram_rmd(char *arg) +{ + unsigned int code; + unsigned char *e=encrypted; + int i; + + doserv(); smtp_to("AUTH CRAM-RIPEMD"); smtp_eol(); + code = smtpcode(); + if (code != 334) return ERR_AUTH_FAILED; + if (b64decode(&resp, smtptext.s+4, smtptext.len-5) != 0) + return ERR_AUTH_INPUT; + resp.s[resp.len]=0; + + hmac_ripemd(resp.s, authpass.s, digest); + for (i=0; i<20; i++) { + *e = hextab[digest[i]/16]; ++e; + *e = hextab[digest[i]%16]; ++e; + } *e=0; + + if (!stralloc_copy(&slop, &authuser)) temp_nomem(); + if (!stralloc_cats(&slop, " ")) temp_nomem(); + if (!stralloc_cats(&slop, encrypted)) temp_nomem(); + if (b64encode(&temp, &slop) != 0) return ERR_AUTH_INPUT; + + doserv(); smtp_nto(temp.s, temp.len); smtp_eol(); + code = smtpcode(); + if (code != 235) return ERR_AUTH_FAILED; + + return 0; +} + +/* XXX */ +int client_auth_digest_md5(char *arg) +{ + unsigned int code; + + doserv(); smtp_to("AUTH DIGEST-MD5"); smtp_eol(); + code = smtpcode(); + return 0; +} + +int client_auth_notsupported(char *arg) +{ + quit("DConnected to "," but can't do authentication with of that type!"); + return 1; +} + +void doauth(char *arg) +{ + int i; + +// doname(); Log("trying auth with: "); Log(arg); Log(" ...\n"); flush(); + for (i=0; authcmds[i].text; ++i) + if (case_equals(authcmds[i].text, arg)) break; + if (!stralloc_copys(&resp, "")) temp_nomem(); + if (!stralloc_copys(&slop, "")) temp_nomem(); + if (!stralloc_copys(&temp, "")) temp_nomem(); + switch (authcmds[i].fun(arg)) { + case 0: return; + case ERR_AUTH_INPUT: + quit("DConnected to "," but we got incorrect authentication input!"); + break; + case ERR_AUTH_FAILED: + quit("DConnected to "," but authentication failed!"); + break; + case ERR_AUTH_ABORT: + quit("DConnected to "," but aborted!"); + break; + } +} + void outsmtptext() { - int i; + int i; if (smtptext.s) if (smtptext.len) { out("Remote host said: "); for (i = 0;i < smtptext.len;++i) @@ -175,16 +471,16 @@ } } -void quit(prepend,append) -char *prepend; -char *append; +void quit(char *prepend, char *append) { - substdio_putsflush(&smtpto,"QUIT\r\n"); - /* waiting for remote side is just too ridiculous */ + doserv(); + smtp_to("QUIT"); out(prepend); outhost(); out(append); out(".\n"); + smtp_eol(); + outsmtptext(); zerodie(); } @@ -203,47 +499,165 @@ while (ch != '\n') { substdio_put(&smtpto,&ch,1); r = substdio_get(&ssin,&ch,1); - if (r == 0) perm_partialline(); + if (r == 0) perm_pl(); if (r == -1) temp_read(); } substdio_put(&smtpto,"\r\n",2); } - + flagcritical = 1; substdio_put(&smtpto,".\r\n",3); - substdio_flush(&smtpto); + doserv(); Log("[...]\n"); flush(); } -stralloc recip = {0}; +char *partner_fqdn = 0; -void smtp() +#define F_EHLO_AUTH 0x01 +#define F_EHLO_SIZE 0x02 +int maxehlokwlen=0; +unsigned long ehlo() { + stralloc *sa; + char *s, *e, *p; unsigned long code; - int flagbother; - int i; - - if (smtpcode() != 220) quit("ZConnected to "," but greeting failed"); - - substdio_puts(&smtpto,"HELO "); - substdio_put(&smtpto,helohost.s,helohost.len); - substdio_puts(&smtpto,"\r\n"); - substdio_flush(&smtpto); - if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected"); - - substdio_puts(&smtpto,"MAIL FROM:<"); - substdio_put(&smtpto,sender.s,sender.len); - substdio_puts(&smtpto,">\r\n"); - substdio_flush(&smtpto); + + if (ehlokw.len > maxehlokwlen) maxehlokwlen = ehlokw.len; + ehlokw.len = 0; + + doserv(); + smtp_to("EHLO "); + smtp_nto(helohost.s, helohost.len); + smtp_eol(); + + code = smtpcode(); + if (code != 250) return code; + + s = smtptext.s; + while (*s++ != '\n') ; /* skip the first line: contains the domain */ + + e = smtptext.s + smtptext.len - 6; /* 250-?\n */ + while (s <= e) + { + if (!saa_readyplus(&ehlokw, 1)) temp_nomem(); + sa = ehlokw.sa + ehlokw.len++; + if (ehlokw.len > maxehlokwlen) *sa = sauninit; else sa->len = 0; + + /* smtptext is known to end in a '\n' */ + for (p = (s += 4); ; ++p) + if (*p == '\n' || *p == ' ' || *p == '\t') { + if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem(); + if (*p++ == '\n') break; + while (*p == ' ' || *p == '\t') p++; + s = p; + } + s = p; + /* keyword should consist of alpha-num and '-' + * broken AUTH might use '=' instead of space */ + for (p = sa->s; *p; ++p) if (*p == '=') { *p = 0; break; } + } + + return 250; +} + +void smtp(char *size) +{ + unsigned long code=0; + int flagbother, i; + + code = smtpcode(); + if (code >= 400 && code < 600) return; /* try next MX, see RFC-2821 */ + if (code != 220) quit("ZConnected to "," but greeting failed"); + + //doname(); Log("stelle1"); Log("\n"); flush(); + code = ehlo(); + if (code == 250) { + if (ehlokw.len) + for (i=0; i= ehlokw.sa[i].len) break; + } + break; + } + /* does the server support ESMTP SIZE? */ + if (case_equals(x, "SIZE")) ehloflags |= F_EHLO_SIZE; + break; + } + } + } else { + /* EHLO failed, we will try it with HELO */ + doserv(); + smtp_to("HELO "); + smtp_nto(helohost.s, helohost.len); + smtp_eol(); + if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected"); + } + + //doname(); Log("stelle3"); Log("\n"); flush(); + + /* if needed, we authenticate now */ + if (needauth) { + if (authtype.len) { + /* smtprelays gives us a mechanism */ + authtype.s[authtype.len]=0; doauth(authtype.s); + } else if (ehloflags & F_EHLO_AUTH) { + for (i=SASL_MAX; i>=0; i--) { + if ((authflags & 1<"); + if (ehloflags & F_EHLO_SIZE) { + smtp_to(" SIZE="); + smtp_to(size); + } + smtp_eol(); + code = smtpcode(); if (code >= 500) quit("DConnected to "," but sender was rejected"); if (code >= 400) quit("ZConnected to "," but sender was rejected"); - + flagbother = 0; for (i = 0;i < reciplist.len;++i) { - substdio_puts(&smtpto,"RCPT TO:<"); - substdio_put(&smtpto,reciplist.sa[i].s,reciplist.sa[i].len); - substdio_puts(&smtpto,">\r\n"); - substdio_flush(&smtpto); + doserv(); + smtp_to("RCPT TO:<"); + smtp_nto(reciplist.sa[i].s, reciplist.sa[i].len); + smtp_to(">"); + smtp_eol(); + code = smtpcode(); if (code >= 500) { out("h"); outhost(); out(" does not like recipient.\n"); @@ -259,33 +673,142 @@ } } if (!flagbother) quit("DGiving up on ",""); - - substdio_putsflush(&smtpto,"DATA\r\n"); + + doserv(); + smtp_to("DATA"); + smtp_eol(); + code = smtpcode(); if (code >= 500) quit("D"," failed on DATA command"); if (code >= 400) quit("Z"," failed on DATA command"); - + blast(); code = smtpcode(); + flagcritical = 0; if (code >= 500) quit("D"," failed after I sent the message"); if (code >= 400) quit("Z"," failed after I sent the message"); quit("K"," accepted message"); } +int qmtp_priority(int pref) +{ + if (pref < 12800) return 0; + if (pref > 13055) return 0; + if (pref % 16 == 1) return 1; + return 0; +} + +void qmtp() +{ + struct stat st; + unsigned long len; + char *x; + int i, n; + unsigned char ch; + char num[FMT_ULONG]; + int flagallok; + + if (fstat(0,&st) == -1) quit("Z", " unable to fstat stdin"); + len = st.st_size; + + num[fmt_ulong(num,len+1)]=0; + doserv(); + smtp_to(num); + smtp_to(":\n"); + while (len > 0) { + n = substdio_feed(&ssin); + if (n <= 0) _exit(32); /* wise guy again */ + x = substdio_PEEK(&ssin); + smtp_nto(x,n); + substdio_SEEK(&ssin,n); + len -= n; + } + smtp_to(","); + + len = sender.len; + num[fmt_ulong(num,len)]=0; + smtp_to(num); + smtp_to(":"); + smtp_nto(sender.s,sender.len); + smtp_to(","); + + len = 0; + for (i = 0;i < reciplist.len;++i) + len += fmt_ulong(num,reciplist.sa[i].len) + 1 + reciplist.sa[i].len + 1; + num[fmt_ulong(num,len)]=0; + smtp_to(num); + smtp_to(":"); + for (i = 0;i < reciplist.len;++i) { + num[fmt_ulong(num,reciplist.sa[i].len)]=0; + smtp_to(num); + smtp_to(":"); + smtp_nto(reciplist.sa[i].s,reciplist.sa[i].len); + smtp_to(","); + } + smtp_to(","); + flush(); + + flagallok = 1; + + for (i = 0;i < reciplist.len;++i) { + len = 0; + for (;;) { + get(&ch); + if (ch == ':') break; + if (len > 200000000) temp_proto(); + if (ch - '0' > 9) temp_proto(); + len = 10 * len + (ch - '0'); + } + if (!len) temp_proto(); + get(&ch); --len; + if ((ch != 'Z') && (ch != 'D') && (ch != 'K')) temp_proto(); + + if (!stralloc_copyb(&smtptext,&ch,1)) temp_proto(); + if (!stralloc_cats(&smtptext,"qmtp: ")) temp_nomem(); + + while (len > 0) { get(&ch); --len; } + + for (len = 0;len < smtptext.len;++len) { + ch = smtptext.s[len]; + if ((ch < 32) || (ch > 126)) smtptext.s[len] = '?'; + } + get(&ch); + if (ch != ',') temp_proto(); + smtptext.s[smtptext.len-1] = '\n'; + + if (smtptext.s[0] == 'K') out("r"); + else if (smtptext.s[0] == 'D') { + out("h"); + flagallok = 0; + } else { + out("s"); + flagallok = 0; + } + smtp_nto(smtptext.s+1, smtptext.len-1); + zero(); + } + if (!flagallok) { + out("DGiving up on ");outhost();out("\n"); + } else { + out("KAll received okay by ");outhost();out("\n"); + } + zerodie(); +} + stralloc canonhost = {0}; stralloc canonbox = {0}; void addrmangle(saout,s,flagalias,flagcname) -stralloc *saout; /* host has to be canonical, box has to be quoted */ -char *s; -int *flagalias; -int flagcname; + stralloc *saout; /* host has to be canonical, box has to be quoted */ + char *s; + int *flagalias; + int flagcname; { int j; - + *flagalias = flagcname; - + j = str_rchr(s,'@'); if (!s[j]) { if (!stralloc_copys(saout,s)) temp_nomem(); @@ -295,12 +818,12 @@ canonbox.len = j; if (!quote(saout,&canonbox)) temp_nomem(); if (!stralloc_cats(saout,"@")) temp_nomem(); - + if (!stralloc_copys(&canonhost,s + j + 1)) temp_nomem(); if (flagcname) switch(dns_cname(&canonhost)) { case 0: *flagalias = 0; break; - case DNS_MEM: temp_nomem(); + case DNS_MEM: temp_nomem(); case DNS_SOFT: temp_dnscanon(); case DNS_HARD: ; /* alias loop, not our problem */ } @@ -310,118 +833,264 @@ void getcontrols() { - if (control_init() == -1) temp_control(); - if (control_readint(&timeout,"control/timeoutremote") == -1) temp_control(); - if (control_readint(&timeoutconnect,"control/timeoutconnect") == -1) + if (control_init() == -1) temp_control(); - if (control_rldef(&helohost,"control/helohost",1,(char *) 0) != 1) - temp_control(); - switch(control_readfile(&routes,"control/smtproutes",0)) { + + if (control_readint(&timeoutconnect,"control/timeoutconnect") == -1) temp_control(); + if (control_readint(&timeout,"control/timeoutremote") == -1) temp_control(); + if (control_rldef(&helohost,"control/helohost",1,(char *) 0) != 1) temp_control(); + + switch (control_readfile(&routes,"control/smtproutes",0)) { + case -1: + temp_control(); + break; + case 0: + if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); + break; + case 1: + if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); + break; + } + + switch (control_readfile(&relays,"control/smtprelays",0)) { + case -1: + temp_control(); + break; + case 0: + if (!constmap_init(&maprelays,"",0,1)) temp_nomem(); + break; + case 1: + if (!constmap_init(&maprelays,relays.s,relays.len,1)) temp_nomem(); + break; + } + + switch (control_readfile(&qroutes,"control/qmtproutes",0)) { case -1: temp_control(); + break; case 0: - if (!constmap_init(&maproutes,"",0,1)) temp_nomem(); break; + if (!constmap_init(&mapqroutes,"",0,1)) temp_nomem(); + break; case 1: - if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break; + if (!constmap_init(&mapqroutes,qroutes.s,qroutes.len,1)) temp_nomem(); + break; + } + + switch (control_readline(&outgoingip,"control/outgoingip")) { + case -1: + if (errno == error_nomem) temp_nomem(); + temp_control(); + break; + case 0: + if (!stralloc_copys(&outgoingip, "0.0.0.0")) temp_nomem(); + break; } + if (str_equal(outgoingip.s, "0.0.0.0")) { + outip.d[0]=outip.d[1]=outip.d[2]=outip.d[3]=(unsigned long)0; + } else if (!ip_scan(outgoingip.s, &outip)) temp_noip(); + + /* logging */ + if (control_readint(&ctl_log_fd,"control/log/remote_fd") == -1) temp_control(); + if (ctl_log_fd < 0) ctl_log_fd=0; + if (ctl_log_fd) subfderr->fd = ctl_log_fd; + + return; } -void main(argc,argv) -int argc; -char **argv; + +int main(int argc, char **argv) { static ipalloc ip = {0}; - int i; - unsigned long random; + unsigned long random, prefme; char **recips; - unsigned long prefme; - int flagallaliases; - int flagalias; - char *relayhost; - + char *relayhost=0, *relayuser=0; + int flagallaliases, flagalias, flagqmtp=0; + int i; + sig_pipeignore(); - if (argc < 4) perm_usage(); + if (argc < 5) perm_usage(); if (chdir(auto_qmail) == -1) temp_chdir(); getcontrols(); - - + if (!stralloc_copys(&host,argv[1])) temp_nomem(); - - relayhost = 0; - for (i = 0;i <= host.len;++i) + if (!stralloc_copys(&authuser,"")) temp_nomem(); + if (!stralloc_copys(&authpass,"")) temp_nomem(); + if (!stralloc_copys(&authtype,"")) temp_nomem(); + addrmangle(&sender, argv[2], &flagalias, 0); + +/* + * smtprelays: mailuser@host.domain:virtual-relay|authuser|authpass|authtype + * mailuser@host.domain:virtual-relay + * mailuser@host.domain:relaysmtp|authuser|authpass|authtype + * + * smtproutes: virtual-relay:host.domain + * virtual-relay:host.domain:port + * host.domain:host2.domain + * + * qmtproutes: virtual-relay:host.domain + * virtual-relay:host.domain:port + * host.domain:host2.domain + */ + + /* control/smtprelays */ + for (i = 0; i <= sender.len; ++i) + if ((i == 0) || (i == sender.len) || (sender.s[i] == '.')) + if ((relayuser = constmap(&maprelays, sender.s + i, sender.len - i))) break; + if (relayuser && !*relayuser) relayuser = 0; + + if (relayuser) { + /* V1|mcmilk|password2 */ + /* V2|mcmilk|password2|cram-md5 */ + char *x=relayuser, *y; + + y=x; + /* forwards also non password users to virtual servers in smtproutes */ + while (*++x) if (*x == '|' || !*x) break; + if (!stralloc_copyb(&host, y, x-y)) temp_nomem(); + + y=x; + if (*x == '|') while (*++x) if (*x == '|' || !*x) { + if (!stralloc_copyb(&authuser, y+1, x-y-1)) temp_nomem(); + authuser.s[authuser.len]=0; break; + } + + y=x; + if (*x == '|') while (*++x) if (*x == '|' || !*x) { + if (!stralloc_copyb(&authpass, y+1, x-y-1)) temp_nomem(); + authpass.s[authpass.len]=0; break; + } + + /* authuser is given, so we need a password! */ + if (authuser.len && !authpass.len) temp_control(); + if (authuser.len && authpass.len) needauth=1; + + y=x; + /* optional authtype, so we don't have to parse the ehlo resp. */ + if (*x == '|') { + while (*++x); + if (!stralloc_copyb(&authtype, y+1, x-y-1)) temp_nomem(); + } + } +#if 0 + //if (relayhost) { doname(); Log("DEBUG1: relayhost="); Log(relayhost); Log("\n"); } + //if (relayuser) { doname(); Log("DEBUG1: relayuser="); Log(relayuser); Log("\n"); } + doname(); Log("DEBUG1: host="); Logn(host.s, host.len); Log("\n"); + doname(); Log("DEBUG1: authuser="); Logn(authuser.s, authuser.len); Log("\n"); + doname(); Log("DEBUG1: authpass="); Logn(authpass.s, authpass.len); Log("\n"); + doname(); Log("DEBUG1: authtype="); Logn(authtype.s, authtype.len); Log("\n"); + flush(); +#endif + + /* control/smtproutes */ + for (i = 0; i <= host.len; ++i) if ((i == 0) || (i == host.len) || (host.s[i] == '.')) - if (relayhost = constmap(&maproutes,host.s + i,host.len - i)) - break; + if ((relayhost = constmap(&maproutes,host.s + i,host.len - i))) break; if (relayhost && !*relayhost) relayhost = 0; - + if (relayhost) { i = str_chr(relayhost,':'); if (relayhost[i]) { - scan_ulong(relayhost + i + 1,&port); + scan_ulong(relayhost + i + 1, &smtp_port); relayhost[i] = 0; } if (!stralloc_copys(&host,relayhost)) temp_nomem(); + } else { + /* control/qmtproutes */ + for (i = 0; i <= host.len; ++i) + if ((i == 0) || (i == host.len) || (host.s[i] == '.')) + if ((relayhost = constmap(&mapqroutes,host.s + i,host.len - i))) break; + if (relayhost && !*relayhost) relayhost = 0; + + if (relayhost) { + i = str_chr(relayhost,':'); + if (relayhost[i]) { + scan_ulong(relayhost + i + 1, &qmtp_port); + relayhost[i] = 0; + } + if (!stralloc_copys(&host,relayhost)) temp_nomem(); + flagqmtp=1; + } } +#if 0 + //if (relayhost) { doname(); Log("DEBUG2: relayhost="); Log(relayhost); Log("\n"); } + //if (relayuser) { doname(); Log("DEBUG2: relayuser="); Log(relayuser); Log("\n"); } + doname(); Log("DEBUG2: host="); Logn(host.s, host.len); Log("\n"); + doname(); Log("DEBUG2: authuser="); Logn(authuser.s, authuser.len); Log("\n"); + doname(); Log("DEBUG2: authpass="); Logn(authpass.s, authpass.len); Log("\n"); + doname(); Log("DEBUG2: authtype="); Logn(authtype.s, authtype.len); Log("\n"); + flush(); +#endif - addrmangle(&sender,argv[2],&flagalias,0); - if (!saa_readyplus(&reciplist,0)) temp_nomem(); if (ipme_init() != 1) temp_oserr(); - + flagallaliases = 1; - recips = argv + 3; + recips = argv + 4; while (*recips) { if (!saa_readyplus(&reciplist,1)) temp_nomem(); reciplist.sa[reciplist.len] = sauninit; - addrmangle(reciplist.sa + reciplist.len,*recips,&flagalias,!relayhost); + addrmangle(reciplist.sa + reciplist.len, *recips, &flagalias, !relayhost); if (!flagalias) flagallaliases = 0; ++reciplist.len; ++recips; } - random = now() + (getpid() << 16); - switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip,&host,random)) { - case DNS_MEM: temp_nomem(); + switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip, &host, random)) { + case DNS_MEM: temp_nomem(); case DNS_SOFT: temp_dns(); case DNS_HARD: perm_dns(); - case 1: - if (ip.len <= 0) temp_dns(); + case 1: if (ip.len <= 0) temp_dns(); } - + if (ip.len <= 0) perm_nomx(); - + prefme = 100000; for (i = 0;i < ip.len;++i) if (ipme_is(&ip.ix[i].ip)) if (ip.ix[i].pref < prefme) prefme = ip.ix[i].pref; - + if (relayhost) prefme = 300000; if (flagallaliases) prefme = 500000; - + for (i = 0;i < ip.len;++i) - if (ip.ix[i].pref < prefme) - break; - - if (i >= ip.len) - perm_ambigmx(); - - for (i = 0;i < ip.len;++i) if (ip.ix[i].pref < prefme) { + if (ip.ix[i].pref < prefme) break; + if (i >= ip.len) perm_ambigmx(); + + for (i = 0; i < ip.len; ++i) + if (ip.ix[i].pref < prefme) { if (tcpto(&ip.ix[i].ip)) continue; - + smtpfd = socket(AF_INET,SOCK_STREAM,0); if (smtpfd == -1) temp_oserr(); - - if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { + + /* 1. try qmtp */ + if (flagqmtp || qmtp_priority(ip.ix[i].pref)) { + if (timeoutconn(smtpfd, &ip.ix[i].ip, &outip, + (unsigned int) qmtp_port, timeoutconnect) == 0) { + tcpto_err(&ip.ix[i].ip,0); + partner = ip.ix[i].ip; + qmtp(); /* does normally not return */ + } + close(smtpfd); + smtpfd = socket(AF_INET,SOCK_STREAM,0); + if (smtpfd == -1) temp_oserr(); + } + + /* 2. try smtp, for all possible mx records! */ + if (timeoutconn(smtpfd, &ip.ix[i].ip, &outip, + (unsigned int) smtp_port, timeoutconnect) == 0) { tcpto_err(&ip.ix[i].ip,0); partner = ip.ix[i].ip; - smtp(); /* does not return */ + partner_fqdn = ip.ix[i].fqdn; + smtp(argv[3]); /* next MX is to be tried */ } tcpto_err(&ip.ix[i].ip,errno == error_timeout); close(smtpfd); } - + temp_noconn(); + return 111; /* gcc */ } diff -urN qmail-1.03/qmail-rspawn.c qmail-1.03-md/qmail-rspawn.c --- qmail-1.03/qmail-rspawn.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-rspawn.c 2011-03-11 10:56:43.153416606 +0100 @@ -4,6 +4,7 @@ #include "exit.h" #include "fork.h" #include "error.h" +#include "fmt.h" #include "tcpto.h" void initialize(argc,argv) @@ -77,18 +78,20 @@ } } -int spawn(fdmess,fdout,s,r,at) -int fdmess; int fdout; -char *s; char *r; int at; +int +spawn(int fdmess, int fdout, unsigned long msgsize, char *s, char *r, int at) { int f; - char *(args[5]); + char *(args[6]); + char size_buf[FMT_ULONG]; + size_buf[fmt_ulong(size_buf, msgsize)] = 0; args[0] = "qmail-remote"; args[1] = r + at + 1; args[2] = s; - args[3] = r; - args[4] = 0; + args[3] = size_buf; + args[4] = r; + args[5] = 0; if (!(f = vfork())) { diff -urN qmail-1.03/qmail-sasl.c qmail-1.03-md/qmail-sasl.c --- qmail-1.03/qmail-sasl.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/qmail-sasl.c 2011-03-11 10:56:43.153416606 +0100 @@ -0,0 +1,429 @@ + +#include +#include "qmail-sasl.h" + +const char hextab[]="0123456789abcdef"; +char *sasl[] = { "LOGIN","PLAIN","CRAM-MD5","CRAM-SHA1","CRAM-RIPEMD","DIGEST-MD5" }; +char unique[FMT_ULONG + FMT_ULONG + 3]; + +int auth_for=0; /* MODE_POPUP / MODE_SMTPD */ + +substdio ssauth; +stralloc auth = {0}; /* incoming from client */ +stralloc user = {0}; /* username */ +stralloc pass = {0}; /* password */ +stralloc resp = {0}; /* response */ +stralloc slop = {0}; + +authcmd_t authcmds[] = { + { "login", auth_login } +, { "plain", auth_plain } +, { "cram-md5", auth_cram_md5 } +, { "cram-sha1", auth_cram_sha1 } +, { "cram-ripemd", auth_cram_rmd } +, { "digest-md5", auth_digest_md5 } +, { 0, err_noauth } +}; + +int authgetl(void) { + int i; + + if (!stralloc_copys(&auth, "")) die_nomem(); + for (;;) { + if (!stralloc_readyplus(&auth,1)) die_nomem(); + i = substdio_get(&ssin,auth.s + auth.len,1); + if (i != 1) die_read(); + if (auth.s[auth.len] == '\n') break; + ++auth.len; + } + + if (auth.len > 0) if (auth.s[auth.len - 1] == '\r') --auth.len; + auth.s[auth.len] = 0; + doname();Log("C: ");Log(auth.s);Log("\n"); + + if (*auth.s == '*' && *(auth.s + 1) == 0) { return ERR_AUTH_ABORT; } + if (auth.len == 0) { return ERR_AUTH_INPUT; } + + return auth.len; +} + +/* method: + * 0 = login / plain / cram + * 1 = digest-md5 + */ +#define METHOD_DIGEST_MD5 1 +int authenticate(int method) +{ + char upbuf[512]; + int child, wstat, pi[2]; + + if (!stralloc_0(&user)) die_nomem(); + if (!stralloc_0(&pass)) die_nomem(); + if (!stralloc_0(&resp)) die_nomem(); + + if (env_get("DEBUG_AUTH")) { + Log("SASL user:");Log(user.s);Log("\n"); + Log("SASL pass:");Log(pass.s);Log("\n"); + Log("SASL resp:");Log(resp.s);Log("\n"); + } + flush(); + + /* if (fd_copy(2,1) == -1) die_pipe(); */ + close(3); + if (pipe(pi) == -1) die_pipe(); + if (pi[0] != 3) die_pipe(); + switch (child = fork()) { + case -1: + die_fork(); + break; + case 0: + close(pi[1]); + sig_pipedefault(); + execvp(*childargs, childargs); + break; + } + close(pi[0]); + + substdio_fdbuf(&ssauth,safewrite,pi[1],upbuf,sizeof upbuf); + if (substdio_put(&ssauth,user.s,user.len) == -1) die_write(); + if (substdio_put(&ssauth,pass.s,pass.len) == -1) die_write(); + if (substdio_put(&ssauth,resp.s,resp.len) == -1) die_write(); + if (substdio_flush(&ssauth) == -1) die_write(); + + close(pi[1]); + byte_zero(pass.s,pass.len); + byte_zero(upbuf,sizeof upbuf); + if (wait_pid(&wstat,child) == -1) die_child(); + if (wait_crashed(wstat)) die_child(); + if (wait_exitcode(wstat)) { + sleep(ctl_auth_delay); /* wait seconds, defined @ control/auth/delay */ + return ERR_AUTH_FAILED; + } /* bad auth */ + + /* qmail-pop3d handles it self */ + if (auth_for != MODE_SMTPD) return 0; + + /* qmail-smtpd auth: */ + if (method == METHOD_DIGEST_MD5) { + /* digest-md5 requires a special okay response ... */ + int fd=open_read(resp.s); + if (read(fd, &upbuf, 33) != 32) { + close(fd); + return ERR_AUTH_FAILED; + } + close(fd); unlink(resp.s); + upbuf[32]=0; + stralloc_copys(&slop, "rspauth="); + stralloc_cats(&slop, upbuf); + slop.s[slop.len]=0; + b64encode(&resp,&slop); + resp.s[resp.len]=0; + doserv();out("334 ");out(resp.s);doeol();flush(); + if (authgetl() < 0) return ERR_AUTH_INPUT; + } + doserv(); out("235 2.0.0 auth for "); out(user.s); out(" ok, go ahad"); + doeol(); flush(); + + /* yes, good auth done */ + return 0; +} + +/* user+pass is set */ +int auth_login(char *arg) +{ + /* some clients do: 'auth login b64(username)', some not */ + if (*arg) { + if (b64decode(&user,arg,str_len(arg)) != 0) + return ERR_AUTH_INPUT; + } else { + /* Username: */ + switch (auth_for) { + case MODE_SMTPD: out_err("334 VXNlcm5hbWU6"); break; + case MODE_POPUP: out_err("+ VXNlcm5hbWU6"); break; + } + if (authgetl() < 0) return ERR_AUTH_INPUT; + if (b64decode(&user,auth.s,auth.len) != 0) + return ERR_AUTH_INPUT; + } + + /* Password: */ + switch (auth_for) { + case MODE_SMTPD: out_err("334 UGFzc3dvcmQ6"); break; + case MODE_POPUP: out_err("+ UGFzc3dvcmQ6"); break; + } + if (authgetl() < 0) return ERR_AUTH_INPUT; + if (b64decode(&pass,auth.s,auth.len) != 0) + return ERR_AUTH_INPUT; + + if (!user.len || !pass.len) + return ERR_AUTH_INPUT; + + env_put2("SASL", "LOGIN"); + return authenticate(0); +} + +/* user+pass is set */ +int auth_plain(char *arg) +{ + int i=0; + char *r_pass, *r_user, x[123]; + + doname(); Log("SASL 1("); Log(arg); Log(")\n"); flush(); + if (*arg) { + if (b64decode(&slop,arg,str_len(arg)) != 0) + return ERR_AUTH_INPUT; + } else { + switch (auth_for) { + case MODE_SMTPD: out_err("334 "); break; + case MODE_POPUP: out_err("+ "); break; + } + + if (authgetl() < 0) return ERR_AUTH_INPUT; + if (b64decode(&slop,auth.s,auth.len) != 0) + return ERR_AUTH_INPUT; + } + + if (!stralloc_0(&slop)) die_nomem(); + doname(); Log("SASL slop("); Logn(slop.s, slop.len); Log(")\n"); flush(); + + /* ignore authorize-id */ + while (slop.s[i++]) { + if (i >= slop.len) { + return ERR_AUTH_INPUT; + } + } + + r_user = slop.s + i; + doname(); Log("SASL user("); Log(r_user); Log(")\n"); flush(); + if (!stralloc_copys(&user, r_user)) die_nomem(); + while (slop.s[i++]) { + if (i >= slop.len) { + return ERR_AUTH_INPUT; + } + } + + r_pass = slop.s + i; + doname(); Log("SASL pass("); Log(r_pass); Log(")\n"); flush(); + if (!stralloc_copys(&pass, r_pass)) die_nomem(); + while (slop.s[i++]) { + if (i >= slop.len) { + return ERR_AUTH_INPUT; + } + } + + if (!pass.len || !user.len) + return ERR_AUTH_INPUT; + + env_put2("SASL", "PLAIN"); + return authenticate(0); +} + +/* user+resp is set */ +int auth_cram(char *arg) +{ + int i; + char *s; + + dounique(); + if (!stralloc_copys(&pass,"<")) die_nomem(); + if (!stralloc_cats(&pass,unique)) die_nomem(); + if (!stralloc_cats(&pass,hostname)) die_nomem(); + if (!stralloc_cats(&pass,">")) die_nomem(); + if (b64encode(&slop,&pass) != 0) die_nomem(); + if (!stralloc_0(&slop)) die_nomem(); + + doserv(); + switch (auth_for) { + case MODE_SMTPD: out("334 "); break; + case MODE_POPUP: out("+ "); break; + } + out(slop.s); doeol(); flush(); + + if (authgetl() < 0) return ERR_AUTH_INPUT; + if (b64decode(&slop,auth.s,auth.len) != 0) return ERR_AUTH_INPUT; + if (!stralloc_0(&slop)) die_nomem(); + + i = str_chr(slop.s,' '); + s = slop.s + i; + while (*s == ' ') ++s; + slop.s[i] = 0; + if (!stralloc_copys(&user,slop.s)) die_nomem(); + if (!stralloc_copys(&resp,s)) die_nomem(); + + if (!user.len || !resp.len) return ERR_AUTH_INPUT; + return authenticate(0); +} + +int auth_cram_md5(char *arg) { + env_put2("SASL", "CRAM-MD5"); + return auth_cram(arg); +} + +int auth_cram_sha1(char *arg) { + env_put2("SASL", "CRAM-SHA1"); + return auth_cram(arg); +} + +int auth_cram_rmd(char *arg) { + env_put2("SASL", "CRAM-RIPEMD"); + return auth_cram(arg); +} + +/* parse digest response */ +unsigned int scan_response(stralloc *dst, stralloc *src, const char *search) { + char *x=src->s; + int slen=strlen(search); + int i, len; + + if (!stralloc_copys(dst,"")) die_nomem(); + for (i=0; src->len>i+slen; i+=str_chr(x+i, ',')+1) { + char *s=x+i; + if (case_diffb(s, slen, search) == 0) { + s+=slen; /* skip name */ + if (*s++ != '=') return 0; /* has to be here! */ + if (*s == '"') { /* var="value" */ + s++; + len=str_chr(s, '"'); + if (!len) return 0; + if (!stralloc_catb(dst, s, len)) die_nomem(); + } else { /* var=value */ + len=str_chr(s, ','); + if (!len) str_len(s); /* should be the end */ + if (!stralloc_catb(dst, s, len)) die_nomem(); + } + return dst->len; + } + } + return 0; +} + +/* rfc 2831 + * + * sets all 3 variables: user\0pass\0resp\0 + */ +#define QOP_AUTH 1 +#define QOP_AUTH_INT 2 +#define QOP_AUTH_CONF 3 +int auth_digest_md5(char *arg) +{ + unsigned char digest[20], encrypted[41]; + char *x=encrypted; + int i,fd,qop=1; + stralloc tmp = {0}; + stralloc nonce = {0}; + + /* user+pass+resp are allready empty */ + if (!stralloc_copys(&slop,"")) die_nomem(); + + dounique(); /* create nonce */ + hmac_sha1(unique, unique+3, digest); /* should be enough :) */ + for (i=0; i<20; i++) { + *x = hextab[digest[i]/16]; ++x; + *x = hextab[digest[i]%16]; ++x; + } + *x=0; + + if (!stralloc_copys(&tmp, encrypted)) die_nomem(); + if (b64encode(&nonce,&tmp) != 0) die_nomem(); + if (!stralloc_cats(&slop,"realm=\"")) die_nomem(); + if (!stralloc_cats(&slop,hostname)) die_nomem(); + if (!stralloc_cats(&slop,"\",nonce=\"")) die_nomem(); + if (!stralloc_cat(&slop,&nonce)) die_nomem(); + if (!stralloc_cats(&slop,"\",qop=\"auth\"")) die_nomem(); + if (!stralloc_cats(&slop,",algorithm=md5-sess")) die_nomem(); + if (!stralloc_0(&slop)) die_nomem(); + if (b64encode(&tmp,&slop) != 0) die_nomem(); + + /* send digest-challenge */ + doname(); Log("SASL: we send("); Log(slop.s); Log(")\n"); flush(); + doserv(); + switch (auth_for) { + case MODE_SMTPD: out("334 "); break; + case MODE_POPUP: out("+ "); break; + } + outn(tmp.s,tmp.len); doeol(); flush(); + + /* get digest-response */ + if (authgetl() < 0) return ERR_AUTH_INPUT; + if (b64decode(&slop,auth.s,auth.len) != 0) return ERR_AUTH_INPUT; + if (!stralloc_0(&slop)) die_nomem(); + doname(); Log("SASL we got("); Log(slop.s); Log(")\n"); flush(); + + /* scan slop for all required fields, fill resp for later auth. */ + if (scan_response(&user,&slop, "username") == 0) return ERR_AUTH_INPUT; + + if (scan_response(&tmp,&slop, "digest-uri") == 0) return ERR_AUTH_INPUT; + if (!stralloc_cats(&resp, "digest-uri=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* check nc field */ + if (scan_response(&tmp,&slop, "nc") == 0) return ERR_AUTH_INPUT; + if (tmp.len != 8) return ERR_AUTH_INPUT; + if (case_diffb("00000001", 8, tmp.s) != 0) return ERR_AUTH_INPUT; + if (!stralloc_cats(&resp, "\nnc=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* check nonce */ + if (scan_response(&tmp,&slop, "nonce") == 0) return ERR_AUTH_INPUT; + if (tmp.len != nonce.len) return ERR_AUTH_INPUT; + if (case_diffb(nonce.s, tmp.len, tmp.s) != 0) return ERR_AUTH_INPUT; + if (!stralloc_cats(&resp, "\nnonce=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* check cnonce */ + if (scan_response(&tmp,&slop, "cnonce") == 0) return ERR_AUTH_INPUT; + if (!stralloc_cats(&resp, "\ncnonce=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* check qop */ + if (scan_response(&tmp,&slop, "qop") == 0) return ERR_AUTH_INPUT; + switch (tmp.len) { + case 4: qop=1; if (case_diffb("auth", 4, tmp.s) != 0) return ERR_AUTH_INPUT; break; + case 8: qop=2; if (case_diffb("auth-int", 8, tmp.s) != 0) return ERR_AUTH_INPUT; break; + case 9: qop=3; if (case_diffb("auth-conf", 9, tmp.s) != 0) return ERR_AUTH_INPUT; break; + default: return ERR_AUTH_INPUT; + } + if (!stralloc_cats(&resp, "\nqop=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* xxx: todo / check realm against control/realms or so ?! */ + if (scan_response(&tmp,&slop, "realm") == 0) return ERR_AUTH_INPUT; +// i=strlen(hostname); +// if (tmp.len != i) return ERR_AUTH_INPUT; +// if (case_diffb(hostname, i, tmp.s) != 0) return ERR_AUTH_INPUT; + if (!stralloc_cats(&resp, "\nrealm=")) die_nomem(); + if (!stralloc_cat(&resp, &tmp)) die_nomem(); + + /* check response */ + if (scan_response(&pass,&slop, "response") == 0) return ERR_AUTH_INPUT; + if (pass.len != 32) return ERR_AUTH_INPUT; + + /* user=username + * pass=response (md5 hash = 32) + * resp=authfile (with all required vars for the checkpassword utility) + * -> nc,qop,realm,nonce,cnonce,digesturi + * + * a1 = md5(user:realm:pass) : nonce : cnonce + * qop=auth: a2 = 'AUTHENTICATE' : digesturi + * qop=auth-*: a2 = 'AUTHENTICATE' : digesturi : '00000000000000000000000000000000' + * resp = md5(a1) + nonce + nc + conce + qop + md5(a2) + */ + + if (!stralloc_copys(&tmp,"/var/qmail/authdir/")) die_nomem(); + if (!stralloc_cat(&tmp, &pass)) die_nomem(); + if (!stralloc_0(&tmp)) die_nomem(); + + if ((fd=open_trunc(tmp.s)) < 0) die_child(); + if (write(fd, resp.s, resp.len) != resp.len) die_child(); + if (close(fd) < 0) die_child(); + if (!stralloc_copy(&resp,&tmp)) die_nomem(); + + /* - we call now checkqpasswd + * - it reads needed variables from in resp.s given filename + * - it checks validity + */ + if (!user.len || !pass.len || !resp.len) return ERR_AUTH_INPUT; + env_put2("SASL", "DIGEST-MD5"); + + return authenticate(1); +} diff -urN qmail-1.03/qmail-sasl.h qmail-1.03-md/qmail-sasl.h --- qmail-1.03/qmail-sasl.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/qmail-sasl.h 2011-03-11 10:56:43.153416606 +0100 @@ -0,0 +1,75 @@ +#include + +#include "byte.h" +#include "base64.h" +#include "fd.h" +#include "fmt.h" +#include "str.h" +#include "wait.h" +#include "substdio.h" +#include "open.h" +#include "exit.h" +#include "fork.h" +#include "error.h" +#include "tcpto.h" +#include "now.h" +#include "sig.h" +#include "case.h" +#include "env.h" +#include "out_log.h" +#include "hmac_sha1.h" +#include "stralloc.h" + +/* BEGIN have to be defined from extern */ +extern char unique[]; +extern char *hostname; +extern char **childargs; +extern substdio ssin; + +extern int ctl_log_err; +extern int *ctl_auth_current; + +extern int auth_for; +#define MODE_UNKNOWN 0 +#define MODE_POPUP 1 +#define MODE_SMTPD 2 + +extern int safewrite(int fd, char *buf, int len); +extern int saferead(int fd, char *buf, int len); +extern int err_noauth(); +extern void die_nomem(); +extern void die_child(); +extern void die_read(); +extern void die_pipe(); +extern void die_fork(); +extern void die_write(); +/* END OF have to be defined */ + +/* qmail-sasl.h variables */ +#define ERR_AUTH_FAILED 1 +#define ERR_AUTH_INPUT 2 +#define ERR_AUTH_ABORT 3 +extern int ctl_auth_delay; /* standard = 5 */ + +extern char upbuf[128]; +extern substdio ssauth; +extern stralloc auth; +extern stralloc user; +extern stralloc pass; +extern stralloc resp; +extern stralloc slop; + +#define SASL_MAX 6 +extern char *sasl[]; +/* 1 */ extern int auth_login(char *arg); +/* 2 */ extern int auth_plain(char *arg); +/* 4 */ extern int auth_cram_md5(char *arg); +/* 8 */ extern int auth_cram_sha1(char *arg); +/* 16 */ extern int auth_cram_rmd(char *arg); +/* 32 */ extern int auth_digest_md5(char *arg); + +typedef struct { + char *text; + int (*fun)(); +} authcmd_t; +extern authcmd_t authcmds[]; diff -urN qmail-1.03/qmail-send.9 qmail-1.03-md/qmail-send.9 --- qmail-1.03/qmail-send.9 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-send.9 2011-03-11 10:56:43.153416606 +0100 @@ -51,7 +51,9 @@ .B qmail-send receives a HUP signal, it will reread -.I locals +.IR concurrencylocal , +.IR concurrencyremote , +.IR locals and .IR virtualdomains . .TP 5 diff -urN qmail-1.03/qmail-send.c qmail-1.03-md/qmail-send.c --- qmail-1.03/qmail-send.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-send.c 2011-03-11 10:56:43.153416606 +0100 @@ -1,5 +1,7 @@ #include #include +#include + #include "readwrite.h" #include "sig.h" #include "direntry.h" @@ -96,7 +98,7 @@ } void fnmake_info(id) unsigned long id; { fn.len = fmtqfn(fn.s,"info/",id,1); } -void fnmake_todo(id) unsigned long id; { fn.len = fmtqfn(fn.s,"todo/",id,0); } +void fnmake_todo(id) unsigned long id; { fn.len = fmtqfn(fn.s,"todo/",id,1); } void fnmake_mess(id) unsigned long id; { fn.len = fmtqfn(fn.s,"mess/",id,1); } void fnmake_foop(id) unsigned long id; { fn.len = fmtqfn(fn.s,"foop/",id,0); } void fnmake_split(id) unsigned long id; { fn.len = fmtqfn(fn.s,"",id,1); } @@ -262,6 +264,8 @@ while (!stralloc_copys(&comm_buf[c],"")) nomem(); ch = delnum; while (!stralloc_append(&comm_buf[c],&ch)) nomem(); + ch = delnum >> 8; + while (!stralloc_append(&comm_buf[c],&ch)) nomem(); fnmake_split(id); while (!stralloc_cats(&comm_buf[c],fn.s)) nomem(); while (!stralloc_0(&comm_buf[c])) nomem(); @@ -452,15 +456,14 @@ { int c; struct prioq_elt pe; - time_t ut[2]; /* XXX: more portable than utimbuf, but still worrisome */ + struct utimbuf ut; /* this is correct /TR !!! */ for (c = 0;c < CHANNELS;++c) - while (prioq_min(&pqchan[c],&pe)) - { + while (prioq_min(&pqchan[c],&pe)) { prioq_delmin(&pqchan[c]); fnmake_chanaddr(pe.id,c); - ut[0] = ut[1] = pe.dt; - if (utime(fn.s,ut) == -1) + ut.actime = ut.modtime = pe.dt; + if (utime(fn.s,&ut) == -1) log3("warning: unable to utime ",fn.s,"; message will be retried too soon\n"); } } @@ -906,41 +909,42 @@ dline[c].len = REPORTMAX; /* qmail-lspawn and qmail-rspawn are responsible for keeping it short */ /* but from a security point of view, we don't trust rspawn */ - if (!ch && (dline[c].len > 1)) + if (!ch && (dline[c].len > 2)) { delnum = (unsigned int) (unsigned char) dline[c].s[0]; + delnum += (unsigned int) ((unsigned int) dline[c].s[1]) << 8; if ((delnum < 0) || (delnum >= concurrency[c]) || !d[c][delnum].used) log1("warning: internal error: delivery report out of range\n"); else { strnum3[fmt_ulong(strnum3,d[c][delnum].delid)] = 0; - if (dline[c].s[1] == 'Z') + if (dline[c].s[2] == 'Z') if (jo[d[c][delnum].j].flagdying) { - dline[c].s[1] = 'D'; + dline[c].s[2] = 'D'; --dline[c].len; while (!stralloc_cats(&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem(); while (!stralloc_0(&dline[c])) nomem(); } - switch(dline[c].s[1]) + switch(dline[c].s[2]) { case 'K': log3("delivery ",strnum3,": success: "); - logsafe(dline[c].s + 2); + logsafe(dline[c].s + 3); log1("\n"); markdone(c,jo[d[c][delnum].j].id,d[c][delnum].mpos); --jo[d[c][delnum].j].numtodo; break; case 'Z': log3("delivery ",strnum3,": deferral: "); - logsafe(dline[c].s + 2); + logsafe(dline[c].s + 3); log1("\n"); break; case 'D': log3("delivery ",strnum3,": failure: "); - logsafe(dline[c].s + 2); + logsafe(dline[c].s + 3); log1("\n"); - addbounce(jo[d[c][delnum].j].id,d[c][delnum].recip.s,dline[c].s + 2); + addbounce(jo[d[c][delnum].j].id,d[c][delnum].recip.s,dline[c].s + 3); markdone(c,jo[d[c][delnum].j].id,d[c][delnum].mpos); --jo[d[c][delnum].j].numtodo; break; @@ -1216,7 +1220,8 @@ /* this file is too long ---------------------------------------------- TODO */ datetime_sec nexttodorun; -DIR *tododir; /* if 0, have to opendir again */ +int flagtododir = 0; /* if 0, have to readsubdir_init again */ +readsubdir todosubdir; stralloc todoline = {0}; char todobuf[SUBSTDIO_INSIZE]; char todobufinfo[512]; @@ -1224,7 +1229,7 @@ void todo_init() { - tododir = 0; + flagtododir = 0; nexttodorun = now(); trigger_set(); } @@ -1236,7 +1241,7 @@ { if (flagexitasap) return; trigger_selprep(nfds,rfds); - if (tododir) *wakeup = 0; + if (flagtododir) *wakeup = 0; if (*wakeup > nexttodorun) *wakeup = nexttodorun; } @@ -1253,8 +1258,6 @@ char ch; int match; unsigned long id; - unsigned int len; - direntry *d; int c; unsigned long uid; unsigned long pid; @@ -1265,32 +1268,26 @@ if (flagexitasap) return; - if (!tododir) + if (!flagtododir) { if (!trigger_pulled(rfds)) if (recent < nexttodorun) return; trigger_set(); - tododir = opendir("todo"); - if (!tododir) - { - pausedir("todo"); - return; - } + readsubdir_init(&todosubdir, "todo", pausedir); + flagtododir = 1; nexttodorun = recent + SLEEP_TODO; } - d = readdir(tododir); - if (!d) + switch(readsubdir_next(&todosubdir, &id)) { - closedir(tododir); - tododir = 0; - return; + case 1: + break; + case 0: + flagtododir = 0; + default: + return; } - if (str_equal(d->d_name,".")) return; - if (str_equal(d->d_name,"..")) return; - len = scan_ulong(d->d_name,&id); - if (!len || d->d_name[len]) return; fnmake_todo(id); @@ -1478,10 +1475,17 @@ if (control_readfile(&newlocals,"control/locals",1) != 1) { log1("alert: unable to reread control/locals\n"); return; } + r = control_readfile(&newvdoms,"control/virtualdomains",0); if (r == -1) { log1("alert: unable to reread control/virtualdomains\n"); return; } + if (control_readint(&concurrency[0],"control/concurrencylocal") == -1) + { log1("alert: unable to reread control/concurrencylocal\n",0); return; } + + if (control_readint(&concurrency[1],"control/concurrencyremote") == -1) + { log1("alert: unable to reread control/concurrencyremote\n",0); return; } + constmap_free(&maplocals); constmap_free(&mapvdoms); @@ -1512,7 +1516,7 @@ } } -void main() +int main() { int fd; datetime_sec wakeup; @@ -1544,7 +1548,7 @@ numjobs = 0; for (c = 0;c < CHANNELS;++c) { - char ch; + char ch, ch1; int u; int r; do @@ -1552,7 +1556,13 @@ while ((r == -1) && (errno == error_intr)); if (r < 1) { log1("alert: cannot start: hath the daemon spawn no fire?\n"); _exit(111); } + do + r = read(chanfdin[c],&ch1,1); + while ((r == -1) && (errno == error_intr)); + if (r < 1) + { log1("alert: cannot start: hath the daemon spawn no fire?\n"); _exit(111); } u = (unsigned int) (unsigned char) ch; + u += (unsigned int) ((unsigned char) ch1) << 8; if (concurrency[c] > u) concurrency[c] = u; numjobs += concurrency[c]; } @@ -1608,5 +1618,5 @@ } pqfinish(); log1("status: exiting\n"); - _exit(0); + return 0; } diff -urN qmail-1.03/qmail-showctl.c qmail-1.03-md/qmail-showctl.c --- qmail-1.03/qmail-showctl.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-showctl.c 2011-03-11 10:56:43.153416606 +0100 @@ -1,5 +1,6 @@ #include #include +#include #include "substdio.h" #include "subfd.h" #include "exit.h" @@ -16,9 +17,6 @@ #include "auto_spawn.h" #include "auto_split.h" -stralloc me = {0}; -int meok; - stralloc line = {0}; char num[FMT_ULONG]; @@ -136,7 +134,7 @@ } } -void main() +int main() { DIR *dir; direntry *d; @@ -215,11 +213,14 @@ } do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM."); + do_lst("badmailto","Any RCPT TO is allowed.",""," not accepted in RCPT TO."); + do_lst("badhelo","Any HELO is allowed.",""," not accepted in HELO."); do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is "); do_str("bouncehost",1,"bouncehost","Bounce host name is "); do_int("concurrencylocal","10","Local concurrency is ",""); do_int("concurrencyremote","20","Remote concurrency is ",""); do_int("databytes","0","SMTP DATA limit is "," bytes"); + do_int("databytes+","5000","MAIL SIZE can differ an about "," bytes"); do_str("defaultdomain",1,"defaultdomain","Default domain name is "); do_str("defaulthost",1,"defaulthost","Default host name is "); do_str("doublebouncehost",1,"doublebouncehost","2B recipient host: "); @@ -230,6 +231,7 @@ do_str("localiphost",1,"localiphost","Local IP address becomes "); do_lst("locals","Messages for me are delivered locally.","Messages for "," are delivered locally."); do_str("me",0,"undefined! Uh-oh","My name is "); + do_str("outgoingip",0,"0.0.0.0","Outgoing IP address is "); do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@","."); do_str("plusdomain",1,"plusdomain","Plus domain name is "); do_lst("qmqpservers","No QMQP servers.","QMQP server: ","."); @@ -239,7 +241,6 @@ do_lst("morercpthosts","No effect.","SMTP clients may send messages to recipients at ","."); else do_lst("morercpthosts","No rcpthosts; morercpthosts is irrelevant.","No rcpthosts; doesn't matter that morercpthosts has ","."); - /* XXX: check morercpthosts.cdb contents */ substdio_puts(subfdout,"\nmorercpthosts.cdb: "); if (stat("morercpthosts",&stmrh) == -1) if (stat("morercpthosts.cdb",&stmrhcdb) == -1) @@ -257,22 +258,35 @@ do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 "); do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ",""); + do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds"); do_int("timeoutremote","1200","SMTP client data timeout is "," seconds"); do_int("timeoutsmtpd","1200","SMTP server data timeout is "," seconds"); do_lst("virtualdomains","No virtual domains.","Virtual domain: ",""); - while (d = readdir(dir)) { + /* from patches */ + do_int("mfcheck", "off (0)", "The FQDN MX or A record check is ",""); + do_int("maxrcpt", "off (0)", "The maximum recipients a client may want to use is ",""); + do_int("maxcmdlen", "off (0)", "The maximum command length can be ",""); + do_int("tarpitcount", "0", "The actual tarpitcount is ",""); + do_int("tarpitdelay", "0", "The tarpitdelay is "," seconds"); + do_lst("datechecks", "No datechecks will be done.","mailaddress "," days."); + + while ((d = readdir(dir))) { if (str_equal(d->d_name,".")) continue; if (str_equal(d->d_name,"..")) continue; if (str_equal(d->d_name,"bouncefrom")) continue; if (str_equal(d->d_name,"bouncehost")) continue; if (str_equal(d->d_name,"badmailfrom")) continue; + if (str_equal(d->d_name,"badmailto")) continue; + if (str_equal(d->d_name,"badhelo")) continue; if (str_equal(d->d_name,"bouncefrom")) continue; if (str_equal(d->d_name,"bouncehost")) continue; if (str_equal(d->d_name,"concurrencylocal")) continue; if (str_equal(d->d_name,"concurrencyremote")) continue; if (str_equal(d->d_name,"databytes")) continue; + if (str_equal(d->d_name,"databytes+")) continue; + if (str_equal(d->d_name,"datechecks")) continue; if (str_equal(d->d_name,"defaultdomain")) continue; if (str_equal(d->d_name,"defaulthost")) continue; if (str_equal(d->d_name,"doublebouncehost")) continue; @@ -282,7 +296,16 @@ if (str_equal(d->d_name,"idhost")) continue; if (str_equal(d->d_name,"localiphost")) continue; if (str_equal(d->d_name,"locals")) continue; + + /* these are directories @ my servers */ + if (str_equal(d->d_name,"certs")) continue; + if (str_equal(d->d_name,"auth")) continue; + if (str_equal(d->d_name,"log")) continue; + + if (str_equal(d->d_name,"maxrcpt")) continue; + if (str_equal(d->d_name,"maxcmdlen")) continue; if (str_equal(d->d_name,"me")) continue; + if (str_equal(d->d_name,"mfcheck")) continue; if (str_equal(d->d_name,"morercpthosts")) continue; if (str_equal(d->d_name,"morercpthosts.cdb")) continue; if (str_equal(d->d_name,"percenthack")) continue; @@ -292,10 +315,31 @@ if (str_equal(d->d_name,"rcpthosts")) continue; if (str_equal(d->d_name,"smtpgreeting")) continue; if (str_equal(d->d_name,"smtproutes")) continue; + + if (str_equal(d->d_name,"spfbehavior")) continue; + if (str_equal(d->d_name,"spfexp")) continue; + if (str_equal(d->d_name,"spfguess")) continue; + if (str_equal(d->d_name,"spfrules")) continue; + + if (str_equal(d->d_name,"softlimit")) continue; /* some use this place */ + if (str_equal(d->d_name,"tarpitcount")) continue; + if (str_equal(d->d_name,"tarpitdelay")) continue; if (str_equal(d->d_name,"timeoutconnect")) continue; if (str_equal(d->d_name,"timeoutremote")) continue; if (str_equal(d->d_name,"timeoutsmtpd")) continue; if (str_equal(d->d_name,"virtualdomains")) continue; + + /* tls/ssl stuff */ + if (str_equal(d->d_name,"certs")) continue; /* ignored */ + if (str_equal(d->d_name,"clientcert.pem")) continue; + if (str_equal(d->d_name,"tlsclientciphers")) continue; + if (str_equal(d->d_name,"tlshosts")) continue; /* special dir with FQDN.pem's */ + if (str_equal(d->d_name,"clientca.pem")) continue; + if (str_equal(d->d_name,"rsa512.pem")) continue; + if (str_equal(d->d_name,"servercert.pem")) continue; + if (str_equal(d->d_name,"tlsclients")) continue; + if (str_equal(d->d_name,"tlsserverciphers")) continue; + substdio_puts(subfdout,"\n"); substdio_puts(subfdout,d->d_name); substdio_puts(subfdout,": I have no idea what this file does.\n"); diff -urN qmail-1.03/qmail-smtpd.8 qmail-1.03-md/qmail-smtpd.8 --- qmail-1.03/qmail-smtpd.8 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-smtpd.8 2011-03-11 10:56:43.153416606 +0100 @@ -1,11 +1,15 @@ .TH qmail-smtpd 8 .SH NAME -qmail-smtpd \- receive mail via SMTP +qmail-smtpd \- receive mail via SMTP or ESMTP .SH SYNOPSIS .B qmail-smtpd +.I checkpassword +[ +.I args +] .SH DESCRIPTION .B qmail-smtpd -receives mail messages via the Simple Mail Transfer Protocol (SMTP) +receives mail messages via the Simple Mail Transfer Protocol (SMTP/ESMTP) and invokes .B qmail-queue to deposit them into the outgoing queue. @@ -15,15 +19,17 @@ .BR tcp-environ(5) . .B qmail-smtpd -is responsible for counting hops. -It rejects any message with 100 or more +is responsible for counting hops. It rejects any message with 100 or more .B Received or .B Delivered-To -header fields. +header fields. The Default value of 100 is changeable via the +.I maxhops +contrilfile. .B qmail-smtpd -supports ESMTP, including the 8BITMIME and PIPELINING options. +supports ESMTP, including the 8BITMIME, PIPELINING, STARTTLS, AUTH and SIZE +options. .SH TRANSPARENCY .B qmail-smtpd converts the SMTP newline convention into the UNIX newline convention @@ -39,30 +45,67 @@ .TP 5 .I badmailfrom Unacceptable envelope sender addresses. -.B qmail-smtpd -will reject every recipient address for a message -if the envelope sender address is listed in -.IR badmailfrom . -A line in -.I badmailfrom -may be of the form -.BR @\fIhost , -meaning every address at -.IR host . +.br +This file contains in each line one regular expression. The matching is done +against the +.I XYZ +contents of the SMTP command \fIMAIL FROM:\fR +.br +If \fIBADMAILFROM\fR is set, this file will be use instead of +\fIcontrol/badmailfrom\fR, and if \fINO_BADMAILFROM\fR is set, no badhelo +checks at all will be done. + +.TP 5 +.I badmailto +Unacceptable recipient addresses. +.br +This file contains in each line one regular expression. The matching is done +against the +.I XYZ +contents of the SMTP command \fIRCPT TO:\fR +.br +If \fIBADMAILTO\fR is set, this file will be use instead of +\fIcontrol/badmailto\fR, and if \fINO_BADMAILTO\fR is set, no badmailto checks +at all will be done. + +.TP 5 +.I badhelo +Unacceptable helohost. +.br +This file contains in each line one regular expression. The matching is done +against the +.I XYZ +contents of the SMTP commands \fIHELO YXZ\fR or \fIEHLO XYZ\fR. +.br +If \fIBADHELO\fR is set, this file will be use instead of \fIcontrol/badhelo\fR, +and if \fINO_BADHELO\fR is set, no badhelochecks at all will be done. + +.TP 5 +.I datechecks +A list of string:day pairs, where string means a start of a mailaddress and +day means a number. It can be used to specify mailaddresses e.g. in the +usenet, which have only a short lifetime. +.br +Here is an example: +.I datechecks +has an entry like this \fInews-:6\fR, that means, if today is the 2004-07-02, +than a mail like \fInews-20040704@some.domain.com\fR will accepted, because it +is in the 6 day limit. But a mail like \fInews-20040622@some.domain.com\fR +will be rejected. + .TP 5 .I databytes -Maximum number of bytes allowed in a message, -or 0 for no limit. +Maximum number of bytes allowed in a message, or 0 for no limit. Default: 0. If a message exceeds this limit, .B qmail-smtpd -returns a permanent error code to the client; -in contrast, if -the disk is full or +returns a permanent error code to the client; in contrast, if the disk is full +or .B qmail-smtpd hits a resource limit, .B qmail-smtpd -returns a temporary error code. +returns a temporary error code. This value is also used for the ESMTP SIZE +extension. .I databytes counts bytes as stored on disk, not as transmitted through the network. @@ -71,11 +114,23 @@ Received line, the .B qmail-queue Received line, or the envelope. - If the environment variable .B DATABYTES is set, it overrides .IR databytes . + +.TP 5 +.I databytes+ +This integer value is added to the maximum databytes a message can have, when +the client sends mail via the ESMTP SIZE extension. +.br +Sample: if +.I databytes+ +is 100 and a client sends \fIMAIL FROM: SIZE=12345\fR, than the +maximum data in the DATA transfer can be databytes+100 at most! +.I databytes+ +defaults to 5000. + .TP 5 .I localiphost Replacement host name for local IP addresses. @@ -96,6 +151,50 @@ .IR localiphost . This is done before .IR rcpthosts . + +.TP 5 +.I maxcmdlen +When a client sends a command which is longer than +.IR maxcmdlen , +than the client gets tarpitted and the connection is closed. + +.TP 5 +.I maxaddrlen +When the client's sender or recipient mailaddress is longer than +.IR maxaddrlen , +the client gets tarpitted and the connection is closed. + +.TP 5 +.I maxhops +The maximum number of hops an email is allowd to have. See above, for a complete +description of counting hops. + +.TP 5 +.I maxrcpt +When the number of \fIRCPT TO:\fR commands is greater or equal with the number +which is stored in this file, than qmail will tarpit+close the connection. +Default: 0, which means no maximum. +The environment variable \fINO_MAXRCPT\fR and \fIMAXRCPT\fR override the +contents of \fImaxrcpt\fR. + +.TP 5 +.I mfcheck +If this file exists and contains a non-zero integer, the envelope sender's +domain must have an MX or A record associated. Temporary failures will result in +a temporary SMTP error. By setting the \fINO_MFCHECK\fR variable you can +disable the check, but by setting the \fIMFCHECK\fR variable to an integer, you +can even enable/disable the mfchecks. + 0 - no checking @all (default value) + 1 - mx record will be checked + 2 - SMTP callback/sender verification will be done () + +.TP 5 +.I mxblacklist +This file contains one ip per line, which itentifies bad mx adresses for +mailserver. Spammer use for example some dnsmx, which points to '127.0.0.1', +which can be forbidden by that file. +Maybe someone tries to explain this control file a bit better ;) + .TP 5 .I morercpthosts Extra allowed RCPT domains. @@ -119,6 +218,11 @@ .IR rcpthosts , and the rest into .IR morercpthosts . + +.TP 5 +.I rcptchecks +xxx todo (interface unclear, any comments??) + .TP 5 .I rcpthosts Allowed RCPT domains. @@ -140,17 +244,15 @@ and will append the value of .B RELAYCLIENT to each incoming recipient address. - .I rcpthosts may include wildcards: - .EX heaven.af.mil .heaven.af.mil .EE - Envelope recipient addresses without @ signs are always allowed through. + .TP 5 .I smtpgreeting SMTP greeting message. @@ -163,17 +265,126 @@ The first word of .I smtpgreeting should be the current host's name. + .TP 5 .I timeoutsmtpd Number of seconds .B qmail-smtpd will wait for each new buffer of data from the remote SMTP client. Default: 1200. + +.TP 5 +.I tarpitcount +if +.I NO_TARPITTING +is not set, than tarpitcount is the number of RCPT TO: +.B qmail-smtpd +accepts before it starts tarpitting. Default: 0 which means no tarpitting. +The environment variable +.B TARPITCOUNT +overrides the default. + +.TP 5 +.I tarpitdelay +if +.I NO_TARPITTING +is not set, than tarpitdelay is the time in seconds of delay to be introduced +after each subsequent RCPT TO: Default: 5. The environment variable +.B TARPITDELAY +overrides the default. + +.SH "ESMTP STARTTLS" +.TP 5 +.I clientca.pem +A list of Certifying Authority (CA) certificates that are used to verify +the client-presented certificates during a TLS-encrypted session. + +.TP 5 +.I tlsclients +A list of email addresses. When relay rules would reject an incoming message, +.B qmail-smtpd +can allow it if the client presents a certificate that can be verified against +the CA list in +.I clientca.pem +and the certificate email address is in +.IR tlsclients . + +.TP 5 +.I tlsserverciphers +A set of OpenSSL cipher strings. Multiple ciphers contained in a +string should be separated by a colon. If the environment variable +.B TLSCIPHERS +is set to such a string, it takes precedence. + + +.SH "ESMTP AUTH" +ESMTP Authentication is now fully functional implemented into +.BR qmail-smtpd . +Clients can send commands like +\fIMAIL FROM: SIZE=1234 AUTH=LOGIN\fR and qmail will know about +that! + +.TP 5 +.I auth/delay +This file holds the number of seconds +.B qmail-smtpd +has to wait, when a user authenticates with a wrong password. + +.TP 5 +.I auth/smtp +This file holds a number, which tells +.B qmail-smtpd +what authentication methods for insecure email transfer can be used. THe default +is 60, which means LOGIN and PLAIN are forbidden! + +.TP 5 +.I auth/smtps +This file holds a number, which tells +.B qmail-smtpd +what authentication methods for secure email transfer can be used. The default +value is 63, which means all currently available methods can be used! + +.TP 5 +.I REQUIREAUTH +When this environment variable is set, +.B qmail-smtpd +will refuse to do anything, if the client hasn't authenticated. + +.SH "LOGGING OPTIONS" +.TP 5 +.I log/bmchecks +Enable or disable logging of badmailfrom, badmailto and badhelo checks. + +.TP 5 +.I log/datechecks +Enable or disable logging of the datechecking. + +.TP 5 +.I log/orchecks +Enable or disable logging of the open relay tests. + +.TP 5 +.I log/smtp_in +Enable or disable logging of the open relay tests. + +.TP 5 +.I log/smtp_fd +You should put in here a valid filedescriptor, which can be used for logging. + +.TP 5 +.I log/smtp_out +Enable or disable logging of the open relay tests. + +.TP 5 +.I log/tarpitting +Enable or disable the logging of some info about the client which gets tarpitted. + .SH "SEE ALSO" -tcp-env(1), -tcp-environ(5), -qmail-control(5), -qmail-inject(8), -qmail-newmrh(8), -qmail-queue(8), -qmail-remote(8) +.BR tcp-env (1), +.BR tcp-environ (5), +.BR qmail-control (5), +.BR qmail-inject (8), +.BR qmail-newmrh (8), +.BR qmail-queue (8), +.BR qmail-remote (8), +.BR rblsmtpd (8) diff -urN qmail-1.03/qmail-smtpd.c qmail-1.03-md/qmail-smtpd.c --- qmail-1.03/qmail-smtpd.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-smtpd.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,3 +1,18 @@ + +#define DEFAULT_TIMEOUT 100 +#define DEFAULT_MAXHOPS 100 +#define HUGESMTPTEXT 5000 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "sig.h" #include "readwrite.h" #include "stralloc.h" @@ -22,136 +37,612 @@ #include "rcpthosts.h" #include "timeoutread.h" #include "timeoutwrite.h" +#include "timeoutconn.h" #include "commands.h" +#include "dns.h" +#include "wait.h" +#include "fd.h" +#include "out_log.h" +#include "qmail-sasl.h" +#include "qmail-p0f.h" +#include "ucspitls.h" + +/* global /var/qmail/controls */ +int ctl_localiphost; +int ctl_databytes; /* default: 0 = no limit */ +int ctl_databytesP; /* default: 5000 */ +int ctl_timeout; /* timeout for connection to die */ +int ctl_maxrcpt; /* max number of recipient we allow */ +int ctl_maxhops; /* max number of hops we allow */ +int ctl_maxaddrlen; /* max length a mailaddress can have */ +int ctl_maxcmdlen; /* max length a smtp command may have */ +int ctl_tarpitcount; /* when do we want to tarpit */ +int ctl_tarpitdelay; /* tarpitdelay in seconds */ +int ctl_rcpttofixed; /* if set, we have a fixed RCPT TO: */ +int ctl_reqbrackets; /* enforce <> in the mail from & rcpt to / defaults to YES */ +char *ctl_p0fsock=0; /* p0f socket, if 0 - no socket is there! */ + +int tls_available = 0; +int tls_started = 0; + +#define BMCHECK_BMF 1 /* badmailfrom */ +#define BMCHECK_BMT 2 /* badmailto */ +#define BMCHECK_BMH 3 /* badhelo */ +#define GMCHECK_GMF 4 /* goodmailfrom */ +int ctl_bmh, ctl_bmf, ctl_bmt, ctl_gmf; + +int ctl_clamd; /* cheking for viruses via clamd / ip:port */ +int ctl_mfcheck; /* enable/disable dns mx/a check */ +int ctl_orcheck; /* enable/disable open relay checks */ +int ctl_rcptchecks; /* enable/disable rcptchecks via external programs */ +int ctl_datechecks; /* enable/disable usenet-YYYYMMDD checking */ +int ctl_bigbrother; /* see TODO */ +int ctl_mxblacklist; /* mxblacklist */ +stralloc ctl_outgoingip = {0}; /* outgoing ip */ + +/* logging */ +int ctl_log_fd; /* fd, where we want to log to */ +int ctl_log_in; /* enable/disable incoming network traffik (S: ...) */ +int ctl_log_out; /* enable/disable outgoing network traffik (C: ...) */ +int ctl_log_bmchecks; /* enable/disable bad mail checks logging */ +int ctl_log_orchecks; /* enable/disable open relay checks logging */ +int ctl_log_datechecks; /* enable/disable datechecks logging */ +int ctl_log_tarpitting; /* enable/disable tarpitting logging */ + +/* esmtp auth */ +int ctl_auth_oldauth; /* if >0, then the old ehlo resp. "AUTH=x1 x2" is also used */ +int ctl_auth_delay; /* auth-delay is issued, when a password failure has occured */ +int ctl_auth_secure=(1|2|4|8|16); /* sasl methods in TLS mode */ +int ctl_auth_insecure=(4|8|16); /* sasl methods in NON-TLS mode */ +int *ctl_auth_current = &ctl_auth_insecure; /* depends on the current tls state */ + +stralloc bmf = {0}; /* control/badmailfrom content */ +stralloc bmt = {0}; /* control/badmailto content */ +stralloc bmh = {0}; /* control/badhelo content */ +stralloc gmf = {0}; /* control/goodmailfrom content */ +stralloc dcf = {0}; /* control/datechecks content */ +stralloc bbr = {0}; /* control/bigbrother content */ + +stralloc mxbl = {0}; /* mx blacklist */ +stralloc clamd = {0}; +unsigned int clamd_port; /* daemon */ +unsigned int clamd_sport; /* stream */ +unsigned int clamd_streamok = 0; /* stream state */ +struct ip_address clamd_ip; +struct ip_address outip; + +/* misc variables */ +char *name="qmail-smtpd"; /* for commands.c */ +char smtpsize[FMT_ULONG+10]; +char **childargs; +char *hostname; +char *remoteip; +char *remotehost; +char *remoteinfo; +char *local; +char *relayclient; +char *fakehelo; +char *requireauth; -#define MAXHOPS 100 -unsigned int databytes = 0; +/* counting */ +int seenrcpt=0; /* "rcpt to:" counting - tarpitting */ +int rcptcount=0; /* how much rcpt to: we have allready */ +int seenmail=0; /* "mail from:" counting - tarpitting */ +int authdone=0; /* if 1, relay mail is okay */ +int auth_available=0;/* 1, if AUTH command can be used */ +int databytes=0; /* current max size */ +int spamfeed=0; /* are we getting spm via $BLCKLISTED */ +int timeoutconnect = 3*60; int timeout = 1200; -int safewrite(fd,buf,len) int fd; char *buf; int len; -{ - int r; - r = timeoutwrite(timeout,fd,buf,len); - if (r <= 0) _exit(1); - return r; -} +stralloc addr = {0}; +stralloc helohost = {0}; +stralloc greeting = {0}; +stralloc mailfrom = {0}; +stralloc rcptto = {0}; +stralloc liphost = {0}; +stralloc rcptchk = {0}; +stralloc proto = {0}; + +/* function prototypes */ +int addrallowed(void); +int addrparse(char *arg); +int bmcheck(int which, char *what); /* badmail* check */ +int mfcheck(void); /* mail from check */ +int orcheck(void); /* open relay check */ +int datecheck(void); /* usenet-YYYYMMDD check */ +int rcptcheck(void); /* rcpt to: check against external prog */ +int safewrite(int fd, char *buf, int len); +int saferead(int fd, char *buf, int len); +void dohelo(char *arg); +void tarpit(char*,char*,char*); +void acceptmessage(unsigned long qp); + +/* command functions */ +void smtp_rset(void); +void smtp_quit(void); +void smtp_noop(void); +void smtp_vrfy(void); +void smtp_data(void); +void smtp_help(void); +void smtp_rcpt(char *arg); +void smtp_mail(char *arg); +void smtp_helo(char *arg); +void smtp_ehlo(char *arg); +void smtp_auth(char *arg); +void smtp_starttls(char *arg); + +extern void realrcptto_init(); +extern int realrcptto(); + +#define DNS_VRFY -4 + +/* our buffers */ +char clamdbuf[256]; +char clamsbuf[256]; +char ssinbuf[1024]; +char ssoutbuf[1024]; +char sserrbuf[1024]; +char smtpfrombuf[1024]; -char ssoutbuf[512]; +substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); +substdio sserr = SUBSTDIO_FDBUF(safewrite,-1,sserrbuf,sizeof sserrbuf); +substdio smtpfrom = SUBSTDIO_FDBUF(saferead,-1,smtpfrombuf,sizeof smtpfrombuf); +substdio clamdsock = SUBSTDIO_FDBUF(saferead, -1, clamdbuf, sizeof clamdbuf); +substdio clamssock = SUBSTDIO_FDBUF(saferead, -1, clamsbuf, sizeof clamsbuf); + +void die() { flush(); _exit(1); } +void out_die(char *s) { out_err(s); die(); } +void dogreet(char *s) { doserv(); out(s); out(greeting.s); doeol(); } + +/* rfc2554 + * 530 Authentication required + * 534 Authentication mechanism is too weak + * 538 Encryption required for requested authentication mechanism + * 454 Temporary authentication failure + * + * rfc3207 + * 220 Ready to start TLS + * 501 Syntax error (no parameters allowed) + * 454 TLS not available due to temporary reason + * + * rfc1893 + rfc2034 + rfc3463 + * where: codes must appear in all 2xx, 4xx, and 5xx lines + * except: initial greeting and any response to HELO or EHLO + * note: 3xx responses are NOT included in this list + */ +void (*die_alarm)(void); +void die_alarm1() { out_die("451 4.4.2 timeout"); } +void die_alarm2() { Log("die_alarm2()"); flush(); } + +void die_read() { doname(); Log("ERROR: eof from client - SPAMMER?\n"); die(); } +void die_nomem() { out_die("421 4.3.0 out of memory"); } +void die_control() { out_die("421 4.3.0 unable to read controls"); } +void die_ipme() { out_die("421 4.3.0 unable to figure out my IP addresses"); } +void die_newline() { out_die("451 4.3.0 see http://pobox.com/~djb/docs/smtplf.html."); } +void die_smf() { out_die("451 4.3.0 dns temporary failure"); } +void die_callback() { out_die("451 4.3.0 sender address verification failed"); } +void die_nosocket() { out_die("454 4.3.0 too much load / unable to create socket"); } +void die_qqt() { out_die("451 4.3.0 qqt failure"); } +void die_child() { out_die("454 4.3.0 can't do auth (problem with child)"); } +void die_fork() { out_die("454 4.3.0 unable to fork()"); } +void die_pipe() { out_die("454 4.3.0 can't do auth (unable to open pipe)"); } +void die_write() { out_die("454 4.3.0 can't do auth (unable to write pipe)"); } +void die_cdb() { out_die("421 4.3.0 unable to read cdb user database"); } +void die_sys() { out_die("421 4.3.0 unable to read system user database"); } +void die_syserr() { out_die("421 4.3.0 system error"); } + +void die_with1() { out_die("553 5.1.1 sorry, no mailbox here by that name."); } +void die_with2() { out_die("421 4.3.0 unable to verify recipient/sender (misuse)"); } +void die_with3() { out_die("421 4.3.0 unable to verify recipient/sender (internal)"); } +void die_with11() { out_die("451 4.1.1 bad destination mailbox address"); } +void die_with12() { out_die("451 4.1.2 bad destination system address"); } +void die_with13() { out_die("451 4.1.3 bad destination mailbox address syntax"); } +void die_with14() { out_die("451 4.1.4 destination mailbox address ambiguous"); } +void die_with16() { out_die("451 4.1.6 mailbox has moved"); } +void die_with17() { out_die("451 4.1.7 bad sender's mailbox address syntax"); } +void die_with18() { out_die("451 4.1.8 bad sender's system address"); } +void die_with21() { out_die("452 4.2.1 mailbox disabled, not accepting messages"); } +void die_with22() { out_die("452 4.2.2 mailbox full"); } +void die_with111() { out_die("421 4.3.0 unable to verify recipient/sender (temporary)"); } +void die_with112() { out_die("421 4.3.0 unable to verify recipient/sender (greylisting)"); } + +/* this is stolen from postfix :) */ +void die_wantrcpt() { out_die("221 2.0.0 error: I can break rules, too. goodbye!"); } + +void err_unrecog() { out_err("500 5.5.2 unrecognised command"); } +void err_authabrt() { out_err("501 5.0.0 auth exchange cancelled"); } +void err_authdone() { out_err("503 5.5.0 you're already authenticated"); } +void err_authmail() { out_err("503 5.5.0 no auth during mail transaction"); } +void err_unimpl() { out_err("502 5.5.1 unimplemented"); } +void err_wantmail() { out_err("503 5.5.1 MAIL first"); } +int err_noauth() { out_err("504 5.5.1 auth type unimplemented"); return -1; } +int err_authin() { out_err("501 5.5.1 malformed auth input"); return -1; } +void err_authreq() { out_err("503 5.5.1 you must authenticate first"); } +void err_authnot() { out_err("503 5.3.3 auth not available"); } +void err_synsize() { out_err("501 5.0.0 bad message size syntax"); } +void err_size() { out_err("552 5.3.4 sorry, that message size exceeds my limit"); } +void err_tmh() { out_err("554 5.4.6 too many hops, this message is looping"); } +void err_syntax() { out_err("501 5.5.4 syntax error"); } +void err_helo() { out_err("501 5.5.4 syntax error, I need your hostname"); } +void err_npa() { out_err("501 5.5.4 syntax error, no parameters allowed"); } +void err_badaddr() { out_err("501 5.5.4 syntax error, bad mail address"); } +void err_authfail() { out_err("535 5.7.0 authorization failed"); } +void err_authweak() { out_err("534 5.7.0 authentication mechanism is too weak"); } +void err_badrcpt() { out_err("553 5.1.1 sorry, no mailbox here by that name."); } + +/* we die after tarpitting! */ +void die_bmf() { tarpit("553", "5.7.1", "sorry, your envelope sender has been denied"); } +void die_bmt() { tarpit("553", "5.7.1", "sorry, your envelope recipient has been denied"); } +void die_bmh() { tarpit("553", "5.7.1", "sorry, your helo or ehlo is incorrect"); } +void die_hmf() { tarpit("553", "5.7.1", "sorry, your envelope sender domain must exist"); } +void die_tmr() { tarpit("553", "5.5.3", "sorry, to many recipients"); } +void die_rbuf() { tarpit("553", "5.5.3", "sorry, my recipients buffer is to small for you"); } +void die_nogw() { tarpit("553", "5.7.1", "sorry, that domain isn't in my list of allowed rcpthosts"); } +void die_lcmd() { tarpit("553", "5.5.2", "sorry, the given command is t00 long!"); } +void die_date() { tarpit("553", "5.7.1", "sorry, this mailaddy is not valid anymore!"); } + +/* tarpit 2 logs some extra info + tarpits */ +void tarpit2(char *code, char *ext, char *msg, char *type, stralloc *smtp) { + int l=0,i=0; -void flush() { substdio_flush(&ssout); } -void out(s) char *s; { substdio_puts(&ssout,s); } + if (!stralloc_0(smtp)) die_nomem(); + for (;;) { + l=str_chr(smtp->s+i, '\n'); + if (!smtp->s[i]) break; + doname(); Log(type); Logn(smtp->s+i, l); Log("\n"); + i+=l+1; + } + tarpit(code, ext, msg); +} -void die_read() { _exit(1); } -void die_alarm() { out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1); } -void die_nomem() { out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); } -void die_control() { out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1); } -void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); } -void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); } - -void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } -void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } -void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } -void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } -void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } -void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } -void err_noop() { out("250 ok\r\n"); } -void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); } -void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } +void tarpit(char *code, char *ext, char *msg) { + int i=ctl_tarpitdelay; + if (ctl_log_tarpitting) { + doname(); Log("TARPIT: "); + if (mailfrom.len){ Log("<"); Logn(mailfrom.s, mailfrom.len-1); Log("> to "); } + if (addr.len) { Log("<"); Logn(addr.s, addr.len-1); Log(">"); } + if (helohost.s) { Log(" | helo("); Log(helohost.s); Log(")"); } + if (remoteinfo) { Log(" | remoteinfo("); Log(remoteinfo); Log(")"); } + Log("\n"); + } -stralloc greeting = {0}; + doserv(); + out(code);Out("-");Log(" ");out(ext);out(" "); + out(msg);doeol(); + + sleep(i*1+1); + Out(code);Out("-");Out(ext);Out(" "); + Out("hm let me see ...\r\n"); + if (flush() == -1) die(); + + sleep(i*2+1); + Out(code);Out("-");Out(ext);Out(" "); + Out("hm does it look good ?\r\n"); + if (flush() == -1) die(); + + sleep(i*3+1); + Out(code);Out("-");Out(ext);Out(" "); + Out("No! You are a bad guy!\r\n"); + if (flush() == -1) die(); + + sleep(i*4+1); + Out(code);Out(" ");Out(ext);Out(" "); + Out(msg);Out("\r\n"); + die(); /* die() flushes */ +} -void smtp_greet(code) char *code; +void smtp_help(void) { - substdio_puts(&ssout,code); - substdio_put(&ssout,greeting.s,greeting.len); + out_err("214 2.0.0 qmail patched (version: " VERSION ")!"); } -void smtp_help() + +void smtp_noop(void) { - out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); + out_err("250 2.0.0 noop okay"); } -void smtp_quit() + +void smtp_vrfy(void) { - smtp_greet("221 "); out("\r\n"); flush(); _exit(0); + out_err("252 2.0.0 send some mail, I'll try my best"); } -char *remoteip; -char *remotehost; -char *remoteinfo; -char *local; -char *relayclient; +void smtp_quit(void) +{ + out_err("221 2.0.0 good bye!"); + _exit(0); +} -stralloc helohost = {0}; -char *fakehelo; /* pointer into helohost, or 0 */ +void smtp_helo(char *arg) +{ + if (!*arg) { err_helo(); return; } + dohelo(arg); -void dohelo(arg) char *arg; { - if (!stralloc_copys(&helohost,arg)) die_nomem(); - if (!stralloc_0(&helohost)) die_nomem(); - fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0; + if (ctl_bmh) if (bmcheck(BMCHECK_BMH, helohost.s)) die_bmh(); + + rcptcount = 0; seenmail = 0; + dogreet("250 "); } -int liphostok = 0; -stralloc liphost = {0}; -int bmfok = 0; -stralloc bmf = {0}; -struct constmap mapbmf; +void dosasl() { + int i=0,space=0; + while (ii+wl; i+=str_chr(x, ' ')+1) { + x+=i; + while (*x == ' ') x++; /* skip spaces */ + if (case_diffb(x, wl, what) == 0) return x+wl; + } + + return 0; +} + +void smtp_mail(char *arg) { char *x; - unsigned long u; - - if (control_init() == -1) die_control(); - if (control_rldef(&greeting,"control/smtpgreeting",1,(char *) 0) != 1) - die_control(); - liphostok = control_rldef(&liphost,"control/localiphost",1,(char *) 0); - if (liphostok == -1) die_control(); - if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control(); - if (timeout <= 0) timeout = 1; - if (rcpthosts_init() == -1) die_control(); + if (!addrparse(arg)) { err_badaddr(); return; } - bmfok = control_readfile(&bmf,"control/badmailfrom",0); - if (bmfok == -1) die_control(); - if (bmfok) - if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem(); - - if (control_readint(&databytes,"control/databytes") == -1) die_control(); - x = env_get("DATABYTES"); - if (x) { scan_ulong(x,&u); databytes = u; } - if (!(databytes + 1)) --databytes; - - remoteip = env_get("TCPREMOTEIP"); - if (!remoteip) remoteip = "unknown"; - local = env_get("TCPLOCALHOST"); - if (!local) local = env_get("TCPLOCALIP"); - if (!local) local = "unknown"; - remotehost = env_get("TCPREMOTEHOST"); - if (!remotehost) remotehost = "unknown"; - remoteinfo = env_get("TCPREMOTEINFO"); - relayclient = env_get("RELAYCLIENT"); - dohelo(remotehost); + if (spamfeed) { + if (!seenmail) { + if (!stralloc_copys(&mailfrom,addr.s)) die_nomem(); + if (!stralloc_0(&mailfrom)) die_nomem(); + } + out_err("250 2.1.0 welcome spammer :)"); + seenmail = 1; return; + } + + /* This is the real databytes initialisation. + * If spamfeed is set, the maximum is defined by databytes+ :) + */ + databytes=ctl_databytes; + if (ctl_databytes) { + if ((x=argparse(arg, "SIZE="))) { + if (scan_ulong(x, &databytes) == 0) { err_synsize(); return; } + if (databytes > ctl_databytes) { err_size(); return; } + } + } + + if (ctl_gmf) { + if (bmcheck(GMCHECK_GMF, addr.s)) { + out_err("250 2.1.0 ok!"); + if (!stralloc_copys(&rcptto,"")) die_nomem(); + if (!stralloc_copys(&mailfrom,addr.s)) die_nomem(); + if (!stralloc_0(&mailfrom)) die_nomem(); + seenmail = 1; return; + } + } + if (ctl_bmf) { if (bmcheck(BMCHECK_BMF, addr.s)) die_bmf(); } + + switch (mfcheck()) { + case DNS_HARD: die_hmf(); + case DNS_SOFT: die_smf(); + case DNS_MEM: die_nomem(); + case DNS_VRFY: die_callback(); + } + + if (requireauth && !authdone) { err_authreq(); return; } + + if (!stralloc_copys(&rcptto,"")) die_nomem(); + if (!stralloc_copys(&mailfrom,addr.s)) die_nomem(); + if (!stralloc_0(&mailfrom)) die_nomem(); + out_err("250 2.1.0 ok"); + seenmail = 1; +} + +void smtp_rcpt(char *arg) +{ + static int init_done=0; + + if (!seenmail) { + err_wantmail(); + return; + } + + if (spamfeed) { + out_err("250 2.1.5 I feed spamassassin now!"); + seenrcpt = 1; + return; + } + + if (ctl_rcpttofixed) { + out_err("250 2.1.5 ok!"); /* ok! */ + seenrcpt = 1; + return; + } + + if (!init_done) { + realrcptto_init(); + init_done=1; + } + + if (!addrparse(arg)) { err_badaddr(); return; } + if (ctl_bmt) { if (bmcheck(BMCHECK_BMT, addr.s)) die_bmt(); } + + if (relayclient) { + --addr.len; /* remove '\0' */ + if (!stralloc_cats(&addr,relayclient)) die_nomem(); + if (!stralloc_0(&addr)) die_nomem(); + } else { + if (!addrallowed()) { die_nogw(); return; } + } + + if (!realrcptto(addr.s)) { + err_badrcpt(); return; + } + + if (authdone) { + /* if the user is a 'user@host.domain', than only relaying with a + * MAIL FROM: is allowed! + */ + if (str_chr(remoteinfo, '@') != strlen(remoteinfo)) { + if (!str_equal(mailfrom.s, remoteinfo)) { + die_bmf(); /* this function does a tarpit! */ + } + } + } + + if (ctl_maxrcpt) + if (rcptcount > ctl_maxrcpt) + if (!authdone) die_tmr(); + + if (ctl_tarpitcount) + if (rcptcount > ctl_tarpitcount) + if (!authdone) while (sleep(ctl_tarpitdelay)); + + datecheck(); + + if (!authdone) + if (rcptcheck() != 0) { err_badrcpt(); return; } + + if (!stralloc_cats(&rcptto,"T")) die_nomem(); + if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); + if (!stralloc_0(&rcptto)) die_nomem(); + + seenrcpt = 1; + rcptcount += 1; + out_err("250 2.1.5 ok"); } +void smtp_auth(char *arg) +{ + char *cmd=arg; + int i; + + if (!auth_available) { err_unimpl(); return; } + if (authdone) { err_authdone(); return; } + if (seenmail) { err_authmail(); return; } + + if (!stralloc_copys(&user,"")) die_nomem(); + if (!stralloc_copys(&pass,"")) die_nomem(); + if (!stralloc_copys(&resp,"")) die_nomem(); + + i = str_chr(cmd,' '); + arg = cmd + i; + while (*arg == ' ') ++arg; + cmd[i] = 0; + for (i = 0; authcmds[i].text; ++i) + if (case_equals(authcmds[i].text,cmd)) + break; + auth_for=MODE_SMTPD; + switch (authcmds[i].fun(arg)) { + case 0: + authdone = 1; + relayclient = ""; + remoteinfo = user.s; + if (!env_unset("TCPREMOTEINFO")) die_read(); + if (!env_put2("TCPREMOTEINFO", remoteinfo)) die_nomem(); + /* for user, which have authenticated, $BLACKLISTED will not work! */ + spamfeed=0; + break; + case ERR_AUTH_FAILED: err_authfail(); break; + case ERR_AUTH_INPUT: err_authin(); break; + case ERR_AUTH_ABORT: err_authabrt(); break; + } +} + +void smtp_starttls(arg) char *arg; { + + if (!tls_available || tls_started) + return err_unimpl(arg); + out_err("220 2.0.0 Ready to start TLS"); -stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */ + if (!ucspitls()) + die_syserr(); -int addrparse(arg) -char *arg; + tls_started = 1; + /* reset SMTP state */ + seenmail = 0; +} + +void dohelo(char *arg) +{ + if (!stralloc_copys(&helohost,arg)) die_nomem(); + if (!stralloc_0(&helohost)) die_nomem(); + fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0; +} + +int safewrite(int fd, char *buf, int len) +{ + int r; + r = timeoutwrite(ctl_timeout,fd,buf,len); + if (r <= 0) die(); + return r; +} + +int saferead(int fd, char *buf, int len) +{ + int r; + flush(); + r = timeoutread(ctl_timeout,fd,buf,len); + if (r == -1) if (errno == error_timeout) die_alarm(); + if (r <= 0) die_read(); + return r; +} + +int addrparse(char *arg) { int i; char ch; char terminator; struct ip_address ip; - int flagesc; - int flagquoted; - + int flagesc=0; + int flagquoted=0; + terminator = '>'; i = str_chr(arg,'<'); - if (arg[i]) + if (arg[i]) { arg += i + 1; - else { /* partner should go read rfc 821 */ + } else { + if (ctl_reqbrackets) return 0; /* partner should go read rfc 821 */ + /* old style, without <> */ terminator = ' '; arg += str_chr(arg,':'); if (*arg == ':') ++arg; @@ -162,9 +653,7 @@ if (*arg == '@') while (*arg) if (*arg++ == ':') break; if (!stralloc_copys(&addr,"")) die_nomem(); - flagesc = 0; - flagquoted = 0; - for (i = 0;ch = arg[i];++i) { /* copy arg to addr, stripping quotes */ + for (i = 0; (ch = arg[i]); ++i) { /* copy arg to addr, stripping quotes */ if (flagesc) { if (!stralloc_append(&addr,&ch)) die_nomem(); flagesc = 0; @@ -178,10 +667,11 @@ } } } + /* could check for termination failure here, but why bother? */ if (!stralloc_append(&addr,"")) die_nomem(); - if (liphostok) { + if (ctl_localiphost) { i = byte_rchr(addr.s,addr.len,'@'); if (i < addr.len) /* if not, partner should go read rfc 821 */ if (addr.s[i + 1] == '[') @@ -193,118 +683,446 @@ } } - if (addr.len > 900) return 0; + if (addr.len > ctl_maxaddrlen) return 0; return 1; } -int bmfcheck() +/* return values: + * + * 0 == not found / no match + * 1 == regex matches + */ +int bmcheck(int which, char *what) { - int j; - if (!bmfok) return 0; - if (constmap(&mapbmf,addr.s,addr.len - 1)) return 1; - j = byte_rchr(addr.s,addr.len,'@'); - if (j < addr.len) - if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1; + stralloc *bmb=0; + char *type=0; + int i=0; + regex_t r; + + if (!*what) return 0; + switch (which) { + case BMCHECK_BMF: type="badmailfrom"; bmb=&bmf; break; + case BMCHECK_BMT: type="badmailto"; bmb=&bmt; break; + case BMCHECK_BMH: type="badmailhelo"; bmb=&bmh; break; + case GMCHECK_GMF: type="goodmailfrom"; bmb=&gmf; break; + default: die_control(); + } + if (!bmb) return 0; + + for (i=0; i < bmb->len; i+=strlen(bmb->s+i)+1) { + if (ctl_log_bmchecks) { + doname();Log("checking ");Log(type);Log(": "); + } + if (regcomp(&r,bmb->s+i,REG_NOSUB|REG_EXTENDED) == 0) { + if (ctl_log_bmchecks) { + char *buf=alloca(strlen(bmb->s+i)+strlen(what)+100); + int j=fmt_str(buf,"\""); + j+=fmt_str(buf+j,bmb->s+i); + j+=fmt_str(buf+j,"\" / \""); + j+=fmt_str(buf+j,what); + j+=fmt_str(buf+j,"\" ("); + j+=fmt_ulong(buf+j,i); + j+=fmt_str(buf+j,"/"); + j+=fmt_ulong(buf+j,bmb->len); + j+=fmt_str(buf+j,")\n"); + buf[j]=0; Log(buf); + } + if (regexec(&r,what,0,0,0) == 0) { regfree(&r); return 1; } + } else { + char *buf=alloca(strlen(bmb->s+i)+strlen(what)+100); + int j=fmt_str(buf,"FAILED REGEX: regcomp(\""); + j+=fmt_str(buf+j,bmb->s+i); + j+=fmt_str(buf+j,"\" / \""); + j+=fmt_str(buf+j,what); + j+=fmt_str(buf+j,"\") lengths: ("); + j+=fmt_ulong(buf+j,i); + j+=fmt_str(buf+j,"/"); + j+=fmt_ulong(buf+j,bmb->len); + j+=fmt_str(buf+j,")\n"); + buf[j]=0; Log(buf); + } + } return 0; } int addrallowed() { int r; + r = rcpthosts(addr.s,str_len(addr.s)); if (r == -1) die_control(); + return r; } +/* news-mail-abuse-YYYYMMDD@svc-box.de */ +int datecheck(void) +{ + int len=0; + + if (!ctl_datechecks) return 0; -int seenmail = 0; -int flagbarf; /* defined if seenmail */ -stralloc mailfrom = {0}; -stralloc rcptto = {0}; + for (;;) { + unsigned long days=0; + char *start=dcf.s+len, *sep; + int slen; + + len+=strlen(start)+1; /* for the next one */ + sep=start+str_chr(start, ':'); + if (!*sep) { + slen=strlen(start); + } else { + if (scan_ulong(sep+1, &days) == 0) die_control(); + slen=sep-start; + } + if (days <= 0) days=7; /* default is a week */ + if (slen > addr.len) continue; -void smtp_helo(arg) char *arg; -{ - smtp_greet("250 "); out("\r\n"); - seenmail = 0; dohelo(arg); + if (!case_diffb(addr.s, slen, start)) { + time_t max=time(0); + time_t min=max-60*60*24*days; /* (60sek * 60min * 24h = tage) */ + unsigned long actual; + if (scan_ulong(addr.s+slen,&actual)==8) { + char *x=addr.s+slen; + time_t check; + struct tm t; + t.tm_sec=t.tm_min=t.tm_hour=0; + t.tm_year=(x[0]-'0')*1000 + (x[1]-'0')*100 + (x[2]-'0')*10 + (x[3]-'0'); + t.tm_mon= (x[4]-'0')*10 + (x[5]-'0'); + t.tm_mday=(x[6]-'0')*10 + (x[7]-'0'); + t.tm_year-=1900; t.tm_mon-=1; + check=mktime(&t); + if (ctl_log_datechecks) { + doname(); Log("doing datecheck: "); Log(start); Log(" / "); Log(addr.s); Log("\n"); + } + if (checkmax) die_date(); + } + } + + if (len >= dcf.len) break; + } + + return 0; } -void smtp_ehlo(arg) char *arg; + +stralloc smtptext = {0}; + +void get(char *ch) { - smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); - seenmail = 0; dohelo(arg); + substdio_get(&smtpfrom,ch,1); + if (*ch != '\r') + if (smtptext.len < HUGESMTPTEXT) + if (!stralloc_append(&smtptext,ch)) die_nomem(); } -void smtp_rset() + +unsigned int smtpcode(void) { - seenmail = 0; - out("250 flushed\r\n"); + char ch; + unsigned int code; + + if (!stralloc_copys(&smtptext,"")) die_nomem(); + + get(&ch); code = ch - '0'; + get(&ch); code = code * 10 + (ch - '0'); + get(&ch); code = code * 10 + (ch - '0'); + for (;;) { + get(&ch); + if (ch != '-') break; + while (ch != '\n') get(&ch); + get(&ch); get(&ch); get(&ch); + } + while (ch != '\n') { get(&ch); } + + return code; } -void smtp_mail(arg) char *arg; + +/** + * ip_is_in_mx_blacklist() - test, if the ip isn't allowed as mx + * + * 0 = okay + * 1 = not okay (is listed) + */ +int ip_is_in_mx_blacklist(struct ip_address *mx) { - if (!addrparse(arg)) { err_syntax(); return; } - 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"); -} -void smtp_rcpt(arg) char *arg; { - if (!seenmail) { err_wantmail(); return; } - if (!addrparse(arg)) { err_syntax(); return; } - if (flagbarf) { err_bmf(); return; } - if (relayclient) { - --addr.len; - if (!stralloc_cats(&addr,relayclient)) die_nomem(); - if (!stralloc_0(&addr)) die_nomem(); + int i,k=0; + char *x; + struct ip_address ip; + + for (i=0; i < mxbl.len; i+=strlen(mxbl.s+i)+1) { + x=mxbl.s+i; + k=ip_scan(mxbl.s, &ip); + if (k) { + if (byte_equal(mx, sizeof(struct ip_address), &ip)) { + return 1; + } + } + k=0; } - else - if (!addrallowed()) { err_nogateway(); return; } - if (!stralloc_cats(&rcptto,"T")) die_nomem(); - if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); - if (!stralloc_0(&rcptto)) die_nomem(); - out("250 ok\r\n"); + + return 0; } +void mfcheck_close(void) +{ + timeoutwrite(timeout, smtpfrom.fd,"RSET\r\n", 6); + timeoutwrite(timeout, smtpfrom.fd,"QUIT\r\n", 6); + close(smtpfrom.fd); + return; +} -int saferead(fd,buf,len) int fd; char *buf; int len; +/* mail from: check + * + * 0 = okay + * -1 = dns soft + * -2 = dns hard + * -3 = dns mem + * -4 = callback temp. failed (DNS_VRFY) + */ +int mfcheck(void) { - int r; - flush(); - r = timeoutread(timeout,fd,buf,len); - if (r == -1) if (errno == error_timeout) die_alarm(); - if (r <= 0) die_read(); - return r; + stralloc sa = {0}; + ipalloc ia = {0}; + unsigned int random; + int i,code; + + if (authdone) return 0; /* valid auth. was done, no need for checking */ + if (ctl_mfcheck <= 0) return 0; /* mfcheck is disabled */ + + i = byte_rchr(addr.s, addr.len, '@') + 1; + if (i >= addr.len) return 0; + random = now() + (getpid() << 16); + dns_init(0); + if (!stralloc_copys(&sa, addr.s + i)) die_nomem(); + i = dns_mxip(&ia,&sa,random); + if (i < 0) return i; /* -1 -2 -3 */ + if (ia.len < 1) { stralloc_0(&sa); return DNS_SOFT; } + if (ctl_mfcheck <= 1) return 0; /* mfcheck is only 1 */ + + /* SMTP callback/sender verification */ + for (i=0; i= 400) { + mfcheck_close(); + continue; /* try next one */ + } + + if (!stralloc_ready(&sa,20+me.len)) die_nomem(); + if (!stralloc_copys(&sa,"HELO ")) die_nomem(); + if (!stralloc_cat(&sa,&me)) die_nomem(); + if (!stralloc_cats(&sa,"\r\n")) die_nomem(); + if (timeoutwrite(timeout,smtpfrom.fd,sa.s,sa.len) == -1) { + tarpit("451", "4.1.8", "bad sender's system address, sending data failed!"); + } + + code = smtpcode(); + if (code >= 400) { + mfcheck_close(); + continue; /* try next one */ + } + + if (timeoutwrite(timeout,smtpfrom.fd,"MAIL FROM:<>\r\n",14) == -1) { + tarpit("451", "4.1.8", "bad sender's system address, sending data failed!"); + } + + code = smtpcode(); + if (code >= 400) { + mfcheck_close(); + continue; /* try next one */ + } + + if (!stralloc_ready(&sa,20+addr.len)) die_nomem(); + if (!stralloc_copys(&sa,"RCPT TO:<")) die_nomem(); + if (!stralloc_cats(&sa, addr.s)) die_nomem(); + if (!stralloc_cats(&sa,">\r\n")) die_nomem(); + if (timeoutwrite(timeout,smtpfrom.fd,sa.s,sa.len) == -1) { + tarpit("451", "4.1.8", "bad sender's mailbox address, sending data failed!"); + } + + code = smtpcode(); + if (code >= 500) { /* temp. errors are okay / greylisting! */ + if (!stralloc_copys(&sa, "bad sender's mailbox address, RCPT TO:<")) die_nomem(); + if (!stralloc_cats(&sa, addr.s)) die_nomem(); + if (!stralloc_cats(&sa, "> failed")) die_nomem(); + if (!stralloc_0(&sa)) die_nomem(); + mfcheck_close(); + tarpit2("550", "5.1.8", sa.s, "BounceTest: ", &smtptext); + } + + mfcheck_close(); /* testbounce was okay */ + if (!stralloc_copys(&sa, "bad sender's mailbox address, RCPT TO:<")) die_nomem(); + if (!stralloc_cats(&sa, addr.s)) die_nomem(); + if (!stralloc_cats(&sa, "> failed")) die_nomem(); + if (!stralloc_0(&sa)) die_nomem(); + return 0; /* return OK */ + } /* for(all mx) */ + + return DNS_VRFY; } -char ssinbuf[1024]; -substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); +int rcptcheck(void) +{ + int pid; + int wstat; + char *av[2] = { rcptchk.s, 0 }; + + if (!ctl_rcptchecks) return 0; + + switch (pid=fork()) { + case -1: + die_fork(); + break; + case 0: + if (!env_put2("SENDER", mailfrom.s)) die_nomem(); + if (!env_put2("RECIPIENT", addr.s)) die_nomem(); + execv(av[0], av); + _exit(120); + break; + } + + if (wait_pid(&wstat,pid) == -1) die_with3(); + if (wait_crashed(wstat)) die_with3(); + + switch (wait_exitcode(wstat)) { + case 0: return 0; + case 2: die_with2(); + case 11: die_with11(); + case 12: die_with12(); + case 13: die_with13(); + case 14: die_with14(); + case 15: return 0; + case 16: die_with16(); + case 17: die_with17(); + case 18: die_with18(); + case 21: die_with21(); + case 22: die_with22(); + case 111: die_with111(); + case 112: die_with112(); + } + + /* invalid addresses */ + return 1; +} struct qmail qqt; unsigned int bytestooverflow = 0; +stralloc clamtext = {0}; -void put(ch) -char *ch; +void clamget(char *ch) { + substdio_get(&clamdsock,ch,1); + if (*ch != '\r') + if (clamtext.len < HUGESMTPTEXT) + if (!stralloc_append(&clamtext,ch)) die_nomem(); +} + +void put(char *ch) +{ + if (clamd_streamok) { + if (timeoutwrite(timeout,clamssock.fd,ch,1) == -1) { + doname(); + Log("problem sending data to clamd stream, skipping the scan!\n"); + flush(); + /* we have reached the maximum stream length? */ + close(clamdsock.fd); close(clamssock.fd); clamd_streamok=0; + } + } + if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qqt); + qmail_put(&qqt,ch,1); } -void blast(hops) -int *hops; +unsigned int clamport(void) +{ + char ch; + unsigned int port; + + for (;;) { clamget(&ch); if (ch == ' ') break; } + if (!stralloc_copys(&clamtext,"")) die_nomem(); + for (;;) { clamget(&ch); if (ch == '\n') break; } + clamtext.s[clamtext.len]=0; + if (scan_ulong(clamtext.s, &port) == 0) return 0; + + return port; +} + +void blast(int *hops) { char ch; int state; int flaginheader; - int pos; /* number of bytes since most recent \n, if fih */ + unsigned int pos; /* number of bytes since most recent \n, if fih */ int flagmaybex; /* 1 if this line might match RECEIVED, if fih */ int flagmaybey; /* 1 if this line might match \r\n, if fih */ int flagmaybez; /* 1 if this line might match DELIVERED, if fih */ - + state = 1; *hops = 0; flaginheader = 1; pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; + + if (ctl_clamd) { + clamd_streamok = 0; /* reset to unknown state */ + if (clamd.s) { + /* use unix domain socket for control connection */ + struct sockaddr_un un; + clamdsock.fd = socket(AF_UNIX,SOCK_STREAM,0); + if (clamdsock.fd == -1) goto blast; + un.sun_family = AF_UNIX; + un.sun_path[fmt_strn(un.sun_path, clamd.s, sizeof(un.sun_path))]=0; + if (connect(clamdsock.fd, (struct sockaddr*)&un, sizeof(un)) == -1) { + doname(); Log("problem while connecting to clamd unix socket!\n"); flush(); + goto blast; + } + } else { + /* use tcp stream for control connection */ + clamdsock.fd = socket(AF_INET,SOCK_STREAM,0); + if (clamdsock.fd == -1) { + doname(); Log("problem creating socket for clamd control connection!\n"); flush(); + goto blast; + } + if (timeoutconn(clamdsock.fd, &clamd_ip, &outip, clamd_port, timeoutconnect) != 0) { + doname(); Log("problem while connecting to clamd!\n"); flush(); + goto blast; + } + } + /* scanning stream */ + clamssock.fd = socket(AF_INET,SOCK_STREAM,0); + if (clamssock.fd == -1) { + doname(); Log("problem creating socket for clamd scan stream!\n"); flush(); + goto blast; + } + if (timeoutwrite(timeout,clamdsock.fd,"STREAM\n",7) == -1) { + doname(); Log("problem sending STREAM command to clamd!\n"); flush(); + goto blast; + } + clamd_sport = clamport(); + if (clamd_sport == 0) goto blast; + if (timeoutconn(clamssock.fd, &clamd_ip, &outip, clamd_sport, timeoutconnect) != 0) { + doname(); Log("problem with connecting to clamd stream!\n"); flush(); + goto blast; + } + clamd_streamok=1; + } + + blast: for (;;) { substdio_get(&ssin,&ch,1); if (flaginheader) { @@ -322,17 +1140,17 @@ } switch(state) { case 0: - if (ch == '\n') straynewline(); + if (ch == '\n') die_newline(); if (ch == '\r') { state = 4; continue; } break; case 1: /* \r\n */ - if (ch == '\n') straynewline(); + if (ch == '\n') die_newline(); if (ch == '.') { state = 2; continue; } if (ch == '\r') { state = 4; continue; } state = 0; break; case 2: /* \r\n + . */ - if (ch == '\n') straynewline(); + if (ch == '\n') die_newline(); if (ch == '\r') { state = 3; continue; } state = 0; break; @@ -351,71 +1169,426 @@ } } -char accept_buf[FMT_ULONG]; -void acceptmessage(qp) unsigned long qp; + +void acceptmessage(unsigned long qp) { + char accept_buf[FMT_ULONG]; datetime_sec when; when = now(); - out("250 ok "); + doserv(); out("250 2.6.0 ok "); accept_buf[fmt_ulong(accept_buf,(unsigned long) when)] = 0; out(accept_buf); out(" qp "); accept_buf[fmt_ulong(accept_buf,qp)] = 0; out(accept_buf); - out("\r\n"); + doeol(); } -void smtp_data() { +void smtp_data(void) { int hops; unsigned long qp; char *qqx; - + char at[FMT_ULONG]; + if (!seenmail) { err_wantmail(); return; } - if (!rcptto.len) { err_wantrcpt(); return; } + if (!seenrcpt) { die_wantrcpt(); } seenmail = 0; - if (databytes) bytestooverflow = databytes + 1; - if (qmail_open(&qqt) == -1) { err_qqt(); return; } + + /* rfc 1870 says: + * A server is permitted, but not required, to accept a message which + * is, in fact, larger than declared in the extended MAIL command, such + * as might occur if the client employed a size-estimation heuristic + * which was inaccurate. + * -> we take 5kb +/- for the given size + * -> the size stands for message+headers! + */ + if (ctl_databytes) { + bytestooverflow = ctl_databytes + ctl_databytesP; + } + if (qmail_open(&qqt) == -1) { die_qqt(); } qp = qmail_qp(&qqt); - out("354 go ahead\r\n"); - - received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); + out_err("354 go ahead"); + + doname(); Log("C: [...] "); + at[fmt_ulong(at,bytestooverflow)]=0; Log(" bytestooverflow=");Log(at); + Log("\n"); + + /* rfc3848 support: ESMTPA => auth | ESMTPS => tls | ESMTPSA => tls+auth */ + if (tls_started && authdone) { + if (!stralloc_cats(&proto, "ESMTPSA")) die_nomem(); + } else if (authdone) { + if (!stralloc_copys(&proto, "SMTPA")) die_nomem(); + } else if (tls_started) { + if (!stralloc_cats(&proto, "ESMTPS")) die_nomem(); + } else { + if (!stralloc_copys(&proto, "SMTP")) die_nomem(); + } + if (!stralloc_0(&proto)) die_nomem(); + + received(&qqt,proto.s,local,remoteip,remotehost,remoteinfo,fakehelo); + if (ctl_p0fsock) p0f_received(&qqt, remoteip); blast(&hops); - hops = (hops >= MAXHOPS); + hops = (hops >= ctl_maxhops); if (hops) qmail_fail(&qqt); qmail_from(&qqt,mailfrom.s); qmail_put(&qqt,rcptto.s,rcptto.len); - + + if (clamd_streamok) { + fd_set rfds; + struct timeval tv; + char ch; + stralloc sa = {0}; + + close(clamssock.fd); + FD_ZERO(&rfds); + FD_SET(clamdsock.fd, &rfds); + tv.tv_sec = 1; tv.tv_usec = 0; + if (select(clamdsock.fd+1, &rfds, NULL, NULL, &tv)) { + if (FD_ISSET(clamdsock.fd, &rfds)) { + if (!stralloc_copys(&clamtext,"")) die_nomem(); + for (;;) { clamget(&ch); if (ch == '\n') break; } + /* "stream: Worm.Sober.I FOUND\n" -> "Worm.Sober.I" */ + clamtext.s[clamtext.len-1]=0; + if (strstr(clamtext.s, "FOUND")) { + clamtext.s[clamtext.len-7]=0; + doname(); Log("CLAMD: virus '"); Log(clamtext.s+8); Log("' was found!\n"); flush(); + if (!stralloc_copys(&sa, "your email contains the virus '")) die_nomem(); + if (!stralloc_cats(&sa, clamtext.s+8)) die_nomem(); + if (!stralloc_cats(&sa, "'!")) die_nomem(); + if (!stralloc_0(&sa)) die_nomem(); + tarpit("554", "5.7.7", sa.s); + } + } + } + close(clamdsock.fd); + } + qqx = qmail_close(&qqt); if (!*qqx) { acceptmessage(qp); return; } - if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; } - if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; } - if (*qqx == 'D') out("554 "); else out("451 "); - out(qqx + 1); - out("\r\n"); + if (hops) { err_tmh(); return; } + + doname(); Log("debug: got a message, which was to big: "); + at[fmt_ulong(at,bytestooverflow)]=0; Log(" bytestooverflow=");Log(at); + at[fmt_ulong(at,ctl_databytes)]=0; Log(" ctl_databytes=");Log(at); + at[fmt_ulong(at,databytes)]=0; Log(" databytes=");Log(at); + Log("\n"); + + if (ctl_databytes) if (!bytestooverflow) { err_size(); return; } + doserv(); if (*qqx == 'D') out("554 "); else out("451 "); out(qqx + 1); doeol(); +} + +void setup() +{ + char *x=0; + + /* change to QMAILHOME/control */ + if (chdir(auto_qmail) == -1) die_control(); + + die_alarm=&die_alarm1; /* set the default */ + + /* reading control/me */ + if (control_init() == -1) die_control(); hostname=me.s; + if (rcpthosts_init() == -1) die_control(); + + /* fill greeting.s */ + if (control_readfile(&greeting,"control/smtpgreeting",1) != 1) die_control(); + greeting.s[greeting.len]=0; + + /* overides controlfile */ + if ((x=getenv("SMTPGREETING"))) { + greeting.s=x; greeting.len=strlen(x); + } + + /* now the logging stuff */ + if (control_readint(&ctl_log_in, "control/log/smtp_in") == -1) die_control(); + if (control_readint(&ctl_log_fd, "control/log/smtp_fd") == -1) die_control(); + if (control_readint(&ctl_log_out,"control/log/smtp_out") == -1) die_control(); + if (ctl_log_in < 0) ctl_log_in=0; + if (ctl_log_out < 0) ctl_log_out=0; + if (ctl_log_fd < 0) ctl_log_fd=2; + sserr.fd = ctl_log_fd; + + /* is there a p0f socket for remote OS information */ + ctl_p0fsock=env_get("P0FSOCK"); + if (!ctl_p0fsock) ctl_p0fsock="control/p0fsock"; + if ((access(ctl_p0fsock, R_OK|W_OK) != 0)) ctl_p0fsock=0; + + /* checking for viruses with clamav */ + ctl_clamd = control_readline(&clamd, "control/clamd"); + if (ctl_clamd == -1) die_control(); + if (ctl_clamd) { + clamd.s[clamd.len]=0; + if (clamd.s[0] == '/') { + /* hopefully a full path to the socket */ + clamd.s[clamd.len]=0; + } else { + /* ip:port */ + int i=ip_scan(clamd.s, &clamd_ip); + if (!i) die_control(); + i=scan_ulong(clamd.s+i+1, &clamd_port); + if (!i) die_control(); + clamd.s=0; + } + } + + if (env_get("NO_CLAMD")) { + ctl_clamd=0; /* disable checking, regardless of good control files */ + } + + switch (control_readline(&ctl_outgoingip,"control/outgoingip")) { + case -1: + if (errno == error_nomem) die_nomem(); + die_control(); + break; + case 0: + if (!stralloc_copys(&ctl_outgoingip, "0.0.0.0")) die_nomem(); + break; + } + if (str_equal(ctl_outgoingip.s, "0.0.0.0")) { + outip.d[0]=outip.d[1]=outip.d[2]=outip.d[3]=(unsigned long)0; + } else if (!ip_scan(ctl_outgoingip.s, &outip)) die_control(); + + + + ctl_localiphost = control_rldef(&liphost,"control/localiphost",1,(char *) 0); + if (ctl_localiphost == -1) die_control(); + + if (control_readint(&ctl_timeout,"control/timeoutsmtpd") == -1) die_control(); + if (ctl_timeout <= 0) ctl_timeout = DEFAULT_TIMEOUT; + + /* log checks of misc stuff ? (all default to off) */ + if (control_readint(&ctl_log_bmchecks,"control/log/bmchecks") == -1) die_control(); + if (ctl_log_bmchecks < 0) ctl_log_bmchecks = 0; + if (control_readint(&ctl_log_orchecks,"control/log/orchecks") == -1) die_control(); + if (ctl_log_orchecks < 0) ctl_log_orchecks = 0; + if (control_readint(&ctl_log_tarpitting,"control/log/tarpitting") == -1) die_control(); + if (ctl_log_tarpitting < 0) ctl_log_tarpitting = 0; + if (control_readint(&ctl_log_datechecks,"control/log/datechecks") == -1) die_control(); + if (ctl_log_datechecks < 0) ctl_log_datechecks = 0; + + /* mfcheck patch (dns check) */ + if (env_get("NO_MFCHECK")) { + ctl_mfcheck=0; + } else { + x = env_get("MFCHECK"); + if (x) { + if (scan_ulong(x,&ctl_mfcheck) == 0) die_control(); + } else { + if (control_readint(&ctl_mfcheck,"control/mfcheck") == -1) die_control(); + } + } + + /* orcheck patch (open relay checks) */ + if (env_get("NO_ORCHECK")) { + ctl_orcheck=0; + } else { + x = env_get("ORCHECK"); + if (x) { + if (scan_ulong(x,&ctl_orcheck) == 0) die_control(); + } else { + if (control_readint(&ctl_orcheck,"control/orcheck") == -1) die_control(); + } + } + + /* tarpitting */ + if (env_get("NO_TARPITTING")) { + ctl_tarpitcount=0; + ctl_tarpitdelay=0; + } else { + x = env_get("TARPITCOUNT"); + if (x) { + if (scan_ulong(x,&ctl_tarpitcount) == 0) die_control(); + } else { + if (control_readint(&ctl_tarpitcount,"control/tarpitcount") == -1) + die_control(); + } + x = env_get("TARPITDELAY"); + if (x) { + if (scan_ulong(x,&ctl_tarpitdelay) == 0) die_control(); + } else { + if (control_readint(&ctl_tarpitdelay,"control/tarpitdelay") == -1) + die_control(); + } + } + + if ((x=env_get("BLACKLISTED"))) { + /* each "RCPT TO" will be ignored and send to <$BLACKLISTED> */ + spamfeed=1; + if (!stralloc_copys(&rcptto, "T")) die_nomem(); + if (!stralloc_cats(&rcptto, x)) die_nomem(); + if (!stralloc_0(&rcptto)) die_nomem(); + } else if ((x=env_get("RCPTTOFIXED"))) { + /* each mail goes to <$RCPTTOFIXED> */ + ctl_rcpttofixed=1; + if (!stralloc_copys(&rcptto, "T")) die_nomem(); + if (!stralloc_cats(&rcptto, x)) die_nomem(); + if (!stralloc_0(&rcptto)) die_nomem(); + } + + /* esmtp auth options */ + if (control_readint(&ctl_auth_delay, "control/auth/delay") == -1) die_control(); + if (control_readint(&ctl_auth_secure, "control/auth/smtps") == -1) die_control(); + if (control_readint(&ctl_auth_insecure, "control/auth/smtp") == -1) die_control(); + if (control_readint(&ctl_auth_oldauth, "control/auth/oldauth") == -1) die_control(); + + /* checking of sender/recipient via external program */ + ctl_rcptchecks = control_readline(&rcptchk, "control/rcptcheck"); + if (ctl_rcptchecks == -1) die_control(); + x=env_get("RCPTCHECK"); /* overrides controlfile */ + if (x) { ctl_rcptchecks=1; stralloc_copys(&rcptchk, x); } + if (ctl_rcptchecks) rcptchk.s[rcptchk.len]=0; + + /* badhelo - checking against HELO/EHLO */ + if (env_get("NO_BADHELO")) { + ctl_bmh=0; + } else { + x = env_get("BADHELO"); if (!x) x = "control/badhelo"; + ctl_bmh = control_readfile(&bmh,x,0); + if (ctl_bmh == -1) die_control(); + } + + /* badmailfrom - checking against MAIL FROM: */ + if (env_get("NO_BADMAILFROM")) { + ctl_bmf=0; + } else { + x = env_get("BADMAILFROM"); if (!x) x = "control/badmailfrom"; + ctl_bmf = control_readfile(&bmf,x,0); + if (ctl_bmf == -1) die_control(); + } + + /* badmailto - checking against RCPT TO: */ + if (env_get("NO_BADMAILTO")) { + ctl_bmt=0; + } else { + x = env_get("BADMAILTO"); if (!x) x = "control/badmailto"; + ctl_bmt = control_readfile(&bmt,x,0); + if (ctl_bmt == -1) die_control(); + } + + /* goodmailfrom - checking against MAIL FROM: */ + if (env_get("NO_GOODMAILFROM")) { + ctl_gmf=0; + } else { + x = env_get("GOODMAILFROM"); if (!x) x = "control/goodmailfrom"; + ctl_gmf = control_readfile(&gmf,x,0); + if (ctl_gmf == -1) die_control(); + } + + /* maxrcpt */ + if (env_get("NO_MAXRCPT")) { + ctl_bmf=0; + } else { /* XXX: should MAXRCPT contain the int? */ + x = env_get("MAXRCPT"); if (!x) x = "control/maxrcpt"; + if (control_readint(&ctl_maxrcpt,x,0) == -1) die_control(); + if (ctl_maxrcpt < 0) ctl_maxrcpt=0; + } + + /* maxhops limit is now changeable on the fly */ + if (control_readint(&ctl_maxhops, "control/maxhops") == -1) die_control(); + if (ctl_maxhops <= 0) ctl_maxhops=DEFAULT_MAXHOPS; + + /* max length of an email address */ + if (control_readint(&ctl_maxaddrlen, "control/maxaddrlen") == -1) die_control(); + if (ctl_maxaddrlen <= 0) ctl_maxaddrlen=900; /* default from djb */ + + /* buffer limit for commands */ + if (control_readint(&ctl_maxcmdlen, "control/maxcmdlen") == -1) die_control(); + if (ctl_maxcmdlen < 0) ctl_maxcmdlen=0; + + /* enforce <> in the mail from & rcpt to */ + if (control_readint(&ctl_reqbrackets, "control/reqbrackets") == -1) die_control(); + if (ctl_reqbrackets < 0) ctl_reqbrackets=1; + + /* read file into dcf (date control file) */ + ctl_datechecks = control_readfile(&dcf, "control/datechecks", 0); + if (ctl_datechecks == -1) die_control(); + + /* load ip blacklist of not useable ip's as dnsmx */ + ctl_mxblacklist = control_readfile(&mxbl,"control/mxblacklist", 0); + if (ctl_mxblacklist == -1) die_control(); + if (ctl_mxblacklist) { + int ip=0,i=0; + if (!stralloc_0(&mxbl)) die_nomem(); + for (; i10000) die_control(); + } + } + + /* size limits */ + if (control_readint(&ctl_databytesP,"control/databytes+") == -1) die_control(); + if (ctl_databytesP <= 0) ctl_databytesP=5000; + + if (control_readint(&ctl_databytes,"control/databytes") == -1) die_control(); + x = env_get("DATABYTES"); + if (x) { scan_ulong(x,&ctl_databytes); } + if (ctl_databytes < 0) ctl_databytes=0; + + if (ctl_databytes) { + x=smtpsize; + x+=fmt_str(x,"250-SIZE "); + x+=fmt_uint(x,ctl_databytes); + *x=0; + } + + x="unknown"; + remoteip = env_get("TCPREMOTEIP"); + if (!remoteip) remoteip = x; + + local = env_get("TCPLOCALHOST"); + if (!local) local = env_get("TCPLOCALIP"); + if (!local) local = x; + + remotehost = env_get("TCPREMOTEHOST"); + if (!remotehost) remotehost = x; + + remoteinfo = env_get("TCPREMOTEINFO"); + relayclient = env_get("RELAYCLIENT"); + requireauth = env_get("REQUIREAUTH"); + + dohelo(remotehost); } struct commands smtpcommands[] = { { "rcpt", smtp_rcpt, 0 } , { "mail", smtp_mail, 0 } +, { "rset", smtp_rset, 0 } , { "data", smtp_data, flush } , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush } -, { "rset", smtp_rset, 0 } , { "help", smtp_help, flush } -, { "noop", err_noop, flush } -, { "vrfy", err_vrfy, flush } -, { 0, err_unimpl, flush } -} ; +, { "auth", smtp_auth, flush } +, { "noop", smtp_noop, flush } +, { "vrfy", smtp_vrfy, flush } +, { "starttls", smtp_starttls, flush } +, { 0, err_unrecog, flush } +}; -void main() +int main(int argc, char **argv) { + int i=0; + childargs = argv + 1; + sig_pipeignore(); - if (chdir(auto_qmail) == -1) die_control(); setup(); + p0f_query(); + + tls_available = !!env_get("UCSPITLS"); + if (ipme_init() != 1) die_ipme(); - smtp_greet("220 "); - out(" ESMTP\r\n"); - if (commands(&ssin,&smtpcommands) == 0) die_read(); - die_nomem(); + while (1) { + i+=strlen(greeting.s+i)+1; + if (i >= greeting.len) { + doserv(); out("220 "); out(greeting.s); doeol(); break; + } else { + doserv(); out("220-"); out(greeting.s+i); doeol(); + } + } + + if (!*childargs) { auth_available=0; } else { auth_available=1; } + if (commands(&ssin, &sserr, &smtpcommands) == 0) die_read(); + die(); + + return 0; /* gcc happyness */ } diff -urN qmail-1.03/qmail-start.c qmail-1.03-md/qmail-start.c --- qmail-1.03/qmail-start.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-start.c 2011-03-11 10:56:43.156750038 +0100 @@ -27,7 +27,7 @@ close(pi5[0]); close(pi5[1]); close(pi6[0]); close(pi6[1]); } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -117,4 +117,5 @@ closepipes(); execvp(*qsargs,qsargs); die(); + return 0; /* cc happyness */ } diff -urN qmail-1.03/qmail-tcpok.c qmail-1.03-md/qmail-tcpok.c --- qmail-1.03/qmail-tcpok.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-tcpok.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "strerr.h" #include "substdio.h" #include "lock.h" @@ -11,7 +13,7 @@ char buf[1024]; /* XXX: must match size in tcpto_clean.c, tcpto.c */ substdio ss; -void main() +int main() { int fd; int i; diff -urN qmail-1.03/qmail-tcpto.c qmail-1.03-md/qmail-tcpto.c --- qmail-1.03/qmail-tcpto.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qmail-tcpto.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,5 +1,7 @@ /* XXX: this program knows quite a bit about tcpto's internals */ +#include +#include #include "substdio.h" #include "subfd.h" #include "auto_qmail.h" @@ -10,6 +12,8 @@ #include "exit.h" #include "datetime.h" #include "now.h" +#include "open.h" +#include "byte.h" void die(n) int n; { substdio_flush(subfdout); _exit(n); } @@ -32,7 +36,7 @@ char tmp[FMT_ULONG + IPFMT]; -void main() +int main() { int fdlock; int fd; @@ -81,5 +85,6 @@ record += 16; } - die(0); + _exit(0); + return 0; } diff -urN qmail-1.03/qreceipt.c qmail-1.03-md/qreceipt.c --- qmail-1.03/qreceipt.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qreceipt.c 2011-03-11 10:56:43.156750038 +0100 @@ -92,9 +92,10 @@ qmail_to(&qqt,returnpath); qqx = qmail_close(&qqt); - if (*qqx) + if (*qqx) { if (*qqx == 'D') die_qqperm(); else die_qqtemp(); + } } stralloc hfbuf = {0}; @@ -119,7 +120,7 @@ void dobody(h) stralloc *h; { ; } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -128,4 +129,5 @@ if (!(returnpath = env_get("SENDER"))) die_usage(); if (headerbody(subfdin,doheaderfield,finishheader,dobody) == -1) die_read(); die_noreceipt(); + return 0; } diff -urN qmail-1.03/qsmhook.c qmail-1.03-md/qsmhook.c --- qmail-1.03/qsmhook.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qsmhook.c 2011-03-11 10:56:43.156750038 +0100 @@ -35,7 +35,7 @@ substdio ssin; char inbuf[SUBSTDIO_INSIZE]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -78,7 +78,7 @@ if (!*argv) die_usage(); - for (arg = argv;x = *arg;++arg) + for (arg = argv;(x = *arg);++arg) { if (!stralloc_copys(&newarg,"")) die_temp(); flagesc = 0; diff -urN qmail-1.03/qsutil.c qmail-1.03-md/qsutil.c --- qmail-1.03/qsutil.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/qsutil.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "stralloc.h" #include "readwrite.h" #include "substdio.h" diff -urN qmail-1.03/rcpthosts.c qmail-1.03-md/rcpthosts.c --- qmail-1.03/rcpthosts.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/rcpthosts.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,5 +1,6 @@ #include "cdb.h" #include "byte.h" +#include "case.h" #include "open.h" #include "error.h" #include "control.h" diff -urN qmail-1.03/readwrite.h qmail-1.03-md/readwrite.h --- qmail-1.03/readwrite.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/readwrite.h 2011-03-11 10:56:43.156750038 +0100 @@ -1,7 +1,6 @@ #ifndef READWRITE_H #define READWRITE_H -extern int read(); -extern int write(); +#include "unistd.h" #endif diff -urN qmail-1.03/realrcptto.c qmail-1.03-md/realrcptto.c --- qmail-1.03/realrcptto.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/realrcptto.c 2011-03-11 10:56:43.156750038 +0100 @@ -0,0 +1,282 @@ +#include +#include +#include +#include +#include "auto_break.h" +#include "auto_usera.h" +#include "byte.h" +#include "case.h" +#include "cdb.h" +#include "constmap.h" +#include "error.h" +#include "control.h" +#include "fmt.h" +#include "open.h" +#include "str.h" +#include "stralloc.h" +#include "uint32.h" +#include "substdio.h" +#include "env.h" + +extern void die_nomem(); +extern void die_control(); +extern void die_cdb(); +extern void die_sys(); + +static stralloc envnoathost = {0}; +static stralloc percenthack = {0}; +static stralloc locals = {0}; +static stralloc vdoms = {0}; +static struct constmap mappercenthack; +static struct constmap maplocals; +static struct constmap mapvdoms; + +static char *dash; +static char *extension; +static char *local; +static struct passwd *pw; + +static char pidbuf[64]; +static char remoteipbuf[64]=" "; + +void realrcptto_init() +{ + char *x; + + if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) + die_control(); + + if (control_readfile(&locals,"control/locals",1) != 1) die_control(); + if (!constmap_init(&maplocals,locals.s,locals.len,0)) die_nomem(); + switch(control_readfile(&percenthack,"control/percenthack",0)) { + case -1: die_control(); + case 0: if (!constmap_init(&mappercenthack,"",0,0)) die_nomem(); + case 1: + if (!constmap_init(&mappercenthack,percenthack.s,percenthack.len,0)) + die_nomem(); + } + switch(control_readfile(&vdoms,"control/virtualdomains",0)) { + case -1: die_control(); + case 0: if (!constmap_init(&mapvdoms,"",0,1)) die_nomem(); + case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) die_nomem(); + } + + str_copy(pidbuf + fmt_ulong(pidbuf,getpid())," "); + x=env_get("PROTO"); + if (x) { + static char const remoteip[]="REMOTEIP"; + unsigned int len = str_len(x); + if (len <= sizeof remoteipbuf - sizeof remoteip) { + byte_copy(remoteipbuf,len,x); + byte_copy(remoteipbuf + len,sizeof remoteip,remoteip); + x = env_get(remoteipbuf); + len = str_len(x); + if (len + 1 < sizeof remoteipbuf) { + byte_copy(remoteipbuf,len,x); + remoteipbuf[len]=' '; + remoteipbuf[len + 1]='\0'; + } + } + } +} + +#define GETPW_USERLEN 32 + +static int userext() +{ + char username[GETPW_USERLEN]; + struct stat st; + + extension = local + str_len(local); + for (;;) { + if (extension - local < sizeof(username)) + if (!*extension || (*extension == *auto_break)) { + byte_copy(username,extension - local,local); + username[extension - local] = 0; + case_lowers(username); + errno = 0; + pw = getpwnam(username); + if (errno == error_txtbsy) die_sys(); + if (pw) + if (pw->pw_uid) + if (stat(pw->pw_dir,&st) == 0) { + if (st.st_uid == pw->pw_uid) { + dash = ""; + if (*extension) { ++extension; dash = "-"; } + return 1; + } + } + else + if (error_temp(errno)) die_sys(); + } + if (extension == local) return 0; + --extension; + } +} + +int realrcptto(addr) +char *addr; +{ + char *homedir; + static stralloc localpart = {0}; + static stralloc lower = {0}; + static stralloc nughde = {0}; + static stralloc wildchars = {0}; + static stralloc safeext = {0}; + static stralloc qme = {0}; + + /* qmail-send:rewrite */ + unsigned int i,at; + if (!stralloc_copys(&localpart,addr)) die_nomem(); + i = byte_rchr(localpart.s,localpart.len,'@'); + if (i == localpart.len) { + if (!stralloc_cats(&localpart,"@")) die_nomem(); + if (!stralloc_cat(&localpart,&envnoathost)) die_nomem(); + } + while (constmap(&mappercenthack,localpart.s + i + 1,localpart.len - i - 1)) { + unsigned int j = byte_rchr(localpart.s,i,'%'); + if (j == i) break; + localpart.len = i; + i = j; + localpart.s[i] = '@'; + } + at = byte_rchr(localpart.s,localpart.len,'@'); + if (constmap(&maplocals,localpart.s + at + 1,localpart.len - at - 1)) { + localpart.len = at; + localpart.s[at] = '\0'; + } else { + unsigned int xlen,newlen; + char *x; + for (i = 0;;++i) { + if (i > localpart.len) return 1; + if (!i || (i == at + 1) || (i == localpart.len) || + ((i > at) && (localpart.s[i] == '.'))) { + x = constmap(&mapvdoms,localpart.s + i,localpart.len - i); + if (x) break; + } + } + if (!*x) return 1; + xlen = str_len(x) + 1; /* +1 for '-' */ + newlen = xlen + at + 1; /* +1 for \0 */ + if (xlen < 1 || newlen - 1 < xlen || newlen < 1 || + !stralloc_ready(&localpart,newlen)) + die_nomem(); + localpart.s[newlen - 1] = '\0'; + byte_copyr(localpart.s + xlen,at,localpart.s); + localpart.s[xlen - 1] = '-'; + byte_copy(localpart.s,xlen - 1,x); + localpart.len = newlen; + } + + /* qmail-lspawn:nughde_get */ + { + int r,fd,flagwild; + if (!stralloc_copys(&lower,"!")) die_nomem(); + if (!stralloc_cats(&lower,localpart.s)) die_nomem(); + if (!stralloc_0(&lower)) die_nomem(); + case_lowerb(lower.s,lower.len); + if (!stralloc_copys(&nughde,"")) die_nomem(); + fd = open_read("users/cdb"); + if (fd == -1) { + if (errno != error_noent) die_cdb(); + } else { + uint32 dlen; + r = cdb_seek(fd,"",0,&dlen); + if (r != 1) die_cdb(); + if (!stralloc_ready(&wildchars,(unsigned int) dlen)) die_nomem(); + wildchars.len = dlen; + if (cdb_bread(fd,wildchars.s,wildchars.len) == -1) die_cdb(); + i = lower.len; + flagwild = 0; + do { /* i > 0 */ + if (!flagwild || (i == 1) || + (byte_chr(wildchars.s,wildchars.len,lower.s[i - 1]) + < wildchars.len)) { + r = cdb_seek(fd,lower.s,i,&dlen); + if (r == -1) die_cdb(); + if (r == 1) { + char *x; + if (!stralloc_ready(&nughde,(unsigned int) dlen)) die_nomem(); + nughde.len = dlen; + if (cdb_bread(fd,nughde.s,nughde.len) == -1) die_cdb(); + if (flagwild) + if (!stralloc_cats(&nughde,localpart.s + i - 1)) die_nomem(); + if (!stralloc_0(&nughde)) die_nomem(); + close(fd); + x=nughde.s; + /* skip username */ + x += byte_chr(x,nughde.s + nughde.len - x,'\0'); + if (x == nughde.s + nughde.len) return 1; + ++x; + /* skip uid */ + x += byte_chr(x,nughde.s + nughde.len - x,'\0'); + if (x == nughde.s + nughde.len) return 1; + ++x; + /* skip gid */ + x += byte_chr(x,nughde.s + nughde.len - x,'\0'); + if (x == nughde.s + nughde.len) return 1; + ++x; + /* skip homedir */ + homedir=x; + x += byte_chr(x,nughde.s + nughde.len - x,'\0'); + if (x == nughde.s + nughde.len) return 1; + ++x; + /* skip dash */ + dash=x; + x += byte_chr(x,nughde.s + nughde.len - x,'\0'); + if (x == nughde.s + nughde.len) return 1; + ++x; + extension=x; + goto got_nughde; + } + } + --i; + flagwild = 1; + } while (i); + close(fd); + } + } + + /* qmail-getpw */ + local = localpart.s; + if (!userext()) { + extension = local; + dash = "-"; + pw = getpwnam(auto_usera); + } + if (!pw) { return 0; } + if (!stralloc_copys(&nughde,pw->pw_dir)) die_nomem(); + if (!stralloc_0(&nughde)) die_nomem(); + homedir=nughde.s; + + got_nughde: + + /* qmail-local:qmesearch */ + if (!*dash) return 1; + if (!stralloc_copys(&safeext,extension)) die_nomem(); + case_lowerb(safeext.s,safeext.len); + for (i = 0;i < safeext.len;++i) + if (safeext.s[i] == '.') + safeext.s[i] = ':'; + { + struct stat st; + int i; + if (!stralloc_copys(&qme,homedir)) die_nomem(); + if (!stralloc_cats(&qme,"/.qmail")) die_nomem(); + if (!stralloc_cats(&qme,dash)) die_nomem(); + if (!stralloc_cat(&qme,&safeext)) die_nomem(); + if (!stralloc_0(&qme)) die_nomem(); + if (stat(qme.s, &st) == 0 || errno != error_noent) return 1; + for (i = safeext.len;i >= 0;--i) + if (!i || (safeext.s[i - 1] == '-')) { + if (!stralloc_copys(&qme,homedir)) die_nomem(); + if (!stralloc_cats(&qme,"/.qmail")) die_nomem(); + if (!stralloc_cats(&qme,dash)) die_nomem(); + if (!stralloc_catb(&qme,safeext.s,i)) die_nomem(); + if (!stralloc_cats(&qme,"default")) die_nomem(); + if (!stralloc_0(&qme)) die_nomem(); + if (stat(qme.s, &st) == 0 || errno != error_noent) return 1; + } + return 0; + } +} diff -urN qmail-1.03/received.c qmail-1.03-md/received.c --- qmail-1.03/received.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/received.c 2011-03-11 10:56:43.156750038 +0100 @@ -26,7 +26,7 @@ char *s; { char ch; - while (ch = *s++) { + while ((ch = *s++)) { if (!issafe(ch)) ch = '?'; qmail_put(qqt,&ch,1); } diff -urN qmail-1.03/received.h qmail-1.03-md/received.h --- qmail-1.03/received.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/received.h 2011-03-11 10:56:43.156750038 +0100 @@ -2,5 +2,6 @@ #define RECEIVED_H extern void received(); +extern void safeput(); #endif diff -urN qmail-1.03/remoteinfo.c qmail-1.03-md/remoteinfo.c --- qmail-1.03/remoteinfo.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/remoteinfo.c 2011-03-11 10:56:43.156750038 +0100 @@ -32,7 +32,6 @@ { char *x; int s; - struct sockaddr_in sin; substdio ss; char buf[32]; unsigned int len; @@ -44,12 +43,7 @@ s = socket(AF_INET,SOCK_STREAM,0); if (s == -1) return 0; - byte_zero(&sin,sizeof(sin)); - sin.sin_family = AF_INET; - byte_copy(&sin.sin_addr,4,ipl); - sin.sin_port = 0; - if (bind(s,(struct sockaddr *) &sin,sizeof(sin)) == -1) { close(s); return 0; } - if (timeoutconn(s,ipr,113,timeout) == -1) { close(s); return 0; } + if (timeoutconn(s,ipr,ipl,113,timeout) == -1) { close(s); return 0; } fcntl(s,F_SETFL,fcntl(s,F_GETFL,0) & ~O_NDELAY); len = 0; diff -urN qmail-1.03/ripemd.c qmail-1.03-md/ripemd.c --- qmail-1.03/ripemd.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/ripemd.c 2011-03-11 10:56:43.156750038 +0100 @@ -0,0 +1,353 @@ +#include "ripemd.h" + +static void compress(RIPEMD160_CTX *ctx); + +/* ROL(x, n) cyclically rotates x over n bits to the left */ +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define GG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define HH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define II(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define JJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define FFF(a, b, c, d, e, x, s) {\ + (a) += F((b), (c), (d)) + (x);\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define GGG(a, b, c, d, e, x, s) {\ + (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define HHH(a, b, c, d, e, x, s) {\ + (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define III(a, b, c, d, e, x, s) {\ + (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } +#define JJJ(a, b, c, d, e, x, s) {\ + (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ + (a) = ROL((a), (s)) + (e);\ + (c) = ROL((c), 10); } + +/* collect four u8s into one word: */ +#define bytes_TO_u32(strptr) \ + (((u32) *((strptr)+3) << 24) | \ + ((u32) *((strptr)+2) << 16) | \ + ((u32) *((strptr)+1) << 8) | \ + ((u32) *(strptr))) + +static void compress(RIPEMD160_CTX *ctx) +{ + u32 aa = ctx->MD[0], aaa = ctx->MD[0]; + u32 bb = ctx->MD[1], bbb = ctx->MD[1]; + u32 cc = ctx->MD[2], ccc = ctx->MD[2]; + u32 dd = ctx->MD[3], ddd = ctx->MD[3]; + u32 ee = ctx->MD[4], eee = ctx->MD[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, ctx->X[ 0], 11); + FF(ee, aa, bb, cc, dd, ctx->X[ 1], 14); + FF(dd, ee, aa, bb, cc, ctx->X[ 2], 15); + FF(cc, dd, ee, aa, bb, ctx->X[ 3], 12); + FF(bb, cc, dd, ee, aa, ctx->X[ 4], 5); + FF(aa, bb, cc, dd, ee, ctx->X[ 5], 8); + FF(ee, aa, bb, cc, dd, ctx->X[ 6], 7); + FF(dd, ee, aa, bb, cc, ctx->X[ 7], 9); + FF(cc, dd, ee, aa, bb, ctx->X[ 8], 11); + FF(bb, cc, dd, ee, aa, ctx->X[ 9], 13); + FF(aa, bb, cc, dd, ee, ctx->X[10], 14); + FF(ee, aa, bb, cc, dd, ctx->X[11], 15); + FF(dd, ee, aa, bb, cc, ctx->X[12], 6); + FF(cc, dd, ee, aa, bb, ctx->X[13], 7); + FF(bb, cc, dd, ee, aa, ctx->X[14], 9); + FF(aa, bb, cc, dd, ee, ctx->X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, ctx->X[ 7], 7); + GG(dd, ee, aa, bb, cc, ctx->X[ 4], 6); + GG(cc, dd, ee, aa, bb, ctx->X[13], 8); + GG(bb, cc, dd, ee, aa, ctx->X[ 1], 13); + GG(aa, bb, cc, dd, ee, ctx->X[10], 11); + GG(ee, aa, bb, cc, dd, ctx->X[ 6], 9); + GG(dd, ee, aa, bb, cc, ctx->X[15], 7); + GG(cc, dd, ee, aa, bb, ctx->X[ 3], 15); + GG(bb, cc, dd, ee, aa, ctx->X[12], 7); + GG(aa, bb, cc, dd, ee, ctx->X[ 0], 12); + GG(ee, aa, bb, cc, dd, ctx->X[ 9], 15); + GG(dd, ee, aa, bb, cc, ctx->X[ 5], 9); + GG(cc, dd, ee, aa, bb, ctx->X[ 2], 11); + GG(bb, cc, dd, ee, aa, ctx->X[14], 7); + GG(aa, bb, cc, dd, ee, ctx->X[11], 13); + GG(ee, aa, bb, cc, dd, ctx->X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, ctx->X[ 3], 11); + HH(cc, dd, ee, aa, bb, ctx->X[10], 13); + HH(bb, cc, dd, ee, aa, ctx->X[14], 6); + HH(aa, bb, cc, dd, ee, ctx->X[ 4], 7); + HH(ee, aa, bb, cc, dd, ctx->X[ 9], 14); + HH(dd, ee, aa, bb, cc, ctx->X[15], 9); + HH(cc, dd, ee, aa, bb, ctx->X[ 8], 13); + HH(bb, cc, dd, ee, aa, ctx->X[ 1], 15); + HH(aa, bb, cc, dd, ee, ctx->X[ 2], 14); + HH(ee, aa, bb, cc, dd, ctx->X[ 7], 8); + HH(dd, ee, aa, bb, cc, ctx->X[ 0], 13); + HH(cc, dd, ee, aa, bb, ctx->X[ 6], 6); + HH(bb, cc, dd, ee, aa, ctx->X[13], 5); + HH(aa, bb, cc, dd, ee, ctx->X[11], 12); + HH(ee, aa, bb, cc, dd, ctx->X[ 5], 7); + HH(dd, ee, aa, bb, cc, ctx->X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, ctx->X[ 1], 11); + II(bb, cc, dd, ee, aa, ctx->X[ 9], 12); + II(aa, bb, cc, dd, ee, ctx->X[11], 14); + II(ee, aa, bb, cc, dd, ctx->X[10], 15); + II(dd, ee, aa, bb, cc, ctx->X[ 0], 14); + II(cc, dd, ee, aa, bb, ctx->X[ 8], 15); + II(bb, cc, dd, ee, aa, ctx->X[12], 9); + II(aa, bb, cc, dd, ee, ctx->X[ 4], 8); + II(ee, aa, bb, cc, dd, ctx->X[13], 9); + II(dd, ee, aa, bb, cc, ctx->X[ 3], 14); + II(cc, dd, ee, aa, bb, ctx->X[ 7], 5); + II(bb, cc, dd, ee, aa, ctx->X[15], 6); + II(aa, bb, cc, dd, ee, ctx->X[14], 8); + II(ee, aa, bb, cc, dd, ctx->X[ 5], 6); + II(dd, ee, aa, bb, cc, ctx->X[ 6], 5); + II(cc, dd, ee, aa, bb, ctx->X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, ctx->X[ 4], 9); + JJ(aa, bb, cc, dd, ee, ctx->X[ 0], 15); + JJ(ee, aa, bb, cc, dd, ctx->X[ 5], 5); + JJ(dd, ee, aa, bb, cc, ctx->X[ 9], 11); + JJ(cc, dd, ee, aa, bb, ctx->X[ 7], 6); + JJ(bb, cc, dd, ee, aa, ctx->X[12], 8); + JJ(aa, bb, cc, dd, ee, ctx->X[ 2], 13); + JJ(ee, aa, bb, cc, dd, ctx->X[10], 12); + JJ(dd, ee, aa, bb, cc, ctx->X[14], 5); + JJ(cc, dd, ee, aa, bb, ctx->X[ 1], 12); + JJ(bb, cc, dd, ee, aa, ctx->X[ 3], 13); + JJ(aa, bb, cc, dd, ee, ctx->X[ 8], 14); + JJ(ee, aa, bb, cc, dd, ctx->X[11], 11); + JJ(dd, ee, aa, bb, cc, ctx->X[ 6], 8); + JJ(cc, dd, ee, aa, bb, ctx->X[15], 5); + JJ(bb, cc, dd, ee, aa, ctx->X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, ctx->X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, ctx->X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, ctx->X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, ctx->X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, ctx->X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, ctx->X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, ctx->X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, ctx->X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, ctx->X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, ctx->X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, ctx->X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, ctx->X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, ctx->X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, ctx->X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, ctx->X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, ctx->X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, ctx->X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, ctx->X[11], 13); + III(ccc, ddd, eee, aaa, bbb, ctx->X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, ctx->X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, ctx->X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, ctx->X[13], 8); + III(ddd, eee, aaa, bbb, ccc, ctx->X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, ctx->X[10], 11); + III(bbb, ccc, ddd, eee, aaa, ctx->X[14], 7); + III(aaa, bbb, ccc, ddd, eee, ctx->X[15], 7); + III(eee, aaa, bbb, ccc, ddd, ctx->X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, ctx->X[12], 7); + III(ccc, ddd, eee, aaa, bbb, ctx->X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, ctx->X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, ctx->X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, ctx->X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, ctx->X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, ctx->X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, ctx->X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, ctx->X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, ctx->X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, ctx->X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, ctx->X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, ctx->X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, ctx->X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, ctx->X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, ctx->X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, ctx->X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, ctx->X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, ctx->X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, ctx->X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, ctx->X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, ctx->X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, ctx->X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, ctx->X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, ctx->X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, ctx->X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, ctx->X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, ctx->X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, ctx->X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, ctx->X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, ctx->X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, ctx->X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, ctx->X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, ctx->X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, ctx->X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, ctx->X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, ctx->X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, ctx->X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, ctx->X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, ctx->X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, ctx->X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, ctx->X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, ctx->X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, ctx->X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, ctx->X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, ctx->X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, ctx->X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, ctx->X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, ctx->X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, ctx->X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, ctx->X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, ctx->X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, ctx->X[11] , 11); + + /* combine results */ + ddd += cc + ctx->MD[1]; + ctx->MD[1] = ctx->MD[2] + dd + eee; + ctx->MD[2] = ctx->MD[3] + ee + aaa; + ctx->MD[3] = ctx->MD[4] + aa + bbb; + ctx->MD[4] = ctx->MD[0] + bb + ccc; + ctx->MD[0] = ddd; + ctx->len+=64; + + memset(ctx->X, 0, 16*sizeof(u32)); + return; +} + +void RIPEMD160_Init(RIPEMD160_CTX *ctx) +{ + ctx->MD[0] = 0x67452301UL; + ctx->MD[1] = 0xefcdab89UL; + ctx->MD[2] = 0x98badcfeUL; + ctx->MD[3] = 0x10325476UL; + ctx->MD[4] = 0xc3d2e1f0UL; + ctx->len=ctx->l=0; + return; +} + +void RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data, u32 size) +{ + u8 *message=(u8 *)data; + u32 i,bytes; + + /* process message in 16-word chunks */ + for (bytes=size; bytes > 63; bytes-=64) { + for (i=0; i<16; i++) { + ctx->X[i] = bytes_TO_u32(message); message += 4; + } + compress(ctx); + } + + /* XXX, is this correct: + * - I process firstly the chunks + * - then I add the rest to the data... ist this really okay? + * - Tino Reichardt + */ + if (bytes+ctx->l >= 64) { + u8 *m=ctx->D; + memcpy(m+ctx->l, message, 64-ctx->l); + for (i=0; i<16; i++) { + ctx->X[i] = bytes_TO_u32(m); m += 4; + } + compress(ctx); + bytes-=64-ctx->l; message+=64-ctx->l; ctx->l=0; + } + + if (bytes > 0) { + memcpy(ctx->D+ctx->l, message, bytes); + ctx->l+=bytes; + } + + return; +} + +void RIPEMD160_Final(u8 *result, RIPEMD160_CTX *ctx) +{ + int i,bytes=ctx->len+ctx->l; + u8 *message=ctx->D; + + memset(ctx->X, 0, 16 * sizeof(u32)); + + for (i=0; i<(bytes&63); i++) { + ctx->X[i>>2] ^= (u32) *message++ << (8*(i&3)); + } + ctx->X[(bytes>>2)&15] ^= (u32)1 << (8*(bytes&3) + 7); + if ((bytes & 63) > 55) { compress(ctx); } + ctx->X[14] = bytes << 3; + ctx->X[15] = bytes >> 29; + compress(ctx); + for (i=0; i<20; i+=4) { + result[i] = ctx->MD[i>>2]; + result[i+1] = (ctx->MD[i>>2] >> 8); + result[i+2] = (ctx->MD[i>>2] >> 16); + result[i+3] = (ctx->MD[i>>2] >> 24); + } + + return; +} +#undef F +#undef FF +#undef FFF +#undef G +#undef GG +#undef GGG +#undef H +#undef HH +#undef HHH +#undef I +#undef II +#undef III +#undef J +#undef JJ +#undef JJJ +#undef ROL +#undef bytes_TO_u32 diff -urN qmail-1.03/ripemd.h qmail-1.03-md/ripemd.h --- qmail-1.03/ripemd.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/ripemd.h 2011-03-11 10:56:43.156750038 +0100 @@ -0,0 +1,19 @@ +#ifndef QP_RMD_H +#define QP_RMD_H + +#include "typesx.h" +#include + +typedef struct { + u32 MD[5]; /* used for the digest */ + u32 X[16]; /* current 16 bit chunk */ + u32 len; /* full length */ + u8 D[64]; /* 512 bit data block */ + u32 l; /* current length of data block -> D[l] */ +} RIPEMD160_CTX; + +void RIPEMD160_Init(RIPEMD160_CTX *ctx); +void RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data, u32 size); +void RIPEMD160_Final(u8 *result, RIPEMD160_CTX *ctx); + +#endif diff -urN qmail-1.03/scan.h qmail-1.03-md/scan.h --- qmail-1.03/scan.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/scan.h 2011-03-11 10:56:43.156750038 +0100 @@ -23,5 +23,6 @@ extern unsigned int scan_memcmp(); extern unsigned int scan_long(); +extern unsigned int scan_8long(); #endif diff -urN qmail-1.03/seek_cur.c qmail-1.03-md/seek_cur.c --- qmail-1.03/seek_cur.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/seek_cur.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,4 +1,3 @@ -#include #include "seek.h" #define CUR 1 /* sigh */ diff -urN qmail-1.03/seek_end.c qmail-1.03-md/seek_end.c --- qmail-1.03/seek_end.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/seek_end.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,4 +1,3 @@ -#include #include "seek.h" #define END 2 /* sigh */ diff -urN qmail-1.03/seek.h qmail-1.03-md/seek.h --- qmail-1.03/seek.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/seek.h 2011-03-11 10:56:43.156750038 +0100 @@ -1,6 +1,9 @@ #ifndef SEEK_H #define SEEK_H +#include +#include + typedef unsigned long seek_pos; extern seek_pos seek_cur(); diff -urN qmail-1.03/seek_set.c qmail-1.03-md/seek_set.c --- qmail-1.03/seek_set.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/seek_set.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,4 +1,3 @@ -#include #include "seek.h" #define SET 0 /* sigh */ diff -urN qmail-1.03/seek_trunc.c qmail-1.03-md/seek_trunc.c --- qmail-1.03/seek_trunc.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/seek_trunc.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,4 +1,3 @@ -#include #include "seek.h" int seek_trunc(fd,pos) int fd; seek_pos pos; diff -urN qmail-1.03/sendmail.c qmail-1.03-md/sendmail.c --- qmail-1.03/sendmail.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/sendmail.c 2011-03-11 10:56:43.156750038 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "sgetopt.h" #include "substdio.h" #include "subfd.h" @@ -37,6 +39,37 @@ _exit(111); } +void do_sender(const char *s) +{ + char *x; + int n; + int a; + int i; + + env_unset("QMAILNAME"); + env_unset("MAILNAME"); + env_unset("NAME"); + env_unset("QMAILHOST"); + env_unset("MAILHOST"); + + n = str_len(s); + a = str_rchr(s, '@'); + if (a == n) + { + env_put2("QMAILUSER", s); + return; + } + env_put2("QMAILHOST", s + a + 1); + + x = (char *) alloc((a + 1) * sizeof(char)); + if (!x) nomem(); + for (i = 0; i < a; i++) + x[i] = s[i]; + x[i] = 0; + env_put2("QMAILUSER", x); + alloc_free(x); +} + char *qreadarg[] = { "bin/qmail-qread", 0 }; void mailq() { @@ -48,7 +81,7 @@ int flagh; char *sender; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -64,8 +97,9 @@ flagh = 0; sender = 0; - while ((opt = getopt(argc,argv,"vimte:f:p:o:B:F:EJxb:")) != opteof) + while ((opt = getopt(argc,argv,"vimte:f:p:o:B:F:EJxb:N:")) != opteof) switch(opt) { + case 'N': break; /* ignore DSN option */ case 'B': break; case 't': flagh = 1; break; case 'f': sender = optarg; break; @@ -118,6 +152,7 @@ if (sender) { *arg++ = "-f"; *arg++ = sender; + do_sender(sender); } *arg++ = "--"; for (i = 0;i < argc;++i) *arg++ = argv[i]; diff -urN qmail-1.03/sha1.c qmail-1.03-md/sha1.c --- qmail-1.03/sha1.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/sha1.c 2011-03-11 10:56:43.160083553 +0100 @@ -0,0 +1,187 @@ + +/** + * Copyright (C) 2005-2006 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "sha1.h" + +/* define the SHA1 circular left shift macro */ +#define SHA1CircularShift(bits,word) \ + (((word) << (bits)) | ((word) >> (32-(bits)))) + +static void SHA1PadMessage(SHA1_CTX *); +static void SHA1ProcessMessageBlock(SHA1_CTX *); + +void SHA1_Init(SHA1_CTX *ctx) +{ + ctx->Length_Low = 0; + ctx->Length_High = 0; + ctx->Message_Block_Index = 0; + ctx->Intermediate_Hash[0] = 0x67452301; + ctx->Intermediate_Hash[1] = 0xEFCDAB89; + ctx->Intermediate_Hash[2] = 0x98BADCFE; + ctx->Intermediate_Hash[3] = 0x10325476; + ctx->Intermediate_Hash[4] = 0xC3D2E1F0; +} + +void SHA1_Update(SHA1_CTX *ctx, const void *data, u32 size) +{ + const u8 *ptr=data; + + while (size--) { + ctx->Message_Block[ctx->Message_Block_Index++] = (*ptr & 0xFF); + ctx->Length_Low += 8; + + if (ctx->Length_Low == 0) { + ctx->Length_High++; + if (ctx->Length_High == 0) return; /* ERR */ + } + + if (ctx->Message_Block_Index == 64) { + SHA1ProcessMessageBlock(ctx); + } + ptr++; + } +} + +void SHA1_Final(u8 *Message_Digest, SHA1_CTX *ctx) +{ + int i; + + SHA1PadMessage(ctx); + for(i=0; i<64; ++i) { + /* message may be sensitive, clear it out */ + ctx->Message_Block[i] = 0; + } + ctx->Length_Low = 0; /* and clear length */ + ctx->Length_High = 0; + + for(i = 0; i < SHA1HashSize; ++i) { + Message_Digest[i] = ctx->Intermediate_Hash[i>>2] >> 8*(3-(i&0x03)); + } +} + +static void SHA1ProcessMessageBlock(SHA1_CTX *ctx) +{ + /* Constants defined in SHA-1 */ + const u32 K[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; + int t; /* Loop counter */ + u32 temp; /* Temporary word value */ + u32 W[80]; /* Word sequence */ + u32 A,B,C,D,E; /* Word buffers */ + + for (t = 0; t < 16; t++) { + W[t] = ctx->Message_Block[t * 4] << 24; + W[t] |= ctx->Message_Block[t * 4 + 1] << 16; + W[t] |= ctx->Message_Block[t * 4 + 2] << 8; + W[t] |= ctx->Message_Block[t * 4 + 3]; + } + + for (t = 16; t < 80; t++) { + W[t] = SHA1CircularShift(1,W[t-3] ^ + W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = ctx->Intermediate_Hash[0]; + B = ctx->Intermediate_Hash[1]; + C = ctx->Intermediate_Hash[2]; + D = ctx->Intermediate_Hash[3]; + E = ctx->Intermediate_Hash[4]; + + for (t = 0; t < 20; t++) { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for (t = 20; t < 40; t++) { + temp = SHA1CircularShift(5,A) + + (B ^ C ^ D) + E + W[t] + K[1]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for (t = 40; t < 60; t++) { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for (t = 60; t < 80; t++) { + temp = SHA1CircularShift(5,A) + + (B ^ C ^ D) + E + W[t] + K[3]; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + ctx->Intermediate_Hash[0] += A; + ctx->Intermediate_Hash[1] += B; + ctx->Intermediate_Hash[2] += C; + ctx->Intermediate_Hash[3] += D; + ctx->Intermediate_Hash[4] += E; + ctx->Message_Block_Index = 0; +} + +static void SHA1PadMessage(SHA1_CTX *ctx) +{ + if (ctx->Message_Block_Index > 55) { + ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; + + while (ctx->Message_Block_Index < 64) { + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(ctx); + + while (ctx->Message_Block_Index < 56) { + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + + } else { + + ctx->Message_Block[ctx->Message_Block_Index++] = 0x80; + while (ctx->Message_Block_Index < 56) { + ctx->Message_Block[ctx->Message_Block_Index++] = 0; + } + } + + /* Store the message length as the last 8 octets */ + ctx->Message_Block[56] = ctx->Length_High >> 24; + ctx->Message_Block[57] = ctx->Length_High >> 16; + ctx->Message_Block[58] = ctx->Length_High >> 8; + ctx->Message_Block[59] = ctx->Length_High; + ctx->Message_Block[60] = ctx->Length_Low >> 24; + ctx->Message_Block[61] = ctx->Length_Low >> 16; + ctx->Message_Block[62] = ctx->Length_Low >> 8; + ctx->Message_Block[63] = ctx->Length_Low; + + SHA1ProcessMessageBlock(ctx); +} +#undef SHA1CircularShift diff -urN qmail-1.03/sha1.h qmail-1.03-md/sha1.h --- qmail-1.03/sha1.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/sha1.h 2011-03-11 10:56:43.160083553 +0100 @@ -0,0 +1,39 @@ +#ifndef SW_SHA1_H +#define SW_SHA1_H + +/** + * Copyright (C) 2005-2006 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "typesx.h" +#include + +#define SHA1HashSize 20 + +typedef struct SHA1_CTX +{ + u32 Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ + u32 Length_Low; /* Message length in bits */ + u32 Length_High; /* Message length in bits */ + u32 Message_Block_Index; /* Index into message block array */ + u8 Message_Block[64]; /* 512-bit message blocks */ +} SHA1_CTX; + +extern void SHA1_Init(SHA1_CTX *ctx); +extern void SHA1_Update(SHA1_CTX *ctx, const void *data, u32 size); +extern void SHA1_Final(u8 *result, SHA1_CTX *ctx); + +#endif diff -urN qmail-1.03/sig_catch.c qmail-1.03-md/sig_catch.c --- qmail-1.03/sig_catch.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/sig_catch.c 2011-03-11 10:56:43.160083553 +0100 @@ -3,13 +3,18 @@ #include "hassgact.h" void sig_catch(sig,f) -int sig; -void (*f)(); + int sig; + void (*f)(); { #ifdef HASSIGACTION struct sigaction sa; sa.sa_handler = f; +#ifdef SA_RESTART + /* if available */ + sa.sa_flags = SA_RESTART; +#else sa.sa_flags = 0; +#endif sigemptyset(&sa.sa_mask); sigaction(sig,&sa,(struct sigaction *) 0); #else diff -urN qmail-1.03/slurpclose.c qmail-1.03-md/slurpclose.c --- qmail-1.03/slurpclose.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/slurpclose.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,3 +1,6 @@ +#include +#include + #include "stralloc.h" #include "readwrite.h" #include "slurpclose.h" diff -urN qmail-1.03/spawn.c qmail-1.03-md/spawn.c --- qmail-1.03/spawn.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/spawn.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,10 +1,13 @@ #include #include +#include + #include "sig.h" #include "wait.h" #include "substdio.h" #include "byte.h" #include "str.h" +#include "alloc.h" #include "stralloc.h" #include "select.h" #include "exit.h" @@ -63,7 +66,7 @@ int flagreading = 1; char outbuf[1024]; substdio ssout; -int stage = 0; /* reading 0:delnum 1:messid 2:sender 3:recip */ +int stage = 0; /* reading 0:delnum 1:delnum2 2:messid 3:sender 4:recip */ int flagabort = 0; /* if 1, everything except delnum is garbage */ int delnum; stralloc messid = {0}; @@ -73,6 +76,7 @@ void err(s) char *s; { char ch; ch = delnum; substdio_put(&ssout,&ch,1); + ch = delnum >> 8; substdio_put(&ssout,&ch,1); substdio_puts(&ssout,s); substdio_putflush(&ssout,"",1); } @@ -85,44 +89,44 @@ int pi[2]; struct stat st; - if (flagabort) { err("Zqmail-spawn out of memory. (#4.3.0)\n"); return; } - if (delnum < 0) { err("ZInternal error: delnum negative. (#4.3.5)\n"); return; } - if (delnum >= auto_spawn) { err("ZInternal error: delnum too big. (#4.3.5)\n"); return; } - if (d[delnum].used) { err("ZInternal error: delnum in use. (#4.3.5)\n"); return; } + if (flagabort) { err("Z4.3.0 qmail-spawn out of memory\n"); return; } + if (delnum < 0) { err("Z4.3.5 Internal error: delnum negative\n"); return; } + if (delnum >= auto_spawn) { err("Z4.3.5 Internal error: delnum too big\n"); return; } + if (d[delnum].used) { err("Z4.3.5 Internal error: delnum in use\n"); return; } for (i = 0;i < messid.len;++i) if (messid.s[i]) if (!i || (messid.s[i] != '/')) if ((unsigned char) (messid.s[i] - '0') > 9) - { err("DInternal error: messid has nonnumerics. (#5.3.5)\n"); return; } - if (messid.len > 100) { err("DInternal error: messid too long. (#5.3.5)\n"); return; } - if (!messid.s[0]) { err("DInternal error: messid too short. (#5.3.5)\n"); return; } + { err("D5.3.5 Internal error: messid has nonnumerics\n"); return; } + if (messid.len > 100) { err("D5.3.5 Internal error: messid too long\n"); return; } + if (!messid.s[0]) { err("D5.3.5 Internal error: messid too short\n"); return; } if (!stralloc_copys(&d[delnum].output,"")) - { err("Zqmail-spawn out of memory. (#4.3.0)\n"); return; } + { err("Z4.3.0 qmail-spawn out of memory\n"); return; } j = byte_rchr(recip.s,recip.len,'@'); - if (j >= recip.len) { err("DSorry, address must include host name. (#5.1.3)\n"); return; } + if (j >= recip.len) { err("D5.1.3 Sorry, address must include host name\n"); return; } fdmess = open_read(messid.s); - if (fdmess == -1) { err("Zqmail-spawn unable to open message. (#4.3.0)\n"); return; } + if (fdmess == -1) { err("Z4.3.0 qmail-spawn unable to open message\n"); return; } if (fstat(fdmess,&st) == -1) - { close(fdmess); err("Zqmail-spawn unable to fstat message. (#4.3.0)\n"); return; } + { close(fdmess); err("Z4.3.0 qmail-spawn unable to fstat message\n"); return; } if ((st.st_mode & S_IFMT) != S_IFREG) - { close(fdmess); err("ZSorry, message has wrong type. (#4.3.5)\n"); return; } + { close(fdmess); err("Z4.3.5 Sorry, message has wrong type\n"); return; } if (st.st_uid != auto_uidq) /* aaack! qmailq has to be trusted! */ /* your security is already toast at this point. damage control... */ - { close(fdmess); err("ZSorry, message has wrong owner. (#4.3.5)\n"); return; } + { close(fdmess); err("Z4.3.5 Sorry, message has wrong owner\n"); return; } if (pipe(pi) == -1) - { close(fdmess); err("Zqmail-spawn unable to create pipe. (#4.3.0)\n"); return; } + { close(fdmess); err("Z4.3.0 qmail-spawn unable to create pipe\n"); return; } coe(pi[0]); - f = spawn(fdmess,pi[1],sender.s,recip.s,j); + f = spawn(fdmess,pi[1],st.st_size,sender.s,recip.s,j); close(fdmess); if (f == -1) - { close(pi[0]); close(pi[1]); err("Zqmail-spawn unable to fork. (#4.3.0)\n"); return; } + { close(pi[0]); close(pi[1]); err("Z4.3.0 qmail-spawn unable to fork\n"); return; } d[delnum].fdin = pi[0]; d[delnum].fdout = pi[1]; coe(pi[1]); @@ -155,16 +159,19 @@ { case 0: delnum = (unsigned int) (unsigned char) ch; - messid.len = 0; stage = 1; break; + stage = 1; break; case 1: + delnum += (unsigned int) ((unsigned int) ch) << 8; + messid.len = 0; stage = 2; break; + case 2: if (!stralloc_append(&messid,&ch)) flagabort = 1; if (ch) break; - sender.len = 0; stage = 2; break; - case 2: + sender.len = 0; stage = 3; break; + case 3: if (!stralloc_append(&sender,&ch)) flagabort = 1; if (ch) break; - recip.len = 0; stage = 3; break; - case 3: + recip.len = 0; stage = 4; break; + case 4: if (!stralloc_append(&recip,&ch)) flagabort = 1; if (ch) break; docmd(); @@ -175,7 +182,7 @@ char inbuf[128]; -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { @@ -201,7 +208,8 @@ initialize(argc,argv); - ch = auto_spawn; substdio_putflush(&ssout,&ch,1); + ch = auto_spawn; substdio_put(&ssout,&ch,1); + ch = auto_spawn >> 8; substdio_putflush(&ssout,&ch,1); for (i = 0;i < auto_spawn;++i) { d[i].used = 0; d[i].output.s = 0; } @@ -236,7 +244,8 @@ continue; /* read error on a readable pipe? be serious */ if (r == 0) { - ch = i; substdio_put(&ssout,&ch,1); + char ch; ch = i; substdio_put(&ssout,&ch,1); + ch = i >> 8; substdio_put(&ssout,&ch,1); report(&ssout,d[i].wstat,d[i].output.s,d[i].output.len); substdio_put(&ssout,"",1); substdio_flush(&ssout); diff -urN qmail-1.03/splogger.c qmail-1.03-md/splogger.c --- qmail-1.03/splogger.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/splogger.c 2011-03-11 10:56:43.160083553 +0100 @@ -45,7 +45,7 @@ bufpos = 0; } -void main(argc,argv) +int main(argc,argv) int argc; char **argv; { diff -urN qmail-1.03/str_cpyb.c qmail-1.03-md/str_cpyb.c --- qmail-1.03/str_cpyb.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/str_cpyb.c 2011-03-11 10:56:43.160083553 +0100 @@ -0,0 +1,18 @@ +#include "str.h" + +unsigned int str_copyb(s,t,max) +register char *s; +register char *t; +unsigned int max; +{ + register int len; + + len = 0; + while (max-- > 0) { + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + if (!(*s = *t)) return len; ++s; ++t; ++len; + } + return len; +} diff -urN qmail-1.03/str.h qmail-1.03-md/str.h --- qmail-1.03/str.h 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/str.h 2011-03-11 10:56:43.160083553 +0100 @@ -1,13 +1,15 @@ #ifndef STR_H #define STR_H -extern unsigned int str_copy(); extern int str_diff(); extern int str_diffn(); +extern int str_start(); + extern unsigned int str_len(); extern unsigned int str_chr(); extern unsigned int str_rchr(); -extern int str_start(); +extern unsigned int str_copy(); +extern unsigned int str_copyb(); #define str_equal(s,t) (!str_diff((s),(t))) diff -urN qmail-1.03/strsalloc.c qmail-1.03-md/strsalloc.c --- qmail-1.03/strsalloc.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/strsalloc.c 2011-03-11 10:56:43.160083553 +0100 @@ -0,0 +1,7 @@ +#include "alloc.h" +#include "gen_allocdefs.h" +#include "stralloc.h" +#include "strsalloc.h" + +GEN_ALLOC_readyplus(strsalloc,stralloc,sa,len,a,i,n,x,10,strsalloc_readyplus) +GEN_ALLOC_append(strsalloc,stralloc,sa,len,a,i,n,x,10,strsalloc_readyplus,strsalloc_append) diff -urN qmail-1.03/strsalloc.h qmail-1.03-md/strsalloc.h --- qmail-1.03/strsalloc.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/strsalloc.h 2011-03-11 10:56:43.160083553 +0100 @@ -0,0 +1,12 @@ +#ifndef STRSALLOC_H +#define STRSALLOC_H + +#include "stralloc.h" + +#include "gen_alloc.h" + +GEN_ALLOC_typedef(strsalloc,stralloc,sa,len,a) +extern int strsalloc_readyplus(); +extern int strsalloc_append(); + +#endif diff -urN qmail-1.03/subfderr.c qmail-1.03-md/subfderr.c --- qmail-1.03/subfderr.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/subfderr.c 2011-03-11 10:56:43.160083553 +0100 @@ -2,6 +2,6 @@ #include "substdio.h" #include "subfd.h" -char subfd_errbuf[256]; -static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,256); +char subfd_errbuf[1024]; +static substdio it = SUBSTDIO_FDBUF(write,2,subfd_errbuf,1024); substdio *subfderr = ⁢ diff -urN qmail-1.03/TARGETS qmail-1.03-md/TARGETS --- qmail-1.03/TARGETS 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/TARGETS 2011-03-11 10:56:43.160083553 +0100 @@ -1,387 +1,354 @@ +alloc.a +alloc.o +alloc_re.o +auto_break.c +auto_break.o auto-ccld.sh -make-load -find-systype -systype -load -make-compile -compile -fork.h -qmail-local.o -qmail.o -quote.o -now.o -gfrom.o -myctime.o -slurpclose.o -make-makelib -makelib +auto-gid +auto-gid.o +auto-int +auto-int8 +auto-int8.o +auto-int.o +auto_patrn.c +auto_patrn.o +auto_qmail.c +auto_qmail.o +auto_spawn.c +auto_spawn.o +auto_split.c +auto_split.o +auto-str +auto-str.o +auto-uid +auto-uid.o +auto_uids.c +auto_uids.o +auto_usera.c +auto_usera.o +base64.o +binm1 +binm1+df +binm2 +binm2+df +binm3 +binm3+df +bouncesaying +bouncesaying.o +byte_chr.o +byte_copy.o +byte_cr.o +byte_cspn.o +byte_diff.o +byte_rchr.o +byte_rcspn.o +byte_zero.o +case.a case_diffb.o case_diffs.o case_lowerb.o case_lowers.o case_starts.o -case.a -getln.o -getln2.o -getln.a -subgetopt.o -sgetopt.o -getopt.a -sig_alarm.o -hassgprm.h -sig_block.o -hassgact.h -sig_catch.o -sig_pause.o -sig_pipe.o -sig_child.o -sig_hup.o -sig_term.o -sig_bug.o -sig_misc.o -sig.a -open_append.o -open_excl.o -open_read.o -open_trunc.o -open_write.o -open.a -seek_cur.o -seek_end.o -seek_set.o -seek_trunc.o -seek.a -hasflock.h -lock_ex.o -lock_exnb.o -lock_un.o -lock.a -fd_copy.o -fd_move.o -fd.a -haswaitp.h -wait_pid.o -wait_nohang.o -wait.a +cdb.a +cdb_hash.o +cdbmake.a +cdbmake_add.o +cdbmake_hash.o +cdbmake_pack.o +cdbmss.o +cdb_seek.o +cdb_unpack.o +check +chkshsgr +chkshsgr.o +chkspawn +chkspawn.o +coe.o +commands.o +compile +condredirect +condredirect.o +config +config-fast +constmap.o +control.o +date822fmt.o +datemail +datetime.a +datetime.o +datetime_un.o +direntry.h +dnscname +dnscname.o +dnsdoe.o +dnsfq +dnsfq.o +dnsip +dnsip.o +dns.lib +dnsmxip +dnsmxip.o +dns.o +dnsptr +dnsptr.o +dnstxt +dnstxt.o +dot-qmail.5 +elq +env.a env.o envread.o -env.a -stralloc_eady.o -stralloc_pend.o -stralloc_copy.o -stralloc_opys.o -stralloc_opyb.o -stralloc_cat.o -stralloc_cats.o -stralloc_catb.o -stralloc_arts.o -stralloc.a -alloc.o -alloc_re.o -alloc.a -strerr_sys.o -strerr_die.o -strerr.a -substdio.o -substdi.o -substdo.o -subfderr.o -subfdout.o -subfdouts.o -subfdin.o -subfdins.o -substdio_copy.o -substdio.a +error.a error.o error_str.o error_temp.o -error.a -str_len.o -str_diff.o -str_diffn.o -str_cpy.o -str_chr.o -str_rchr.o -str_start.o -byte_chr.o -byte_rchr.o -byte_diff.o -byte_copy.o -byte_cr.o -byte_zero.o -str.a -fmt_str.o +except +except.o +fd.a +fd_copy.o +fd_move.o +fifo.o +find-systype +fmtqfn.o fmt_strn.o -fmt_uint.o +fmt_str.o fmt_uint0.o +fmt_uint.o fmt_ulong.o -scan_ulong.o -scan_8long.o +fork.h +forward +forward.o fs.a -datetime.o -datetime_un.o -datetime.a -auto-str.o -auto-str -auto_qmail.c -auto_qmail.o -auto-int8.o -auto-int8 -auto_patrn.c -auto_patrn.o -socket.lib -qmail-local -uint32.h -qmail-lspawn.o -select.h -chkspawn.o -auto-int.o -auto-int -auto_spawn.c -auto_spawn.o -chkspawn -spawn.o -chkshsgr.o -chkshsgr +getln2.o +getln.a +getln.o +getopt.a +gfrom.o +hasflock.h +hasmkffo.h +hasnpbg1.h +hassalen.h +hassgact.h +hassgprm.h hasshsgr.h -prot.o -coe.o -cdb_hash.o -cdb_unpack.o -cdb_seek.o -cdb.a -auto-uid.o -auto-uid -auto-gid.o -auto-gid -auto_uids.c -auto_uids.o -qmail-lspawn -qmail-getpw.o -auto_break.c -auto_break.o -auto_usera.c -auto_usera.o -qmail-getpw -qmail-remote.o -control.o -constmap.o -timeoutread.o -timeoutwrite.o -timeoutconn.o -tcpto.o -dns.o -ip.o +haswaitp.h +headerbody.o +hfield.o +hier.o +hmac_md5.o +hmac_ripemd.o +hmac_sha1.o +home +home+df +hostname +hostname.o +idedit +idedit.o +install +install-big +install-big.o +install.o +instcheck +instcheck.o ipalloc.o -hassalen.h ipme.o +ipmeprint +ipmeprint.o +ip.o +it +load +lock.a +lock_exnb.o +lock_ex.o +lock_un.o +maildir2mbox +maildir2mbox.o +maildirmake +maildirmake.o +maildir.o +maildirwatch +maildirwatch.o +mailsubj +make-compile +makelib +make-load +make-makelib +man +md5.o +myctime.o +ndelay.a ndelay.o ndelay_off.o -ndelay.a -dns.lib -qmail-remote -qmail-rspawn.o -tcpto_clean.o -qmail-rspawn -direntry.h -qmail-clean.o -fmtqfn.o -auto_split.c -auto_split.o -qmail-clean -qmail-send.o -qsutil.o newfield.o +now.o +open.a +open_append.o +open_excl.o +open_read.o +open_trunc.o +open_write.o +out_log.o +pinq +predate +predate.o +preline +preline.o prioq.o -hasmkffo.h -fifo.o -hasnpbg1.h -trigger.o -readsubdir.o -date822fmt.o -qmail-send -qmail-start.o -qmail-start -splogger.o -syslog.lib -splogger -qmail-queue.o -triggerpull.o -qmail-queue -qmail-inject.o -headerbody.o -hfield.o -token822.o +proc +proc+df +prot.o +qail +qbiff +qbiff.o +qmail-clean +qmail-clean.o +qmail-control.5 +qmail-getpw +qmail-getpw.8 +qmail-getpw.o qmail-inject -predate.o -predate -datemail -mailsubj -qmail-upq -qmail-showctl.o -qmail-showctl -qmail-newu.o -cdbmss.o -cdbmake_pack.o -cdbmake_hash.o -cdbmake_add.o -cdbmake.a +qmail-inject.o +qmail-limits.7 +qmail-local +qmail-local.o +qmail-lspawn +qmail-lspawn.o +qmail-newmrh +qmail-newmrh.8 +qmail-newmrh.o qmail-newu -qmail-pw2u.o -qmail-pw2u -qmail-qread.o -qmail-qread -qmail-qstat -qmail-tcpto.o -qmail-tcpto -qmail-tcpok.o -qmail-tcpok -qmail-pop3d.o -commands.o -maildir.o +qmail-newu.8 +qmail-newu.o +qmail.o +qmail-p0f.o qmail-pop3d -qmail-popup.o +qmail-pop3d.o qmail-popup -qmail-qmqpc.o +qmail-popup.o +qmail-pw2u +qmail-pw2u.8 +qmail-pw2u.o qmail-qmqpc -qmail-qmqpd.o -received.o +qmail-qmqpc.o qmail-qmqpd -qmail-qmtpd.o -rcpthosts.o +qmail-qmqpd.o qmail-qmtpd -qmail-smtpd.o -qmail-smtpd -sendmail.o -sendmail -tcp-env.o -remoteinfo.o -tcp-env -qmail-newmrh.o -qmail-newmrh -config -config-fast -dnscname.o -dnsdoe.o -dnscname -dnsptr.o -dnsptr -dnsip.o -dnsip -dnsmxip.o -dnsmxip -dnsfq.o -dnsfq -hostname.o -hostname -ipmeprint.o -ipmeprint -qreceipt.o -qreceipt -qsmhook.o -qsmhook -qbiff.o -qbiff -forward.o -forward -preline.o -preline -condredirect.o -condredirect -bouncesaying.o -bouncesaying -except.o -except -maildirmake.o -maildirmake -maildir2mbox.o -maildir2mbox -maildirwatch.o -maildirwatch -qail -elq -pinq -idedit.o -idedit -install-big.o -install.o -install-big -hier.o -install -instcheck.o -instcheck -home -home+df -proc -proc+df -binm1 -binm1+df -binm2 -binm2+df -binm3 -binm3+df -it -qmail-local.0 -qmail-lspawn.0 -qmail-getpw.8 -qmail-getpw.0 -qmail-remote.0 -qmail-rspawn.0 -qmail-clean.0 +qmail-qmtpd.o +qmail-qread +qmail-qread.o +qmail-qstat +qmail-queue +qmail-queue.o +qmail-remote +qmail-remote.o +qmail-rspawn +qmail-rspawn.o +qmail-sasl.o +qmail-send qmail-send.8 -qmail-send.0 +qmail-send.o +qmail-showctl +qmail-showctl.o +qmail-smtpd +qmail-smtpd.o +qmail-start qmail-start.8 -qmail-start.0 -splogger.0 -qmail-queue.0 -qmail-inject.0 -mailsubj.0 -qmail-showctl.0 -qmail-newu.8 -qmail-newu.0 -qmail-pw2u.8 -qmail-pw2u.0 -qmail-qread.0 -qmail-qstat.0 -qmail-tcpto.0 -qmail-tcpok.0 -qmail-pop3d.0 -qmail-popup.0 -qmail-qmqpc.0 -qmail-qmqpd.0 -qmail-qmtpd.0 -qmail-smtpd.0 -tcp-env.0 -qmail-newmrh.8 -qmail-newmrh.0 -qreceipt.0 -qbiff.0 -forward.0 -preline.0 -condredirect.0 -bouncesaying.0 -except.0 -maildirmake.0 -maildir2mbox.0 -maildirwatch.0 -qmail.0 -qmail-limits.7 -qmail-limits.0 -qmail-log.0 -qmail-control.5 -qmail-control.0 -qmail-header.0 +qmail-start.o +qmail-tcpok +qmail-tcpok.o +qmail-tcpto +qmail-tcpto.o +qmail-upq qmail-users.5 -qmail-users.0 -dot-qmail.5 -dot-qmail.0 -qmail-command.0 -tcp-environ.0 -maildir.0 -mbox.0 -addresses.0 -envelopes.0 -forgeries.0 -man +qreceipt +qreceipt.o +qsmhook +qsmhook.o +qsutil.o +quote.o +rcpthosts.o +readsubdir.o +realrcptto.o +received.o +remoteinfo.o +ripemd.o +scan_8long.o +scan_ulong.o +seek.a +seek_cur.o +seek_end.o +seek_set.o +seek_trunc.o +select.h +sendmail +sendmail.o setup -check +sgetopt.o +sha1.o +sig.a +sig_alarm.o +sig_block.o +sig_bug.o +sig_catch.o +sig_child.o +sig_hup.o +sig_misc.o +sig_pause.o +sig_pipe.o +sig_term.o +slurpclose.o +socket.lib +spawn.o +splogger +splogger.o +str.a +stralloc.a +stralloc_arts.o +stralloc_catb.o +stralloc_cat.o +stralloc_cats.o +stralloc_copy.o +stralloc_eady.o +stralloc_opyb.o +stralloc_opys.o +stralloc_pend.o +str_chr.o +str_cpyb.o +str_cpy.o +str_diffn.o +str_diff.o +strerr.a +strerr_die.o +strerr_sys.o +str_len.o +str_rchr.o +strsalloc.o +str_start.o +subfderr.o +subfdin.o +subfdins.o +subfdout.o +subfdouts.o +subgetopt.o +substdi.o +substdio.a +substdio_copy.o +substdio.o +substdo.o +syslog.lib +systype +tcp-env +tcp-env.o +tcpto_clean.o +tcpto.o +timeoutconn.o +timeoutread.o +timeoutwrite.o +token822.o +trigger.o +triggerpull.o +ucspitls.o +uint32.h +wait.a +wait_nohang.o +wait_pid.o diff -urN qmail-1.03/tcp-env.c qmail-1.03-md/tcp-env.c --- qmail-1.03/tcp-env.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tcp-env.c 2011-03-11 10:56:43.160083553 +0100 @@ -2,6 +2,8 @@ #include #include #include +#include + #include "sig.h" #include "stralloc.h" #include "str.h" @@ -10,6 +12,7 @@ #include "scan.h" #include "subgetopt.h" #include "ip.h" +#include "strsalloc.h" #include "dns.h" #include "byte.h" #include "remoteinfo.h" @@ -30,10 +33,11 @@ char temp[IPFMT + FMT_ULONG]; -void main(argc,argv) +int main(argc,argv) int argc; char *argv[]; { + strsalloc ssa = {0}; int dummy; char *proto; int opt; @@ -74,12 +78,13 @@ temp[ip_fmt(temp,&iplocal)] = 0; if (!env_put2("TCPLOCALIP",temp)) die(); - switch(dns_ptr(&localname,&iplocal)) + switch(dns_ptr(&ssa,&iplocal)) { case DNS_MEM: die(); case DNS_SOFT: if (!stralloc_copys(&localname,"softdnserror")) die(); case 0: + if (!stralloc_copy(&localname,&ssa.sa[0])) die(); if (!stralloc_0(&localname)) die(); case_lowers(localname.s); if (!env_put2("TCPLOCALHOST",localname.s)) die(); @@ -99,12 +104,13 @@ temp[ip_fmt(temp,&ipremote)] = 0; if (!env_put2("TCPREMOTEIP",temp)) die(); - switch(dns_ptr(&remotename,&ipremote)) + switch(dns_ptr(&ssa,&ipremote)) { case DNS_MEM: die(); case DNS_SOFT: if (!stralloc_copys(&remotename,"softdnserror")) die(); case 0: + if (!stralloc_copy(&remotename,&ssa.sa[0])) die(); if (!stralloc_0(&remotename)) die(); case_lowers(remotename.s); if (!env_put2("TCPREMOTEHOST",remotename.s)) die(); @@ -125,5 +131,5 @@ sig_pipedefault(); execvp(*argv,argv); - die(); + return 111; } diff -urN qmail-1.03/tcpto.c qmail-1.03-md/tcpto.c --- qmail-1.03/tcpto.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tcpto.c 2011-03-11 10:56:43.160083553 +0100 @@ -73,7 +73,7 @@ int i; char *record; datetime_sec when; - datetime_sec firstwhen; + datetime_sec firstwhen=0; int firstpos; datetime_sec lastwhen; diff -urN qmail-1.03/tcpto_clean.c qmail-1.03-md/tcpto_clean.c --- qmail-1.03/tcpto_clean.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tcpto_clean.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "tcpto.h" #include "open.h" #include "substdio.h" diff -urN qmail-1.03/timeoutconn.c qmail-1.03-md/timeoutconn.c --- qmail-1.03/timeoutconn.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/timeoutconn.c 2011-03-11 10:56:43.160083553 +0100 @@ -10,38 +10,46 @@ #include "byte.h" #include "timeoutconn.h" -int timeoutconn(s,ip,port,timeout) -int s; -struct ip_address *ip; -unsigned int port; -int timeout; +int timeoutconn(s,ip,outip,port,timeout) + int s; + struct ip_address *ip; + struct ip_address *outip; + unsigned int port; + int timeout; { char ch; struct sockaddr_in sin; char *x; fd_set wfds; struct timeval tv; - + + /* bind() an outgoing ipaddr */ + byte_zero(&sin,sizeof(sin)); + byte_copy(&sin.sin_addr.s_addr,4,outip); + sin.sin_family = AF_INET; + + if (-1 == bind(s,(struct sockaddr *) &sin,sizeof(sin))) return -1; + byte_zero(&sin,sizeof(sin)); byte_copy(&sin.sin_addr,4,ip); x = (char *) &sin.sin_port; x[1] = port; port >>= 8; x[0] = port; sin.sin_family = AF_INET; - + if (ndelay_on(s) == -1) return -1; - + /* XXX: could bind s */ - + if (connect(s,(struct sockaddr *) &sin,sizeof(sin)) == 0) { ndelay_off(s); return 0; } if ((errno != error_inprogress) && (errno != error_wouldblock)) return -1; - + FD_ZERO(&wfds); FD_SET(s,&wfds); tv.tv_sec = timeout; tv.tv_usec = 0; - + if (select(s + 1,(fd_set *) 0,&wfds,(fd_set *) 0,&tv) == -1) return -1; if (FD_ISSET(s,&wfds)) { int dummy; @@ -53,7 +61,7 @@ ndelay_off(s); return 0; } - + errno = error_timeout; /* note that connect attempt is continuing */ return -1; } diff -urN qmail-1.03/trigger.c qmail-1.03-md/trigger.c --- qmail-1.03/trigger.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trigger.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "select.h" #include "open.h" #include "trigger.h" diff -urN qmail-1.03/triggerpull.c qmail-1.03-md/triggerpull.c --- qmail-1.03/triggerpull.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/triggerpull.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,3 +1,5 @@ +#include +#include #include "ndelay.h" #include "open.h" #include "triggerpull.h" diff -urN qmail-1.03/trycpp.c qmail-1.03-md/trycpp.c --- qmail-1.03/trycpp.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trycpp.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,4 +1,4 @@ -void main() +int main() { #ifdef NeXT printf("nextstep\n"); exit(0); diff -urN qmail-1.03/tryflock.c qmail-1.03-md/tryflock.c --- qmail-1.03/tryflock.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tryflock.c 2011-03-11 10:56:43.160083553 +0100 @@ -2,7 +2,7 @@ #include #include -void main() +int main() { flock(0,LOCK_EX | LOCK_UN | LOCK_NB); } diff -urN qmail-1.03/trymkffo.c qmail-1.03-md/trymkffo.c --- qmail-1.03/trymkffo.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trymkffo.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,7 +1,7 @@ #include #include -void main() +int main() { mkfifo("temp-trymkffo",0); } diff -urN qmail-1.03/trynpbg1.c qmail-1.03-md/trynpbg1.c --- qmail-1.03/trynpbg1.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trynpbg1.c 2011-03-11 10:56:43.160083553 +0100 @@ -4,7 +4,7 @@ #define FN "temp-trynpbg1.fifo" -void main() +int main() { int flagbug; struct timeval instant; diff -urN qmail-1.03/trysgact.c qmail-1.03-md/trysgact.c --- qmail-1.03/trysgact.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trysgact.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,6 +1,6 @@ #include -void main() +int main() { struct sigaction sa; sa.sa_handler = 0; diff -urN qmail-1.03/trysgprm.c qmail-1.03-md/trysgprm.c --- qmail-1.03/trysgprm.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trysgprm.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,6 +1,6 @@ #include -void main() +int main() { sigset_t ss; diff -urN qmail-1.03/tryshsgr.c qmail-1.03-md/tryshsgr.c --- qmail-1.03/tryshsgr.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tryshsgr.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,4 +1,4 @@ -void main() +int main() { short x[4]; diff -urN qmail-1.03/tryulong32.c qmail-1.03-md/tryulong32.c --- qmail-1.03/tryulong32.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tryulong32.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,4 +1,4 @@ -void main() +int main() { unsigned long u; u = 1; diff -urN qmail-1.03/tryvfork.c qmail-1.03-md/tryvfork.c --- qmail-1.03/tryvfork.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/tryvfork.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,4 +1,4 @@ -void main() +int main() { vfork(); } diff -urN qmail-1.03/trywaitp.c qmail-1.03-md/trywaitp.c --- qmail-1.03/trywaitp.c 1998-06-15 12:53:16.000000000 +0200 +++ qmail-1.03-md/trywaitp.c 2011-03-11 10:56:43.160083553 +0100 @@ -1,7 +1,7 @@ #include #include -void main() +int main() { waitpid(0,0,0); } diff -urN qmail-1.03/typesx.h qmail-1.03-md/typesx.h --- qmail-1.03/typesx.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/typesx.h 2011-03-11 10:56:43.163417022 +0100 @@ -0,0 +1,26 @@ +#ifndef MISC_TYPES_H +#define MISC_TYPES_H + +#include +#include + +/* used for crypto routines */ +#ifdef uint32_t +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef int32_t i32; +typedef int16_t i16; +typedef int8_t i8; +#else +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; + +typedef signed int i32; +typedef signed short i16; +typedef signed char i8; +#endif + +#endif diff -urN qmail-1.03/ucspitls.c qmail-1.03-md/ucspitls.c --- qmail-1.03/ucspitls.c 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/ucspitls.c 2011-03-11 10:56:43.163417022 +0100 @@ -0,0 +1,31 @@ +#include "scan.h" +#include "env.h" + +int ucspitls(void) +{ + unsigned long fd; + char *fdstr; + + if (!(fdstr=env_get("SSLCTLFD"))) + return 0; + if (!scan_ulong(fdstr,&fd)) + return 0; + if (write((int)fd, "y", 1) < 1) + return 0; + + if (!(fdstr=env_get("SSLREADFD"))) + return 0; + if (!scan_ulong(fdstr,&fd)) + return 0; + if (dup2((int)fd,0) == -1) + return 0; + + if (!(fdstr=env_get("SSLWRITEFD"))) + return 0; + if (!scan_ulong(fdstr,&fd)) + return 0; + if (dup2((int)fd,1) == -1) + return 0; + + return 1; +} diff -urN qmail-1.03/ucspitls.h qmail-1.03-md/ucspitls.h --- qmail-1.03/ucspitls.h 1970-01-01 01:00:00.000000000 +0100 +++ qmail-1.03-md/ucspitls.h 2011-03-11 10:56:43.163417022 +0100 @@ -0,0 +1 @@ +int ucspitls(void);