diff -u -N orig/case_startb.c ./case_startb.c --- orig/case_startb.c 1969-12-31 19:00:00.000000000 -0500 +++ ./case_startb.c 2003-03-06 17:53:59.000000000 -0500 @@ -0,0 +1,21 @@ +#include "case.h" + +int case_startb(s,len,t) +register char *s; +unsigned int len; +register char *t; +{ + register unsigned char x; + register unsigned char y; + + for (;;) { + y = *t++ - 'A'; + if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; + if (!y) return 1; + if (!len) return 0; + --len; + x = *s++ - 'A'; + if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; + if (x != y) return 0; + } +} diff -u -N orig/Makefile ./Makefile --- orig/Makefile 1998-06-15 06:53:16.000000000 -0400 +++ ./Makefile 2003-03-10 10:49:44.000000000 -0500 @@ -217,9 +217,9 @@ case.a: \ makelib case_diffb.o case_diffs.o case_lowerb.o case_lowers.o \ -case_starts.o +case_starts.o case_startb.o ./makelib case.a case_diffb.o case_diffs.o case_lowerb.o \ - case_lowers.o case_starts.o + case_lowers.o case_starts.o case_startb.o case_diffb.o: \ compile case_diffb.c case.h @@ -237,6 +237,10 @@ compile case_lowers.c case.h ./compile case_lowers.c +case_startb.o: \ +compile case_startb.c case.h + ./compile case_startb.c + case_starts.o: \ compile case_starts.c case.h ./compile case_starts.c diff -u -N orig/qmail-smtpd.c ./qmail-smtpd.c --- orig/qmail-smtpd.c 1998-06-15 06:53:16.000000000 -0400 +++ ./qmail-smtpd.c 2003-03-10 10:40:31.000000000 -0500 @@ -281,9 +281,100 @@ struct qmail qqt; unsigned int bytestooverflow = 0; +int putinheader; +int linespastheader; /* =0 after boundary is found in body, */ + /* until blank line */ +char linetype; +int flagexecutable; + +stralloc line = {0}; +stralloc content = {0}; +stralloc boundary = {0}; + void put(ch) char *ch; { + char *cp, *cpstart, *cpafter; + unsigned int len; + + if (line.len < 1024) + if (!stralloc_catb(&line,ch,1)) die_nomem(); + + if (*ch == '\n') { + if (putinheader) { + /*substdio_put(&ssout,line.s,line.len);*/ + if (line.len == 1) { + putinheader = 0; + if (content.len) { /* MIME header */ + cp = content.s; + len = content.len; + while (len && *cp == ' ' || *cp == '\t') { ++cp; --len; } + cpstart = cp; + if (len && *cp == '"') { /* might be commented */ + ++cp; --len; cpstart = cp; + while (len && *cp != '"') { ++cp; --len; } + } else { + while (len && *cp != ' ' && *cp != '\t' && *cp != ';') { + ++cp; --len; + } + } + + cpafter = content.s+content.len; + while((cp += byte_chr(cp,cpafter-cp,';')) != cpafter) { + ++cp; + while (cp < cpafter && (*cp == ' ') || (*cp == '\t')) ++cp; + if (case_startb(cp,cpafter - cp,"boundary=")) { + cp += 9; /* after boundary= */ + if (cp < cpafter && *cp == '"') { + ++cp; + cpstart = cp; + while (cp < cpafter && *cp != '"') ++cp; + } else { + cpstart = cp; + while (cp < cpafter && + *cp != ';' && *cp != ' ' && *cp != '\t') ++cp; + } + if (!stralloc_copys(&boundary,"--")) die_nomem(); + if (!stralloc_catb(&boundary,cpstart,cp-cpstart)) + die_nomem(); + break; + } + } + } + } else { + if ((*line.s == ' ' || *line.s == '\t')) { + switch(linetype) { + case 'C': if (!stralloc_catb(&content,line.s,line.len-1)) die_nomem(); break; + default: break; + } + } else { + if (case_startb(line.s,line.len,"content-type:")) { + if (!stralloc_copyb(&content,line.s+13,line.len-14)) die_nomem(); + linetype = 'C'; + } else { + linetype = ' '; + } + } + } + } else { + if (boundary.len && *line.s == '-' && line.len > boundary.len && + !str_diffn(line.s,boundary.s,boundary.len)) { + linespastheader = 0; + } else if (linespastheader == 0 && line.len == 1) { + linespastheader = 1; + } else if (linespastheader == 1) { + if (line.len >= 9) + if (!str_diffn(line.s,"TVqQAAMAA",9) || + !str_diffn(line.s,"TVpQAAIAA",9)) { + flagexecutable = 1; + qmail_fail(&qqt); + } + linespastheader = 2; + } + } + line.len = 0; + } + if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qqt); @@ -374,6 +465,12 @@ if (!rcptto.len) { err_wantrcpt(); return; } seenmail = 0; if (databytes) bytestooverflow = databytes + 1; + boundary.len = 0; + content.len = 0; + putinheader = 1; + linespastheader = -1; + flagexecutable = 0; + linetype = ' '; if (qmail_open(&qqt) == -1) { err_qqt(); return; } qp = qmail_qp(&qqt); out("354 go ahead\r\n"); @@ -389,6 +486,7 @@ 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 (flagexecutable) { out("552 we don't accept email with executable content (#5.3.4)\r\n"); return; } if (*qqx == 'D') out("554 "); else out("451 "); out(qqx + 1); out("\r\n"); .