diff -u /usr/src/qmail-src/qmail-1.03/Makefile qmail-jb-1.03+smtp-virscan/Makefile --- /usr/src/qmail-src/qmail-1.03/Makefile Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/Makefile Wed Jan 14 14:16:35 2004 @@ -136,6 +136,10 @@ compile auto_usera.c ./compile auto_usera.c +base64.o: \ +compile base64.c base64.h stralloc.h substdio.h str.h + ./compile base64.c + binm1: \ binm1.sh conf-qmail cat binm1.sh \ @@ -217,9 +221,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 +241,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 @@ -1483,12 +1491,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 @@ -1535,14 +1543,14 @@ load qmail-smtpd.o rcpthosts.o commands.o timeoutread.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 +open.a sig.a case.a env.a stralloc.a strerr.a alloc.a substdio.a error.a str.a \ +fs.a auto_qmail.o base64.o socket.lib dns.o dns.lib ./load qmail-smtpd rcpthosts.o commands.o timeoutread.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 \ - socket.lib` + alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o base64.o `cat \ + socket.lib` dns.o `cat dns.lib` qmail-smtpd.0: \ qmail-smtpd.8 @@ -1553,7 +1561,8 @@ substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \ error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \ substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \ -exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h +exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h wait.h \ +fd.h base64.h ./compile qmail-smtpd.c qmail-start: \ diff -u /usr/src/qmail-src/qmail-1.03/TARGETS qmail-jb-1.03+smtp-virscan/TARGETS --- /usr/src/qmail-src/qmail-1.03/TARGETS Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/TARGETS Wed Nov 19 14:03:40 2003 @@ -250,6 +250,7 @@ qmail-qmtpd.o rcpthosts.o qmail-qmtpd +base64.o qmail-smtpd.o qmail-smtpd sendmail.o Only in qmail-jb-1.03+smtp-virscan/: base64.c Only in qmail-jb-1.03+smtp-virscan/: base64.h diff -u /usr/src/qmail-src/qmail-1.03/binm1+df.sh qmail-jb-1.03+smtp-virscan/binm1+df.sh --- /usr/src/qmail-src/qmail-1.03/binm1+df.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm1+df.sh Wed Nov 19 14:00:49 2003 @@ -5,7 +5,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using BSD 4.4 binmail interface: /usr/libexec/mail.local -r -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|dot-forward .forward |preline -f /usr/libexec/mail.local -r "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/binm1.sh qmail-jb-1.03+smtp-virscan/binm1.sh --- /usr/src/qmail-src/qmail-1.03/binm1.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm1.sh Wed Nov 19 14:00:49 2003 @@ -4,7 +4,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using BSD 4.4 binmail interface: /usr/libexec/mail.local -r -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start \ '|preline -f /usr/libexec/mail.local -r "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/binm2+df.sh qmail-jb-1.03+smtp-virscan/binm2+df.sh --- /usr/src/qmail-src/qmail-1.03/binm2+df.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm2+df.sh Wed Nov 19 14:00:49 2003 @@ -5,7 +5,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using SVR4 binmail interface: /bin/mail -r -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|dot-forward .forward |preline -f /bin/mail -r "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/binm2.sh qmail-jb-1.03+smtp-virscan/binm2.sh --- /usr/src/qmail-src/qmail-1.03/binm2.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm2.sh Wed Nov 19 14:00:49 2003 @@ -4,7 +4,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using SVR4 binmail interface: /bin/mail -r -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start \ '|preline -f /bin/mail -r "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/binm3+df.sh qmail-jb-1.03+smtp-virscan/binm3+df.sh --- /usr/src/qmail-src/qmail-1.03/binm3+df.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm3+df.sh Wed Nov 19 14:00:49 2003 @@ -5,7 +5,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using V7 binmail interface: /bin/mail -f -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|dot-forward .forward |preline -f /bin/mail -f "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/binm3.sh qmail-jb-1.03+smtp-virscan/binm3.sh --- /usr/src/qmail-src/qmail-1.03/binm3.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/binm3.sh Wed Nov 19 14:00:49 2003 @@ -4,7 +4,7 @@ # Using binmail to deliver messages to /var/spool/mail/$USER by default. # Using V7 binmail interface: /bin/mail -f -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start \ '|preline -f /bin/mail -f "${SENDER:-MAILER-DAEMON}" -d "$USER"' \ splogger qmail Only in qmail-jb-1.03+smtp-virscan/: case_startb.c Only in qmail-jb-1.03+smtp-virscan/: case_startb.o diff -u /usr/src/qmail-src/qmail-1.03/conf-groups qmail-jb-1.03+smtp-virscan/conf-groups --- /usr/src/qmail-src/qmail-1.03/conf-groups Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/conf-groups Wed Nov 19 14:00:49 2003 @@ -1,5 +1,5 @@ qmail -nofiles +nogroup These are the qmail groups. The second group should not have access to any files, but it must be usable for processes; this requirement diff -u /usr/src/qmail-src/qmail-1.03/config-fast.sh qmail-jb-1.03+smtp-virscan/config-fast.sh --- /usr/src/qmail-src/qmail-1.03/config-fast.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/config-fast.sh Wed Nov 19 14:00:49 2003 @@ -1,29 +1,29 @@ fqdn="$1" echo Your fully qualified host name is "$fqdn". -echo Putting "$fqdn" into control/me... +echo Putting "$fqdn" into QMAIL/control/me... echo "$fqdn" > QMAIL/control/me chmod 644 QMAIL/control/me ( echo "$fqdn" | sed 's/^\([^\.]*\)\.\([^\.]*\)\./\2\./' | ( read ddom - echo Putting "$ddom" into control/defaultdomain... + echo Putting "$ddom" into QMAIL/control/defaultdomain... echo "$ddom" > QMAIL/control/defaultdomain chmod 644 QMAIL/control/defaultdomain ) ) ( echo "$fqdn" | sed 's/^.*\.\([^\.]*\)\.\([^\.]*\)$/\1.\2/' | ( read pdom - echo Putting "$pdom" into control/plusdomain... + echo Putting "$pdom" into QMAIL/control/plusdomain... echo "$pdom" > QMAIL/control/plusdomain chmod 644 QMAIL/control/plusdomain ) ) -echo Putting "$fqdn" into control/locals... +echo Putting "$fqdn" into QMAIL/control/locals... echo "$fqdn" >> QMAIL/control/locals chmod 644 QMAIL/control/locals -echo Putting "$fqdn" into control/rcpthosts... +echo Putting "$fqdn" into QMAIL/control/rcpthosts... echo "$fqdn" >> QMAIL/control/rcpthosts chmod 644 QMAIL/control/rcpthosts echo "Now qmail will refuse to accept SMTP messages except to $fqdn." diff -u /usr/src/qmail-src/qmail-1.03/config.sh qmail-jb-1.03+smtp-virscan/config.sh --- /usr/src/qmail-src/qmail-1.03/config.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/config.sh Wed Nov 19 14:00:49 2003 @@ -6,18 +6,18 @@ if read fqdn then echo Your host\'s fully qualified name in DNS is "$fqdn". - echo Putting "$fqdn" into control/me... + echo Putting "$fqdn" into QMAIL/control/me ... echo "$fqdn" > QMAIL/control/me chmod 644 QMAIL/control/me ( echo "$fqdn" | sed 's/^\([^\.]*\)\.\([^\.]*\)\./\2\./' | ( read ddom - echo Putting "$ddom" into control/defaultdomain... + echo Putting "$ddom" into QMAIL/control/defaultdomain ... echo "$ddom" > QMAIL/control/defaultdomain chmod 644 QMAIL/control/defaultdomain ) ) ( echo "$fqdn" | sed 's/^.*\.\([^\.]*\)\.\([^\.]*\)$/\1.\2/' | ( read pdom - echo Putting "$pdom" into control/plusdomain... + echo Putting "$pdom" into QMAIL/control/plusdomain ... echo "$pdom" > QMAIL/control/plusdomain chmod 644 QMAIL/control/plusdomain ) ) @@ -34,7 +34,7 @@ ./dnsptr "$localip" 2>/dev/null | ( if read local then - echo Adding "$local" to control/locals... + echo Adding "$local" to QMAIL/control/locals... echo "$local" >> QMAIL/control/locals else echo PTR lookup failed. I assume this address has no DNS name. @@ -54,11 +54,11 @@ echo 'Make sure to change rcpthosts if you add hosts to locals or virtualdomains!' else echo Sorry, I couldn\'t find your host\'s canonical name in DNS. - echo You will have to set up control/me yourself. + echo You will have to set up QMAIL/control/me yourself. fi ) else echo Sorry, I couldn\'t find your hostname. - echo You will have to set up control/me yourself. + echo You will have to set up QMAIL/control/me yourself. fi ) Only in qmail-jb-1.03+smtp-virscan/: contrib diff -u /usr/src/qmail-src/qmail-1.03/datemail.sh qmail-jb-1.03+smtp-virscan/datemail.sh --- /usr/src/qmail-src/qmail-1.03/datemail.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/datemail.sh Wed Nov 19 14:00:49 2003 @@ -1 +1 @@ -exec QMAIL/bin/predate QMAIL/bin/sendmail ${1+"$@"} +exec /usr/sbin/predate /usr/sbin/sendmail ${1+"$@"} Only in qmail-jb-1.03+smtp-virscan/: debian diff -u /usr/src/qmail-src/qmail-1.03/dns.c qmail-jb-1.03+smtp-virscan/dns.c --- /usr/src/qmail-src/qmail-1.03/dns.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/dns.c Wed Nov 19 14:00:49 2003 @@ -21,10 +21,12 @@ 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 u_long saveresoptions; static int numanswers; static char name[MAXDNAME]; @@ -45,18 +47,33 @@ 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) + if (response.buf = (unsigned char *)alloc(PACKETSZ+1)) + 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 +83,7 @@ if (i < QFIXEDSZ) return DNS_SOFT; responsepos += QFIXEDSZ; } - numanswers = ntohs(response.hdr.ancount); + numanswers = ntohs(((HEADER *)response.buf)->ancount); return 0; } diff -u /usr/src/qmail-src/qmail-1.03/elq.sh qmail-jb-1.03+smtp-virscan/elq.sh --- /usr/src/qmail-src/qmail-1.03/elq.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/elq.sh Wed Nov 19 14:00:49 2003 @@ -1 +1 @@ -QMAIL/bin/maildir2mbox && exec elm ${1+"$@"} +/usr/bin/maildir2mbox && exec elm ${1+"$@"} diff -u /usr/src/qmail-src/qmail-1.03/home+df.sh qmail-jb-1.03+smtp-virscan/home+df.sh --- /usr/src/qmail-src/qmail-1.03/home+df.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/home+df.sh Wed Nov 19 14:00:49 2003 @@ -4,6 +4,6 @@ # Using dot-forward to support sendmail-style ~/.forward files. # Using qmail-local to deliver messages to ~/Mailbox by default. -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|dot-forward .forward ./Mailbox' splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/home.sh qmail-jb-1.03+smtp-virscan/home.sh --- /usr/src/qmail-src/qmail-1.03/home.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/home.sh Wed Nov 19 14:00:49 2003 @@ -3,5 +3,5 @@ # Using splogger to send the log through syslog. # Using qmail-local to deliver messages to ~/Mailbox by default. -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start ./Mailbox splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/install.c qmail-jb-1.03+smtp-virscan/install.c --- /usr/src/qmail-src/qmail-1.03/install.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/install.c Wed Nov 19 14:00:49 2003 @@ -33,7 +33,9 @@ int gid; int mode; { - if (chdir(home) == -1) + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); + if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (mkdir(subdir,0700) == -1) if (errno != error_exist) @@ -51,6 +53,8 @@ int gid; int mode; { + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (fifo_make(fifo,0700) == -1) @@ -127,6 +131,8 @@ { int fdout; + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); diff -u /usr/src/qmail-src/qmail-1.03/mailsubj.sh qmail-jb-1.03+smtp-virscan/mailsubj.sh --- /usr/src/qmail-src/qmail-1.03/mailsubj.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/mailsubj.sh Wed Nov 19 14:00:49 2003 @@ -4,4 +4,4 @@ echo To: ${1+"$@"} echo '' cat -) | QMAIL/bin/qmail-inject +) | /usr/sbin/qmail-inject Only in qmail-jb-1.03+smtp-virscan/: msg00151.txt Only in qmail-jb-1.03+smtp-virscan/: netscape-progress.patch diff -u /usr/src/qmail-src/qmail-1.03/pinq.sh qmail-jb-1.03+smtp-virscan/pinq.sh --- /usr/src/qmail-src/qmail-1.03/pinq.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/pinq.sh Wed Nov 19 14:00:49 2003 @@ -1 +1 @@ -QMAIL/bin/maildir2mbox && exec pine ${1+"$@"} +/usr/bin/maildir2mbox && exec pine ${1+"$@"} Only in qmail-jb-1.03+smtp-virscan/: pop3-supplementarygroups.diff diff -u /usr/src/qmail-src/qmail-1.03/proc+df.sh qmail-jb-1.03+smtp-virscan/proc+df.sh --- /usr/src/qmail-src/qmail-1.03/proc+df.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/proc+df.sh Wed Nov 19 14:00:49 2003 @@ -4,6 +4,6 @@ # Using dot-forward to support sendmail-style ~/.forward files. # Using procmail to deliver messages to /var/spool/mail/$USER by default. -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|dot-forward .forward |preline procmail' splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/proc.sh qmail-jb-1.03+smtp-virscan/proc.sh --- /usr/src/qmail-src/qmail-1.03/proc.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/proc.sh Wed Nov 19 14:00:49 2003 @@ -3,5 +3,5 @@ # Using splogger to send the log through syslog. # Using procmail to deliver messages to /var/spool/mail/$USER by default. -exec env - PATH="QMAIL/bin:$PATH" \ +exec \ qmail-start '|preline procmail' splogger qmail diff -u /usr/src/qmail-src/qmail-1.03/qail.sh qmail-jb-1.03+smtp-virscan/qail.sh --- /usr/src/qmail-src/qmail-1.03/qail.sh Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qail.sh Wed Nov 19 14:00:49 2003 @@ -1 +1 @@ -QMAIL/bin/maildir2mbox && exec Mail ${1+"$@"} +/usr/bin/maildir2mbox && exec Mail ${1+"$@"} diff -u /usr/src/qmail-src/qmail-1.03/qmail-control.9 qmail-jb-1.03+smtp-virscan/qmail-control.9 --- /usr/src/qmail-src/qmail-1.03/qmail-control.9 Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-control.9 Wed Nov 19 14:33:39 2003 @@ -55,6 +55,7 @@ .I idhost \fIme \fRqmail-inject .I localiphost \fIme \fRqmail-smtpd .I locals \fIme \fRqmail-send +.I mfcheck \fR0 \fRqmail-smtpd .I morercpthosts \fR(none) \fRqmail-smtpd .I percenthack \fR(none) \fRqmail-send .I plusdomain \fIme \fRqmail-inject Only in qmail-jb-1.03+smtp-virscan/: qmail-link-sync.patch diff -u /usr/src/qmail-src/qmail-1.03/qmail-local.c qmail-jb-1.03+smtp-virscan/qmail-local.c --- /usr/src/qmail-src/qmail-1.03/qmail-local.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-local.c Wed Nov 19 14:00:49 2003 @@ -1,5 +1,6 @@ #include #include +#include #include "readwrite.h" #include "sig.h" #include "env.h" @@ -128,6 +129,9 @@ 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); diff -u /usr/src/qmail-src/qmail-1.03/qmail-lspawn.c qmail-jb-1.03+smtp-virscan/qmail-lspawn.c --- /usr/src/qmail-src/qmail-1.03/qmail-lspawn.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-lspawn.c Wed Nov 19 14:00:49 2003 @@ -139,7 +139,7 @@ } if (pipe(pi) == -1) _exit(QLX_SYS); - args[0] = "bin/qmail-getpw"; + args[0] = "/usr/sbin/qmail-getpw"; args[1] = local; args[2] = 0; switch(gpwpid = vfork()) @@ -191,7 +191,7 @@ x = nughde.s; xlen = nughde.len; - args[0] = "bin/qmail-local"; + args[0] = "/usr/sbin/qmail-local"; args[1] = "--"; args[2] = x; n = byte_chr(x,xlen,0); if (n++ == xlen) _exit(QLX_USAGE); x += n; xlen -= n; diff -u /usr/src/qmail-src/qmail-1.03/qmail-pop3d.c qmail-jb-1.03+smtp-virscan/qmail-pop3d.c --- /usr/src/qmail-src/qmail-1.03/qmail-pop3d.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-pop3d.c Wed Nov 19 14:00:49 2003 @@ -267,7 +267,11 @@ fd = open_read(m[i].fn); if (fd == -1) { err_nosuch(); return; } - okay(); + /* okay(); */ + puts("+OK "); + put(strnum,fmt_ulong(strnum,m[i].size)); + puts(" octets\r\n"); + flush(); substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf)); blast(&ssmsg,limit); close(fd); diff -u /usr/src/qmail-src/qmail-1.03/qmail-queue.c qmail-jb-1.03+smtp-virscan/qmail-queue.c --- /usr/src/qmail-src/qmail-1.03/qmail-queue.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-queue.c Wed Nov 19 14:00:49 2003 @@ -1,5 +1,6 @@ #include #include +#include #include "readwrite.h" #include "sig.h" #include "exit.h" @@ -155,6 +156,7 @@ { unsigned int len; char ch; + int fd; sig_blocknone(); umask(033); @@ -183,7 +185,7 @@ todofn = fnnum("todo/",0); intdfn = fnnum("intd/",0); - if (link(pidfn,messfn) == -1) die(64); + if (link(pidfn,messfn) == -1) die(64); if (unlink(pidfn) == -1) die(63); flagmademess = 1; @@ -248,6 +250,8 @@ 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); Only in qmail-jb-1.03+smtp-virscan/: qmail-smtpd-bmtpatch.diff diff -u /usr/src/qmail-src/qmail-1.03/qmail-smtpd.8 qmail-jb-1.03+smtp-virscan/qmail-smtpd.8 --- /usr/src/qmail-src/qmail-1.03/qmail-smtpd.8 Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-smtpd.8 Wed Nov 19 14:33:39 2003 @@ -3,6 +3,11 @@ qmail-smtpd \- receive mail via SMTP .SH SYNOPSIS .B qmail-smtpd +[ +.I hostname +.I checkprogram +.I subprogram +] .SH DESCRIPTION .B qmail-smtpd receives mail messages via the Simple Mail Transfer Protocol (SMTP) @@ -23,7 +28,29 @@ header fields. .B qmail-smtpd -supports ESMTP, including the 8BITMIME and PIPELINING options. +supports ESMTP, including the 8BITMIME, PIPELINING, and AUTH options. + +.B qmail-smtpd +can accept LOGIN, PLAIN, and CRAM-MD5 AUTH types. It invokes +.IR checkprogram , +which reads on file descriptor 3 the username, a 0 byte, the password +or challenge derived from +.IR hostname , +another 0 byte, a CRAM-MD5 response (if applicable to the AUTH type), +and a final 0 byte. +.I checkprogram +invokes +.I subprogram +upon successful authentication, which should in turn return 0 to +.BR qmail-smtpd , +effectively setting the environment variables RELAYCLIENT and TCPREMOTEINFO +(any supplied value replaced with the authenticated username). +.B qmail-smtpd +will reject the authentication attempt if it receives a nonzero return +value from +.I checkprogram +or +.IR subprogram . .SH TRANSPARENCY .B qmail-smtpd converts the SMTP newline convention into the UNIX newline convention @@ -97,6 +124,12 @@ This is done before .IR rcpthosts . .TP 5 +.I mfcheck +If set, +.B qmail-smtpd +tries to resolve the domain of the envelope from address. It can be +handy when you want to filter out spamhosts. +.TP 5 .I morercpthosts Extra allowed RCPT domains. If @@ -177,3 +210,6 @@ qmail-newmrh(8), qmail-queue(8), qmail-remote(8) +.SH "HISTORY" +The patch enabling the ESMTP AUTH option is not part of the standard +qmail-1.03 distribution. diff -u /usr/src/qmail-src/qmail-1.03/qmail-smtpd.c qmail-jb-1.03+smtp-virscan/qmail-smtpd.c --- /usr/src/qmail-src/qmail-1.03/qmail-smtpd.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail-smtpd.c Wed Jan 14 18:43:59 2004 @@ -23,10 +23,16 @@ #include "timeoutread.h" #include "timeoutwrite.h" #include "commands.h" +#include "dns.h" +#include "strerr.h" +#include "wait.h" +#include "fd.h" +#undef AUTHCRAM #define MAXHOPS 100 unsigned int databytes = 0; int timeout = 1200; +unsigned int mfchk = 0; int safewrite(fd,buf,len) int fd; char *buf; int len; { @@ -49,7 +55,10 @@ 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_bmf() { out("553 badmailfrom - see http://www.rb-hosting.de/spamblock.php (#5.7.1)\r\n"); } +void err_bmt() { out("553 badmailto - see http://www.rb-hosting.de/spamblock.php (#5.7.1)\r\n"); } +void err_hmf() { out("553 sorry, your envelope sender domain must exist (#5.7.1)\r\n"); } +void err_smf() { out("451 DNS temporary failure (#4.3.0)\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"); } @@ -59,6 +68,15 @@ 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"); } +int err_child() { out("454 oops, problem with child and I can't auth (#4.3.0)\r\n"); return -1; } +int err_fork() { out("454 oops, child won't start and I can't auth (#4.3.0)\r\n"); return -1; } +int err_pipe() { out("454 oops, unable to open pipe and I can't auth (#4.3.0)\r\n"); return -1; } +int err_write() { out("454 oops, unable to write pipe and I can't auth (#4.3.0)\r\n"); return -1; } +void err_authd() { out("503 you're already authenticated (#5.5.0)\r\n"); } +void err_authmail() { out("503 no auth during mail transaction (#5.5.0)\r\n"); } +int err_noauth() { out("504 auth type unimplemented (#5.5.1)\r\n"); return -1; } +int err_authabrt() { out("501 auth exchange cancelled (#5.0.0)\r\n"); return -1; } +int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } stralloc greeting = {0}; @@ -96,6 +114,13 @@ int bmfok = 0; stralloc bmf = {0}; struct constmap mapbmf; +int bmtok = 0; +stralloc bmt = {0}; +struct constmap mapbmt; +int tarpitcount = 0; +int tarpitdelay = 5; +int sigsok = 0; +stralloc sigs = {0}; void setup() { @@ -110,13 +135,34 @@ if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control(); if (timeout <= 0) timeout = 1; + if (control_readint(&tarpitcount,"control/tarpitcount") == -1) die_control(); + if (tarpitcount < 0) tarpitcount = 0; + x = env_get("TARPITCOUNT"); + if (x) { scan_ulong(x,&u); tarpitcount = u; }; + if (control_readint(&tarpitdelay,"control/tarpitdelay") == -1) die_control(); + if (tarpitdelay < 0) tarpitdelay = 0; + x = env_get("TARPITDELAY"); + if (x) { scan_ulong(x,&u); tarpitdelay = u; }; + if (rcpthosts_init() == -1) die_control(); + if (control_readint(&mfchk,"control/mfcheck") == -1) die_control(); + x = env_get("MFCHECK"); + if (x) { scan_ulong(x,&u); mfchk = u; } + 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(); + bmtok = control_readfile(&bmt,"control/badmailto",0); + if (bmtok == -1) die_control(); + if (bmtok) + if (!constmap_init(&mapbmt,bmt.s,bmt.len,0)) die_nomem(); + + sigsok = control_readfile(&sigs,"control/signatures",0); + if (sigsok == -1) die_control(); + if (control_readint(&databytes,"control/databytes") == -1) die_control(); x = env_get("DATABYTES"); if (x) { scan_ulong(x,&u); databytes = u; } @@ -208,6 +254,49 @@ return 0; } +int bmtcheck() +{ + int j; + if (!bmtok) return 0; + if (constmap(&mapbmt,addr.s,addr.len - 1)) return 1; + j = byte_rchr(addr.s,addr.len,'@'); + if (j < addr.len) + if (constmap(&mapbmt,addr.s + j,addr.len - j - 1)) return 1; + return 0; +} + +int mfcheck() +{ + stralloc sa = {0}; + ipalloc ia = {0}; + unsigned int random; + int j; + + if (!mfchk) return 0; + random = now() + (getpid() << 16); + j = byte_rchr(addr.s,addr.len,'@') + 1; + if (j < addr.len) { + stralloc_copys(&sa, addr.s + j); + dns_init(0); + j = dns_mxip(&ia,&sa,random); + if (j < 0) return j; + } + return 0; +} + +int sigscheck(stralloc *line) { + int i, j; + + j = 0; + for (i = 0; i < sigs.len; i++) if (!sigs.s[i]) { + if (i-j < line->len) + if (!str_diffn(line->s,sigs.s+j,i-j)) + return 1; + j = i+1; + } + return 0; +} + int addrallowed() { int r; @@ -219,8 +308,10 @@ int seenmail = 0; int flagbarf; /* defined if seenmail */ +int bmtbarf; /* defined if seenmail */ stralloc mailfrom = {0}; stralloc rcptto = {0}; +int rcptcount; void smtp_helo(arg) char *arg; { @@ -229,7 +320,15 @@ } void smtp_ehlo(arg) char *arg; { - smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); + smtp_greet("250-"); +#ifdef AUTHCRAM + out("\r\n250-AUTH LOGIN CRAM-MD5 PLAIN"); + out("\r\n250-AUTH=LOGIN CRAM-MD5 PLAIN"); +#else + out("\r\n250-AUTH LOGIN PLAIN"); + out("\r\n250-AUTH=LOGIN PLAIN"); +#endif + out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); seenmail = 0; dohelo(arg); } void smtp_rset() @@ -241,16 +340,34 @@ { if (!addrparse(arg)) { err_syntax(); return; } flagbarf = bmfcheck(); + switch(mfcheck()) { + case DNS_HARD: err_hmf(); return; + case DNS_SOFT: err_smf(); return; + case DNS_MEM: die_nomem(); + } seenmail = 1; if (!stralloc_copys(&rcptto,"")) die_nomem(); if (!stralloc_copys(&mailfrom,addr.s)) die_nomem(); if (!stralloc_0(&mailfrom)) die_nomem(); + rcptcount = 0; 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; } + bmtbarf = bmtcheck(); + // if (flagbarf) { err_bmf(); return; } + // if (bmtbarf) { err_bmt(); return; } + if (flagbarf) { + strerr_warn4("qmail-smtpd: badmailfrom: ",mailfrom.s," at ",remoteip,0); + err_bmf(); + return; + } + if (bmtbarf) { + strerr_warn4("qmail-smtpd: badmailto: ",addr.s," at ",remoteip,0); + err_bmt(); + return; + } if (relayclient) { --addr.len; if (!stralloc_cats(&addr,relayclient)) die_nomem(); @@ -261,6 +378,7 @@ if (!stralloc_cats(&rcptto,"T")) die_nomem(); if (!stralloc_cats(&rcptto,addr.s)) die_nomem(); if (!stralloc_0(&rcptto)) die_nomem(); + if (tarpitcount && ++rcptcount >= tarpitcount) while (sleep(tarpitdelay)); out("250 ok\r\n"); } @@ -281,9 +399,131 @@ struct qmail qqt; unsigned int bytestooverflow = 0; +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}; +int boundary_start; + +/* + +def put(ch): + line.append(ch) + if ch == '\n': + if linepastheader == 0: + if line.beginswith('Content-Type:'): + content = + + put() puts characters into the queue. We remember those characters + and form them into a line. When we get a newline, we examine the + line. If we're currently in a header (0 linespastheader), we look + for Content-Type. If we're at the newline that ends a header, we + look to see if the content is multipart. If it is, then we push + the current boundary, remember the boundary, otherwise we set the + boundary to the empty string. Set the linespastheader to 1. When + linespastheader is 1, and the boundary is empty, scan the line for + signatures. If the boundary is non-empty, look for a match against + the boundary. If it matches and is followed by two dashes, pop the + boundary, otherwise set linespastheader to 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 (linespastheader == 0) { + if (line.len == 1) { + linespastheader = 1; + 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; + } + /* push the current boundary. Append a null and remember start. */ + if (!stralloc_0(&boundary)) die_nomem(); + boundary_start = boundary.len; + if (!stralloc_cats(&boundary,"--")) die_nomem(); + if (!stralloc_catb(&boundary,cpstart,cp-cpstart)) + die_nomem(); + break; + } + } + } + } else { /* non-blank header line */ + 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 { /* non-header line */ + if (boundary.len-boundary_start && *line.s == '-' && line.len > (boundary.len-boundary_start) && + !str_diffn(line.s,boundary.s+boundary_start,boundary.len-boundary_start)) { /* matches a boundary */ + if (line.len > boundary.len-boundary_start + 2 && + line.s[boundary.len-boundary_start+0] == '-' && + line.s[boundary.len-boundary_start+1] == '-') { + /* XXXX - pop the boundary here */ + if (boundary_start) boundary.len = boundary_start - 1; + boundary_start = boundary.len; + while(boundary_start--) if (!boundary.s[boundary_start]) break; + boundary_start++; + linespastheader = 2; + } else { + linespastheader = 0; + } + } else if (linespastheader == 1) { /* first line -- match a signature? */ + if (sigscheck(&line)) { + flagexecutable = 1; + qmail_fail(&qqt); + } + linespastheader = 2; + } + } + line.len = 0; + } + if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qqt); @@ -374,6 +614,12 @@ if (!rcptto.len) { err_wantrcpt(); return; } seenmail = 0; if (databytes) bytestooverflow = databytes + 1; + boundary.len = 0; + boundary_start = 0; + content.len = 0; + linespastheader = 0; + flagexecutable = 0; + linetype = ' '; if (qmail_open(&qqt) == -1) { err_qqt(); return; } qp = qmail_qp(&qqt); out("354 go ahead\r\n"); @@ -389,15 +635,236 @@ 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 executable content - see http://www.rb-hosting.de/spamblock.php (#5.3.4)\r\n"); + strerr_warn6("qmail-smtpd: executable content: from ",mailfrom.s," to " rcptto.s," at ",remoteip,0); + //strerr_warn4("qmail-smtpd: executable content: from ",mailfrom.s," at ",remoteip,0); + return; } if (*qqx == 'D') out("554 "); else out("451 "); out(qqx + 1); out("\r\n"); } + +char unique[FMT_ULONG + FMT_ULONG + 3]; +static stralloc authin = {0}; +static stralloc user = {0}; +static stralloc pass = {0}; +static stralloc resp = {0}; +static stralloc slop = {0}; +char *hostname; +char **childargs; +substdio ssup; +char upbuf[128]; +int authd = 0; + +int authgetl(void) { + int i; + + if (!stralloc_copys(&authin, "")) die_nomem(); + + for (;;) { + if (!stralloc_readyplus(&authin,1)) die_nomem(); /* XXX */ + i = substdio_get(&ssin,authin.s + authin.len,1); + if (i != 1) die_read(); + if (authin.s[authin.len] == '\n') break; + ++authin.len; + } + + if (authin.len > 0) if (authin.s[authin.len - 1] == '\r') --authin.len; + authin.s[authin.len] = 0; + + if (*authin.s == '*' && *(authin.s + 1) == 0) { return err_authabrt(); } + if (authin.len == 0) { return err_input(); } + return authin.len; +} + +int authenticate(void) +{ + int child; + int wstat; + int pi[2]; + + if (!stralloc_0(&user)) die_nomem(); + if (!stralloc_0(&pass)) die_nomem(); + if (!stralloc_0(&resp)) die_nomem(); + + if (fd_copy(2,1) == -1) return err_pipe(); + close(3); + if (pipe(pi) == -1) return err_pipe(); + if (pi[0] != 3) return err_pipe(); + switch(child = fork()) { + case -1: + return err_fork(); + case 0: + close(pi[1]); + sig_pipedefault(); + execvp(*childargs, childargs); + _exit(1); + } + close(pi[0]); + + substdio_fdbuf(&ssup,write,pi[1],upbuf,sizeof upbuf); + if (substdio_put(&ssup,user.s,user.len) == -1) return err_write(); + if (substdio_put(&ssup,pass.s,pass.len) == -1) return err_write(); + if (substdio_put(&ssup,resp.s,resp.len) == -1) return err_write(); + if (substdio_flush(&ssup) == -1) return err_write(); + + close(pi[1]); + byte_zero(pass.s,pass.len); + byte_zero(upbuf,sizeof upbuf); + if (wait_pid(&wstat,child) == -1) return err_child(); + if (wait_crashed(wstat)) return err_child(); + if (wait_exitcode(wstat)) { sleep(5); return 1; } /* no */ + return 0; /* yes */ +} + +int auth_login(arg) char *arg; +{ + int r; + + if (*arg) { + if (r = b64decode(arg,str_len(arg),&user) == 1) return err_input(); + } + else { + out("334 VXNlcm5hbWU6\r\n"); flush(); /* Username: */ + if (authgetl() < 0) return -1; + if (r = b64decode(authin.s,authin.len,&user) == 1) return err_input(); + } + if (r == -1) die_nomem(); + + out("334 UGFzc3dvcmQ6\r\n"); flush(); /* Password: */ + + if (authgetl() < 0) return -1; + if (r = b64decode(authin.s,authin.len,&pass) == 1) return err_input(); + if (r == -1) die_nomem(); + + if (!user.len || !pass.len) return err_input(); + return authenticate(); +} + +int auth_plain(arg) char *arg; +{ + int r, id = 0; + + if (*arg) { + if (r = b64decode(arg,str_len(arg),&slop) == 1) return err_input(); + } + else { + out("334 \r\n"); flush(); + if (authgetl() < 0) return -1; + if (r = b64decode(authin.s,authin.len,&slop) == 1) return err_input(); + } + if (r == -1 || !stralloc_0(&slop)) die_nomem(); + while (slop.s[id]) id++; /* ignore authorize-id */ + + if (slop.len > id + 1) + if (!stralloc_copys(&user,slop.s + id + 1)) die_nomem(); + if (slop.len > id + user.len + 2) + if (!stralloc_copys(&pass,slop.s + id + user.len + 2)) die_nomem(); + + if (!user.len || !pass.len) return err_input(); + return authenticate(); +} + +#ifdef AUTHCRAM +int auth_cram() +{ + int i, r; + char *s; + + s = unique; + s += fmt_uint(s,getpid()); + *s++ = '.'; + s += fmt_ulong(s,(unsigned long) now()); + *s++ = '@'; + *s++ = 0; + + 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(&pass,&slop) < 0) die_nomem(); + if (!stralloc_0(&slop)) die_nomem(); + + out("334 "); + out(slop.s); + out("\r\n"); + flush(); + + if (authgetl() < 0) return -1; + if (r = b64decode(authin.s,authin.len,&slop) == 1) return err_input(); + if (r == -1 || !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_input(); + return authenticate(); +} +#endif + +struct authcmd { + char *text; + int (*fun)(); +} authcmds[] = { + { "login", auth_login } +, { "plain", auth_plain } +#ifdef AUTHCRAM +, { "cram-md5", auth_cram } +#endif +, { 0, err_noauth } +}; + +void smtp_auth(arg) +char *arg; +{ + int i; + char *cmd = arg; + + if (!hostname || !*childargs) + { + out("503 auth not available (#5.3.3)\r\n"); + return; + } + if (authd) { err_authd(); 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; + + switch (authcmds[i].fun(arg)) { + case 0: + authd = 1; + relayclient = ""; + remoteinfo = user.s; + if (!env_unset("TCPREMOTEINFO")) die_read(); + if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem(); + out("235 ok, go ahead (#2.0.0)\r\n"); + break; + case 1: + out("535 authorization failed (#5.7.0)\r\n"); + } +} + struct commands smtpcommands[] = { { "rcpt", smtp_rcpt, 0 } , { "mail", smtp_mail, 0 } , { "data", smtp_data, flush } +, { "auth", smtp_auth, flush } , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush } @@ -408,8 +875,13 @@ , { 0, err_unimpl, flush } } ; -void main() +void main(argc,argv) +int argc; +char **argv; { + hostname = argv[1]; + childargs = argv + 2; + sig_pipeignore(); if (chdir(auto_qmail) == -1) die_control(); setup(); diff -u /usr/src/qmail-src/qmail-1.03/qmail.c qmail-jb-1.03+smtp-virscan/qmail.c --- /usr/src/qmail-src/qmail-1.03/qmail.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/qmail.c Wed Nov 19 14:00:49 2003 @@ -6,14 +6,25 @@ #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; { 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; } Only in qmail-jb-1.03+smtp-virscan/: qmailqueue-patch diff -u /usr/src/qmail-src/qmail-1.03/sendmail.c qmail-jb-1.03+smtp-virscan/sendmail.c --- /usr/src/qmail-src/qmail-1.03/sendmail.c Mon Jun 15 12:53:16 1998 +++ qmail-jb-1.03+smtp-virscan/sendmail.c Wed Nov 19 14:00:49 2003 @@ -19,7 +19,7 @@ _exit(100); } -char *smtpdarg[] = { "bin/qmail-smtpd", 0 }; +char *smtpdarg[] = { "/usr/sbin/qmail-smtpd", 0 }; void smtpd() { if (!env_get("PROTO")) { @@ -37,7 +37,7 @@ _exit(111); } -char *qreadarg[] = { "bin/qmail-qread", 0 }; +char *qreadarg[] = { "/usr/sbin/qmail-qread", 0 }; void mailq() { execv(*qreadarg,qreadarg); @@ -113,7 +113,7 @@ if (!qiargv) nomem(); arg = qiargv; - *arg++ = "bin/qmail-inject"; + *arg++ = "/usr/sbin/qmail-inject"; *arg++ = (flagh ? "-H" : "-a"); if (sender) { *arg++ = "-f";