VERSION: 20060105 This patch for netqmail 1.05 is a composite of the latest versions of Frederik Vermulen's TLS patch (20060104) and Erwin Hoffmann's SMTP-AUTH (0.5.7) update to Eric M. Johnston's and Krzysztof Dabrowski's qmail-smtpd-auth-0.31 patch. To install, get netqmail 1.05, put it in the same directory as this patch, and then set it up: wget http://qmail.org/netqmail-1.05.tar.gz tar -xzf netqmail-1.05.tar.gz cd netqmail-1.05 ./collate.sh cd netqmail-1.05 patch -p0 < ../../netqmail-1.05-tls-smtpauth-20060105.patch cd netqmail-1.05 make make setup check make cert make tmprsadh Voila! You should now have TLS and SMTP-AUTH support working in qmail-smtpd. VPOPMAIL NOTE: This version will only work with vpopmail versions 5.4.0 and later Here are the relevant URLs: Netqmail: http://www.qmail.org/netqmail/ TLS: http://inoa.net/qmail-tls/ Qmail SMTP-AUTH: http://www.fehcom.de/qmail/smtpauth.html This composite patch was put together by Bill Shupp (hostmaster@shupp.org) diff -urN ../../netqmail-1.05-orig/netqmail-1.05/FILES.auth ./FILES.auth --- ../../netqmail-1.05-orig/netqmail-1.05/FILES.auth 1969-12-31 16:00:00.000000000 -0800 +++ ./FILES.auth 2006-01-05 15:23:08.863056256 -0800 @@ -0,0 +1,18 @@ +The qmail-smtpd Auth patch modifies the following QMAIL 1.03 files: + += TARGETS += Makefile += qmail-smtpd.c += qmail-smtpd.8 + +Added files: + ++ base64.c ++ base64.h ++ case_startb.c + +Informational files: + +% install_auth.sh (Installation shell script) +% README.auth +% README.auth.old (old description of SMTP Auth) diff -urN ../../netqmail-1.05-orig/netqmail-1.05/Makefile ./Makefile --- ../../netqmail-1.05-orig/netqmail-1.05/Makefile 2006-01-05 15:28:41.091549848 -0800 +++ ./Makefile 2006-01-05 15:27:25.782998488 -0800 @@ -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 \ @@ -808,7 +812,7 @@ forward preline condredirect bouncesaying except maildirmake \ maildir2mbox maildirwatch qail elq pinq idedit install-big install \ instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ -binm3 binm3+df +binm3 binm3+df update_tmprsadh load: \ make-load warn-auto.sh systype @@ -1444,6 +1448,7 @@ 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 \ + tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \ ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \ 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` @@ -1536,12 +1541,13 @@ 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 +fs.a auto_qmail.o base64.o socket.lib ./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \ timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \ + tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \ 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 base64.o `cat \ socket.lib` qmail-smtpd.0: \ @@ -1553,7 +1559,7 @@ 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 base64.h ./compile qmail-smtpd.c qmail-start: \ @@ -1827,7 +1833,8 @@ ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \ ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \ prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \ -maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c +maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \ +update_tmprsadh shar -m `cat FILES` > shar chmod 400 shar @@ -2108,6 +2115,19 @@ compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h ./compile timeoutwrite.c +qmail-smtpd: tls.o ssl_timeoutio.o ndelay.a +qmail-remote: tls.o ssl_timeoutio.o +qmail-smtpd.o: tls.h ssl_timeoutio.h +qmail-remote.o: tls.h ssl_timeoutio.h + +tls.o: \ +compile tls.c exit.h error.h + ./compile tls.c + +ssl_timeoutio.o: \ +compile ssl_timeoutio.c ssl_timeoutio.h select.h error.h ndelay.h + ./compile ssl_timeoutio.c + token822.o: \ compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \ gen_alloc.h gen_allocdefs.h @@ -2139,3 +2159,26 @@ wait_pid.o: \ compile wait_pid.c error.h haswaitp.h ./compile wait_pid.c + +cert cert-req: \ +Makefile-cert + @$(MAKE) -sf $< $@ + +Makefile-cert: \ +conf-qmail conf-users conf-groups Makefile-cert.mk + @cat Makefile-cert.mk \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > $@ + +update_tmprsadh: \ +conf-qmail conf-users conf-groups update_tmprsadh.sh + @cat update_tmprsadh.sh\ + | sed s}UGQMAILD}"`head -2 conf-users|tail -1`:`head -1 conf-groups`"}g \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > $@ + chmod 755 update_tmprsadh + +tmprsadh: \ +update_tmprsadh + echo "Creating new temporary RSA and DH parameters" + ./update_tmprsadh diff -urN ../../netqmail-1.05-orig/netqmail-1.05/Makefile-cert.mk ./Makefile-cert.mk --- ../../netqmail-1.05-orig/netqmail-1.05/Makefile-cert.mk 1969-12-31 16:00:00.000000000 -0800 +++ ./Makefile-cert.mk 2006-01-05 15:27:25.785998032 -0800 @@ -0,0 +1,21 @@ +cert-req: req.pem +cert cert-req: QMAIL/control/clientcert.pem + @: + +QMAIL/control/clientcert.pem: QMAIL/control/servercert.pem + ln -s $< $@ + +QMAIL/control/servercert.pem: + PATH=$$PATH:/usr/local/ssl/bin \ + openssl req -new -x509 -nodes -days 366 -out $@ -keyout $@ + chmod 640 $@ + chown `head -2 conf-users | tail -1`:`head -1 conf-groups` $@ + +req.pem: + PATH=$$PATH:/usr/local/ssl/bin openssl req \ + -new -nodes -out $@ -keyout QMAIL/control/servercert.pem + chmod 640 QMAIL/control/servercert.pem + chown `head -2 conf-users | tail -1`:`head -1 conf-groups` QMAIL/control/servercert.pem + @echo + @echo "Send req.pem to your CA to obtain signed_req.pem, and do:" + @echo "cat signed_req.pem >> QMAIL/control/servercert.pem" diff -urN ../../netqmail-1.05-orig/netqmail-1.05/Makefile.056 ./Makefile.056 --- ../../netqmail-1.05-orig/netqmail-1.05/Makefile.056 1969-12-31 16:00:00.000000000 -0800 +++ ./Makefile.056 2006-01-05 15:23:08.876054280 -0800 @@ -0,0 +1,2141 @@ +# Don't edit Makefile! Use conf-* for configuration. + +SHELL=/bin/sh + +default: it + +addresses.0: \ +addresses.5 + nroff -man addresses.5 > addresses.0 + +alloc.a: \ +makelib alloc.o alloc_re.o + ./makelib alloc.a alloc.o alloc_re.o + +alloc.o: \ +compile alloc.c alloc.h error.h + ./compile alloc.c + +alloc_re.o: \ +compile alloc_re.c alloc.h byte.h + ./compile alloc_re.c + +auto-ccld.sh: \ +conf-cc conf-ld warn-auto.sh + ( cat warn-auto.sh; \ + echo CC=\'`head -1 conf-cc`\'; \ + echo LD=\'`head -1 conf-ld`\' \ + ) > auto-ccld.sh + +auto-gid: \ +load auto-gid.o substdio.a error.a str.a fs.a + ./load auto-gid substdio.a error.a str.a fs.a + +auto-gid.o: \ +compile auto-gid.c subfd.h substdio.h substdio.h readwrite.h exit.h \ +scan.h fmt.h + ./compile auto-gid.c + +auto-int: \ +load auto-int.o substdio.a error.a str.a fs.a + ./load auto-int substdio.a error.a str.a fs.a + +auto-int.o: \ +compile auto-int.c substdio.h readwrite.h exit.h scan.h fmt.h + ./compile auto-int.c + +auto-int8: \ +load auto-int8.o substdio.a error.a str.a fs.a + ./load auto-int8 substdio.a error.a str.a fs.a + +auto-int8.o: \ +compile auto-int8.c substdio.h readwrite.h exit.h scan.h fmt.h + ./compile auto-int8.c + +auto-str: \ +load auto-str.o substdio.a error.a str.a + ./load auto-str substdio.a error.a str.a + +auto-str.o: \ +compile auto-str.c substdio.h readwrite.h exit.h + ./compile auto-str.c + +auto-uid: \ +load auto-uid.o substdio.a error.a str.a fs.a + ./load auto-uid substdio.a error.a str.a fs.a + +auto-uid.o: \ +compile auto-uid.c subfd.h substdio.h substdio.h readwrite.h exit.h \ +scan.h fmt.h + ./compile auto-uid.c + +auto_break.c: \ +auto-str conf-break + ./auto-str auto_break \ + "`head -1 conf-break`" > auto_break.c + +auto_break.o: \ +compile auto_break.c + ./compile auto_break.c + +auto_patrn.c: \ +auto-int8 conf-patrn + ./auto-int8 auto_patrn `head -1 conf-patrn` > auto_patrn.c + +auto_patrn.o: \ +compile auto_patrn.c + ./compile auto_patrn.c + +auto_qmail.c: \ +auto-str conf-qmail + ./auto-str auto_qmail `head -1 conf-qmail` > auto_qmail.c + +auto_qmail.o: \ +compile auto_qmail.c + ./compile auto_qmail.c + +auto_spawn.c: \ +auto-int conf-spawn + ./auto-int auto_spawn `head -1 conf-spawn` > auto_spawn.c + +auto_spawn.o: \ +compile auto_spawn.c + ./compile auto_spawn.c + +auto_split.c: \ +auto-int conf-split + ./auto-int auto_split `head -1 conf-split` > auto_split.c + +auto_split.o: \ +compile auto_split.c + ./compile auto_split.c + +auto_uids.c: \ +auto-uid auto-gid conf-users conf-groups + ( ./auto-uid auto_uida `head -1 conf-users` \ + &&./auto-uid auto_uidd `head -2 conf-users | tail -1` \ + &&./auto-uid auto_uidl `head -3 conf-users | tail -1` \ + &&./auto-uid auto_uido `head -4 conf-users | tail -1` \ + &&./auto-uid auto_uidp `head -5 conf-users | tail -1` \ + &&./auto-uid auto_uidq `head -6 conf-users | tail -1` \ + &&./auto-uid auto_uidr `head -7 conf-users | tail -1` \ + &&./auto-uid auto_uids `head -8 conf-users | tail -1` \ + &&./auto-gid auto_gidq `head -1 conf-groups` \ + &&./auto-gid auto_gidn `head -2 conf-groups | tail -1` \ + ) > auto_uids.c.tmp && mv auto_uids.c.tmp auto_uids.c + +auto_uids.o: \ +compile auto_uids.c + ./compile auto_uids.c + +auto_usera.c: \ +auto-str conf-users + ./auto-str auto_usera `head -1 conf-users` > auto_usera.c + +auto_usera.o: \ +compile auto_usera.c + ./compile auto_usera.c + +binm1: \ +binm1.sh conf-qmail + cat binm1.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm1 + chmod 755 binm1 + +binm1+df: \ +binm1+df.sh conf-qmail + cat binm1+df.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm1+df + chmod 755 binm1+df + +binm2: \ +binm2.sh conf-qmail + cat binm2.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm2 + chmod 755 binm2 + +binm2+df: \ +binm2+df.sh conf-qmail + cat binm2+df.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm2+df + chmod 755 binm2+df + +binm3: \ +binm3.sh conf-qmail + cat binm3.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm3 + chmod 755 binm3 + +binm3+df: \ +binm3+df.sh conf-qmail + cat binm3+df.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > binm3+df + chmod 755 binm3+df + +bouncesaying: \ +load bouncesaying.o strerr.a error.a substdio.a str.a wait.a + ./load bouncesaying strerr.a error.a substdio.a str.a \ + wait.a + +bouncesaying.0: \ +bouncesaying.1 + nroff -man bouncesaying.1 > bouncesaying.0 + +bouncesaying.o: \ +compile bouncesaying.c fork.h strerr.h error.h wait.h sig.h exit.h + ./compile bouncesaying.c + +byte_chr.o: \ +compile byte_chr.c byte.h + ./compile byte_chr.c + +byte_copy.o: \ +compile byte_copy.c byte.h + ./compile byte_copy.c + +byte_cr.o: \ +compile byte_cr.c byte.h + ./compile byte_cr.c + +byte_diff.o: \ +compile byte_diff.c byte.h + ./compile byte_diff.c + +byte_rchr.o: \ +compile byte_rchr.c byte.h + ./compile byte_rchr.c + +byte_zero.o: \ +compile byte_zero.c byte.h + ./compile byte_zero.c + +case.a: \ +makelib case_diffb.o case_diffs.o case_lowerb.o case_lowers.o \ +case_starts.o + ./makelib case.a case_diffb.o case_diffs.o case_lowerb.o \ + case_lowers.o case_starts.o + +case_diffb.o: \ +compile case_diffb.c case.h + ./compile case_diffb.c + +case_diffs.o: \ +compile case_diffs.c case.h + ./compile case_diffs.c + +case_lowerb.o: \ +compile case_lowerb.c case.h + ./compile case_lowerb.c + +case_lowers.o: \ +compile case_lowers.c case.h + ./compile case_lowers.c + +case_starts.o: \ +compile case_starts.c case.h + ./compile case_starts.c + +cdb.a: \ +makelib cdb_hash.o cdb_unpack.o cdb_seek.o + ./makelib cdb.a cdb_hash.o cdb_unpack.o cdb_seek.o + +cdb_hash.o: \ +compile cdb_hash.c cdb.h uint32.h + ./compile cdb_hash.c + +cdb_seek.o: \ +compile cdb_seek.c cdb.h uint32.h + ./compile cdb_seek.c + +cdb_unpack.o: \ +compile cdb_unpack.c cdb.h uint32.h + ./compile cdb_unpack.c + +cdbmake.a: \ +makelib cdbmake_pack.o cdbmake_hash.o cdbmake_add.o + ./makelib cdbmake.a cdbmake_pack.o cdbmake_hash.o \ + cdbmake_add.o + +cdbmake_add.o: \ +compile cdbmake_add.c cdbmake.h alloc.h uint32.h + ./compile cdbmake_add.c + +cdbmake_hash.o: \ +compile cdbmake_hash.c cdbmake.h uint32.h + ./compile cdbmake_hash.c + +cdbmake_pack.o: \ +compile cdbmake_pack.c cdbmake.h uint32.h + ./compile cdbmake_pack.c + +cdbmss.o: \ +compile cdbmss.c readwrite.h seek.h alloc.h cdbmss.h cdbmake.h \ +uint32.h substdio.h + ./compile cdbmss.c + +check: \ +it man + ./instcheck + +chkshsgr: \ +load chkshsgr.o + ./load chkshsgr + +chkshsgr.o: \ +compile chkshsgr.c exit.h + ./compile chkshsgr.c + +chkspawn: \ +load chkspawn.o substdio.a error.a str.a fs.a auto_spawn.o + ./load chkspawn substdio.a error.a str.a fs.a auto_spawn.o + +chkspawn.o: \ +compile chkspawn.c substdio.h subfd.h substdio.h fmt.h select.h \ +exit.h auto_spawn.h + ./compile chkspawn.c + +clean: \ +TARGETS + rm -f `cat TARGETS` + +coe.o: \ +compile coe.c coe.h + ./compile coe.c + +commands.o: \ +compile commands.c commands.h substdio.h stralloc.h gen_alloc.h str.h \ +case.h + ./compile commands.c + +compile: \ +make-compile warn-auto.sh systype + ( cat warn-auto.sh; ./make-compile "`cat systype`" ) > \ + compile + chmod 755 compile + +condredirect: \ +load condredirect.o qmail.o strerr.a fd.a sig.a wait.a seek.a env.a \ +substdio.a error.a str.a fs.a auto_qmail.o + ./load condredirect qmail.o strerr.a fd.a sig.a wait.a \ + seek.a env.a substdio.a error.a str.a fs.a auto_qmail.o + +condredirect.0: \ +condredirect.1 + nroff -man condredirect.1 > condredirect.0 + +condredirect.o: \ +compile condredirect.c sig.h readwrite.h exit.h env.h error.h fork.h \ +wait.h seek.h qmail.h substdio.h strerr.h substdio.h fmt.h + ./compile condredirect.c + +config: \ +warn-auto.sh config.sh conf-qmail conf-break conf-split + cat warn-auto.sh config.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > config + chmod 755 config + +config-fast: \ +warn-auto.sh config-fast.sh conf-qmail conf-break conf-split + cat warn-auto.sh config-fast.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > config-fast + chmod 755 config-fast + +constmap.o: \ +compile constmap.c constmap.h alloc.h case.h + ./compile constmap.c + +control.o: \ +compile control.c readwrite.h open.h getln.h stralloc.h gen_alloc.h \ +substdio.h error.h control.h alloc.h scan.h + ./compile control.c + +date822fmt.o: \ +compile date822fmt.c datetime.h fmt.h date822fmt.h + ./compile date822fmt.c + +datemail: \ +warn-auto.sh datemail.sh conf-qmail conf-break conf-split + cat warn-auto.sh datemail.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > datemail + chmod 755 datemail + +datetime.a: \ +makelib datetime.o datetime_un.o + ./makelib datetime.a datetime.o datetime_un.o + +datetime.o: \ +compile datetime.c datetime.h + ./compile datetime.c + +datetime_un.o: \ +compile datetime_un.c datetime.h + ./compile datetime_un.c + +direntry.h: \ +compile trydrent.c direntry.h1 direntry.h2 + ( ./compile trydrent.c >/dev/null 2>&1 \ + && cat direntry.h2 || cat direntry.h1 ) > direntry.h + rm -f trydrent.o + +dns.lib: \ +tryrsolv.c compile load socket.lib dns.o ipalloc.o ip.o stralloc.a \ +alloc.a error.a fs.a str.a + ( ( ./compile tryrsolv.c && ./load tryrsolv dns.o \ + 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 + rm -f tryrsolv.o tryrsolv + +dns.o: \ +compile dns.c ip.h ipalloc.h ip.h gen_alloc.h fmt.h alloc.h str.h \ +stralloc.h gen_alloc.h dns.h case.h + ./compile dns.c + +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 + ./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` + +dnscname.o: \ +compile dnscname.c substdio.h subfd.h substdio.h stralloc.h \ +gen_alloc.h dns.h dnsdoe.h readwrite.h exit.h + ./compile dnscname.c + +dnsdoe.o: \ +compile dnsdoe.c substdio.h subfd.h substdio.h exit.h dns.h dnsdoe.h + ./compile dnsdoe.c + +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 + ./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` + +dnsfq.o: \ +compile dnsfq.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ +dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h + ./compile dnsfq.c + +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 + ./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` + +dnsip.o: \ +compile dnsip.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ +dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h + ./compile dnsip.c + +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 + ./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` + +dnsmxip.o: \ +compile dnsmxip.c substdio.h subfd.h substdio.h stralloc.h \ +gen_alloc.h fmt.h dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h \ +now.h datetime.h exit.h + ./compile dnsmxip.c + +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 + ./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` + +dnsptr.o: \ +compile dnsptr.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \ +str.h scan.h dns.h dnsdoe.h ip.h exit.h + ./compile dnsptr.c + +dot-qmail.0: \ +dot-qmail.5 + nroff -man dot-qmail.5 > dot-qmail.0 + +dot-qmail.5: \ +dot-qmail.9 conf-break conf-spawn + cat dot-qmail.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > dot-qmail.5 + +elq: \ +warn-auto.sh elq.sh conf-qmail conf-break conf-split + cat warn-auto.sh elq.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > elq + chmod 755 elq + +env.a: \ +makelib env.o envread.o + ./makelib env.a env.o envread.o + +env.o: \ +compile env.c str.h alloc.h env.h + ./compile env.c + +envelopes.0: \ +envelopes.5 + nroff -man envelopes.5 > envelopes.0 + +envread.o: \ +compile envread.c env.h str.h + ./compile envread.c + +error.a: \ +makelib error.o error_str.o error_temp.o + ./makelib error.a error.o error_str.o error_temp.o + +error.o: \ +compile error.c error.h + ./compile error.c + +error_str.o: \ +compile error_str.c error.h + ./compile error_str.c + +error_temp.o: \ +compile error_temp.c error.h + ./compile error_temp.c + +except: \ +load except.o strerr.a error.a substdio.a str.a wait.a + ./load except strerr.a error.a substdio.a str.a wait.a + +except.0: \ +except.1 + nroff -man except.1 > except.0 + +except.o: \ +compile except.c fork.h strerr.h wait.h error.h exit.h + ./compile except.c + +fd.a: \ +makelib fd_copy.o fd_move.o + ./makelib fd.a fd_copy.o fd_move.o + +fd_copy.o: \ +compile fd_copy.c fd.h + ./compile fd_copy.c + +fd_move.o: \ +compile fd_move.c fd.h + ./compile fd_move.c + +fifo.o: \ +compile fifo.c hasmkffo.h fifo.h + ./compile fifo.c + +find-systype: \ +find-systype.sh auto-ccld.sh + cat auto-ccld.sh find-systype.sh > find-systype + chmod 755 find-systype + +fmt_str.o: \ +compile fmt_str.c fmt.h + ./compile fmt_str.c + +fmt_strn.o: \ +compile fmt_strn.c fmt.h + ./compile fmt_strn.c + +fmt_uint.o: \ +compile fmt_uint.c fmt.h + ./compile fmt_uint.c + +fmt_uint0.o: \ +compile fmt_uint0.c fmt.h + ./compile fmt_uint0.c + +fmt_ulong.o: \ +compile fmt_ulong.c fmt.h + ./compile fmt_ulong.c + +fmtqfn.o: \ +compile fmtqfn.c fmtqfn.h fmt.h auto_split.h + ./compile fmtqfn.c + +forgeries.0: \ +forgeries.7 + nroff -man forgeries.7 > forgeries.0 + +fork.h: \ +compile load tryvfork.c fork.h1 fork.h2 + ( ( ./compile tryvfork.c && ./load tryvfork ) >/dev/null \ + 2>&1 \ + && cat fork.h2 || cat fork.h1 ) > fork.h + rm -f tryvfork.o tryvfork + +forward: \ +load forward.o qmail.o strerr.a alloc.a fd.a wait.a sig.a env.a \ +substdio.a error.a str.a fs.a auto_qmail.o + ./load forward qmail.o strerr.a alloc.a fd.a wait.a sig.a \ + env.a substdio.a error.a str.a fs.a auto_qmail.o + +forward.0: \ +forward.1 + nroff -man forward.1 > forward.0 + +forward.o: \ +compile forward.c sig.h readwrite.h exit.h env.h qmail.h substdio.h \ +strerr.h substdio.h fmt.h + ./compile forward.c + +fs.a: \ +makelib fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o fmt_ulong.o \ +scan_ulong.o scan_8long.o + ./makelib fs.a fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o \ + fmt_ulong.o scan_ulong.o scan_8long.o + +getln.a: \ +makelib getln.o getln2.o + ./makelib getln.a getln.o getln2.o + +getln.o: \ +compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h + ./compile getln.c + +getln2.o: \ +compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h + ./compile getln2.c + +getopt.a: \ +makelib subgetopt.o sgetopt.o + ./makelib getopt.a subgetopt.o sgetopt.o + +gfrom.o: \ +compile gfrom.c str.h gfrom.h + ./compile gfrom.c + +hasflock.h: \ +tryflock.c compile load + ( ( ./compile tryflock.c && ./load tryflock ) >/dev/null \ + 2>&1 \ + && echo \#define HASFLOCK 1 || exit 0 ) > hasflock.h + rm -f tryflock.o tryflock + +hasmkffo.h: \ +trymkffo.c compile load + ( ( ./compile trymkffo.c && ./load trymkffo ) >/dev/null \ + 2>&1 \ + && echo \#define HASMKFIFO 1 || exit 0 ) > hasmkffo.h + rm -f trymkffo.o trymkffo + +hasnpbg1.h: \ +trynpbg1.c compile load open.h open.a fifo.h fifo.o select.h + ( ( ./compile trynpbg1.c \ + && ./load trynpbg1 fifo.o open.a && ./trynpbg1 ) \ + >/dev/null 2>&1 \ + && echo \#define HASNAMEDPIPEBUG1 1 || exit 0 ) > \ + hasnpbg1.h + rm -f trynpbg1.o trynpbg1 + +hassalen.h: \ +trysalen.c compile + ( ./compile trysalen.c >/dev/null 2>&1 \ + && echo \#define HASSALEN 1 || exit 0 ) > hassalen.h + rm -f trysalen.o + +hassgact.h: \ +trysgact.c compile load + ( ( ./compile trysgact.c && ./load trysgact ) >/dev/null \ + 2>&1 \ + && echo \#define HASSIGACTION 1 || exit 0 ) > hassgact.h + rm -f trysgact.o trysgact + +hassgprm.h: \ +trysgprm.c compile load + ( ( ./compile trysgprm.c && ./load trysgprm ) >/dev/null \ + 2>&1 \ + && echo \#define HASSIGPROCMASK 1 || exit 0 ) > hassgprm.h + rm -f trysgprm.o trysgprm + +hasshsgr.h: \ +chkshsgr warn-shsgr tryshsgr.c compile load + ./chkshsgr || ( cat warn-shsgr; exit 1 ) + ( ( ./compile tryshsgr.c \ + && ./load tryshsgr && ./tryshsgr ) >/dev/null 2>&1 \ + && echo \#define HASSHORTSETGROUPS 1 || exit 0 ) > \ + hasshsgr.h + rm -f tryshsgr.o tryshsgr + +haswaitp.h: \ +trywaitp.c compile load + ( ( ./compile trywaitp.c && ./load trywaitp ) >/dev/null \ + 2>&1 \ + && echo \#define HASWAITPID 1 || exit 0 ) > haswaitp.h + rm -f trywaitp.o trywaitp + +headerbody.o: \ +compile headerbody.c stralloc.h gen_alloc.h substdio.h getln.h \ +hfield.h headerbody.h + ./compile headerbody.c + +hfield.o: \ +compile hfield.c hfield.h + ./compile hfield.c + +hier.o: \ +compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h + ./compile hier.c + +home: \ +home.sh conf-qmail + cat home.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > home + chmod 755 home + +home+df: \ +home+df.sh conf-qmail + cat home+df.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > home+df + chmod 755 home+df + +hostname: \ +load hostname.o substdio.a error.a str.a dns.lib socket.lib + ./load hostname substdio.a error.a str.a `cat dns.lib` \ + `cat socket.lib` + +hostname.o: \ +compile hostname.c substdio.h subfd.h substdio.h readwrite.h exit.h + ./compile hostname.c + +idedit: \ +load idedit.o strerr.a substdio.a error.a str.a fs.a wait.a open.a \ +seek.a + ./load idedit strerr.a substdio.a error.a str.a fs.a \ + wait.a open.a seek.a + +idedit.o: \ +compile idedit.c readwrite.h exit.h scan.h fmt.h strerr.h open.h \ +seek.h fork.h + ./compile idedit.c + +install: \ +load install.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \ +strerr.a substdio.a open.a error.a str.a fs.a + ./load install fifo.o hier.o auto_qmail.o auto_split.o \ + auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a + +install-big: \ +load install-big.o fifo.o install.o auto_qmail.o auto_split.o \ +auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a + ./load install-big fifo.o install.o auto_qmail.o \ + auto_split.o auto_uids.o strerr.a substdio.a open.a error.a \ + str.a fs.a + +install-big.o: \ +compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \ +fifo.h + ./compile install-big.c + +install.o: \ +compile install.c substdio.h strerr.h error.h open.h readwrite.h \ +exit.h + ./compile install.c + +instcheck: \ +load instcheck.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \ +strerr.a substdio.a error.a str.a fs.a + ./load instcheck fifo.o hier.o auto_qmail.o auto_split.o \ + auto_uids.o strerr.a substdio.a error.a str.a fs.a + +instcheck.o: \ +compile instcheck.c strerr.h error.h readwrite.h exit.h + ./compile instcheck.c + +ip.o: \ +compile ip.c fmt.h scan.h ip.h + ./compile ip.c + +ipalloc.o: \ +compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h ip.h \ +gen_alloc.h + ./compile ipalloc.c + +ipme.o: \ +compile ipme.c hassalen.h byte.h ip.h ipalloc.h ip.h gen_alloc.h \ +stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h + ./compile ipme.c + +ipmeprint: \ +load ipmeprint.o ipme.o ip.o ipalloc.o stralloc.a alloc.a substdio.a \ +error.a str.a fs.a socket.lib + ./load ipmeprint ipme.o ip.o ipalloc.o stralloc.a alloc.a \ + substdio.a error.a str.a fs.a `cat socket.lib` + +ipmeprint.o: \ +compile ipmeprint.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \ +ipalloc.h ip.h gen_alloc.h exit.h + ./compile ipmeprint.c + +it: \ +qmail-local qmail-lspawn qmail-getpw qmail-remote qmail-rspawn \ +qmail-clean qmail-send qmail-start splogger qmail-queue qmail-inject \ +predate datemail mailsubj qmail-upq qmail-showctl qmail-newu \ +qmail-pw2u qmail-qread qmail-qstat qmail-tcpto qmail-tcpok \ +qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \ +qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast dnscname \ +dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \ +forward preline condredirect bouncesaying except maildirmake \ +maildir2mbox maildirwatch qail elq pinq idedit install-big install \ +instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ +binm3 binm3+df + +load: \ +make-load warn-auto.sh systype + ( cat warn-auto.sh; ./make-load "`cat systype`" ) > load + chmod 755 load + +lock.a: \ +makelib lock_ex.o lock_exnb.o lock_un.o + ./makelib lock.a lock_ex.o lock_exnb.o lock_un.o + +lock_ex.o: \ +compile lock_ex.c hasflock.h lock.h + ./compile lock_ex.c + +lock_exnb.o: \ +compile lock_exnb.c hasflock.h lock.h + ./compile lock_exnb.c + +lock_un.o: \ +compile lock_un.c hasflock.h lock.h + ./compile lock_un.c + +maildir.0: \ +maildir.5 + nroff -man maildir.5 > maildir.0 + +maildir.o: \ +compile maildir.c prioq.h datetime.h gen_alloc.h env.h stralloc.h \ +gen_alloc.h direntry.h datetime.h now.h datetime.h str.h maildir.h \ +strerr.h + ./compile maildir.c + +maildir2mbox: \ +load maildir2mbox.o maildir.o prioq.o now.o myctime.o gfrom.o lock.a \ +getln.a env.a open.a strerr.a stralloc.a alloc.a substdio.a error.a \ +str.a fs.a datetime.a + ./load maildir2mbox maildir.o prioq.o now.o myctime.o \ + gfrom.o lock.a getln.a env.a open.a strerr.a stralloc.a \ + alloc.a substdio.a error.a str.a fs.a datetime.a + +maildir2mbox.0: \ +maildir2mbox.1 + nroff -man maildir2mbox.1 > maildir2mbox.0 + +maildir2mbox.o: \ +compile maildir2mbox.c readwrite.h prioq.h datetime.h gen_alloc.h \ +env.h stralloc.h gen_alloc.h subfd.h substdio.h substdio.h getln.h \ +error.h open.h lock.h gfrom.h str.h exit.h myctime.h maildir.h \ +strerr.h + ./compile maildir2mbox.c + +maildirmake: \ +load maildirmake.o strerr.a substdio.a error.a str.a + ./load maildirmake strerr.a substdio.a error.a str.a + +maildirmake.0: \ +maildirmake.1 + nroff -man maildirmake.1 > maildirmake.0 + +maildirmake.o: \ +compile maildirmake.c strerr.h exit.h + ./compile maildirmake.c + +maildirwatch: \ +load maildirwatch.o hfield.o headerbody.o maildir.o prioq.o now.o \ +getln.a env.a open.a strerr.a stralloc.a alloc.a substdio.a error.a \ +str.a + ./load maildirwatch hfield.o headerbody.o maildir.o \ + prioq.o now.o getln.a env.a open.a strerr.a stralloc.a \ + alloc.a substdio.a error.a str.a + +maildirwatch.0: \ +maildirwatch.1 + nroff -man maildirwatch.1 > maildirwatch.0 + +maildirwatch.o: \ +compile maildirwatch.c getln.h substdio.h subfd.h substdio.h prioq.h \ +datetime.h gen_alloc.h stralloc.h gen_alloc.h str.h exit.h hfield.h \ +readwrite.h open.h headerbody.h maildir.h strerr.h + ./compile maildirwatch.c + +mailsubj: \ +warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split + cat warn-auto.sh mailsubj.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > mailsubj + chmod 755 mailsubj + +mailsubj.0: \ +mailsubj.1 + nroff -man mailsubj.1 > mailsubj.0 + +make-compile: \ +make-compile.sh auto-ccld.sh + cat auto-ccld.sh make-compile.sh > make-compile + chmod 755 make-compile + +make-load: \ +make-load.sh auto-ccld.sh + cat auto-ccld.sh make-load.sh > make-load + chmod 755 make-load + +make-makelib: \ +make-makelib.sh auto-ccld.sh + cat auto-ccld.sh make-makelib.sh > make-makelib + chmod 755 make-makelib + +makelib: \ +make-makelib warn-auto.sh systype + ( cat warn-auto.sh; ./make-makelib "`cat systype`" ) > \ + makelib + chmod 755 makelib + +man: \ +qmail-local.0 qmail-lspawn.0 qmail-getpw.0 qmail-remote.0 \ +qmail-rspawn.0 qmail-clean.0 qmail-send.0 qmail-start.0 splogger.0 \ +qmail-queue.0 qmail-inject.0 mailsubj.0 qmail-showctl.0 qmail-newu.0 \ +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.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.0 qmail-log.0 \ +qmail-control.0 qmail-header.0 qmail-users.0 dot-qmail.0 \ +qmail-command.0 tcp-environ.0 maildir.0 mbox.0 addresses.0 \ +envelopes.0 forgeries.0 + +mbox.0: \ +mbox.5 + nroff -man mbox.5 > mbox.0 + +myctime.o: \ +compile myctime.c datetime.h fmt.h myctime.h + ./compile myctime.c + +ndelay.a: \ +makelib ndelay.o ndelay_off.o + ./makelib ndelay.a ndelay.o ndelay_off.o + +ndelay.o: \ +compile ndelay.c ndelay.h + ./compile ndelay.c + +ndelay_off.o: \ +compile ndelay_off.c ndelay.h + ./compile ndelay_off.c + +newfield.o: \ +compile newfield.c fmt.h datetime.h stralloc.h gen_alloc.h \ +date822fmt.h newfield.h stralloc.h + ./compile newfield.c + +now.o: \ +compile now.c datetime.h now.h datetime.h + ./compile now.c + +open.a: \ +makelib open_append.o open_excl.o open_read.o open_trunc.o \ +open_write.o + ./makelib open.a open_append.o open_excl.o open_read.o \ + open_trunc.o open_write.o + +open_append.o: \ +compile open_append.c open.h + ./compile open_append.c + +open_excl.o: \ +compile open_excl.c open.h + ./compile open_excl.c + +open_read.o: \ +compile open_read.c open.h + ./compile open_read.c + +open_trunc.o: \ +compile open_trunc.c open.h + ./compile open_trunc.c + +open_write.o: \ +compile open_write.c open.h + ./compile open_write.c + +pinq: \ +warn-auto.sh pinq.sh conf-qmail conf-break conf-split + cat warn-auto.sh pinq.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > pinq + chmod 755 pinq + +predate: \ +load predate.o datetime.a strerr.a sig.a fd.a wait.a substdio.a \ +error.a str.a fs.a + ./load predate datetime.a strerr.a sig.a fd.a wait.a \ + substdio.a error.a str.a fs.a + +predate.o: \ +compile predate.c datetime.h fork.h wait.h fd.h fmt.h strerr.h \ +substdio.h subfd.h substdio.h readwrite.h exit.h + ./compile predate.c + +preline: \ +load preline.o strerr.a fd.a wait.a sig.a env.a getopt.a substdio.a \ +error.a str.a + ./load preline strerr.a fd.a wait.a sig.a env.a getopt.a \ + substdio.a error.a str.a + +preline.0: \ +preline.1 + nroff -man preline.1 > preline.0 + +preline.o: \ +compile preline.c fd.h sgetopt.h subgetopt.h readwrite.h strerr.h \ +substdio.h exit.h fork.h wait.h env.h sig.h error.h + ./compile preline.c + +prioq.o: \ +compile prioq.c alloc.h gen_allocdefs.h prioq.h datetime.h \ +gen_alloc.h + ./compile prioq.c + +proc: \ +proc.sh conf-qmail + cat proc.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > proc + chmod 755 proc + +proc+df: \ +proc+df.sh conf-qmail + cat proc+df.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + > proc+df + chmod 755 proc+df + +prot.o: \ +compile prot.c hasshsgr.h prot.h + ./compile prot.c + +qail: \ +warn-auto.sh qail.sh conf-qmail conf-break conf-split + cat warn-auto.sh qail.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > qail + chmod 755 qail + +qbiff: \ +load qbiff.o headerbody.o hfield.o getln.a env.a open.a stralloc.a \ +alloc.a substdio.a error.a str.a + ./load qbiff headerbody.o hfield.o getln.a env.a open.a \ + stralloc.a alloc.a substdio.a error.a str.a + +qbiff.0: \ +qbiff.1 + nroff -man qbiff.1 > qbiff.0 + +qbiff.o: \ +compile qbiff.c readwrite.h stralloc.h gen_alloc.h substdio.h subfd.h \ +substdio.h open.h byte.h str.h headerbody.h hfield.h env.h exit.h + ./compile qbiff.c + +qmail-clean: \ +load qmail-clean.o fmtqfn.o now.o getln.a sig.a stralloc.a alloc.a \ +substdio.a error.a str.a fs.a auto_qmail.o auto_split.o + ./load qmail-clean fmtqfn.o now.o getln.a sig.a stralloc.a \ + alloc.a substdio.a error.a str.a fs.a auto_qmail.o \ + auto_split.o + +qmail-clean.0: \ +qmail-clean.8 + nroff -man qmail-clean.8 > qmail-clean.0 + +qmail-clean.o: \ +compile qmail-clean.c readwrite.h sig.h now.h datetime.h str.h \ +direntry.h getln.h stralloc.h gen_alloc.h substdio.h subfd.h \ +substdio.h byte.h scan.h fmt.h error.h exit.h fmtqfn.h auto_qmail.h + ./compile qmail-clean.c + +qmail-command.0: \ +qmail-command.8 + nroff -man qmail-command.8 > qmail-command.0 + +qmail-control.0: \ +qmail-control.5 + nroff -man qmail-control.5 > qmail-control.0 + +qmail-control.5: \ +qmail-control.9 conf-break conf-spawn + cat qmail-control.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-control.5 + +qmail-getpw: \ +load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \ +auto_usera.o + ./load qmail-getpw case.a substdio.a error.a str.a fs.a \ + auto_break.o auto_usera.o + +qmail-getpw.0: \ +qmail-getpw.8 + nroff -man qmail-getpw.8 > qmail-getpw.0 + +qmail-getpw.8: \ +qmail-getpw.9 conf-break conf-spawn + cat qmail-getpw.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-getpw.8 + +qmail-getpw.o: \ +compile qmail-getpw.c readwrite.h substdio.h subfd.h substdio.h \ +error.h exit.h byte.h str.h case.h fmt.h auto_usera.h auto_break.h \ +qlx.h + ./compile qmail-getpw.c + +qmail-header.0: \ +qmail-header.5 + nroff -man qmail-header.5 > qmail-header.0 + +qmail-inject: \ +load qmail-inject.o headerbody.o hfield.o newfield.o quote.o now.o \ +control.o date822fmt.o constmap.o qmail.o case.a fd.a wait.a open.a \ +getln.a sig.a getopt.a datetime.a token822.o env.a stralloc.a alloc.a \ +substdio.a error.a str.a fs.a auto_qmail.o + ./load qmail-inject headerbody.o hfield.o newfield.o \ + quote.o now.o control.o date822fmt.o constmap.o qmail.o \ + case.a fd.a wait.a open.a getln.a sig.a getopt.a datetime.a \ + token822.o env.a stralloc.a alloc.a substdio.a error.a \ + str.a fs.a auto_qmail.o + +qmail-inject.0: \ +qmail-inject.8 + nroff -man qmail-inject.8 > qmail-inject.0 + +qmail-inject.o: \ +compile qmail-inject.c sig.h substdio.h stralloc.h gen_alloc.h \ +subfd.h substdio.h sgetopt.h subgetopt.h getln.h alloc.h str.h fmt.h \ +hfield.h token822.h gen_alloc.h control.h env.h gen_alloc.h \ +gen_allocdefs.h error.h qmail.h substdio.h now.h datetime.h exit.h \ +quote.h headerbody.h auto_qmail.h newfield.h stralloc.h constmap.h + ./compile qmail-inject.c + +qmail-limits.0: \ +qmail-limits.7 + nroff -man qmail-limits.7 > qmail-limits.0 + +qmail-limits.7: \ +qmail-limits.9 conf-break conf-spawn + cat qmail-limits.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-limits.7 + +qmail-local: \ +load qmail-local.o qmail.o quote.o now.o gfrom.o myctime.o \ +slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a lock.a fd.a \ +wait.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \ +fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib + ./load qmail-local qmail.o quote.o now.o gfrom.o myctime.o \ + slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a \ + lock.a fd.a wait.a env.a stralloc.a alloc.a strerr.a \ + substdio.a error.a str.a fs.a datetime.a auto_qmail.o \ + auto_patrn.o `cat socket.lib` + +qmail-local.0: \ +qmail-local.8 + nroff -man qmail-local.8 > qmail-local.0 + +qmail-local.o: \ +compile qmail-local.c readwrite.h sig.h env.h byte.h exit.h fork.h \ +open.h wait.h lock.h seek.h substdio.h getln.h strerr.h subfd.h \ +substdio.h sgetopt.h subgetopt.h alloc.h error.h stralloc.h \ +gen_alloc.h fmt.h str.h now.h datetime.h case.h quote.h qmail.h \ +substdio.h slurpclose.h myctime.h gfrom.h auto_patrn.h + ./compile qmail-local.c + +qmail-log.0: \ +qmail-log.5 + nroff -man qmail-log.5 > qmail-log.0 + +qmail-lspawn: \ +load qmail-lspawn.o spawn.o prot.o slurpclose.o coe.o sig.a wait.a \ +case.a cdb.a fd.a open.a stralloc.a alloc.a substdio.a error.a str.a \ +fs.a auto_qmail.o auto_uids.o auto_spawn.o + ./load qmail-lspawn spawn.o prot.o slurpclose.o coe.o \ + sig.a wait.a case.a cdb.a fd.a open.a stralloc.a alloc.a \ + substdio.a error.a str.a fs.a auto_qmail.o auto_uids.o \ + auto_spawn.o + +qmail-lspawn.0: \ +qmail-lspawn.8 + nroff -man qmail-lspawn.8 > qmail-lspawn.0 + +qmail-lspawn.o: \ +compile qmail-lspawn.c fd.h wait.h prot.h substdio.h stralloc.h \ +gen_alloc.h scan.h exit.h fork.h error.h cdb.h uint32.h case.h \ +slurpclose.h auto_qmail.h auto_uids.h qlx.h + ./compile qmail-lspawn.c + +qmail-newmrh: \ +load qmail-newmrh.o cdbmss.o getln.a open.a cdbmake.a seek.a case.a \ +stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o + ./load qmail-newmrh cdbmss.o getln.a open.a cdbmake.a \ + seek.a case.a stralloc.a alloc.a strerr.a substdio.a \ + error.a str.a auto_qmail.o + +qmail-newmrh.0: \ +qmail-newmrh.8 + nroff -man qmail-newmrh.8 > qmail-newmrh.0 + +qmail-newmrh.8: \ +qmail-newmrh.9 conf-break conf-spawn + cat qmail-newmrh.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-newmrh.8 + +qmail-newmrh.o: \ +compile qmail-newmrh.c strerr.h stralloc.h gen_alloc.h substdio.h \ +getln.h exit.h readwrite.h open.h auto_qmail.h cdbmss.h cdbmake.h \ +uint32.h substdio.h + ./compile qmail-newmrh.c + +qmail-newu: \ +load qmail-newu.o cdbmss.o getln.a open.a seek.a cdbmake.a case.a \ +stralloc.a alloc.a substdio.a error.a str.a auto_qmail.o + ./load qmail-newu cdbmss.o getln.a open.a seek.a cdbmake.a \ + case.a stralloc.a alloc.a substdio.a error.a str.a \ + auto_qmail.o + +qmail-newu.0: \ +qmail-newu.8 + nroff -man qmail-newu.8 > qmail-newu.0 + +qmail-newu.8: \ +qmail-newu.9 conf-break conf-spawn + cat qmail-newu.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-newu.8 + +qmail-newu.o: \ +compile qmail-newu.c stralloc.h gen_alloc.h subfd.h substdio.h \ +getln.h substdio.h cdbmss.h cdbmake.h uint32.h substdio.h exit.h \ +readwrite.h open.h error.h case.h auto_qmail.h + ./compile qmail-newu.c + +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 \ +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 \ + open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \ + fs.a `cat socket.lib` + +qmail-pop3d.0: \ +qmail-pop3d.8 + nroff -man qmail-pop3d.8 > qmail-pop3d.0 + +qmail-pop3d.o: \ +compile qmail-pop3d.c commands.h sig.h getln.h stralloc.h gen_alloc.h \ +substdio.h alloc.h open.h prioq.h datetime.h gen_alloc.h scan.h fmt.h \ +str.h exit.h maildir.h strerr.h readwrite.h timeoutread.h \ +timeoutwrite.h + ./compile qmail-pop3d.c + +qmail-popup: \ +load qmail-popup.o 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 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` + +qmail-popup.0: \ +qmail-popup.8 + nroff -man qmail-popup.8 > qmail-popup.0 + +qmail-popup.o: \ +compile qmail-popup.c commands.h fd.h sig.h stralloc.h gen_alloc.h \ +substdio.h alloc.h wait.h str.h byte.h now.h datetime.h fmt.h exit.h \ +readwrite.h timeoutread.h timeoutwrite.h + ./compile qmail-popup.c + +qmail-pw2u: \ +load qmail-pw2u.o constmap.o control.o open.a getln.a case.a getopt.a \ +stralloc.a alloc.a substdio.a error.a str.a fs.a auto_usera.o \ +auto_break.o auto_qmail.o + ./load qmail-pw2u constmap.o control.o open.a getln.a \ + case.a getopt.a stralloc.a alloc.a substdio.a error.a str.a \ + fs.a auto_usera.o auto_break.o auto_qmail.o + +qmail-pw2u.0: \ +qmail-pw2u.8 + nroff -man qmail-pw2u.8 > qmail-pw2u.0 + +qmail-pw2u.8: \ +qmail-pw2u.9 conf-break conf-spawn + cat qmail-pw2u.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-pw2u.8 + +qmail-pw2u.o: \ +compile qmail-pw2u.c substdio.h readwrite.h subfd.h substdio.h \ +sgetopt.h subgetopt.h control.h constmap.h stralloc.h gen_alloc.h \ +fmt.h str.h scan.h open.h error.h getln.h auto_break.h auto_qmail.h \ +auto_usera.h + ./compile qmail-pw2u.c + +qmail-qmqpc: \ +load qmail-qmqpc.o slurpclose.o timeoutread.o timeoutwrite.o \ +timeoutconn.o ip.o control.o auto_qmail.o sig.a ndelay.a open.a \ +getln.a substdio.a stralloc.a alloc.a error.a str.a fs.a socket.lib + ./load qmail-qmqpc slurpclose.o timeoutread.o \ + timeoutwrite.o timeoutconn.o ip.o control.o auto_qmail.o \ + sig.a ndelay.a open.a getln.a substdio.a stralloc.a alloc.a \ + error.a str.a fs.a `cat socket.lib` + +qmail-qmqpc.0: \ +qmail-qmqpc.8 + nroff -man qmail-qmqpc.8 > qmail-qmqpc.0 + +qmail-qmqpc.o: \ +compile qmail-qmqpc.c substdio.h getln.h readwrite.h exit.h \ +stralloc.h gen_alloc.h slurpclose.h error.h sig.h ip.h timeoutconn.h \ +timeoutread.h timeoutwrite.h auto_qmail.h control.h fmt.h + ./compile qmail-qmqpc.c + +qmail-qmqpd: \ +load qmail-qmqpd.o received.o now.o date822fmt.o qmail.o auto_qmail.o \ +env.a substdio.a sig.a error.a wait.a fd.a str.a datetime.a fs.a + ./load qmail-qmqpd received.o now.o date822fmt.o qmail.o \ + auto_qmail.o env.a substdio.a sig.a error.a wait.a fd.a \ + str.a datetime.a fs.a + +qmail-qmqpd.0: \ +qmail-qmqpd.8 + nroff -man qmail-qmqpd.8 > qmail-qmqpd.0 + +qmail-qmqpd.o: \ +compile qmail-qmqpd.c auto_qmail.h qmail.h substdio.h received.h \ +sig.h substdio.h readwrite.h exit.h now.h datetime.h fmt.h env.h + ./compile qmail-qmqpd.c + +qmail-qmtpd: \ +load qmail-qmtpd.o rcpthosts.o control.o constmap.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 + ./load qmail-qmtpd rcpthosts.o control.o constmap.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 + +qmail-qmtpd.0: \ +qmail-qmtpd.8 + nroff -man qmail-qmtpd.8 > qmail-qmtpd.0 + +qmail-qmtpd.o: \ +compile qmail-qmtpd.c stralloc.h gen_alloc.h substdio.h qmail.h \ +substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h \ +auto_qmail.h readwrite.h control.h received.h + ./compile qmail-qmtpd.c + +qmail-qread: \ +load qmail-qread.o fmtqfn.o readsubdir.o date822fmt.o datetime.a \ +open.a getln.a stralloc.a alloc.a substdio.a error.a str.a fs.a \ +auto_qmail.o auto_split.o + ./load qmail-qread fmtqfn.o readsubdir.o date822fmt.o \ + datetime.a open.a getln.a stralloc.a alloc.a substdio.a \ + error.a str.a fs.a auto_qmail.o auto_split.o + +qmail-qread.0: \ +qmail-qread.8 + nroff -man qmail-qread.8 > qmail-qread.0 + +qmail-qread.o: \ +compile qmail-qread.c stralloc.h gen_alloc.h substdio.h subfd.h \ +substdio.h fmt.h str.h getln.h fmtqfn.h readsubdir.h direntry.h \ +auto_qmail.h open.h datetime.h date822fmt.h readwrite.h error.h \ +exit.h + ./compile qmail-qread.c + +qmail-qstat: \ +warn-auto.sh qmail-qstat.sh conf-qmail conf-break conf-split + cat warn-auto.sh qmail-qstat.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > qmail-qstat + chmod 755 qmail-qstat + +qmail-qstat.0: \ +qmail-qstat.8 + nroff -man qmail-qstat.8 > qmail-qstat.0 + +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 \ + 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 + +qmail-queue.0: \ +qmail-queue.8 + nroff -man qmail-queue.8 > qmail-queue.0 + +qmail-queue.o: \ +compile qmail-queue.c readwrite.h sig.h exit.h open.h seek.h fmt.h \ +alloc.h substdio.h datetime.h now.h datetime.h triggerpull.h extra.h \ +auto_qmail.h auto_uids.h date822fmt.h fmtqfn.h + ./compile qmail-queue.c + +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 \ +ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \ +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 \ + 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` + +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 \ +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 + ./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 + ./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 + +qmail-rspawn.0: \ +qmail-rspawn.8 + nroff -man qmail-rspawn.8 > qmail-rspawn.0 + +qmail-rspawn.o: \ +compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h \ +tcpto.h + ./compile qmail-rspawn.c + +qmail-send: \ +load qmail-send.o 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 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 env.a + +qmail-send.0: \ +qmail-send.8 + nroff -man qmail-send.8 > qmail-send.0 + +qmail-send.8: \ +qmail-send.9 conf-break conf-spawn + cat qmail-send.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-send.8 + +qmail-send.o: \ +compile qmail-send.c readwrite.h sig.h direntry.h control.h select.h \ +open.h seek.h exit.h lock.h ndelay.h now.h datetime.h getln.h \ +substdio.h alloc.h error.h stralloc.h gen_alloc.h str.h byte.h fmt.h \ +scan.h case.h auto_qmail.h trigger.h newfield.h stralloc.h quote.h \ +qmail.h substdio.h qsutil.h prioq.h datetime.h gen_alloc.h constmap.h \ +fmtqfn.h readsubdir.h direntry.h + ./compile qmail-send.c + +qmail-showctl: \ +load qmail-showctl.o auto_uids.o control.o open.a getln.a stralloc.a \ +alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_break.o \ +auto_patrn.o auto_spawn.o auto_split.o + ./load qmail-showctl auto_uids.o control.o open.a getln.a \ + stralloc.a alloc.a substdio.a error.a str.a fs.a \ + auto_qmail.o auto_break.o auto_patrn.o auto_spawn.o \ + auto_split.o + +qmail-showctl.0: \ +qmail-showctl.8 + nroff -man qmail-showctl.8 > qmail-showctl.0 + +qmail-showctl.o: \ +compile qmail-showctl.c substdio.h subfd.h substdio.h exit.h fmt.h \ +str.h control.h constmap.h stralloc.h gen_alloc.h direntry.h \ +auto_uids.h auto_qmail.h auto_break.h auto_patrn.h auto_spawn.h \ +auto_split.h + ./compile qmail-showctl.c + +qmail-smtpd: \ +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 + ./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` + +qmail-smtpd.0: \ +qmail-smtpd.8 + nroff -man qmail-smtpd.8 > qmail-smtpd.0 + +qmail-smtpd.o: \ +compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \ +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 + ./compile qmail-smtpd.c + +qmail-start: \ +load qmail-start.o prot.o fd.a auto_uids.o + ./load qmail-start prot.o fd.a auto_uids.o + +qmail-start.0: \ +qmail-start.8 + nroff -man qmail-start.8 > qmail-start.0 + +qmail-start.8: \ +qmail-start.9 conf-break conf-spawn + cat qmail-start.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-start.8 + +qmail-start.o: \ +compile qmail-start.c fd.h prot.h exit.h fork.h auto_uids.h + ./compile qmail-start.c + +qmail-tcpok: \ +load qmail-tcpok.o open.a lock.a strerr.a substdio.a error.a str.a \ +auto_qmail.o + ./load qmail-tcpok open.a lock.a strerr.a substdio.a \ + error.a str.a auto_qmail.o + +qmail-tcpok.0: \ +qmail-tcpok.8 + nroff -man qmail-tcpok.8 > qmail-tcpok.0 + +qmail-tcpok.o: \ +compile qmail-tcpok.c strerr.h substdio.h lock.h open.h readwrite.h \ +auto_qmail.h exit.h + ./compile qmail-tcpok.c + +qmail-tcpto: \ +load qmail-tcpto.o ip.o now.o open.a lock.a substdio.a error.a str.a \ +fs.a auto_qmail.o + ./load qmail-tcpto ip.o now.o open.a lock.a substdio.a \ + error.a str.a fs.a auto_qmail.o + +qmail-tcpto.0: \ +qmail-tcpto.8 + nroff -man qmail-tcpto.8 > qmail-tcpto.0 + +qmail-tcpto.o: \ +compile qmail-tcpto.c substdio.h subfd.h substdio.h auto_qmail.h \ +fmt.h ip.h lock.h error.h exit.h datetime.h now.h datetime.h + ./compile qmail-tcpto.c + +qmail-upq: \ +warn-auto.sh qmail-upq.sh conf-qmail conf-break conf-split + cat warn-auto.sh qmail-upq.sh \ + | sed s}QMAIL}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPLIT}"`head -1 conf-split`"}g \ + > qmail-upq + chmod 755 qmail-upq + +qmail-users.0: \ +qmail-users.5 + nroff -man qmail-users.5 > qmail-users.0 + +qmail-users.5: \ +qmail-users.9 conf-break conf-spawn + cat qmail-users.9 \ + | sed s}QMAILHOME}"`head -1 conf-qmail`"}g \ + | sed s}BREAK}"`head -1 conf-break`"}g \ + | sed s}SPAWN}"`head -1 conf-spawn`"}g \ + > qmail-users.5 + +qmail.0: \ +qmail.7 + nroff -man qmail.7 > qmail.0 + +qmail.o: \ +compile qmail.c substdio.h readwrite.h wait.h exit.h fork.h fd.h \ +qmail.h substdio.h auto_qmail.h + ./compile qmail.c + +qreceipt: \ +load qreceipt.o headerbody.o hfield.o quote.o token822.o qmail.o \ +getln.a fd.a wait.a sig.a env.a stralloc.a alloc.a substdio.a error.a \ +str.a auto_qmail.o + ./load qreceipt headerbody.o hfield.o quote.o token822.o \ + qmail.o getln.a fd.a wait.a sig.a env.a stralloc.a alloc.a \ + substdio.a error.a str.a auto_qmail.o + +qreceipt.0: \ +qreceipt.1 + nroff -man qreceipt.1 > qreceipt.0 + +qreceipt.o: \ +compile qreceipt.c sig.h env.h substdio.h stralloc.h gen_alloc.h \ +subfd.h substdio.h getln.h alloc.h str.h hfield.h token822.h \ +gen_alloc.h error.h gen_alloc.h gen_allocdefs.h headerbody.h exit.h \ +open.h quote.h qmail.h substdio.h + ./compile qreceipt.c + +qsmhook: \ +load qsmhook.o sig.a case.a fd.a wait.a getopt.a env.a stralloc.a \ +alloc.a substdio.a error.a str.a + ./load qsmhook sig.a case.a fd.a wait.a getopt.a env.a \ + stralloc.a alloc.a substdio.a error.a str.a + +qsmhook.o: \ +compile qsmhook.c fd.h stralloc.h gen_alloc.h readwrite.h sgetopt.h \ +subgetopt.h wait.h env.h byte.h str.h alloc.h exit.h fork.h case.h \ +subfd.h substdio.h error.h substdio.h sig.h + ./compile qsmhook.c + +qsutil.o: \ +compile qsutil.c stralloc.h gen_alloc.h readwrite.h substdio.h \ +qsutil.h + ./compile qsutil.c + +quote.o: \ +compile quote.c stralloc.h gen_alloc.h str.h quote.h + ./compile quote.c + +rcpthosts.o: \ +compile rcpthosts.c cdb.h uint32.h byte.h open.h error.h control.h \ +constmap.h stralloc.h gen_alloc.h rcpthosts.h + ./compile rcpthosts.c + +readsubdir.o: \ +compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \ +auto_split.h + ./compile readsubdir.c + +received.o: \ +compile received.c fmt.h qmail.h substdio.h now.h datetime.h \ +datetime.h date822fmt.h received.h + ./compile received.c + +remoteinfo.o: \ +compile remoteinfo.c byte.h substdio.h ip.h fmt.h timeoutconn.h \ +timeoutread.h timeoutwrite.h remoteinfo.h + ./compile remoteinfo.c + +scan_8long.o: \ +compile scan_8long.c scan.h + ./compile scan_8long.c + +scan_ulong.o: \ +compile scan_ulong.c scan.h + ./compile scan_ulong.c + +seek.a: \ +makelib seek_cur.o seek_end.o seek_set.o seek_trunc.o + ./makelib seek.a seek_cur.o seek_end.o seek_set.o \ + seek_trunc.o + +seek_cur.o: \ +compile seek_cur.c seek.h + ./compile seek_cur.c + +seek_end.o: \ +compile seek_end.c seek.h + ./compile seek_end.c + +seek_set.o: \ +compile seek_set.c seek.h + ./compile seek_set.c + +seek_trunc.o: \ +compile seek_trunc.c seek.h + ./compile seek_trunc.c + +select.h: \ +compile trysysel.c select.h1 select.h2 + ( ./compile trysysel.c >/dev/null 2>&1 \ + && cat select.h2 || cat select.h1 ) > select.h + rm -f trysysel.o trysysel + +sendmail: \ +load sendmail.o env.a getopt.a alloc.a substdio.a error.a str.a \ +auto_qmail.o + ./load sendmail env.a getopt.a alloc.a substdio.a error.a \ + str.a auto_qmail.o + +sendmail.o: \ +compile sendmail.c sgetopt.h subgetopt.h substdio.h subfd.h \ +substdio.h alloc.h auto_qmail.h exit.h env.h str.h + ./compile sendmail.c + +setup: \ +it man + ./install + +sgetopt.o: \ +compile sgetopt.c substdio.h subfd.h substdio.h sgetopt.h subgetopt.h \ +subgetopt.h + ./compile sgetopt.c + +shar: \ +FILES BLURB BLURB2 BLURB3 BLURB4 README FAQ INSTALL INSTALL.alias \ +INSTALL.ctl INSTALL.ids INSTALL.maildir INSTALL.mbox INSTALL.vsm \ +REMOVE.sendmail REMOVE.binmail TEST.deliver TEST.receive UPGRADE \ +THOUGHTS TODO THANKS CHANGES SECURITY INTERNALS SENDMAIL \ +PIC.local2alias PIC.local2ext PIC.local2local PIC.local2rem \ +PIC.local2virt PIC.nullclient PIC.relaybad PIC.relaygood \ +PIC.rem2local FILES VERSION SYSDEPS TARGETS Makefile BIN.README \ +BIN.Makefile BIN.setup idedit.c conf-break auto_break.h conf-spawn \ +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 bouncesaying.1 condredirect.1 dot-qmail.9 \ +envelopes.5 forgeries.7 forward.1 maildir2mbox.1 maildirmake.1 \ +maildirwatch.1 mailsubj.1 mbox.5 preline.1 qbiff.1 qmail-clean.8 \ +qmail-command.8 qmail-control.9 qmail-getpw.9 qmail-header.5 \ +qmail-inject.8 qmail-limits.9 qmail-local.8 qmail-log.5 \ +qmail-lspawn.8 qmail-newmrh.9 qmail-newu.9 qmail-pop3d.8 \ +qmail-popup.8 qmail-pw2u.9 qmail-qmqpc.8 qmail-qmqpd.8 qmail-qmtpd.8 \ +qmail-qread.8 qmail-qstat.8 qmail-queue.8 qmail-remote.8 \ +qmail-rspawn.8 qmail-send.9 qmail-showctl.8 qmail-smtpd.8 \ +qmail-start.9 qmail-tcpok.8 qmail-tcpto.8 qmail-users.9 qmail.7 \ +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 readsubdir.c received.h 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 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 sig.h sig_alarm.c sig_block.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 str.h \ +str_chr.c str_cpy.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 \ +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 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 trylsock.c tryrsolv.c ip.h ip.c \ +ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \ +ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \ +prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \ +maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c + shar -m `cat FILES` > shar + chmod 400 shar + +sig.a: \ +makelib sig_alarm.o sig_block.o sig_catch.o sig_pause.o sig_pipe.o \ +sig_child.o sig_hup.o sig_term.o sig_bug.o sig_misc.o + ./makelib sig.a sig_alarm.o sig_block.o 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_alarm.o: \ +compile sig_alarm.c sig.h + ./compile sig_alarm.c + +sig_block.o: \ +compile sig_block.c sig.h hassgprm.h + ./compile sig_block.c + +sig_bug.o: \ +compile sig_bug.c sig.h + ./compile sig_bug.c + +sig_catch.o: \ +compile sig_catch.c sig.h hassgact.h + ./compile sig_catch.c + +sig_child.o: \ +compile sig_child.c sig.h + ./compile sig_child.c + +sig_hup.o: \ +compile sig_hup.c sig.h + ./compile sig_hup.c + +sig_misc.o: \ +compile sig_misc.c sig.h + ./compile sig_misc.c + +sig_pause.o: \ +compile sig_pause.c sig.h hassgprm.h + ./compile sig_pause.c + +sig_pipe.o: \ +compile sig_pipe.c sig.h + ./compile sig_pipe.c + +sig_term.o: \ +compile sig_term.c sig.h + ./compile sig_term.c + +slurpclose.o: \ +compile slurpclose.c stralloc.h gen_alloc.h readwrite.h slurpclose.h \ +error.h + ./compile slurpclose.c + +socket.lib: \ +trylsock.c compile load + ( ( ./compile trylsock.c && \ + ./load trylsock -lsocket -lnsl ) >/dev/null 2>&1 \ + && echo -lsocket -lnsl || exit 0 ) > socket.lib + rm -f trylsock.o trylsock + +spawn.o: \ +compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \ +stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \ +auto_qmail.h auto_uids.h auto_spawn.h + ./chkspawn + ./compile spawn.c + +splogger: \ +load splogger.o substdio.a error.a str.a fs.a syslog.lib socket.lib + ./load splogger substdio.a error.a str.a fs.a `cat \ + syslog.lib` `cat socket.lib` + +splogger.0: \ +splogger.8 + nroff -man splogger.8 > splogger.0 + +splogger.o: \ +compile splogger.c error.h substdio.h subfd.h substdio.h exit.h str.h \ +scan.h fmt.h + ./compile splogger.c + +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 + ./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 + +str_chr.o: \ +compile str_chr.c str.h + ./compile str_chr.c + +str_cpy.o: \ +compile str_cpy.c str.h + ./compile str_cpy.c + +str_diff.o: \ +compile str_diff.c str.h + ./compile str_diff.c + +str_diffn.o: \ +compile str_diffn.c str.h + ./compile str_diffn.c + +str_len.o: \ +compile str_len.c str.h + ./compile str_len.c + +str_rchr.o: \ +compile str_rchr.c str.h + ./compile str_rchr.c + +str_start.o: \ +compile str_start.c str.h + ./compile str_start.c + +stralloc.a: \ +makelib 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 + ./makelib stralloc.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_arts.o: \ +compile stralloc_arts.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_arts.c + +stralloc_cat.o: \ +compile stralloc_cat.c byte.h stralloc.h gen_alloc.h + ./compile stralloc_cat.c + +stralloc_catb.o: \ +compile stralloc_catb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_catb.c + +stralloc_cats.o: \ +compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_cats.c + +stralloc_copy.o: \ +compile stralloc_copy.c byte.h stralloc.h gen_alloc.h + ./compile stralloc_copy.c + +stralloc_eady.o: \ +compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_eady.c + +stralloc_opyb.o: \ +compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_opyb.c + +stralloc_opys.o: \ +compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h + ./compile stralloc_opys.c + +stralloc_pend.o: \ +compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ +gen_allocdefs.h + ./compile stralloc_pend.c + +strerr.a: \ +makelib strerr_sys.o strerr_die.o + ./makelib strerr.a strerr_sys.o strerr_die.o + +strerr_die.o: \ +compile strerr_die.c substdio.h subfd.h substdio.h exit.h strerr.h + ./compile strerr_die.c + +strerr_sys.o: \ +compile strerr_sys.c error.h strerr.h + ./compile strerr_sys.c + +subfderr.o: \ +compile subfderr.c readwrite.h substdio.h subfd.h substdio.h + ./compile subfderr.c + +subfdin.o: \ +compile subfdin.c readwrite.h substdio.h subfd.h substdio.h + ./compile subfdin.c + +subfdins.o: \ +compile subfdins.c readwrite.h substdio.h subfd.h substdio.h + ./compile subfdins.c + +subfdout.o: \ +compile subfdout.c readwrite.h substdio.h subfd.h substdio.h + ./compile subfdout.c + +subfdouts.o: \ +compile subfdouts.c readwrite.h substdio.h subfd.h substdio.h + ./compile subfdouts.c + +subgetopt.o: \ +compile subgetopt.c subgetopt.h + ./compile subgetopt.c + +substdi.o: \ +compile substdi.c substdio.h byte.h error.h + ./compile substdi.c + +substdio.a: \ +makelib substdio.o substdi.o substdo.o subfderr.o subfdout.o \ +subfdouts.o subfdin.o subfdins.o substdio_copy.o + ./makelib substdio.a substdio.o substdi.o substdo.o \ + subfderr.o subfdout.o subfdouts.o subfdin.o subfdins.o \ + substdio_copy.o + +substdio.o: \ +compile substdio.c substdio.h + ./compile substdio.c + +substdio_copy.o: \ +compile substdio_copy.c substdio.h + ./compile substdio_copy.c + +substdo.o: \ +compile substdo.c substdio.h str.h byte.h error.h + ./compile substdo.c + +syslog.lib: \ +trysyslog.c compile load + ( ( ./compile trysyslog.c && \ + ./load trysyslog -lgen ) >/dev/null 2>&1 \ + && echo -lgen || exit 0 ) > syslog.lib + rm -f trysyslog.o trysyslog + +systype: \ +find-systype trycpp.c + ./find-systype > systype + +tcp-env: \ +load tcp-env.o dns.o remoteinfo.o timeoutread.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 dns.lib socket.lib + ./load tcp-env dns.o remoteinfo.o timeoutread.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` + +tcp-env.0: \ +tcp-env.1 + nroff -man tcp-env.1 > tcp-env.0 + +tcp-env.o: \ +compile tcp-env.c sig.h stralloc.h gen_alloc.h str.h env.h fmt.h \ +scan.h subgetopt.h ip.h dns.h byte.h remoteinfo.h exit.h case.h + ./compile tcp-env.c + +tcp-environ.0: \ +tcp-environ.5 + nroff -man tcp-environ.5 > tcp-environ.0 + +tcpto.o: \ +compile tcpto.c tcpto.h open.h lock.h seek.h now.h datetime.h ip.h \ +byte.h datetime.h readwrite.h + ./compile tcpto.c + +tcpto_clean.o: \ +compile tcpto_clean.c tcpto.h open.h substdio.h readwrite.h + ./compile tcpto_clean.c + +timeoutconn.o: \ +compile timeoutconn.c ndelay.h select.h error.h readwrite.h ip.h \ +byte.h timeoutconn.h + ./compile timeoutconn.c + +timeoutread.o: \ +compile timeoutread.c timeoutread.h select.h error.h readwrite.h + ./compile timeoutread.c + +timeoutwrite.o: \ +compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h + ./compile timeoutwrite.c + +token822.o: \ +compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \ +gen_alloc.h gen_allocdefs.h + ./compile token822.c + +trigger.o: \ +compile trigger.c select.h open.h trigger.h hasnpbg1.h + ./compile trigger.c + +triggerpull.o: \ +compile triggerpull.c ndelay.h open.h triggerpull.h + ./compile triggerpull.c + +uint32.h: \ +tryulong32.c compile load uint32.h1 uint32.h2 + ( ( ./compile tryulong32.c && ./load tryulong32 && \ + ./tryulong32 ) >/dev/null 2>&1 \ + && cat uint32.h2 || cat uint32.h1 ) > uint32.h + rm -f tryulong32.o tryulong32 + +wait.a: \ +makelib wait_pid.o wait_nohang.o + ./makelib wait.a wait_pid.o wait_nohang.o + +wait_nohang.o: \ +compile wait_nohang.c haswaitp.h + ./compile wait_nohang.c + +wait_pid.o: \ +compile wait_pid.c error.h haswaitp.h + ./compile wait_pid.c diff -urN ../../netqmail-1.05-orig/netqmail-1.05/README.auth ./README.auth --- ../../netqmail-1.05-orig/netqmail-1.05/README.auth 1969-12-31 16:00:00.000000000 -0800 +++ ./README.auth 2006-01-05 15:23:08.877054128 -0800 @@ -0,0 +1,66 @@ +README qmail-smtpd SMTP Authentication +====================================== + + +History: +-------- + +This patch is based on Krzysztof Dabrowski's qmail-smtpd-auth-0.31 patch +which itself uses "Mrs. Brisby's" initial code. +Version 0.41 of this patch fixes the "CAPS-LOCK" typo announcing +'CRAM_MD5' instead of 'CRAM-MD5' (german keyboard) - tx to Mike Garrison. +Version 0.42 fixes the '421 unable to read controls (#4.3.0)' problem +(can't read control/morercpthosts.cdb) because FD 3 was already closed - tx Richard Lyons. +Version 0.43 fixes the ba64decode() failure in case CRAM_MD5 is not enabled - tx Vladimir Zidar. +Version 0.51 includes the evaluation of the 'Auth' and the 'Size' parameter in the 'Mail From:' command. +Version 0.52 uses DJB functions to copy FDs. +Version 0.56 corrects some minor mistakes displaying the 'Auth' userid. +Version 0.57 uses keyword "ESMTPA" in Received header in case of authentication to comply with RFC 3848. + + +Scope: +------ + +This patch supports RFC 2554 "SMTP Service Extension for Authentication" for qmail-smtpd. +Additionally, RFC 1870 is honoured ("SMTP Service Extension for Message Size Declaration"). +For more technical details see: http://www.fehcom.de/qmail/docu/smtpauth.html. + + +Installation: +------------- + +* Untar the source in the qmail-1.03 home direcotry. +* Run ./install_auth. +* Modify the compile time option "#define CRAM_MD5" to your needs. +* Re-make qmail. + + +Setup: +------ + +In order to use SMTP Authentication you have to use a 'Pluggable Authentication Module' +PAM to be called by qmail-smtpd; typically + + /var/qmail/bin/qmail-smtpd /bin/checkpassword true 2>&1 + +Since qmail-smtpd does not run as root, checkpassword has to be made sticky. +There is no need to include additionally the hostname in the call. +In order to compute the CRAM-MD5 challenge, qmail-smtpd uses the 'tcplocalhost' information. + + +Changes wrt. Krysztof Dabrowski's patch: +---------------------------------------- + +* Avoid the 'hostname' in the call of the PAM. +* Confirm to Dan Bernstein's checkpassword interface even for CRAM-MD5. +* Doesn't close FD 2; thus not inhibiting logging to STDERR. +* Fixed bugs in base64.c. +* Modified unconditional close of FD 3 in order to sustain reading of 'control/morecpthosts.cdb'. +* Evaluation of the (informational) Mail From: < > Auth=username. +* Additional support for the advertised "Size" via 'Mail From: SIZE=123456780' (RFC 1870). +* RFC 3848 conformance for Received header in case of SMTP Auth. + + +Erwin Hoffmann - Cologne 2005-01-23 (www.fehcom.de) + + diff -urN ../../netqmail-1.05-orig/netqmail-1.05/TARGETS ./TARGETS --- ../../netqmail-1.05-orig/netqmail-1.05/TARGETS 1998-06-15 03:53:16.000000000 -0700 +++ ./TARGETS 2006-01-05 15:23:08.879053824 -0800 @@ -10,6 +10,7 @@ qmail.o quote.o now.o +base64.o gfrom.o myctime.o slurpclose.o @@ -168,6 +169,8 @@ constmap.o timeoutread.o timeoutwrite.o +tls.o +ssl_timeoutio.o timeoutconn.o tcpto.o dns.o @@ -320,6 +323,7 @@ binm2+df binm3 binm3+df +Makefile-cert it qmail-local.0 qmail-lspawn.0 @@ -385,3 +389,4 @@ man setup check +update_tmprsadh diff -urN ../../netqmail-1.05-orig/netqmail-1.05/base64.c ./base64.c --- ../../netqmail-1.05-orig/netqmail-1.05/base64.c 1969-12-31 16:00:00.000000000 -0800 +++ ./base64.c 2006-01-05 15:23:08.883053216 -0800 @@ -0,0 +1,122 @@ +#include "base64.h" +#include "stralloc.h" +#include "substdio.h" +#include "str.h" + +static char *b64alpha = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#define B64PAD '=' + +/* returns 0 ok, 1 illegal, -1 problem */ + +int b64decode(in,l,out) +const unsigned char *in; +int l; +stralloc *out; /* not null terminated */ +{ + int p = 0; + int n; + unsigned int x; + int i, j; + char *s; + unsigned char b[3]; + + if (l == 0) + { + if (!stralloc_copys(out,"")) return -1; + return 0; + } + + while(in[l-1] == B64PAD) { + p ++; + l--; + } + + n = (l + p) / 4; + out->len = (n * 3) - p; + if (!stralloc_ready(out,out->len)) return -1; + s = out->s; + + for(i = 0; i < n - 1 ; i++) { + x = 0; + for(j = 0; j < 4; j++) { + if(in[j] >= 'A' && in[j] <= 'Z') + x = (x << 6) + (unsigned int)(in[j] - 'A' + 0); + else if(in[j] >= 'a' && in[j] <= 'z') + x = (x << 6) + (unsigned int)(in[j] - 'a' + 26); + else if(in[j] >= '0' && in[j] <= '9') + x = (x << 6) + (unsigned int)(in[j] - '0' + 52); + else if(in[j] == '+') + x = (x << 6) + 62; + else if(in[j] == '/') + x = (x << 6) + 63; + else if(in[j] == '=') + x = (x << 6); + } + + s[2] = (unsigned char)(x & 255); x >>= 8; + s[1] = (unsigned char)(x & 255); x >>= 8; + s[0] = (unsigned char)(x & 255); x >>= 8; + s += 3; in += 4; + } + + x = 0; + for(j = 0; j < 4; j++) { + if(in[j] >= 'A' && in[j] <= 'Z') + x = (x << 6) + (unsigned int)(in[j] - 'A' + 0); + else if(in[j] >= 'a' && in[j] <= 'z') + x = (x << 6) + (unsigned int)(in[j] - 'a' + 26); + else if(in[j] >= '0' && in[j] <= '9') + x = (x << 6) + (unsigned int)(in[j] - '0' + 52); + else if(in[j] == '+') + x = (x << 6) + 62; + else if(in[j] == '/') + x = (x << 6) + 63; + else if(in[j] == '=') + x = (x << 6); + } + + b[2] = (unsigned char)(x & 255); x >>= 8; + b[1] = (unsigned char)(x & 255); x >>= 8; + b[0] = (unsigned char)(x & 255); x >>= 8; + + for(i = 0; i < 3 - p; i++) + s[i] = b[i]; + + return 0; +} + +int b64encode(in,out) +stralloc *in; +stralloc *out; /* not null terminated */ +{ + unsigned char a, b, c; + int i; + char *s; + + if (in->len == 0) + { + if (!stralloc_copys(out,"")) return -1; + return 0; + } + + if (!stralloc_ready(out,in->len / 3 * 4 + 4)) return -1; + s = out->s; + + for (i = 0;i < in->len;i += 3) { + a = in->s[i]; + b = i + 1 < in->len ? in->s[i + 1] : 0; + c = i + 2 < in->len ? in->s[i + 2] : 0; + + *s++ = b64alpha[a >> 2]; + *s++ = b64alpha[((a & 3 ) << 4) | (b >> 4)]; + + if (i + 1 >= in->len) *s++ = B64PAD; + else *s++ = b64alpha[((b & 15) << 2) | (c >> 6)]; + + if (i + 2 >= in->len) *s++ = B64PAD; + else *s++ = b64alpha[c & 63]; + } + out->len = s - out->s; + return 0; +} diff -urN ../../netqmail-1.05-orig/netqmail-1.05/base64.h ./base64.h --- ../../netqmail-1.05-orig/netqmail-1.05/base64.h 1969-12-31 16:00:00.000000000 -0800 +++ ./base64.h 2006-01-05 15:23:08.884053064 -0800 @@ -0,0 +1,7 @@ +#ifndef BASE64_H +#define BASE64_H + +extern int b64decode(); +extern int b64encode(); + +#endif diff -urN ../../netqmail-1.05-orig/netqmail-1.05/case_startb.c ./case_startb.c --- ../../netqmail-1.05-orig/netqmail-1.05/case_startb.c 1969-12-31 16:00:00.000000000 -0800 +++ ./case_startb.c 2006-01-05 15:23:08.885052912 -0800 @@ -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 -urN ../../netqmail-1.05-orig/netqmail-1.05/conf-cc ./conf-cc --- ../../netqmail-1.05-orig/netqmail-1.05/conf-cc 1998-06-15 03:53:16.000000000 -0700 +++ ./conf-cc 2006-01-05 15:27:25.785998032 -0800 @@ -1,3 +1,3 @@ -cc -O2 +cc -O2 -DTLS=20060104 -I/usr/local/ssl/include This will be used to compile .c files. diff -urN ../../netqmail-1.05-orig/netqmail-1.05/dns.c ./dns.c --- ../../netqmail-1.05-orig/netqmail-1.05/dns.c 2006-01-05 15:28:41.096549088 -0800 +++ ./dns.c 2006-01-05 15:23:08.887052608 -0800 @@ -267,12 +267,11 @@ 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; @@ -291,9 +290,16 @@ ix.ip = ip; ix.pref = pref; if (r == DNS_SOFT) return DNS_SOFT; - if (r == 1) + if (r == 1) { +#ifdef IX_FQDN + ix.fqdn = glue.s; +#endif if (!ipalloc_append(ia,&ix)) return DNS_MEM; } + } +#ifdef IX_FQDN + glue.s = 0; +#endif return 0; } @@ -313,7 +319,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; @@ -325,7 +331,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; diff -urN ../../netqmail-1.05-orig/netqmail-1.05/hier.c ./hier.c --- ../../netqmail-1.05-orig/netqmail-1.05/hier.c 1998-06-15 03:53:16.000000000 -0700 +++ ./hier.c 2006-01-05 15:23:08.888052456 -0800 @@ -143,6 +143,9 @@ c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755); c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755); c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755); +#ifdef TLS + c(auto_qmail,"bin","update_tmprsadh",auto_uido,auto_gidq,0755); +#endif c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644); c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644); diff -urN ../../netqmail-1.05-orig/netqmail-1.05/install_auth.sh ./install_auth.sh --- ../../netqmail-1.05-orig/netqmail-1.05/install_auth.sh 1969-12-31 16:00:00.000000000 -0800 +++ ./install_auth.sh 2006-01-05 15:23:08.890052152 -0800 @@ -0,0 +1,99 @@ +#!/bin/sh +# +# qmail-smtpd AUTH (UN)INSTALL Script (install_auth.sh) +# ----------------------------------------------------- +# +# Purpose: To install and uninstall the qmail-smtpd Authentication Patch +# +# Parameters: -u (uninstall) +# VRF (Version to be uninstalled) +# +# Usage: ./install_auth.sh [-u] [Version] +# +# Installation: ./install_auth.sh +# Uninstallation: ./install_auth.sh -u 105 +# +# Return Codes: 0 - Patches applied successfully +# 1 - Original QMAIL files not found (Patch not extracted in QMAIL source directory) +# 2 - Patch files not found +# +# Output: install_auth.log +# +# History: 1.0.0 - Erwin Hoffmann - Initial release +# 1.0.1 - - grep fix; Gentoo fix +# 1.0.2 - removed '-v' optio for cp +# +#--------------------------------------------------------------------------------------- +# +DATE=$(date) +LOCDIR=${PWD} +QMAILHOME=$(head -n 1 conf-qmail) +SOLARIS=$(sh ./find-systype.sh | grep -ci "SunOS") +LOGFILE=auth.log +TARGETS=FILES.auth +IFSKEEP=${IFS} +REL=057 # Should be identical to qmail-smtpd AUTH level +BUILD=2005024212941 + + +if [ $# -eq 0 ] ; then + + echo "Installing qmail-smtpd AUTH $REL (Build $BUILD) at $DATE <<<" | tee -a $LOGFILE 2>&1 + + for FILE in $(grep "^= " ${TARGETS} | awk '{print $2}'); do + echo "Targeting file $FILE ..." | tee -a $LOGFILE 2>&1 + if [ -s ${FILE} ] ; then + cp ${FILE} ${FILE}.$REL | tee -a $LOGFILE 2>&1 + echo "--> ${FILE} copied to ${FILE}.$REL" | tee -a $LOGFILE 2>&1 + else + echo "${FILE} not found !" + exit 1 + fi + if [ -s ${FILE}.patch ] ; then + if [ ${SOLARIS} -gt 0 ]; then + echo "--> Patching qmail source file ${FILE} for Solaris ...." | tee -a $LOGFILE 2>&1 + patch -i ${FILE}.patch ${FILE} 2>&1 | tee -a $LOGFILE + else + echo "--> Patching qmail source file ${FILE} ...." | tee -a $LOGFILE 2>&1 + patch ${FILE} ${FILE}.patch 2>&1 | tee -a $LOGFILE + fi + else + echo "!! ${FILE}.patch not found !" + exit 2 + fi + done + + + echo "Copying documentation and samples to ${QMAILHOME}/doc/ ..." | tee -a $LOGFILE 2>&1 + + cp README.auth* ${QMAILHOME}/doc/ | tee -a $LOGFILE 2>&1 + echo "" + echo "If you dont wont CRAM-MD5 suport disable '#define CRAM_MD5' in qmail-smtpd !" + echo "Installation of qmail-smtpd AUTH $REL (Build $BUILD) finished at $DATE <<<" | tee -a $LOGFILE 2>&1 + +# Now go for the uninstallation.... + +elif [ "$1" = "-u" ] ; then + +# Get the Version Number from INPUT + + if [ $# -eq 2 ] ; then + REL=$2 + fi + + echo "De-installing qmail-smtpd AUTH $REL (Build $BUILD) at $DATE <<<" | tee -a $LOGFILE 2>&1 + + for FILE in $(grep "^= " ${TARGETS} | awk '{print $2}'); do + echo "Targeting file $FILE ..." | tee -a $LOGFILE 2>&1 + if [ -s ${FILE}.$REL ] ; then + mv ${FILE}.$REL ${FILE} | tee -a $LOGFILE 2>&1 + touch ${FILE} + echo "--> ${FILE}.$REL moved to ${FILE}" | tee -a $LOGFILE 2>&1 + else + echo "!! ${FILE}.$REL not found !" + fi + done + echo "De-installation of qmail-smtpd AUTH $REL (Build $BUILD) finished at $DATE <<<" | tee -a $LOGFILE 2>&1 +fi + +exit 0 diff -urN ../../netqmail-1.05-orig/netqmail-1.05/ipalloc.h ./ipalloc.h --- ../../netqmail-1.05-orig/netqmail-1.05/ipalloc.h 1998-06-15 03:53:16.000000000 -0700 +++ ./ipalloc.h 2006-01-05 15:23:08.891052000 -0800 @@ -3,7 +3,15 @@ #include "ip.h" +#ifdef TLS +# define IX_FQDN 1 +#endif + +#ifdef IX_FQDN +struct ip_mx { struct ip_address ip; int pref; char *fqdn; } ; +#else struct ip_mx { struct ip_address ip; int pref; } ; +#endif #include "gen_alloc.h" diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-control.9 ./qmail-control.9 --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-control.9 1998-06-15 03:53:16.000000000 -0700 +++ ./qmail-control.9 2006-01-05 15:23:08.892051848 -0800 @@ -43,11 +43,15 @@ .I badmailfrom \fR(none) \fRqmail-smtpd .I bouncefrom \fRMAILER-DAEMON \fRqmail-send .I bouncehost \fIme \fRqmail-send +.I clientca.pem \fR(none) \fRqmail-smtpd +.I clientcert.pem \fR(none) \fRqmail-remote .I concurrencylocal \fR10 \fRqmail-send .I concurrencyremote \fR20 \fRqmail-send .I defaultdomain \fIme \fRqmail-inject .I defaulthost \fIme \fRqmail-inject .I databytes \fR0 \fRqmail-smtpd +.I dh1024.pem \fR(none) \fRqmail-smtpd +.I dh512.pem \fR(none) \fRqmail-smtpd .I doublebouncehost \fIme \fRqmail-send .I doublebounceto \fRpostmaster \fRqmail-send .I envnoathost \fIme \fRqmail-send @@ -61,11 +65,17 @@ .I qmqpservers \fR(none) \fRqmail-qmqpc .I queuelifetime \fR604800 \fRqmail-send .I rcpthosts \fR(none) \fRqmail-smtpd +.I rsa512.pem \fR(none) \fRqmail-smtpd +.I servercert.pem \fR(none) \fRqmail-smtpd .I smtpgreeting \fIme \fRqmail-smtpd .I smtproutes \fR(none) \fRqmail-remote .I timeoutconnect \fR60 \fRqmail-remote .I timeoutremote \fR1200 \fRqmail-remote .I timeoutsmtpd \fR1200 \fRqmail-smtpd +.I tlsclients \fR(none) \fRqmail-smtpd +.I tlsclientciphers \fR(none) \fRqmail-remote +.I tlshosts/FQDN.pem \fR(none) \fRqmail-remote +.I tlsserverciphers \fR(none) \fRqmail-smtpd .I virtualdomains \fR(none) \fRqmail-send .fi .RE diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-remote.8 ./qmail-remote.8 --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-remote.8 1998-06-15 03:53:16.000000000 -0700 +++ ./qmail-remote.8 2006-01-05 15:23:08.893051696 -0800 @@ -114,6 +114,10 @@ always exits zero. .SH "CONTROL FILES" .TP 5 +.I clientcert.pem +SSL certificate that is used to authenticate with the remote server +during a TLS session. +.TP 5 .I helohost Current host name, for use solely in saying hello to the remote SMTP server. @@ -123,6 +127,16 @@ otherwise .B qmail-remote refuses to run. + +.TP 5 +.I notlshosts/ +.B qmail-remote +will not try TLS on servers for which this file exists +.RB ( +is the fully-qualified domain name of the server). +.IR (tlshosts/.pem +takes precedence over this file however). + .TP 5 .I smtproutes Artificial SMTP routes. @@ -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,33 @@ .B qmail-remote will wait for each response from the remote SMTP server. Default: 1200. + +.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 TLS 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. + +.TP 5 +.I tlshosts/exhaustivelist +if this file exists +no TLS will be tried on hosts other than those for which a file +.B tlshosts/.pem +exists. + .SH "SEE ALSO" addresses(5), envelopes(5), diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-remote.c ./qmail-remote.c --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-remote.c 1998-06-15 03:53:16.000000000 -0700 +++ ./qmail-remote.c 2006-01-05 15:27:25.787997728 -0800 @@ -48,6 +48,17 @@ struct ip_address partner; +#ifdef TLS +# include +# include "tls.h" +# include "ssl_timeoutio.h" +# include +# define EHLO 1 + +int tls_init(); +const char *ssl_err_str = 0; +#endif + 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); } @@ -99,6 +110,9 @@ outhost(); out(" but connection died. "); if (flagcritical) out("Possible duplicate! "); +#ifdef TLS + if (ssl_err_str) { out(ssl_err_str); out(" "); } +#endif out("(#4.4.2)\n"); zerodie(); } @@ -110,6 +124,12 @@ int saferead(fd,buf,len) int fd; char *buf; int len; { int r; +#ifdef TLS + if (ssl) { + r = ssl_timeoutread(timeout, smtpfd, smtpfd, ssl, buf, len); + if (r < 0) ssl_err_str = ssl_error_str(); + } else +#endif r = timeoutread(timeout,smtpfd,buf,len); if (r <= 0) dropped(); return r; @@ -117,6 +137,12 @@ int safewrite(fd,buf,len) int fd; char *buf; int len; { int r; +#ifdef TLS + if (ssl) { + r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len); + if (r < 0) ssl_err_str = ssl_error_str(); + } else +#endif r = timeoutwrite(timeout,smtpfd,buf,len); if (r <= 0) dropped(); return r; @@ -163,6 +189,65 @@ return code; } +#ifdef EHLO +saa ehlokw = {0}; /* list of EHLO keywords and parameters */ +int maxehlokwlen = 0; + +unsigned long ehlo() +{ + stralloc *sa; + char *s, *e, *p; + unsigned long code; + + if (ehlokw.len > maxehlokwlen) maxehlokwlen = ehlokw.len; + ehlokw.len = 0; + +# ifdef MXPS + if (type == 's') return 0; +# endif + + substdio_puts(&smtpto, "EHLO "); + substdio_put(&smtpto, helohost.s, helohost.len); + substdio_puts(&smtpto, "\r\n"); + substdio_flush(&smtpto); + + 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) + { + int wasspace = 0; + + 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 (!wasspace) + if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem(); + if (*p == '\n') break; + wasspace = 1; + } else if (wasspace == 1) { + wasspace = 0; + 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; +} +#endif + void outsmtptext() { int i; @@ -179,6 +264,11 @@ char *prepend; char *append; { +#ifdef TLS + /* shouldn't talk to the client unless in an appropriate state */ + int state = ssl ? ssl->state : SSL_ST_BEFORE; + if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE)) +#endif substdio_putsflush(&smtpto,"QUIT\r\n"); /* waiting for remote side is just too ridiculous */ out(prepend); @@ -186,6 +276,30 @@ out(append); out(".\n"); outsmtptext(); + +#if defined(TLS) && defined(DEBUG) + if (ssl) { + X509 *peercert; + + out("STARTTLS proto="); out(SSL_get_version(ssl)); + out("; cipher="); out(SSL_get_cipher(ssl)); + + /* we want certificate details */ + if (peercert = SSL_get_peer_certificate(ssl)) { + char *str; + + str = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0); + out("; subject="); out(str); OPENSSL_free(str); + + str = X509_NAME_oneline(X509_get_issuer_name(peercert), NULL, 0); + out("; issuer="); out(str); OPENSSL_free(str); + + X509_free(peercert); + } + out(";\n"); + } +#endif + zerodie(); } @@ -214,6 +328,194 @@ substdio_flush(&smtpto); } +#ifdef TLS +char *partner_fqdn = 0; + +# define TLS_QUIT quit(ssl ? "; connected to " : "; connecting to ", "") +void tls_quit(const char *s1, const char *s2) +{ + out(s1); if (s2) { out(": "); out(s2); } TLS_QUIT; +} +# define tls_quit_error(s) tls_quit(s, ssl_error()) + +int match_partner(const char *s, int len) +{ + if (!case_diffb(partner_fqdn, len, s) && !partner_fqdn[len]) return 1; + /* we also match if the name is *.domainname */ + if (*s == '*') { + const char *domain = partner_fqdn + str_chr(partner_fqdn, '.'); + if (!case_diffb(domain, --len, ++s) && !domain[len]) return 1; + } + return 0; +} + +/* don't want to fail handshake if certificate can't be verified */ +int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } + +int tls_init() +{ + int i; + SSL *myssl; + SSL_CTX *ctx; + stralloc saciphers = {0}; + const char *ciphers, *servercert = 0; + + if (partner_fqdn) { + struct stat st; + stralloc tmp = {0}; + if (!stralloc_copys(&tmp, "control/tlshosts/") + || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)) + || !stralloc_catb(&tmp, ".pem", 5)) temp_nomem(); + if (stat(tmp.s, &st) == 0) + servercert = tmp.s; + else { + if (!stralloc_copys(&tmp, "control/notlshosts/") + || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)+1)) + temp_nomem(); + if ((stat("control/tlshosts/exhaustivelist", &st) == 0) || + (stat(tmp.s, &st) == 0)) { + alloc_free(tmp.s); + return 0; + } + alloc_free(tmp.s); + } + } + + if (!smtps) { + stralloc *sa = ehlokw.sa; + unsigned int len = ehlokw.len; + /* look for STARTTLS among EHLO keywords */ + for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ; + if (!len) { + if (!servercert) return 0; + out("ZNo TLS achieved while "); out(servercert); + out(" exists"); smtptext.len = 0; TLS_QUIT; + } + } + + SSL_library_init(); + ctx = SSL_CTX_new(SSLv23_client_method()); + if (!ctx) { + if (!smtps && !servercert) return 0; + smtptext.len = 0; + tls_quit_error("ZTLS error initializing ctx"); + } + + if (servercert) { + if (!SSL_CTX_load_verify_locations(ctx, servercert, NULL)) { + SSL_CTX_free(ctx); + smtptext.len = 0; + out("ZTLS unable to load "); tls_quit_error(servercert); + } + /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb); + } + + /* let the other side complain if it needs a cert and we don't have one */ +# define CLIENTCERT "control/clientcert.pem" + if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT)) + SSL_CTX_use_RSAPrivateKey_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM); +# undef CLIENTCERT + + myssl = SSL_new(ctx); + SSL_CTX_free(ctx); + if (!myssl) { + if (!smtps && !servercert) return 0; + smtptext.len = 0; + tls_quit_error("ZTLS error initializing ssl"); + } + + if (!smtps) substdio_putsflush(&smtpto, "STARTTLS\r\n"); + + /* while the server is preparing a responce, do something else */ + if (control_readfile(&saciphers, "control/tlsclientciphers", 0) == -1) + { SSL_free(myssl); temp_control(); } + if (saciphers.len) { + for (i = 0; i < saciphers.len - 1; ++i) + if (!saciphers.s[i]) saciphers.s[i] = ':'; + ciphers = saciphers.s; + } + else ciphers = "DEFAULT"; + SSL_set_cipher_list(myssl, ciphers); + alloc_free(saciphers.s); + + /* SSL_set_options(myssl, SSL_OP_NO_TLSv1); */ + SSL_set_fd(myssl, smtpfd); + + /* read the responce to STARTTLS */ + if (!smtps) { + if (smtpcode() != 220) { + SSL_free(myssl); + if (!servercert) return 0; + out("ZSTARTTLS rejected while "); + out(servercert); out(" exists"); TLS_QUIT; + } + smtptext.len = 0; + } + + ssl = myssl; + if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0) + tls_quit("ZTLS connect failed", ssl_error_str()); + + if (servercert) { + X509 *peercert; + STACK_OF(GENERAL_NAME) *gens; + + int r = SSL_get_verify_result(ssl); + if (r != X509_V_OK) { + out("ZTLS unable to verify server with "); + tls_quit(servercert, X509_verify_cert_error_string(r)); + } + alloc_free(servercert); + + peercert = SSL_get_peer_certificate(ssl); + if (!peercert) { + out("ZTLS unable to verify server "); + tls_quit(partner_fqdn, "no certificate provided"); + } + + /* RFC 2595 section 2.4: find a matching name + * first find a match among alternative names */ + gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0); + if (gens) { + for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i) + { + const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i); + if (gn->type == GEN_DNS) + if (match_partner(gn->d.ia5->data, gn->d.ia5->length)) break; + } + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + } + + /* no alternative name matched, look up commonName */ + if (!gens || i >= r) { + stralloc peer = {0}; + X509_NAME *subj = X509_get_subject_name(peercert); + i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1); + if (i >= 0) { + const ASN1_STRING *s = X509_NAME_get_entry(subj, i)->value; + if (s) { peer.len = s->length; peer.s = s->data; } + } + if (peer.len <= 0) { + out("ZTLS unable to verify server "); + tls_quit(partner_fqdn, "certificate contains no valid commonName"); + } + if (!match_partner(peer.s, peer.len)) { + out("ZTLS unable to verify server "); out(partner_fqdn); + out(": received certificate for "); outsafe(&peer); TLS_QUIT; + } + } + + X509_free(peercert); + } + + if (smtps) if (smtpcode() != 220) + quit("ZTLS Connected to "," but greeting failed"); + + return 1; +} +#endif + stralloc recip = {0}; void smtp() @@ -221,15 +523,54 @@ unsigned long code; int flagbother; int i; + +#ifndef PORT_SMTP + /* the qmtpc patch uses smtp_port and undefines PORT_SMTP */ +# define port smtp_port +#endif + +#ifdef TLS +# ifdef MXPS + if (type == 'S') smtps = 1; + else if (type != 's') +# endif + if (port == 465) smtps = 1; + if (!smtps) +#endif if (smtpcode() != 220) quit("ZConnected to "," but greeting failed"); +#ifdef EHLO +# ifdef TLS + if (!smtps) +# endif + code = ehlo(); + +# ifdef TLS + if (tls_init()) + /* RFC2487 says we should issue EHLO (even if we might not need + * extensions); at the same time, it does not prohibit a server + * to reject the EHLO and make us fallback to HELO */ + code = ehlo(); +# endif + + if (code == 250) { + /* add EHLO response checks here */ + + /* and if EHLO failed, use HELO */ + } else { +#endif + 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"); +#ifdef EHLO + } +#endif + substdio_puts(&smtpto,"MAIL FROM:<"); substdio_put(&smtpto,sender.s,sender.len); substdio_puts(&smtpto,">\r\n"); @@ -417,6 +758,9 @@ if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) { tcpto_err(&ip.ix[i].ip,0); partner = ip.ix[i].ip; +#ifdef TLS + partner_fqdn = ip.ix[i].fqdn; +#endif smtp(); /* does not return */ } tcpto_err(&ip.ix[i].ip,errno == error_timeout); diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.8 ./qmail-smtpd.8 --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.8 1998-06-15 03:53:16.000000000 -0700 +++ ./qmail-smtpd.8 2006-01-05 15:23:08.897051088 -0800 @@ -14,6 +14,15 @@ see .BR tcp-environ(5) . +If the environment variable +.B SMTPS +is non-empty, +.B qmail-smtpd +starts a TLS session (to support the deprecated SMTPS protocol, +normally on port 465). Otherwise, +.B qmail-smtpd +offers the STARTTLS extension to ESMTP. + .B qmail-smtpd is responsible for counting hops. It rejects any message with 100 or more @@ -23,7 +32,30 @@ header fields. .B qmail-smtpd -supports ESMTP, including the 8BITMIME and PIPELINING options. +supports ESMTP, including the 8BITMIME, DATA, PIPELINING, SIZE, and AUTH options. +.B qmail-smtpd +includes a \'MAIL FROM:\' parameter parser and obeys \'Auth\' and \'Size\' advertisements. +.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 CRAM-MD5 digest/response derived from the SMTP client, +another 0 byte, a CRAM-MD5 challenge (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 @@ -49,6 +81,19 @@ .BR @\fIhost , meaning every address at .IR host . + +.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 clientcrl.pem +A list of Certificate Revocation Lists (CRLs). If present it +should contain the CRLs of the CAs in +.I clientca.pem +and client certs will be checked for revocation. + .TP 5 .I databytes Maximum number of bytes allowed in a message, @@ -76,6 +121,18 @@ .B DATABYTES is set, it overrides .IR databytes . + +.TP 5 +.I dh1024.pem +If these 1024 bit DH parameters are provided, +.B qmail-smtpd +will use them for TLS sessions instead of generating one on-the-fly +(which is very timeconsuming). +.TP 5 +.I dh512.pem +512 bit counterpart for +.B dh1024.pem. + .TP 5 .I localiphost Replacement host name for local IP addresses. @@ -151,6 +208,19 @@ Envelope recipient addresses without @ signs are always allowed through. + +.TP 5 +.I rsa512.pem +If this 512 bit RSA key is provided, +.B qmail-smtpd +will use it for TLS sessions instead of generating one on-the-fly. + +.TP 5 +.I servercert.pem +SSL certificate to be presented to clients in TLS-encrypted sessions. +Should contain both the certificate and the private key. Certifying Authority +(CA) and intermediate certificates can be added at the end of the file. + .TP 5 .I smtpgreeting SMTP greeting message. @@ -169,6 +239,24 @@ .B qmail-smtpd will wait for each new buffer of data from the remote SMTP client. Default: 1200. + +.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 "SEE ALSO" tcp-env(1), tcp-environ(5), diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.8.056 ./qmail-smtpd.8.056 --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.8.056 1969-12-31 16:00:00.000000000 -0800 +++ ./qmail-smtpd.8.056 2006-01-05 15:23:08.899050784 -0800 @@ -0,0 +1,179 @@ +.TH qmail-smtpd 8 +.SH NAME +qmail-smtpd \- receive mail via SMTP +.SH SYNOPSIS +.B qmail-smtpd +.SH DESCRIPTION +.B qmail-smtpd +receives mail messages via the Simple Mail Transfer Protocol (SMTP) +and invokes +.B qmail-queue +to deposit them into the outgoing queue. +.B qmail-smtpd +must be supplied several environment variables; +see +.BR tcp-environ(5) . + +.B qmail-smtpd +is responsible for counting hops. +It rejects any message with 100 or more +.B Received +or +.B Delivered-To +header fields. + +.B qmail-smtpd +supports ESMTP, including the 8BITMIME and PIPELINING options. +.SH TRANSPARENCY +.B qmail-smtpd +converts the SMTP newline convention into the UNIX newline convention +by converting CR LF into LF. +It returns a temporary error and drops the connection on bare LFs; +see +.BR http://pobox.com/~djb/docs/smtplf.html . + +.B qmail-smtpd +accepts messages that contain long lines or non-ASCII characters, +even though such messages violate the SMTP protocol. +.SH "CONTROL FILES" +.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 . +.TP 5 +.I databytes +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 +.B qmail-smtpd +hits a resource limit, +.B qmail-smtpd +returns a temporary error code. + +.I databytes +counts bytes as stored on disk, not as transmitted through the network. +It does not count the +.B qmail-smtpd +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 localiphost +Replacement host name for local IP addresses. +Default: +.IR me , +if that is supplied. +.B qmail-smtpd +is responsible for recognizing dotted-decimal addresses for the +current host. +When it sees a recipient address of the form +.IR box@[d.d.d.d] , +where +.I d.d.d.d +is a local IP address, +it replaces +.IR [d.d.d.d] +with +.IR localiphost . +This is done before +.IR rcpthosts . +.TP 5 +.I morercpthosts +Extra allowed RCPT domains. +If +.I rcpthosts +and +.I morercpthosts +both exist, +.I morercpthosts +is effectively appended to +.IR rcpthosts . + +You must run +.B qmail-newmrh +whenever +.I morercpthosts +changes. + +Rule of thumb for large sites: +Put your 50 most commonly used domains into +.IR rcpthosts , +and the rest into +.IR morercpthosts . +.TP 5 +.I rcpthosts +Allowed RCPT domains. +If +.I rcpthosts +is supplied, +.B qmail-smtpd +will reject +any envelope recipient address with a domain not listed in +.IR rcpthosts . + +Exception: +If the environment variable +.B RELAYCLIENT +is set, +.B qmail-smtpd +will ignore +.IR rcpthosts , +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. +Default: +.IR me , +if that is supplied; +otherwise +.B qmail-smtpd +will refuse to run. +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. +.SH "SEE ALSO" +tcp-env(1), +tcp-environ(5), +qmail-control(5), +qmail-inject(8), +qmail-newmrh(8), +qmail-queue(8), +qmail-remote(8) diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.c ./qmail-smtpd.c --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.c 2006-01-05 15:28:41.109547112 -0800 +++ ./qmail-smtpd.c 2006-01-05 15:27:25.790997272 -0800 @@ -23,14 +23,34 @@ #include "timeoutread.h" #include "timeoutwrite.h" #include "commands.h" +#include "wait.h" + +#define CRAM_MD5 +#define AUTHSLEEP 5 #define MAXHOPS 100 unsigned int databytes = 0; int timeout = 1200; +#ifdef TLS +#include +#include "tls.h" +#include "ssl_timeoutio.h" + +void tls_init(); +int tls_verify(); +void tls_nogateway(); +int ssl_rfd = -1, ssl_wfd = -1; /* SSL_get_Xfd() are broken */ +#endif + int safewrite(fd,buf,len) int fd; char *buf; int len; { int r; +#ifdef TLS + if (ssl && fd == ssl_wfd) + r = ssl_timeoutwrite(timeout, ssl_rfd, ssl_wfd, ssl, buf, len); + else +#endif r = timeoutwrite(timeout,fd,buf,len); if (r <= 0) _exit(1); return r; @@ -49,8 +69,18 @@ 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_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); } void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } +#ifndef TLS void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } +#else +void err_nogateway() +{ + out("553 sorry, that domain isn't in my list of allowed rcpthosts"); + tls_nogateway(); + out(" (#5.7.1)\r\n"); +} +#endif void err_unimpl(arg) char *arg; { 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"); } @@ -59,6 +89,16 @@ void err_vrfy(arg) char *arg; { 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 canceled (#5.0.0)\r\n"); return -1; } +int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; } +void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); } stralloc greeting = {0}; @@ -76,6 +116,7 @@ smtp_greet("221 "); out("\r\n"); flush(); _exit(0); } +char *protocol; char *remoteip; char *remotehost; char *remoteinfo; @@ -109,7 +150,6 @@ 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(); bmfok = control_readfile(&bmf,"control/badmailfrom",0); @@ -122,6 +162,7 @@ if (x) { scan_ulong(x,&u); databytes = u; } if (!(databytes + 1)) --databytes; + protocol = "SMTP"; remoteip = env_get("TCPREMOTEIP"); if (!remoteip) remoteip = "unknown"; local = env_get("TCPLOCALHOST"); @@ -131,6 +172,11 @@ if (!remotehost) remotehost = "unknown"; remoteinfo = env_get("TCPREMOTEINFO"); relayclient = env_get("RELAYCLIENT"); + +#ifdef TLS + if (env_get("SMTPS")) { smtps = 1; tls_init(); } + else +#endif dohelo(remotehost); } @@ -213,23 +259,105 @@ int r; r = rcpthosts(addr.s,str_len(addr.s)); if (r == -1) die_control(); +#ifdef TLS + if (r == 0) if (tls_verify()) r = -2; +#endif return r; } int seenmail = 0; int flagbarf; /* defined if seenmail */ +int flagsize; stralloc mailfrom = {0}; stralloc rcptto = {0}; +stralloc fuser = {0}; +stralloc mfparms = {0}; + +int mailfrom_size(arg) char *arg; +{ + long r; + unsigned long sizebytes = 0; + + scan_ulong(arg,&r); + sizebytes = r; + if (databytes) if (sizebytes > databytes) return 1; + return 0; +} + +void mailfrom_auth(arg,len) +char *arg; +int len; +{ + int j; + + if (!stralloc_copys(&fuser,"")) die_nomem(); + if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); } + else + while (len) { + if (*arg == '+') { + if (case_starts(arg,"+3D")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"=")) die_nomem(); } + if (case_starts(arg,"+2B")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"+")) die_nomem(); } + } + else + if (!stralloc_catb(&fuser,arg,1)) die_nomem(); + arg++; len--; + } + if(!stralloc_0(&fuser)) die_nomem(); + if (!remoteinfo) { + remoteinfo = fuser.s; + if (!env_unset("TCPREMOTEINFO")) die_read(); + if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem(); + } +} + +void mailfrom_parms(arg) char *arg; +{ + int i; + int len; + + len = str_len(arg); + if (!stralloc_copys(&mfparms,"")) die_nomem; + i = byte_chr(arg,len,'>'); + if (i > 4 && i < len) { + while (len) { + arg++; len--; + if (*arg == ' ' || *arg == '\0' ) { + if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; } + if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5); + if (!stralloc_copys(&mfparms,"")) die_nomem; + } + else + if (!stralloc_catb(&mfparms,arg,1)) die_nomem; + } + } +} void smtp_helo(arg) char *arg; { smtp_greet("250 "); out("\r\n"); seenmail = 0; dohelo(arg); } +/* ESMTP extensions are published here */ void smtp_ehlo(arg) char *arg; { - smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); +#ifdef TLS + struct stat st; +#endif + char size[FMT_ULONG]; + smtp_greet("250-"); +#ifdef TLS + if (!ssl && (stat("control/servercert.pem",&st) == 0)) + out("\r\n250-STARTTLS"); +#endif + size[fmt_ulong(size,(unsigned int) databytes)] = 0; + out("\r\n250-PIPELINING\r\n250-8BITMIME\r\n"); + out("250-SIZE "); out(size); out("\r\n"); +#ifdef CRAM_MD5 + out("250 AUTH LOGIN PLAIN CRAM-MD5\r\n"); +#else + out("250 AUTH LOGIN PLAIN\r\n"); +#endif seenmail = 0; dohelo(arg); } void smtp_rset(arg) char *arg; @@ -240,6 +368,9 @@ void smtp_mail(arg) char *arg; { if (!addrparse(arg)) { err_syntax(); return; } + flagsize = 0; + mailfrom_parms(arg); + if (flagsize) { err_size(); return; } flagbarf = bmfcheck(); seenmail = 1; if (!stralloc_copys(&rcptto,"")) die_nomem(); @@ -269,6 +400,11 @@ { int r; flush(); +#ifdef TLS + if (ssl && fd == ssl_rfd) + r = ssl_timeoutread(timeout, ssl_rfd, ssl_wfd, ssl, buf, len); + else +#endif r = timeoutread(timeout,fd,buf,len); if (r == -1) if (errno == error_timeout) die_alarm(); if (r <= 0) die_read(); @@ -378,7 +514,7 @@ qp = qmail_qp(&qqt); out("354 go ahead\r\n"); - received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); + received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo); blast(&hops); hops = (hops >= MAXHOPS); if (hops) qmail_fail(&qqt); @@ -388,28 +524,494 @@ 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 (databytes) if (!bytestooverflow) { err_size(); return; } if (*qqx == 'D') out("554 "); else out("451 "); out(qqx + 1); out("\r\n"); } +/* this file is too long ----------------------------------------- SMTP AUTH */ + +char unique[FMT_ULONG + FMT_ULONG + 3]; +static stralloc authin = {0}; /* input from SMTP client */ +static stralloc user = {0}; /* authorization user-id */ +static stralloc pass = {0}; /* plain passwd or digest */ +static stralloc resp = {0}; /* b64 response */ +#ifdef CRAM_MD5 +static stralloc chal = {0}; /* plain challenge */ +static stralloc slop = {0}; /* b64 challenge */ +#endif + +int flagauth = 0; +char **childargs; +char ssauthbuf[512]; +substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf)); + +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(); +#ifdef CRAM_MD5 + if (!stralloc_0(&chal)) die_nomem(); +#endif + + if (pipe(pi) == -1) return err_pipe(); + switch(child = fork()) { + case -1: + return err_fork(); + case 0: + close(pi[1]); + if(fd_copy(3,pi[0]) == -1) return err_pipe(); + sig_pipedefault(); + execvp(*childargs, childargs); + _exit(1); + } + close(pi[0]); + + substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf); + if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write(); + if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write(); +#ifdef CRAM_MD5 + if (substdio_put(&ssauth,chal.s,chal.len) == -1) return err_write(); +#endif + if (substdio_flush(&ssauth) == -1) return err_write(); + + close(pi[1]); +#ifdef CRAM_MD5 + if (!stralloc_copys(&chal,"")) die_nomem(); + if (!stralloc_copys(&slop,"")) die_nomem(); +#endif + byte_zero(ssauthbuf,sizeof ssauthbuf); + if (wait_pid(&wstat,child) == -1) return err_child(); + if (wait_crashed(wstat)) return err_child(); + if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); 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),&resp) == 1) return err_input(); + } + else { + out("334 \r\n"); flush(); + if (authgetl() < 0) return -1; + if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input(); + } + if (r == -1 || !stralloc_0(&resp)) die_nomem(); + while (resp.s[id]) id++; /* "authorize-id\0userid\0passwd\0" */ + + if (resp.len > id + 1) + if (!stralloc_copys(&user,resp.s + id + 1)) die_nomem(); + if (resp.len > id + user.len + 2) + if (!stralloc_copys(&pass,resp.s + id + user.len + 2)) die_nomem(); + + if (!user.len || !pass.len) return err_input(); + return authenticate(); +} + +#ifdef CRAM_MD5 +int auth_cram() +{ + int i, r; + char *s; + + s = unique; /* generate challenge */ + s += fmt_uint(s,getpid()); + *s++ = '.'; + s += fmt_ulong(s,(unsigned long) now()); + *s++ = '@'; + *s++ = 0; + if (!stralloc_copys(&chal,"<")) die_nomem(); + if (!stralloc_cats(&chal,unique)) die_nomem(); + if (!stralloc_cats(&chal,local)) die_nomem(); + if (!stralloc_cats(&chal,">")) die_nomem(); + if (b64encode(&chal,&slop) < 0) die_nomem(); + if (!stralloc_0(&slop)) die_nomem(); + + out("334 "); /* "334 base64_challenge \r\n" */ + out(slop.s); + out("\r\n"); + flush(); + + if (authgetl() < 0) return -1; /* got response */ + if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input(); + if (r == -1 || !stralloc_0(&resp)) die_nomem(); + + i = str_chr(resp.s,' '); + s = resp.s + i; + while (*s == ' ') ++s; + resp.s[i] = 0; + if (!stralloc_copys(&user,resp.s)) die_nomem(); /* userid */ + if (!stralloc_copys(&pass,s)) die_nomem(); /* digest */ + + if (!user.len || !pass.len) return err_input(); + return authenticate(); +} +#endif + +struct authcmd { + char *text; + int (*fun)(); +} authcmds[] = { + { "login",auth_login } +, { "plain",auth_plain } +#ifdef CRAM_MD5 +, { "cram-md5",auth_cram } +#endif +, { 0,err_noauth } +}; + +void smtp_auth(arg) +char *arg; +{ + int i; + char *cmd = arg; + + if (!*childargs) { out("503 auth not available (#5.3.3)\r\n"); return; } + if (flagauth) { 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(); +#ifdef CRAM_MD5 + if (!stralloc_copys(&chal,"")) die_nomem(); +#endif + + 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: + flagauth = 1; + protocol = "ESMTPA"; + relayclient = ""; + remoteinfo = user.s; + if (!env_unset("TCPREMOTEINFO")) die_read(); + if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem(); + if (!env_put2("RELAYCLIENT",relayclient)) die_nomem(); + out("235 ok, go ahead (#2.0.0)\r\n"); + break; + case 1: + err_authfail(user.s,authcmds[i].text); + } +} + + +/* this file is too long --------------------------------------------- GO ON */ + +#ifdef TLS +stralloc proto = {0}; +int ssl_verified = 0; +const char *ssl_verify_err = 0; + +void smtp_tls(char *arg) +{ + if (ssl) err_unimpl(); + else if (*arg) out("501 Syntax error (no parameters allowed) (#5.5.4)\r\n"); + else tls_init(); +} + +RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen) +{ + if (!export) keylen = 512; + if (keylen == 512) { + FILE *in = fopen("control/rsa512.pem", "r"); + if (in) { + RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL); + fclose(in); + if (rsa) return rsa; + } + } + return RSA_generate_key(keylen, RSA_F4, NULL, NULL); +} + +DH *tmp_dh_cb(SSL *ssl, int export, int keylen) +{ + if (!export) keylen = 1024; + if (keylen == 512) { + FILE *in = fopen("control/dh512.pem", "r"); + if (in) { + DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); + fclose(in); + if (dh) return dh; + } + } + if (keylen == 1024) { + FILE *in = fopen("control/dh1024.pem", "r"); + if (in) { + DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL); + fclose(in); + if (dh) return dh; + } + } + return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL); +} + +/* don't want to fail handshake if cert isn't verifiable */ +int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } + +void tls_nogateway() +{ + /* there may be cases when relayclient is set */ + if (!ssl || relayclient) return; + out("; no valid cert for gatewaying"); + if (ssl_verify_err) { out(": "); out(ssl_verify_err); } +} +void tls_out(const char *s1, const char *s2) +{ + out("454 TLS "); out(s1); + if (s2) { out(": "); out(s2); } + out(" (#4.3.0)\r\n"); flush(); +} +void tls_err(const char *s) { tls_out(s, ssl_error()); if (smtps) die_read(); } + +# define CLIENTCA "control/clientca.pem" +# define CLIENTCRL "control/clientcrl.pem" +# define SERVERCERT "control/servercert.pem" + +int tls_verify() +{ + stralloc clients = {0}; + struct constmap mapclients; + + if (!ssl || relayclient || ssl_verified) return 0; + ssl_verified = 1; /* don't do this twice */ + + /* request client cert to see if it can be verified by one of our CAs + * and the associated email address matches an entry in tlsclients */ + switch (control_readfile(&clients, "control/tlsclients", 0)) + { + case 1: + if (constmap_init(&mapclients, clients.s, clients.len, 0)) { + /* if CLIENTCA contains all the standard root certificates, a + * 0.9.6b client might fail with SSL_R_EXCESSIVE_MESSAGE_SIZE; + * it is probably due to 0.9.6b supporting only 8k key exchange + * data while the 0.9.6c release increases that limit to 100k */ + STACK_OF(X509_NAME) *sk = SSL_load_client_CA_file(CLIENTCA); + if (sk) { + SSL_set_client_CA_list(ssl, sk); + SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); + break; + } + constmap_free(&mapclients); + } + case 0: alloc_free(clients.s); return 0; + case -1: die_control(); + } + + if (ssl_timeoutrehandshake(timeout, ssl_rfd, ssl_wfd, ssl) <= 0) { + const char *err = ssl_error_str(); + tls_out("rehandshake failed", err); die_read(); + } + + do { /* one iteration */ + X509 *peercert; + X509_NAME *subj; + stralloc email = {0}; + + int n = SSL_get_verify_result(ssl); + if (n != X509_V_OK) + { ssl_verify_err = X509_verify_cert_error_string(n); break; } + peercert = SSL_get_peer_certificate(ssl); + if (!peercert) break; + + subj = X509_get_subject_name(peercert); + n = X509_NAME_get_index_by_NID(subj, NID_pkcs9_emailAddress, -1); + if (n >= 0) { + const ASN1_STRING *s = X509_NAME_get_entry(subj, n)->value; + if (s) { email.len = s->length; email.s = s->data; } + } + + if (email.len <= 0) + ssl_verify_err = "contains no email address"; + else if (!constmap(&mapclients, email.s, email.len)) + ssl_verify_err = "email address not in my list of tlsclients"; + else { + /* add the cert email to the proto if it helped allow relaying */ + --proto.len; + if (!stralloc_cats(&proto, "\n (cert ") /* continuation line */ + || !stralloc_catb(&proto, email.s, email.len) + || !stralloc_cats(&proto, ")") + || !stralloc_0(&proto)) die_nomem(); + relayclient = ""; + protocol = proto.s; + } + + X509_free(peercert); + } while (0); + constmap_free(&mapclients); alloc_free(clients.s); + + /* we are not going to need this anymore: free the memory */ + SSL_set_client_CA_list(ssl, NULL); + SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); + + return relayclient ? 1 : 0; +} + +void tls_init() +{ + SSL *myssl; + SSL_CTX *ctx; + const char *ciphers; + stralloc saciphers = {0}; + X509_STORE *store; + X509_LOOKUP *lookup; + + SSL_library_init(); + + /* a new SSL context with the bare minimum of options */ + ctx = SSL_CTX_new(SSLv23_server_method()); + if (!ctx) { tls_err("unable to initialize ctx"); return; } + + if (!SSL_CTX_use_certificate_chain_file(ctx, SERVERCERT)) + { SSL_CTX_free(ctx); tls_err("missing certificate"); return; } + SSL_CTX_load_verify_locations(ctx, CLIENTCA, NULL); + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + /* crl checking */ + store = SSL_CTX_get_cert_store(ctx); + if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) && + (X509_load_crl_file(lookup, CLIENTCRL, X509_FILETYPE_PEM) == 1)) + X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | + X509_V_FLAG_CRL_CHECK_ALL); +#endif + + /* set the callback here; SSL_set_verify didn't work before 0.9.6c */ + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb); + + /* a new SSL object, with the rest added to it directly to avoid copying */ + myssl = SSL_new(ctx); + SSL_CTX_free(ctx); + if (!myssl) { tls_err("unable to initialize ssl"); return; } + + /* this will also check whether public and private keys match */ + if (!SSL_use_RSAPrivateKey_file(myssl, SERVERCERT, SSL_FILETYPE_PEM)) + { SSL_free(myssl); tls_err("no valid RSA private key"); return; } + + ciphers = env_get("TLSCIPHERS"); + if (!ciphers) { + if (control_readfile(&saciphers, "control/tlsserverciphers") == -1) + { SSL_free(myssl); die_control(); } + if (saciphers.len) { /* convert all '\0's except the last one to ':' */ + int i; + for (i = 0; i < saciphers.len - 1; ++i) + if (!saciphers.s[i]) saciphers.s[i] = ':'; + ciphers = saciphers.s; + } + } + if (!ciphers || !*ciphers) ciphers = "DEFAULT"; + SSL_set_cipher_list(myssl, ciphers); + alloc_free(saciphers.s); + + SSL_set_tmp_rsa_callback(myssl, tmp_rsa_cb); + SSL_set_tmp_dh_callback(myssl, tmp_dh_cb); + SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin)); + SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout)); + + if (!smtps) { out("220 ready for tls\r\n"); flush(); } + + if (ssl_timeoutaccept(timeout, ssl_rfd, ssl_wfd, myssl) <= 0) { + /* neither cleartext nor any other response here is part of a standard */ + const char *err = ssl_error_str(); + ssl_free(myssl); tls_out("connection failed", err); die_read(); + } + ssl = myssl; + + /* populate the protocol string, used in Received */ + if (!stralloc_copys(&proto, "(") + || !stralloc_cats(&proto, SSL_get_cipher(ssl)) + || !stralloc_cats(&proto, " encrypted) SMTP")) die_nomem(); + if (!stralloc_0(&proto)) die_nomem(); + protocol = proto.s; + + /* have to discard the pre-STARTTLS HELO/EHLO argument, if any */ + dohelo(remotehost); +} + +# undef SERVERCERT +# undef CLIENTCA + +#endif + 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 } , { "rset", smtp_rset, 0 } , { "help", smtp_help, flush } +#ifdef TLS +, { "starttls", smtp_tls, flush } +#endif , { "noop", err_noop, flush } , { "vrfy", err_vrfy, flush } , { 0, err_unimpl, flush } } ; -void main() +void main(argc,argv) +int argc; +char **argv; { + childargs = argv + 1; sig_pipeignore(); if (chdir(auto_qmail) == -1) die_control(); setup(); diff -urN ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.c.056 ./qmail-smtpd.c.056 --- ../../netqmail-1.05-orig/netqmail-1.05/qmail-smtpd.c.056 1969-12-31 16:00:00.000000000 -0800 +++ ./qmail-smtpd.c.056 2006-01-05 15:23:08.905049872 -0800 @@ -0,0 +1,421 @@ +#include "sig.h" +#include "readwrite.h" +#include "stralloc.h" +#include "substdio.h" +#include "alloc.h" +#include "auto_qmail.h" +#include "control.h" +#include "received.h" +#include "constmap.h" +#include "error.h" +#include "ipme.h" +#include "ip.h" +#include "qmail.h" +#include "str.h" +#include "fmt.h" +#include "scan.h" +#include "byte.h" +#include "case.h" +#include "env.h" +#include "now.h" +#include "exit.h" +#include "rcpthosts.h" +#include "timeoutread.h" +#include "timeoutwrite.h" +#include "commands.h" + +#define MAXHOPS 100 +unsigned int databytes = 0; +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; +} + +char ssoutbuf[512]; +substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf); + +void flush() { substdio_flush(&ssout); } +void out(s) char *s; { substdio_puts(&ssout,s); } + +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(arg) char *arg; { 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(arg) char *arg; { out("250 ok\r\n"); } +void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); } +void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } + + +stralloc greeting = {0}; + +void smtp_greet(code) char *code; +{ + substdio_puts(&ssout,code); + substdio_put(&ssout,greeting.s,greeting.len); +} +void smtp_help(arg) char *arg; +{ + out("214 netqmail home page: http://qmail.org/netqmail\r\n"); +} +void smtp_quit(arg) char *arg; +{ + smtp_greet("221 "); out("\r\n"); flush(); _exit(0); +} + +char *remoteip; +char *remotehost; +char *remoteinfo; +char *local; +char *relayclient; + +stralloc helohost = {0}; +char *fakehelo; /* pointer into helohost, or 0 */ + +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; +} + +int liphostok = 0; +stralloc liphost = {0}; +int bmfok = 0; +stralloc bmf = {0}; +struct constmap mapbmf; + +void setup() +{ + 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(); + + 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); +} + + +stralloc addr = {0}; /* will be 0-terminated, if addrparse returns 1 */ + +int addrparse(arg) +char *arg; +{ + int i; + char ch; + char terminator; + struct ip_address ip; + int flagesc; + int flagquoted; + + terminator = '>'; + i = str_chr(arg,'<'); + if (arg[i]) + arg += i + 1; + else { /* partner should go read rfc 821 */ + terminator = ' '; + arg += str_chr(arg,':'); + if (*arg == ':') ++arg; + while (*arg == ' ') ++arg; + } + + /* strip source route */ + 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 */ + if (flagesc) { + if (!stralloc_append(&addr,&ch)) die_nomem(); + flagesc = 0; + } + else { + if (!flagquoted && (ch == terminator)) break; + switch(ch) { + case '\\': flagesc = 1; break; + case '"': flagquoted = !flagquoted; break; + default: if (!stralloc_append(&addr,&ch)) die_nomem(); + } + } + } + /* could check for termination failure here, but why bother? */ + if (!stralloc_append(&addr,"")) die_nomem(); + + if (liphostok) { + i = byte_rchr(addr.s,addr.len,'@'); + if (i < addr.len) /* if not, partner should go read rfc 821 */ + if (addr.s[i + 1] == '[') + if (!addr.s[i + 1 + ip_scanbracket(addr.s + i + 1,&ip)]) + if (ipme_is(&ip)) { + addr.len = i + 1; + if (!stralloc_cat(&addr,&liphost)) die_nomem(); + if (!stralloc_0(&addr)) die_nomem(); + } + } + + if (addr.len > 900) return 0; + return 1; +} + +int bmfcheck() +{ + 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; + return 0; +} + +int addrallowed() +{ + int r; + r = rcpthosts(addr.s,str_len(addr.s)); + if (r == -1) die_control(); + return r; +} + + +int seenmail = 0; +int flagbarf; /* defined if seenmail */ +stralloc mailfrom = {0}; +stralloc rcptto = {0}; + +void smtp_helo(arg) char *arg; +{ + smtp_greet("250 "); out("\r\n"); + seenmail = 0; dohelo(arg); +} +void smtp_ehlo(arg) char *arg; +{ + smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n"); + seenmail = 0; dohelo(arg); +} +void smtp_rset(arg) char *arg; +{ + seenmail = 0; + out("250 flushed\r\n"); +} +void smtp_mail(arg) char *arg; +{ + 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(); + } + 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"); +} + + +int saferead(fd,buf,len) int fd; char *buf; int len; +{ + 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; +} + +char ssinbuf[1024]; +substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf); + +struct qmail qqt; +unsigned int bytestooverflow = 0; + +void put(ch) +char *ch; +{ + if (bytestooverflow) + if (!--bytestooverflow) + qmail_fail(&qqt); + qmail_put(&qqt,ch,1); +} + +void blast(hops) +int *hops; +{ + char ch; + int state; + int flaginheader; + 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; + for (;;) { + substdio_get(&ssin,&ch,1); + if (flaginheader) { + if (pos < 9) { + if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0; + if (flagmaybez) if (pos == 8) ++*hops; + if (pos < 8) + if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0; + if (flagmaybex) if (pos == 7) ++*hops; + if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; + if (flagmaybey) if (pos == 1) flaginheader = 0; + ++pos; + } + if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } + } + switch(state) { + case 0: + if (ch == '\n') straynewline(); + if (ch == '\r') { state = 4; continue; } + break; + case 1: /* \r\n */ + if (ch == '\n') straynewline(); + if (ch == '.') { state = 2; continue; } + if (ch == '\r') { state = 4; continue; } + state = 0; + break; + case 2: /* \r\n + . */ + if (ch == '\n') straynewline(); + if (ch == '\r') { state = 3; continue; } + state = 0; + break; + case 3: /* \r\n + .\r */ + if (ch == '\n') return; + put("."); + put("\r"); + if (ch == '\r') { state = 4; continue; } + state = 0; + break; + case 4: /* + \r */ + if (ch == '\n') { state = 1; break; } + if (ch != '\r') { put("\r"); state = 0; } + } + put(&ch); + } +} + +char accept_buf[FMT_ULONG]; +void acceptmessage(qp) unsigned long qp; +{ + datetime_sec when; + when = now(); + out("250 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"); +} + +void smtp_data(arg) char *arg; { + int hops; + unsigned long qp; + char *qqx; + + if (!seenmail) { err_wantmail(); return; } + if (!rcptto.len) { err_wantrcpt(); return; } + seenmail = 0; + if (databytes) bytestooverflow = databytes + 1; + if (qmail_open(&qqt) == -1) { err_qqt(); return; } + qp = qmail_qp(&qqt); + out("354 go ahead\r\n"); + + received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo); + blast(&hops); + hops = (hops >= MAXHOPS); + if (hops) qmail_fail(&qqt); + qmail_from(&qqt,mailfrom.s); + qmail_put(&qqt,rcptto.s,rcptto.len); + + 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"); +} + +struct commands smtpcommands[] = { + { "rcpt", smtp_rcpt, 0 } +, { "mail", smtp_mail, 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 } +} ; + +void main() +{ + sig_pipeignore(); + if (chdir(auto_qmail) == -1) die_control(); + setup(); + if (ipme_init() != 1) die_ipme(); + smtp_greet("220 "); + out(" ESMTP\r\n"); + if (commands(&ssin,&smtpcommands) == 0) die_read(); + die_nomem(); +} diff -urN ../../netqmail-1.05-orig/netqmail-1.05/ssl_timeoutio.c ./ssl_timeoutio.c --- ../../netqmail-1.05-orig/netqmail-1.05/ssl_timeoutio.c 1969-12-31 16:00:00.000000000 -0800 +++ ./ssl_timeoutio.c 2006-01-05 15:23:08.906049720 -0800 @@ -0,0 +1,94 @@ +#include "select.h" +#include "error.h" +#include "ndelay.h" +#include "ssl_timeoutio.h" + +int ssl_timeoutio(int (*fun)(), + long t, int rfd, int wfd, SSL *ssl, char *buf, int len) +{ + int n; + const long end = t + time(NULL); + + do { + fd_set fds; + struct timeval tv; + + const int r = buf ? fun(ssl, buf, len) : fun(ssl); + if (r > 0) return r; + + t = end - time(NULL); + if (t < 0) break; + tv.tv_sec = t; tv.tv_usec = 0; + + FD_ZERO(&fds); + switch (SSL_get_error(ssl, r)) + { + default: return r; /* some other error */ + case SSL_ERROR_WANT_READ: + FD_SET(rfd, &fds); n = select(rfd + 1, &fds, NULL, NULL, &tv); + break; + case SSL_ERROR_WANT_WRITE: + FD_SET(wfd, &fds); n = select(wfd + 1, NULL, &fds, NULL, &tv); + break; + } + + /* n is the number of descriptors that changed status */ + } while (n > 0); + + if (n != -1) errno = error_timeout; + return -1; +} + +int ssl_timeoutaccept(long t, int rfd, int wfd, SSL *ssl) +{ + int r; + + /* if connection is established, keep NDELAY */ + if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1; + r = ssl_timeoutio(SSL_accept, t, rfd, wfd, ssl, NULL, 0); + + if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); } + else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + + return r; +} + +int ssl_timeoutconn(long t, int rfd, int wfd, SSL *ssl) +{ + int r; + + /* if connection is established, keep NDELAY */ + if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1; + r = ssl_timeoutio(SSL_connect, t, rfd, wfd, ssl, NULL, 0); + + if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); } + else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + + return r; +} + +int ssl_timeoutrehandshake(long t, int rfd, int wfd, SSL *ssl) +{ + int r; + + SSL_renegotiate(ssl); + r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0); + if (r <= 0 || ssl->type == SSL_ST_CONNECT) return r; + + /* this is for the server only */ + ssl->state = SSL_ST_ACCEPT; + return ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0); +} + +int ssl_timeoutread(long t, int rfd, int wfd, SSL *ssl, char *buf, int len) +{ + if (!buf) return 0; + if (SSL_pending(ssl)) return SSL_read(ssl, buf, len); + return ssl_timeoutio(SSL_read, t, rfd, wfd, ssl, buf, len); +} + +int ssl_timeoutwrite(long t, int rfd, int wfd, SSL *ssl, char *buf, int len) +{ + if (!buf) return 0; + return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len); +} diff -urN ../../netqmail-1.05-orig/netqmail-1.05/ssl_timeoutio.h ./ssl_timeoutio.h --- ../../netqmail-1.05-orig/netqmail-1.05/ssl_timeoutio.h 1969-12-31 16:00:00.000000000 -0800 +++ ./ssl_timeoutio.h 2006-01-05 15:23:08.907049568 -0800 @@ -0,0 +1,21 @@ +#ifndef SSL_TIMEOUTIO_H +#define SSL_TIMEOUTIO_H + +#include + +/* the version is like this: 0xMNNFFPPS: major minor fix patch status */ +#if OPENSSL_VERSION_NUMBER < 0x00906000L +# error "Need OpenSSL version at least 0.9.6" +#endif + +int ssl_timeoutconn(long t, int rfd, int wfd, SSL *ssl); +int ssl_timeoutaccept(long t, int rfd, int wfd, SSL *ssl); +int ssl_timeoutrehandshake(long t, int rfd, int wfd, SSL *ssl); + +int ssl_timeoutread(long t, int rfd, int wfd, SSL *ssl, char *buf, int len); +int ssl_timeoutwrite(long t, int rfd, int wfd, SSL *ssl, char *buf, int len); + +int ssl_timeoutio( + int (*fun)(), long t, int rfd, int wfd, SSL *ssl, char *buf, int len); + +#endif diff -urN ../../netqmail-1.05-orig/netqmail-1.05/tls.c ./tls.c --- ../../netqmail-1.05-orig/netqmail-1.05/tls.c 1969-12-31 16:00:00.000000000 -0800 +++ ./tls.c 2006-01-05 15:27:25.793996816 -0800 @@ -0,0 +1,25 @@ +#include "exit.h" +#include "error.h" +#include +#include + +int smtps = 0; +SSL *ssl = NULL; + +void ssl_free(SSL *myssl) { SSL_shutdown(myssl); SSL_free(myssl); } +void ssl_exit(int status) { if (ssl) ssl_free(ssl); _exit(status); } + +const char *ssl_error() +{ + int r = ERR_get_error(); + if (!r) return NULL; + SSL_load_error_strings(); + return ERR_error_string(r, NULL); +} +const char *ssl_error_str() +{ + const char *err = ssl_error(); + if (err) return err; + if (!errno) return 0; + return (errno == error_timeout) ? "timed out" : error_str(errno); +} diff -urN ../../netqmail-1.05-orig/netqmail-1.05/tls.h ./tls.h --- ../../netqmail-1.05-orig/netqmail-1.05/tls.h 1969-12-31 16:00:00.000000000 -0800 +++ ./tls.h 2006-01-05 15:27:25.794996664 -0800 @@ -0,0 +1,16 @@ +#ifndef TLS_H +#define TLS_H + +#include + +extern int smtps; +extern SSL *ssl; + +void ssl_free(SSL *myssl); +void ssl_exit(int status); +# define _exit ssl_exit + +const char *ssl_error(); +const char *ssl_error_str(); + +#endif diff -urN ../../netqmail-1.05-orig/netqmail-1.05/update_tmprsadh.sh ./update_tmprsadh.sh --- ../../netqmail-1.05-orig/netqmail-1.05/update_tmprsadh.sh 1969-12-31 16:00:00.000000000 -0800 +++ ./update_tmprsadh.sh 2006-01-05 15:23:08.910049112 -0800 @@ -0,0 +1,25 @@ +#!/bin/sh + +# Update temporary RSA and DH keys +# Frederik Vermeulen 2004-05-31 GPL + +umask 0077 || exit 0 + +export PATH="$PATH:/usr/local/bin/ssl:/usr/sbin" + +openssl genrsa -out QMAIL/control/rsa512.new 512 && +chmod 600 QMAIL/control/rsa512.new && +chown UGQMAILD QMAIL/control/rsa512.new && +mv -f QMAIL/control/rsa512.new QMAIL/control/rsa512.pem +echo + +openssl dhparam -2 -out QMAIL/control/dh512.new 512 && +chmod 600 QMAIL/control/dh512.new && +chown UGQMAILD QMAIL/control/dh512.new && +mv -f QMAIL/control/dh512.new QMAIL/control/dh512.pem +echo + +openssl dhparam -2 -out QMAIL/control/dh1024.new 1024 && +chmod 600 QMAIL/control/dh1024.new && +chown UGQMAILD QMAIL/control/dh1024.new && +mv -f QMAIL/control/dh1024.new QMAIL/control/dh1024.pem