Index: npl/mailserver/netqmail/netqmail.SlackBuild
===================================================================
--- npl/mailserver/netqmail/netqmail.SlackBuild	(revision cd8630be6536b27ae1c762184795ee87723202ab)
+++ npl/mailserver/netqmail/netqmail.SlackBuild	(revision 1ebb340be23e45ead361b729734f0e82007af6bd)
@@ -116,5 +116,5 @@
 ### all important qmail patches
 # above is all replaced by the great uberpatch from http://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html THANKS Roberto Puzzanghera!
-ROBVERSION="rob20180403"
+ROBVERSION="rob20201204"
 patch < /tmp/build/roberto-netqmail-1.06.patch-latest || exit 1
 ln -s /usr/include/srs2.h /usr/local/include/srs2.h
@@ -140,5 +140,5 @@
 #large inode support
 sed 's/O2$/O2 -D_FILE_OFFSET_BITS=64/' conf-cc -i || exit 1
-make setup check || exit 1
+make -j1 setup check || exit 1
 
 # Default qmail rules
Index: npl/mailserver/netqmail/netqmail.build
===================================================================
--- npl/mailserver/netqmail/netqmail.build	(revision cd8630be6536b27ae1c762184795ee87723202ab)
+++ npl/mailserver/netqmail/netqmail.build	(revision 1ebb340be23e45ead361b729734f0e82007af6bd)
@@ -1,1 +1,1 @@
-6363
+6364
Index: npl/mailserver/netqmail/netqmail.md5
===================================================================
--- npl/mailserver/netqmail/netqmail.md5	(revision cd8630be6536b27ae1c762184795ee87723202ab)
+++ npl/mailserver/netqmail/netqmail.md5	(revision 1ebb340be23e45ead361b729734f0e82007af6bd)
@@ -1,5 +1,5 @@
 26c95bd8faca909f3432c1aa55f251b6  ./netqmail-1.06.tar
-fc09f10879e8fd10880d136de5b51a87  ./netqmail.pkg
-24b173c1fdd1a05abfbd48a6ccba56f4  ./netqmail.SlackBuild
-584232cea7d0ecd5691041e5973edac9  ./netqmail.SlackBuild.log.gz
-2fbc85fee68c868ba2a45e7e84a138b7  ./roberto-netqmail-1.06.patch-latest
+f8967ecfb97c2a65cacf2c2ee0803b82  ./netqmail.pkg
+679d508316e188608a439ac8ab28a2e2  ./netqmail.SlackBuild
+100c02924b4c1c5238f5a661ab72e747  ./netqmail.SlackBuild.log.gz
+353c8724cd1df7c795268528295a274c  ./roberto-netqmail-1.06.patch-latest
Index: npl/mailserver/netqmail/netqmail.version
===================================================================
--- npl/mailserver/netqmail/netqmail.version	(revision cd8630be6536b27ae1c762184795ee87723202ab)
+++ npl/mailserver/netqmail/netqmail.version	(revision 1ebb340be23e45ead361b729734f0e82007af6bd)
@@ -1,1 +1,1 @@
-1.06_rob20180403
+1.06_rob20201204
Index: npl/mailserver/netqmail/roberto-netqmail-1.06.patch-latest
===================================================================
--- npl/mailserver/netqmail/roberto-netqmail-1.06.patch-latest	(revision cd8630be6536b27ae1c762184795ee87723202ab)
+++ npl/mailserver/netqmail/roberto-netqmail-1.06.patch-latest	(revision 1ebb340be23e45ead361b729734f0e82007af6bd)
@@ -1,442 +1,109 @@
-v. 2018.04.03
-Combined patch for netqmail-1.06 by Roberto Puzzanghera [roberto dot puzzanghera at sagredo dot eu]
-More info at http://notes.sagredo.eu/node/82
-==========================================================================================================
-
-= This patch puts together
-* Erwin Hoffmann's qmail-authentication patch v. 0.8.3 (23.08.2015), which updates the patches provided by
-  Krysztof Dabrowski and Bjoern Kalkbrenner.
-  It provides cram-md5, login, plain authentication support for qmail-smtpd and qmail-remote.
-  http://www.fehcom.de/qmail/smtpauth.html##PATCHES
-* Frederik Vermeulen's qmail-tls patch v. 20160908
-  implements SSL or TLS encrypted and authenticated SMTP.
-  http://inoa.net/qmail-tls/
-  The file update_tmprsadh was modified to chown all .pem files to vpopmail.
-* Marcel Telka's force-tls patch v. 2016.05.15
-  optionally gets qmail to require TLS before authentication to improve security.
-  You have to declare FORCETLS=0 if you want to allow the auth without TLS
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06_force-tls.patch-2012.10.28
-* Antonio Nati's chkuser patch v. 2.0.9
-  performs, among the other things, a check for the existence of recipients during the SMTP conversation,
-  bouncing emails of fake senders.
-  http://www.interazioni.it/opensource/chkuser/
-* Flavio Curti's qmail-queue-custom-error patch
-  enables simscan and qmail-dkim to return the appropriate message for each e-mail it refuses to deliver.
-  https://no-way.org/uploads/qmail-error/
-* Christophe Saout's qmail-SPF rc5 patch
-  Modified by Manvendra Bhangui to make it IPv4-mapped IPv6 addresses compliant.
-  checks incoming mails inside the SMTP daemon, add Received-SPF lines and optionally block undesired transfers.
-  http://www.saout.de/misc/spf/
-* Marcelo Coelho's qmail-SRS patch
-  implements Sender Rewriting Scheme fixing SPF break upon email forwarding.
-  http://www.mco2.com.br/opensource/qmail/srs/
-* Christopher K. Davis' oversize dns patch
-  enables qmail to handle large DNS packets.
-  http://www.ckdhr.com/ckd/qmail-103.patch
-* Jul's reread-concurrency v.2 patch
-  rereads control/concurrencylocal and control/concurrencyremote files when qmail-send receives a HUP signal.
-  http://js.hu/package/qmail/index.html
-* Johannes Erdfelt's Big Concurrency patch
-  sets the spawn limit above 255
-  http://qmail.org/big-concurrency.patch
-* Mihai Secasiu's Big Concurrency fix v.1.0 patch
-  fixes a compiler error if you set concurrency higher than 509 in conf-spawn.
-  http://patchlog.com/linux/qmail-big-concurrency/
-* Bill Shupp's netqmail-maildir++.patch
-  adds maildirquota support to qmail-pop3d and qmail-local.
-  Fixed a bug where the filesize part of the S=<filesize> component of the Maildir++ compatible filename is wrong (tx MG).
-  More info here: http://notes.sagredo.eu/en/qmail-notes-185/installing-dovecot-and-sieve-on-a-vpopmail-qmail-server-28.html#comment995
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/netqmail-maildir.patch
-* Kyle B. Wheeler's "Better qmail-smtpd Logging" v.4 (05 Jan 2010) patch
-  facilitates diagnostics of qmail-smtpd logging its actions and decisions (search for a line with qmail-smtp:)
-  http://www.memoryhole.net/qmail/#logging
-* John Simpson's (?) Greeting delay patch
-  adds a user-definable delay after SMTP clients have initiated SMTP sessions, prior to qmail-smtpd responding
-  with "220 ESMTP". It can reject connections from clients which tried to send commands before greeting.
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-greetdelay.patch
-* Manvendra Bhangui's DKIM and SURBL filter v.1.22 patch
-  adds DKIM signing & verification and SURBL filtering support to qmail.
-  qmail-dk is based on Russ Nelson's patch: http//:www.qmail.org/qmail-1.03-dk-0.54.patch
-  qmail-dkim uses hacked libdkim libraries from libdkim project at http://libdkim.sourceforge.net/
-  surbfilter is built on djb functions and some functions have been ruthlessly borrowed from qmail surbl
-  interface by Pieter Droogendijk and the surblhost program at http://surblhost.sourceforge.net/
-  (file hier.c modified to chown /var/qmail/control/cache and subdirs to vpopmail)
-  http://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/ANNOUNCE.surblfilter
-* Claudio Jeker and Andre Oppermann's EXTTODO patch (release 5. Jan. 2003)
-  addresses a problem known as the silly qmail (queue)  problem
-  http://www.nrg4u.com/qmail/ext_todo-20030105.patch
-* Russell Nelson's big-todo patch
-  makes qmail use a hashing mechanism in the todo folder similar to that used in the rest of the queue
-  http://www.qmail.org/big-todo.103.patch
-* Stephane Cottin's qmail-inject-null-sender patch (let's call it in this way)
-  prevents qmail-inject from rewriting the null sender, fixing an issue with sieve vacation/reject messages.
-  More info here: http://www.dovecot.org/list/dovecot/2009-June/040811.html
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-inject-null-sender.patch
-* Russell Nelson's (modified by Charles Cazabon) doublebounce-trim patch, which updates the original
-  version by Russel Nelson
-  prevents double bounces from hitting your queue a second time provided that you delete the first line
-  from /var/qmail/control/doublebounceto
-  http://qmail.org/doublebounce-trim.patch
-* Will Harris' esmtp-size patch
-  enables qmail-smtpd to reject messages if they're larger than the maximum number of bytes allowed
-  according to the /var/qmail/control/databytes control file.
-  http://will.harris.ch/qmail-smtpd.c.diff
-* Inter7's qmail-taps-extended patch
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-tap.diff
-  Extended by Michai Secasiu (http://patchlog.com/patches/qmail-taps-extended/)
-  Provides the ability to archive each email that flows through the system.
-  Archiving only messages from or to certain email addresses is possible as well.
-* Rolf Eike Beer's qmail-remote CRLF patch
-  enables qmail-remote to handle CR properly, always sending the line breaks as CRLF and avoiding to
-  double the CR (like qmail-remote normally does)
-  http://opensource.sf-tec.de/qmail/
-* Andy Repton's outgoingip patch (adjusted by Sergio Gelato)
-  by default all outgoing emails are sent through the first IP address on the interface. In case of a multiple
-  IP server this patch makes qmail send outgoing emails with the IP eventually stored in control/outgoingip.
-  The ehlo domain is NOT modified by this patch.
-  http://www.qmail.org/outgoingip.patch
-  Robbie Walker provided a patch to correct qmail-qmqpc.c's call to timeoutconn(), because the function
-  signature was modified by the original outgoingip patch
-  http://notes.sagredo.eu/node/82#comment-373
-* Iain Patterson's qmail-smtpd pid, qp log patch
-  makes qmail-smtpd log a line similar to the following:
-  @4000000039b89c95026a89b4 mail recv: pid 8155 from <name@domain.xy> qp 8157
-  The pid allows you to match the message up with a given tcpserver process and the qp lets you find a
-  particular delivery.
-  http://iain.cx/qmail/patches.html#smtpd_pidqp
-* Jonathan de Boyne Pollard's any-to-cname patch
-  avoids qmail getting large amounts of DNS data we have no interest in and that may overflow our response
-  buffer.
-  http://www.memoryhole.net/qmail/#any-to-cname
-* Matthias Andree's qmail-rfc2821 patch
-  makes qmail rfc2821 compliant
-  http://www-dt.e-technik.uni-dortmund.de/~ma/qmail/patch-qmail-1.03-rfc2821.diff
-* Jonathan de Boyne Pollard's smtpd-502-to-500 patch
-  makes qmail rfc2821 compliant
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/smtpd-502-to-500.patch
-* Fabio Busatto's qmail-dnsbl patch
-  allows you to reject spam and virus looking at the sender's ip address.
-  Modified by Luca Franceschini to add support for whitelists, TXT and A queries, configurable return codes 
-  451 or 553 with custom messages
-  http://qmail-dnsbl.sourceforge.net/
-* Scott Gifford's qmail-moreipme patch v. 0.6
-  prevents a problem caused by an MX or other mail routing directive instructing qmail to connect to
-  itself without realizing it's connecting to itself, saving CPU time.
-  http://www.suspectclass.com/sgifford/qmail/qmail-1.03-moreipme.README
-  http://www.suspectclass.com/sgifford/qmail/qmail-1.03-moreipme-0.6.patch
-* Alex Nee's qmail-hide-ip-headers patch
-  It will hide your Private or Public IP in the email Headers when you are sending Mail as a Relay Client.
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-hide-ip-headers.patch
-* John Saunders' qmail-date-localtime patch
-  causes the various qmail programs to generate date stamps in the local timezone.
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-date-localtime.patch
-* Dean Gaudet's qmail-liberal-lf patch v. 0.95
-  allow qmail-smtpd to accept messages that are terminated with a single \n instead of the required \r\n
-  sequence.
-  http://www.arctic.org/~dean/patches/qmail-0.95-liberal-lf.patch
-* Michael Samuel's maxrcpt patch
-  allows you to set a limit on how many recipients are specified for any one email message by setting
-  control/maxrcpt. RFC 2821 section 4.5.3.1 says that an MTA MUST allow at least 100 recipients for each
-  message, since this is one of the favourite tricks of the spammer.
-  http://copilotco.com/mail-archives/qmail.1997/msg03066.html
-* Inter7's qmail-eMPF patch
-  More info: http://www.qmailwiki.org/EMPF
-  eMPF follows a set of administrator-defined rules describing who can message whom.  With this, companies can segregate
-  various parts of their organizations email activities, as well as provide a variety of security-enhancing services.
-* qregex (by  Andrew St. Jean http://www.arda.homeunix.net/downloads-qmail/, contributors: Jeremy Kitchen, Alex Pleiner,
-  Thanos Massias. Original patch by Evan Borgstrom)
-  adds the ability to match address evelopes via Regular Expressions (REs) in the qmail-smtpd process.
-  Added new control file 'badhelonorelay', control/badmailto renamed control/badrcptto (Tx Luca Franceschini).
-* brtlimit
-  Luca Franceschini derived this patch from http://netdevice.com/qmail/patch/goodrcptto-12.patch
-  added control/brtlimit and BRTLIMIT variable to limit max invalid recipient errors before closing the connection (man qmail-control)
-* validrcptto
-  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/validrcptto.README
-  Luca Franceschini grabbed the code from several patches with additional features: http://qmail.jms1.net/patches/validrcptto cdb.shtml,
-  http://netdevice.com/qmail/patch/goodrcptto-ms-12.patch, http://patch.be/qmail/badrcptto.html
-  It works in conjunction with chkuser with both cdb and mysql accounts.
-* reject-relay-test by Russell Nelson
-  http://qmail.org/qmail-smtpd-relay-reject
-  It gets qmail to reject relay probes generated by so-called anti-spammers. These relay probes have '!', '%' and '@'
-  in the local (username) part of the address.
-* Luca Franceschini
-  added DISABLETLS environment variable, useful if you want to disable TLS on a desired port
-  added FORCEAUTHMAILFROM environment variable to REQUIRE that authenticated user and 'mail from' are identical
-  added SMTPAUTHMETHOD, SMTPAUTHUSER and SMTP_AUTH_USER env variables for external plugins (see http://qmail-spp.sourceforge.net/doc/)
-* fixed little bug in 'mail from' address handling 
-  patch by Andre Opperman at http://qmail.cr.yp.narkive.com/kBry6GJl/bug-in-qmail-smtpd-c-addrparse-function
-* Luca Franceschini's qlog patch
-  smtpd logging with fixed format. An entry 'qlogenvelope' is generated after accepting or rejecting every recipients in the envelope phase.
-* Luca Franceschini's reject null senders patch
-  useful in special cases if you temporarily need to reject the null sender (although breaks RFC compatibility).
-  You just need to put 1 (actually any number different from 0) in your control/rejectnullsenders to reject the null sender with 421 error message.
-* dnscname patch
-  Removes CNAME check in order to avoid getting large amounts of data of no interest in and that may overflow the response buffer.
-  https://lists.gt.net/qmail/users/138190
-* Luca Franceschini's rcptcheck patch
-  (based on original patch from Jay Soffian (http://www.soffian.org/downloads/qmail/qmail-smtpd-doc.html)
-  Originally designed for the purpose of receipt validation, it can also be used to limit the numbr of email a given IP and/or auth-user and/or domain che send
-  in a given time interval. It has to be used in conjuction with the rcptcheck-overlimit.sh LF's script http://notes.sagredo.eu/files/qmail/rcptcheck-overlimit.sh
-  http://notes.sagredo.eu/files/qmail/patches/rcptcheck.patch
-
-= Disclaimer
-This patch comes with the usual warranty: it works for me, it may not work for you,
-use at your own risk etc. etc. :)
-Comments, suggestions, criticisms are always welcome!
-
-= Usage
-
-* Install libdomainkeys
-wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/tar/libdomainkeys-0.69.tar.gz
-tar xzf libdomainkeys-0.69.tar.gz
-wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/libdomainkeys-0.69.diff
-cd libdomainkeys-0.69
-chown -R root.root .
-patch < ../libdomainkeys-0.69.diff
-make
-cp libdomainkeys.a /usr/lib
-
-* Install libsrs2
-wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/tar/libsrs2-1.0.18.tar.gz
-tar xzf libsrs2-1.0.18.tar.gz
-cd libsrs2-1.0.18
-./configure
-make
-make install
-ldconfig
-cd ../
-
-* Apply the patch and compile
-wget http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06.patch-latest.gz
-wget http://qmail.org/netqmail-1.06.tar.gz
-tar xzf netqmail-1.06.tar.gz
-cd netqmail-1.06
-chown -R root.root .
-gunzip -c ../roberto-netqmail-1.06.patch-latest.gz | patch
-make
-make setup check
-
-* You have to export SMTPAUTH in your run file if you want to do the auth
-
-* You have to export SURBL=1 in your run file if you want to enable SURBL
-
-* /var/qmail/control/cache must be owned by the user who runs qmail-smtpd, vpopmail.vchkpwd in my case.
-  Change the permissions according to your qmail configuration.
-
-=================================================================================================================
-
-= Changelog
-
-2018.04.03
--DKIM patch updated to v. 1.22
- * openssl 1.1.0 port
- * various improvements, bug fixes
-
-2018.01.10
--maildir++
- * fixed a bug where the filesize part of the S=<filesize> component of the Maildir++ compatible filename
-   is wrong (tx MG). More info here: http://notes.sagredo.eu/en/qmail-notes-185/installing-dovecot-and-sieve-on-a-vpopmail-qmail-server-28.html#comment995
--qmail-queue-extra
- * removed, because it was causing more problems than advantages, as the domain of the log@yourdomain.tld
-   had to match the system domain inside control/me and shouldn't be a virtual domain as well.
-
-2017.10.11 (tx Luca Franceschini)
--qlogfix
- * log strings should terminate with \n to avoid trailing ^M using splogger
- * bug reporting custom errors from qmail-queue in qlog
--added dnscname patch
--added rcptcheck patch
-
-2017.08.18
--qmail-smtpd now retains authentication upon rset
- (tx to Andreas http://notes.sagredo.eu/qmail-notes-185/smtp-auth-qmail-tls-forcetls-patch-for-qmail-84.html#comment750)
-
-2017-05-14
--DKIM patch updated to v. 1.20
- It now manages long TXT records, avoiding the rejection of some hotmail.com messages.
-
-2016-12-19
--Several new patches and improvements added (thanks to Luca Franceschini)
-More info here http://notes.sagredo.eu/node/178
- -qregex patch
- -brtlimit patch
- -validrcptto patch
- -rbl patch (updates qmail-dnsbl patch)
- -reject-relay-test patch
- -added DISABLETLS environment variable, useful if you want to disable TLS on a desired port
- -added FORCEAUTHMAILFROM environment variable to REQUIRE that authenticated user and 'mail from' are identical
- -fixed little bug in 'mail from' address handling (patch by Andre Opperman at http://qmail.cr.yp.narkive.com/kBry6GJl/bug-in-qmail-smtpd-c-addrparse-function)
- -added SMTPAUTHMETHOD, SMTPAUTHUSER and SMTP_AUTH_USER env variables for external plugins
- -qlog patch
- -reject null senders patch
- -bouncecontrolmime patch
- -qmail-taps-extended (updates qmail-tap)
-
-2016-12-02
--fixed BUG in qmail-remote.c: in case of remote server who doesn't allow EHLO the response for an alternative
-HELO was checked twice, making the connection to die. (Thanks to Luca Franceschini)
-Patch applied: http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/fix_sagredo_remotehelo.patch
-
-2016-09-19
--qmail-tls patch updated to v. 20160918
-  * bug: qmail-remote accepting any dNSName, without checking that is matches (E. Surovegin)
-  * bug: documentation regarding RSA and DH keys (K. Peter, G. A. Bofill)
-
-2016-05-15
--force-tls patch improved (a big thanks to Marcel Telka). Now qmail-smtpd avoids to write the auth verb if the
- the STARTTLS command was not sent by the client
-
-2016-03-09
--DKIM patch upgraded to v. 1.19
- * verification will not fail when a dkim signature does not include the subject provided that the
-   UNSIGNED_SUBJECT environment variable is declared.
-
-2015-12-26
--qmail-tls patch updated to v. 20151215
- * typo in #if OPENSSL_VERSION_NUMBER for 2015-12-08 patch release (V. Smith)
- * add ECDH to qmail-smtpd
- * increase size of RSA and DH pregenerated keys to 2048 bits
- * qmail-smtpd sets RELAYCLIENT if relaying allowed by cert
- more info at http://inoa.net/qmail-tls/
-
-2015-12-15
--DKIM patch by Manvendra Bhangui updated to v. 1.18
-
-2015-10-03
--qmail-authentication: updated to v. 0.8.3
-
-2015-08-08
--fixed a bug on qmail-remote.c that was causing the sending of an additionale ehlo greeting (thanks to Cristoph Grover)
-
-2015-04-11
--qmail-authentication: updated to v. 0.8.2
--qmail-tls: upgraded to v. 20141216 (POODLE vulnerability fixed)
-
-2015-03-28
--added qmail-eMPF patch
-
-2014-11-19
--security fix: the SSLv3 connection is now switched off
-
-2014-11-15
--modified the QUEUE_EXTRA variable in extra.h to improve the qmail-send's log
-
-2014-04-14
--added maxrcpt patch
-
-2014-03-10
--added qmail-0.95-liberal-lf patch
-
-2013-12-30
--added qmail-srs
--the character "=" is now considered valid in the sender address by chkuser in order to accept SRS
-
-2013-12-18
--added qmail-date-localtime patch
-
-2013-12-14
--added qmail-hide-ip patch
-
-2013-12-10
--the original greetdelay by e.h. has been replaced with the improved patch by John Simpson. Now
-communications trying to send commands before the greeting will be closed. Premature disconnections will be
-logged as well.
--CHKUSER_SENDER_FORMAT enabled to reject fake senders without any domain declared (like <foo>)
--chkuser logging: I slightly modified the log line adding the variables' name just to facilitate its interpretation
--added qmail-moreipme patch
-
-2013-12-07
--added qmail-dnsbl patch
-
-2013-12-05
--added two patches to make qmail rfc2821 compliant
-
-2013-11-23
--added any-to-cname patch
-
-2013-09-27
--DKIM patch upgraded to v. 1.17. Defined -DHAVE_SHA_256 while compiling dkimverify.cpp in the Makefile.
-This solved an issue while verifying signatures using sha256.
-
-2013-09-16
--Minor fixes to the DKIM patch.
-
-2013-09-13
--DKIM patch upgraded to v. 1.16. The signing at qmail-remote level has been revised by its author.
-
-2013-08-25
--qmail-qmqpc.c call to timeoutconn() needed a correction because the function signature was modified by the
- outgoingip patch. Thanks to Robbie Walker (diff here http://notes.sagredo.eu/node/82#comment-373)
-
-2013-08-21
--fixed a bug in hier.c which caused the installation not to build properly the queue/todo dir structure (thanks to
- Scott Ramshaw)
-
-2013-08-18
--DKIM-SURBL patch by Manvendra Bhangui updated to v. 1.14
-
-2013-08-12
--DKIM patch upgraded to v. 1.12. The new patch adds surblfilter functionality.
--added qmail-smtpd pid, qp log patch
-
-2013-08-08
--qmail-SPF modified by Manvendra Bhangui to make it IPv6-mapped IPv4 addresses compliant. In order to have it
-working with such addresses you have to patch tcpserver.c accordingly. You can use a patch fot ucspi-tcp6-0.98
-by Manvendra Bhangui at http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/tcpserver-ipv6mapped_ipv4.patch
-or wait for v. 0.99 relase of ucspi-tcp6
--added outgoingip patch
--added qmail-bounce patch
-
-2013-03-31
-qmail-auth updated to latest v. 0.8.1 Added authentication by recipient domain for qmail-remote.
-Look at README.auth for further details
-
-2013-02-11
-some code adjustments in qmail-smtpd.c smtpd_ehlo() to restore total compatibility with esmtp-size patch
-
-2013-02-08
-qmail-auth updated to latest v. 0.7.6. Look at README.auth for further details
-
-2013-01-28
-fixed an issue on qmail-pop3d which was causing a double +OK after the pass command (thanks to Rakesh, Orbit
-and Simplex for helping in testing and troubleshooting)
-
-2013-01-06
-environment variable GREETDELAY renamed to SMTPD_GREETDELAY
-
-2012-10-31
-qmail-auth updated to latest v. 0.7.5. Look at README.auth for further details
-The qmail-forcetls patch was simplyfied accordingly.
-You MUST export SMTPAUTH="" in your run file now.
-
-2012-04-25
--added qmail-remote CRLF (thanks to Pierre Lauriente for the help on testing and troubleshooting)
-The qmail-remote CRLF patch solved a problem of broken headers after sieve forwarding that was
-caused by a bad handling of the CR (carriage return) by qmail-remote.
-The issue is also reported here http://www.dt.e-technik.uni-dortmund.de/~ma/qmail-bugs.html
-
-2012.04.16
--added qmail-tap
-
-2012.02.08
--added smtp-size patch
-
-2012.01.29
--added doublebounce-trim patch
-
-2011.12.12
--file update_tmprsadh modified to chown the .pem files to vpopmail to avoid hang-ups during the smtp
-conversation on port 587 caused by permission problems.
-
-2011.10.06
--qmail-remote.c: fixed. It was not going into tls on authentication (thanks to Krzysztof Gajdemski)
--force-tls now quits if the starttls command is not provided when required (thanks to Jacekalex)
-
-=================================================================================================================
-
+diff -ruN ../netqmail-1.06-original/CHANNELS netqmail-1.06/CHANNELS
+--- ../netqmail-1.06-original/CHANNELS	1970-01-01 01:00:00.000000000 +0100
++++ netqmail-1.06/CHANNELS	2019-06-26 16:39:31.572826981 +0200
+@@ -0,0 +1,100 @@
++CHANNELS by Reed Sandberg
++Copyright (c) 2007-2008 The SMB Exchange, INC
++
++This patch is free software; you can redistribute it and/or modify
++it under the Artistic License.
++
++This patch for (net)qmail comes with NO WARRANTY.
++
++RELEASE: November 15, 2008
++
++
++qmail manages two different queues
++with different configurable concurrency settings (rates) based on a set
++of domains - those delivered locally (control files: locals,
++virtualdomains, concurrencylocal) and those delivered remotely (domains
++not listed in  above control files and concurrencyremote). Luckily,
++qmail's author (DJB) spent some time abstracting the implementation of
++these channels and this patch advances the abstraction to add an
++arbitrary number of channels - each with a distinct set of domains and
++throttling capabilities.
++
++BIG PICTURE
++With ext_todo patch. Adapted from:
++EXTTODO by Claudio Jeker <jeker@n-r-g.com> and
++Andre Oppermann <opi@nrg4u.com>
++(c) 1998,1999,2000,2001,2002 Internet Business Solutions Ltd.
++
++
++               +-------+   +-------+       +-------+
++               | clean |   | clean |       | logger|
++               +--0-1--+   +--0-1--+       +---0---+           +-----------+
++         trigger  ^ |         ^ |              |             +->0,1 lspawn |
++            |     | v         | v              v            /  +-----------+
++ +-------+  v  +--2-3--+   +--5-6--------------0-------+   /
++ |       |  |  |       0<--7                         1,2<-+
++ | queue |--+--| todo  |   | send                      |
++ |       |  |  |       1-->8                         3,4<-+
++ +-------+     +-------+   +--11,12---...-------X,Y----+   \
++                                |                |          \  +-----------+
++                                v                v           +->0,1 rspwan |
++                            +--0,1-+         +--0,1-+          +-----------+
++                            |rspawn|  ...    |rspawn|    
++                            +------+         +------+       
++
++Communication between qmail-send and qmail-todo
++
++todo -> send:
++   D[01]{n}<mesgid>\0
++          Start delivery for a new message with id <mesgid>.
++          the character '0' or '1' indicates whether this message
++          will go through the corresponding channel (false/true)
++          by position where n is the number of channels. E.g. D1011<msgid>\0:
++          means there are four channels, the first 2 are always
++          the local and default remote channels, and the rest are
++          an optional number of supplemental channels (defined
++          at compile-time by conf-channels). So this message
++          has a local recipient, and a recipient on the first and
++          second supplemental channels.
++   L<string>\0
++          Dump string to the logger without adding additional \n or similar.
++send -> todo:
++   H      Got a SIGHUP, reread ~/control/locals, ~/control/virtualdomains,
++          ~/control/concurrencyremote, ~/control/concurrencylocal,
++          ~/control/concurrencysupplX, ~/control/supplsX
++   X      Quit ASAP.
++
++qmail-todo sends "\0" terminated messages whereas qmail-send just send one
++character to qmail-todo.
++
++
++CAVEATS
++qmail-qread ignores all supplemental channels - contributions are welcome!
++
++Supplemental channels use qmail-rspawn for remote recipients only.
++
++Dynamic throttling and resource limits
++File descriptor limits are imposed on a per-process basis (FD_SET), on a
++per-account basis (ulimit -n, /etc/security/limits.conf on Linux, pam limits, etc.)
++and then on a system-wide basis by the OS (/proc/sys/fs/file-max on Linux, etc).
++concurrencyremote, concurrencysupplX, etc are each subject to the hard limit in
++conf-spawn, which in turn is bounded by per-process limits. Note that this limit
++applies separately to each queue, not to all queues in total. The sum of all
++concurrency limits for each queue in total is bounded on a per-account basis
++(ulimit -n). These limits can easily be approached if you are running many
++supplemental channels.
++
++qmail double checks the concurrency limits on startup for each channel (using FD_SET)
++and silently curbs them if needed because bad things happen if this limit is breached.
++If you're sending qmail-send a HUP signal after editing concurrency limits (dynamic
++throttling) be aware that qmail's builtin checks can be circumvented, here's what
++qmail's author has to say on the subject (from chkspawn.c):
++This means that the qmail daemons could crash if you set the run-time concurrency higher
++than [the per-process limit].
++
++Even if the per-process limits are in check, per-account and system-wide file descriptor
++limits may still cause bad things to happen if you're not careful (you've been warned!).
++
++Enjoy!
++Reed Sandberg
++
 diff -ruN ../netqmail-1.06-original/CHKUSER.automatic_patching netqmail-1.06/CHKUSER.automatic_patching
 --- ../netqmail-1.06-original/CHKUSER.automatic_patching	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.automatic_patching	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.automatic_patching	2019-02-27 20:57:13.376025224 +0100
 @@ -0,0 +1,94 @@
 +Chkuser 2.0.9 automatic patching
@@ -536,5 +203,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.changelog netqmail-1.06/CHKUSER.changelog
 --- ../netqmail-1.06-original/CHKUSER.changelog	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.changelog	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.changelog	2019-02-27 20:57:13.376025224 +0100
 @@ -0,0 +1,183 @@
 +
@@ -723,5 +390,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.copyright netqmail-1.06/CHKUSER.copyright
 --- ../netqmail-1.06-original/CHKUSER.copyright	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.copyright	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.copyright	2019-02-27 20:57:13.376025224 +0100
 @@ -0,0 +1,15 @@
 +
@@ -742,5 +409,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.log_format netqmail-1.06/CHKUSER.log_format
 --- ../netqmail-1.06-original/CHKUSER.log_format	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.log_format	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.log_format	2019-02-27 20:57:13.376025224 +0100
 @@ -0,0 +1,69 @@
 +
@@ -815,5 +482,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.manual_patching netqmail-1.06/CHKUSER.manual_patching
 --- ../netqmail-1.06-original/CHKUSER.manual_patching	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.manual_patching	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.manual_patching	2019-02-27 20:57:13.377025213 +0100
 @@ -0,0 +1,182 @@
 +Chkuser 2.0 manual editing
@@ -1001,5 +668,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.readme netqmail-1.06/CHKUSER.readme
 --- ../netqmail-1.06-original/CHKUSER.readme	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.readme	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.readme	2019-02-27 20:57:13.377025213 +0100
 @@ -0,0 +1,54 @@
 +chkuser 2.0 - README
@@ -1059,5 +726,5 @@
 diff -ruN ../netqmail-1.06-original/CHKUSER.running netqmail-1.06/CHKUSER.running
 --- ../netqmail-1.06-original/CHKUSER.running	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/CHKUSER.running	2016-11-22 21:04:38.804137924 +0100
++++ netqmail-1.06/CHKUSER.running	2019-02-27 20:57:13.377025213 +0100
 @@ -0,0 +1,103 @@
 +
@@ -1166,5 +833,5 @@
 diff -ruN ../netqmail-1.06-original/FILES netqmail-1.06/FILES
 --- ../netqmail-1.06-original/FILES	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/FILES	2016-11-22 21:03:57.061529799 +0100
++++ netqmail-1.06/FILES	2019-06-26 16:39:31.573826970 +0200
 @@ -136,6 +136,8 @@
  dnsip.c
@@ -1202,12 +869,15 @@
  tryrsolv.c
  ip.h
-@@ -432,3 +439,4 @@
+@@ -432,3 +439,7 @@
  tcp-environ.5
  constmap.h
  constmap.c
 +qmail-todo.c
++channels.g
++conf-channels
++CHANNELS
 diff -ruN ../netqmail-1.06-original/LICENSE.authentication netqmail-1.06/LICENSE.authentication
 --- ../netqmail-1.06-original/LICENSE.authentication	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/LICENSE.authentication	2016-11-22 21:03:57.102528432 +0100
++++ netqmail-1.06/LICENSE.authentication	2019-02-27 20:57:13.377025213 +0100
 @@ -0,0 +1,43 @@
 +AUTHOR
@@ -1256,5 +926,5 @@
 diff -ruN ../netqmail-1.06-original/MakeArgs.c netqmail-1.06/MakeArgs.c
 --- ../netqmail-1.06-original/MakeArgs.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/MakeArgs.c	2016-11-22 21:03:57.102528432 +0100
++++ netqmail-1.06/MakeArgs.c	2019-02-27 20:57:13.377025213 +0100
 @@ -0,0 +1,144 @@
 +/*
@@ -1404,5 +1074,5 @@
 diff -ruN ../netqmail-1.06-original/Makefile netqmail-1.06/Makefile
 --- ../netqmail-1.06-original/Makefile	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/Makefile	2018-04-03 15:05:13.390470191 +0200
++++ netqmail-1.06/Makefile	2019-06-26 16:48:00.745225709 +0200
 @@ -1,5 +1,14 @@
  # Don't edit Makefile! Use conf-* for configuration.
@@ -1648,23 +1318,34 @@
  
  fs.a: \
-@@ -703,7 +754,7 @@
+@@ -702,8 +753,15 @@
+ 	./compile hfield.c
  
  hier.o: \
- compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h
+-compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h
 -	./compile hier.c
++compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h channels.h
 +	./compile $(DEFINES) hier.c
++
++channels.h: \
++conf-channels channels.g
++	cat channels.g \
++	| sed s}NUMCHANNELS}"`head -1 conf-channels`"}g \
++	> channels.h
++	chmod 644 channels.h
  
  home: \
  home.sh conf-qmail
-@@ -755,7 +806,7 @@
+@@ -754,8 +812,8 @@
+ 
  install-big.o: \
  compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \
- fifo.h
+-fifo.h
 -	./compile install-big.c
++fifo.h channels.h
 +	./compile $(DEFINES) install-big.c
  
  install.o: \
  compile install.c substdio.h strerr.h error.h open.h readwrite.h \
-@@ -777,38 +828,52 @@
+@@ -777,38 +835,52 @@
  	./compile ip.c
  
@@ -1729,5 +1410,5 @@
  load: \
  make-load warn-auto.sh systype
-@@ -890,6 +955,38 @@
+@@ -890,6 +962,38 @@
  readwrite.h open.h headerbody.h maildir.h strerr.h
  	./compile maildirwatch.c
@@ -1768,5 +1449,5 @@
  warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split
  	cat warn-auto.sh mailsubj.sh \
-@@ -934,8 +1031,9 @@
+@@ -934,8 +1038,9 @@
  preline.0 condredirect.0 bouncesaying.0 except.0 maildirmake.0 \
  maildir2mbox.0 maildirwatch.0 qmail.0 qmail-limits.0 qmail-log.0 \
@@ -1780,5 +1461,5 @@
  mbox.0: \
  mbox.5
-@@ -1107,11 +1205,80 @@
+@@ -1107,11 +1212,80 @@
  	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
  	> qmail-control.5
@@ -1862,5 +1543,5 @@
  qmail-getpw.0: \
  qmail-getpw.8
-@@ -1125,6 +1292,28 @@
+@@ -1125,6 +1299,28 @@
  	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
  	> qmail-getpw.8
@@ -1891,5 +1572,5 @@
  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 \
-@@ -1136,15 +1325,16 @@
+@@ -1136,15 +1332,16 @@
  	nroff -man qmail-header.5 > qmail-header.0
  
@@ -1911,5 +1592,5 @@
  qmail-inject.0: \
  qmail-inject.8
-@@ -1171,15 +1361,20 @@
+@@ -1171,15 +1368,20 @@
  	> qmail-limits.7
  
@@ -1936,5 +1617,5 @@
  qmail-local.0: \
  qmail-local.8
-@@ -1200,11 +1395,11 @@
+@@ -1200,11 +1402,11 @@
  qmail-lspawn: \
  load qmail-lspawn.o spawn.o prot.o slurpclose.o coe.o sig.a wait.a \
@@ -1950,5 +1631,5 @@
  qmail-lspawn.0: \
  qmail-lspawn.8
-@@ -1213,9 +1408,22 @@
+@@ -1213,9 +1415,22 @@
  qmail-lspawn.o: \
  compile qmail-lspawn.c fd.h wait.h prot.h substdio.h stralloc.h \
@@ -1974,5 +1655,5 @@
  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
-@@ -1269,11 +1477,13 @@
+@@ -1269,11 +1484,13 @@
  qmail-pop3d: \
  load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \
@@ -1990,5 +1671,5 @@
  qmail-pop3d.0: \
  qmail-pop3d.8
-@@ -1419,13 +1629,13 @@
+@@ -1419,13 +1636,13 @@
  	nroff -man qmail-qstat.8 > qmail-qstat.0
  
@@ -2010,5 +1691,5 @@
  qmail-queue.0: \
  qmail-queue.8
-@@ -1439,14 +1649,18 @@
+@@ -1439,14 +1656,18 @@
  
  qmail-remote: \
@@ -2033,5 +1714,5 @@
  qmail-remote.0: \
  qmail-remote.8
-@@ -1455,7 +1669,7 @@
+@@ -1455,7 +1676,7 @@
  qmail-remote.o: \
  compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \
@@ -2042,5 +1723,5 @@
  tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h
  	./compile qmail-remote.c
-@@ -1463,11 +1677,11 @@
+@@ -1463,11 +1684,11 @@
  qmail-rspawn: \
  load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \
@@ -2056,5 +1737,5 @@
  qmail-rspawn.0: \
  qmail-rspawn.8
-@@ -1475,20 +1689,21 @@
+@@ -1475,31 +1696,33 @@
  
  qmail-rspawn.o: \
@@ -2070,6 +1751,7 @@
  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
+-auto_split.o env.a
 -	./load qmail-send qsutil.o control.o constmap.o newfield.o \
++auto_split.o env.a auto_spawn.o
 +	./load qmail-send rcpthosts.o cdb.a srs.o qsutil.o control.o constmap.o newfield.o \
  	prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \
@@ -2077,19 +1759,34 @@
  	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
-+	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a \
++	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a auto_spawn.o \
 +	-I/usr/local/include -L/usr/local/lib -lsrs2
  
  qmail-send.0: \
  qmail-send.8
-@@ -1509,7 +1724,7 @@
+ 	nroff -man qmail-send.8 > qmail-send.0
+ 
+ qmail-send.8: \
+-qmail-send.9 conf-break conf-spawn
++qmail-send.9 conf-break conf-spawn conf-channels
+ 	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 \
++	| sed s}CHANNELS}"`head -1 conf-channels`"}g \
+ 	> qmail-send.8
+ 
+ qmail-send.o: \
+@@ -1508,8 +1731,8 @@
+ 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
+-fmtqfn.h readsubdir.h direntry.h
 -	./compile qmail-send.c
++fmtqfn.h readsubdir.h direntry.h channels.h auto_qmail.h
 +	./compile $(DEFINES) qmail-send.c
  
  qmail-showctl: \
  load qmail-showctl.o auto_uids.o control.o open.a getln.a stralloc.a \
-@@ -1528,21 +1743,26 @@
+@@ -1528,21 +1751,26 @@
  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 \
@@ -2129,5 +1826,5 @@
  qmail-smtpd.0: \
  qmail-smtpd.8
-@@ -1551,9 +1771,10 @@
+@@ -1551,9 +1779,10 @@
  qmail-smtpd.o: \
  compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
@@ -2143,14 +1840,16 @@
  
  qmail-start: \
-@@ -1574,7 +1795,7 @@
+@@ -1573,8 +1802,8 @@
+ 	> 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 fd.h prot.h exit.h fork.h auto_uids.h
 -	./compile qmail-start.c
++compile qmail-start.c fd.h prot.h exit.h fork.h auto_uids.h channels.h
 +	./compile $(DEFINES) qmail-start.c
  
  qmail-tcpok: \
  load qmail-tcpok.o open.a lock.a strerr.a substdio.a error.a str.a \
-@@ -1606,6 +1827,20 @@
+@@ -1606,6 +1835,20 @@
  fmt.h ip.h lock.h error.h exit.h datetime.h now.h datetime.h
  	./compile qmail-tcpto.c
@@ -2167,5 +1866,5 @@
 +compile alloc.h auto_qmail.h byte.h constmap.h control.h direntry.h error.h \
 +exit.h fmt.h fmtqfn.h getln.h open.h ndelay.h now.h readsubdir.h readwrite.h \
-+scan.h select.h str.h stralloc.h substdio.h trigger.h
++scan.h select.h str.h stralloc.h substdio.h trigger.h channels.h
 +	./compile $(DEFINES) qmail-todo.c
 +
@@ -2173,5 +1872,5 @@
  warn-auto.sh qmail-upq.sh conf-qmail conf-break conf-split
  	cat warn-auto.sh qmail-upq.sh \
-@@ -1639,10 +1874,10 @@
+@@ -1639,10 +1882,10 @@
  qreceipt: \
  load qreceipt.o headerbody.o hfield.o quote.o token822.o qmail.o \
@@ -2186,5 +1885,5 @@
  qreceipt.0: \
  qreceipt.1
-@@ -1779,7 +2014,7 @@
+@@ -1779,7 +2022,7 @@
  qmail-qread.c qmail-qstat.sh qmail-queue.c qmail-remote.c \
  qmail-rspawn.c qmail-send.c qmail-showctl.c qmail-smtpd.c \
@@ -2195,5 +1894,5 @@
  except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \
  maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \
-@@ -1813,8 +2048,9 @@
+@@ -1813,8 +2056,9 @@
  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 \
@@ -2207,5 +1906,5 @@
  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 \
-@@ -1824,10 +2060,11 @@
+@@ -1824,10 +2068,11 @@
  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 \
@@ -2221,5 +1920,5 @@
  	chmod 400 shar
  
-@@ -1897,6 +2134,23 @@
+@@ -1897,6 +2142,23 @@
  	./chkspawn
  	./compile spawn.c
@@ -2245,5 +1944,5 @@
  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 \
-@@ -1911,13 +2165,33 @@
+@@ -1911,13 +2173,33 @@
  scan.h fmt.h
  	./compile splogger.c
@@ -2285,5 +1984,5 @@
  str_chr.o: \
  compile str_chr.c str.h
-@@ -1927,6 +2201,10 @@
+@@ -1927,6 +2209,10 @@
  compile str_cpy.c str.h
  	./compile str_cpy.c
@@ -2296,5 +1995,5 @@
  compile str_diff.c str.h
  	./compile str_diff.c
-@@ -2006,6 +2284,11 @@
+@@ -2006,6 +2292,11 @@
  compile strerr_sys.c error.h strerr.h
  	./compile strerr_sys.c
@@ -2308,5 +2007,5 @@
  compile subfderr.c readwrite.h substdio.h subfd.h substdio.h
  	./compile subfderr.c
-@@ -2066,11 +2349,11 @@
+@@ -2066,11 +2357,11 @@
  
  tcp-env: \
@@ -2324,5 +2023,5 @@
  
  tcp-env.0: \
-@@ -2108,6 +2391,19 @@
+@@ -2108,6 +2399,19 @@
  compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h
  	./compile timeoutwrite.c
@@ -2344,5 +2043,5 @@
  compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \
  gen_alloc.h gen_allocdefs.h
-@@ -2139,3 +2435,165 @@
+@@ -2139,3 +2443,173 @@
  wait_pid.o: \
  compile wait_pid.c error.h haswaitp.h
@@ -2464,24 +2163,32 @@
 +	> dk-filter
 +
-+DKIMHDRS = dkim.h dkimdns.h dkimbase.h dkimsign.h dkimverify.h
++DKIMHDRS = dkim.h dkimdns.h dkimbase.h dkimsign.h dkimverify.h time_t_size.h
 +DKIMSRCS = dkimfuncs.cpp dkimbase.cpp
 +DKIMOBJS = $(DKIMSRCS:.cpp=.o)
-+dkim : libdkim.a dkim.o dkimdns.o
++dkim: libdkim.a dkim.o dkimdns.o
 +	g++ -o dkim $(LFLAGS) -L. dkim.o dkimdns.o libdkim.a `cat dns.lib` -lcrypto
 +
-+dkimverify.o: dkim.h dkimdns.h dkimverify.h dkimverify.cpp
-+	g++ -DHAVE_CONFIG_H -c dkimverify.cpp
++time_t_size.h: time_t_size.c compile load
++	(./compile time_t_size.c && ./load time_t_size && \
++        	./time_t_size) > time_t_size.h
++	rm -f time_t_size.o time_t_size
++
++dkimfuncs.o: dkimfuncs.cpp time_t_size.h
++	g++ -DHAVE_EVP_SHA256 -c dkimfuncs.cpp
++
++dkimverify.o: dkim.h dkimdns.h dkimverify.h dkimverify.cpp time_t_size.h
++	g++ -DHAVE_EVP_SHA256 -c dkimverify.cpp
 +
 +dkimsign.o: dkim.h dkimsign.h dkimsign.cpp
-+	g++ -DHAVE_CONFIG_H -c dkimsign.cpp
++	g++ -DHAVE_EVP_SHA256 -c dkimsign.cpp
 +
 +dkim.o: dkim.c $(DKIMHDRS)
-+	g++ -DHAVE_CONFIG_H -I. -DHAVE_EVP_SHA256 -c dkim.c
-+
-+libdkim.a: $(DKIMOBJS) dkimverify.o dkimsign.o makelib
++	g++ -DHAVE_EVP_SHA256 -I. -DHAVE_EVP_SHA256 -c dkim.c
++
++libdkim.a: $(DKIMOBJS) dkimverify.o dkimsign.o makelib time_t_size.h
 +	rm -f libdkim.a
 +	./makelib libdkim.a $(DKIMOBJS) dkimsign.o dkimverify.o
 +.cpp.o:
-+	g++ -I. -DHAVE_CONFIG_H $(CFLAGS) $(INCL) -c $<
++	g++ -I. -DHAVE_EVP_SHA256 $(CFLAGS) $(INCL) -c $<
 +
 +cert cert-req: \
@@ -2512,5 +2219,5 @@
 diff -ruN ../netqmail-1.06-original/Makefile-cert.mk netqmail-1.06/Makefile-cert.mk
 --- ../netqmail-1.06-original/Makefile-cert.mk	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/Makefile-cert.mk	2016-11-22 21:03:57.103528399 +0100
++++ netqmail-1.06/Makefile-cert.mk	2019-02-27 20:57:13.379025191 +0100
 @@ -0,0 +1,21 @@
 +cert-req: req.pem
@@ -2535,7 +2242,558 @@
 +	@echo "Send req.pem to your CA to obtain signed_req.pem, and do:"
 +	@echo "cat signed_req.pem >> QMAIL/control/servercert.pem"
+diff -ruN ../netqmail-1.06-original/README.PATCH netqmail-1.06/README.PATCH
+--- ../netqmail-1.06-original/README.PATCH	1970-01-01 01:00:00.000000000 +0100
++++ netqmail-1.06/README.PATCH	2020-07-29 21:22:44.084295087 +0200
+@@ -0,0 +1,547 @@
++v. 2020.07.29
++Combined patch for netqmail-1.06 by Roberto Puzzanghera [roberto dot puzzanghera at sagredo dot eu]
++More info at https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html
++==========================================================================================================
++
++= This patch puts together
++* Erwin Hoffmann's qmail-authentication patch v. 0.8.3, which updates the patches provided by
++  Krysztof Dabrowski and Bjoern Kalkbrenner.
++  It provides cram-md5, login, plain authentication support for qmail-smtpd and qmail-remote.
++  http://www.fehcom.de/qmail/smtpauth.html##PATCHES
++* Frederik Vermeulen's qmail-tls patch v. 20200107
++  implements SSL or TLS encrypted and authenticated SMTP.
++  http://inoa.net/qmail-tls/
++  The file update_tmprsadh was modified to chown all .pem files to vpopmail.
++* Marcel Telka's force-tls patch v. 2016.05.15
++  optionally gets qmail to require TLS before authentication to improve security.
++  You have to declare FORCETLS=0 if you want to allow the auth without TLS
++  https://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06_force-tls.patch-2012.10.28
++* Antonio Nati's chkuser patch v. 2.0.9
++  performs, among the other things, a check for the existence of recipients during the SMTP conversation,
++  bouncing emails of fake senders.
++  http://www.interazioni.it/opensource/chkuser/
++* Flavio Curti's qmail-queue-custom-error patch
++  enables simscan and qmail-dkim to return the appropriate message for each e-mail it refuses to deliver.
++  https://no-way.org/uploads/qmail-error/
++* Christophe Saout's qmail-SPF rc5 patch
++  Modified by Manvendra Bhangui to make it IPv4-mapped IPv6 addresses compliant.
++  checks incoming mails inside the SMTP daemon, add Received-SPF lines and optionally block undesired transfers.
++  http://www.saout.de/misc/spf/
++* Marcelo Coelho's qmail-SRS patch
++  implements Sender Rewriting Scheme fixing SPF break upon email forwarding.
++  http://www.mco2.com.br/opensource/qmail/srs/
++* Christopher K. Davis' oversize dns patch
++  enables qmail to handle large DNS packets.
++  http://www.ckdhr.com/ckd/qmail-103.patch
++* Jul's reread-concurrency v.2 patch
++  rereads control/concurrencylocal and control/concurrencyremote files when qmail-send receives a HUP signal.
++  http://js.hu/package/qmail/index.html
++* Johannes Erdfelt's Big Concurrency patch
++  sets the spawn limit above 255
++  http://qmail.org/big-concurrency.patch
++* Mihai Secasiu's Big Concurrency fix v.1.0 patch
++  fixes a compiler error if you set concurrency higher than 509 in conf-spawn.
++  http://patchlog.com/linux/qmail-big-concurrency/
++* Bill Shupp's netqmail-maildir++.patch
++  adds maildirquota support to qmail-pop3d and qmail-local.
++  Fixed a bug where the filesize part of the S=<filesize> component of the Maildir++ compatible filename
++  is wrong (tx MG). More info here:
++  https://notes.sagredo.eu/en/qmail-notes-185/installing-dovecot-and-sieve-on-a-vpopmail-qmail-server-28.html#comment995
++  https://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/netqmail-maildir.patch
++* Kyle B. Wheeler's "Better qmail-smtpd Logging" v.5 patch
++  facilitates diagnostics of qmail-smtpd logging its actions and decisions (search for a line with qmail-smtp:)
++  http://www.memoryhole.net/qmail/#logging
++* John Simpson's (?) Greeting delay patch
++  adds a user-definable delay after SMTP clients have initiated SMTP sessions, prior to qmail-smtpd responding
++  with "220 ESMTP". It can reject connections from clients which tried to send commands before greeting.
++  https://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/qmail-greetdelay.patch
++* Manvendra Bhangui's DKIM and SURBL filter v.1.28 patch
++  adds DKIM signing & verification and SURBL filtering support to qmail.
++  qmail-dk is based on Russ Nelson's patch: http//:www.qmail.org/qmail-1.03-dk-0.54.patch
++  qmail-dkim uses hacked libdkim libraries from libdkim project at http://libdkim.sourceforge.net/
++  surbfilter is built on djb functions and some functions have been ruthlessly borrowed from qmail surbl
++  interface by Pieter Droogendijk and the surblhost program at http://surblhost.sourceforge.net/
++  (file hier.c modified to chown /var/qmail/control/cache and subdirs to vpopmail)
++  http://sourceforge.net/projects/indimail/files/netqmail-addons/qmail-dkim-1.0/
++  http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/ANNOUNCE.surblfilter
++* Claudio Jeker and Andre Oppermann's EXTTODO patch (release 5. Jan. 2003)
++  addresses a problem known as the silly qmail (queue)  problem
++  http://www.nrg4u.com/qmail/ext_todo-20030105.patch
++* Russell Nelson's big-todo patch
++  makes qmail use a hashing mechanism in the todo folder similar to that used in the rest of the queue
++  http://www.qmail.org/big-todo.103.patch
++* Stephane Cottin's qmail-inject-null-sender patch (let's call it in this way)
++  prevents qmail-inject from rewriting the null sender, fixing an issue with sieve vacation/reject messages.
++  More info here: http://www.dovecot.org/list/dovecot/2009-June/040811.html
++  https://notes.sagredo.eu/files/qmail/patches/qmail-inject-null-sender.patch
++* Russell Nelson's (modified by Charles Cazabon) doublebounce-trim patch, which updates the original
++  version by Russel Nelson
++  prevents double bounces from hitting your queue a second time provided that you delete the first line
++  from /var/qmail/control/doublebounceto
++  http://qmail.org/doublebounce-trim.patch
++* Will Harris' esmtp-size patch
++  enables qmail-smtpd to reject messages if they're larger than the maximum number of bytes allowed
++  according to the /var/qmail/control/databytes control file.
++  http://will.harris.ch/qmail-smtpd.c.diff
++* Inter7's qmail-taps-extended patch
++  http://notes.sagredo.eu/files/qmail/patches/qmail-tap.diff
++  Extended by Michai Secasiu (http://patchlog.com/patches/qmail-taps-extended/)
++  Provides the ability to archive each email that flows through the system.
++  Archiving only messages from or to certain email addresses is possible as well.
++* Rolf Eike Beer's qmail-remote CRLF patch
++  enables qmail-remote to handle CR properly, always sending the line breaks as CRLF and avoiding to
++  double the CR (like qmail-remote normally does)
++  http://opensource.sf-tec.de/qmail/
++* Andy Repton's outgoingip patch (adjusted by Sergio Gelato)
++  by default all outgoing emails are sent through the first IP address on the interface. In case of a multiple
++  IP server this patch makes qmail send outgoing emails with the IP eventually stored in control/outgoingip.
++  The ehlo domain is NOT modified by this patch.
++  http://www.qmail.org/outgoingip.patch
++  Robbie Walker provided a patch to correct qmail-qmqpc.c's call to timeoutconn(), because the function
++  signature was modified by the original outgoingip patch
++  https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html#comment373
++* Iain Patterson's qmail-smtpd pid, qp log patch
++  makes qmail-smtpd log a line similar to the following:
++  @4000000039b89c95026a89b4 mail recv: pid 8155 from <name@domain.xy> qp 8157
++  The pid allows you to match the message up with a given tcpserver process and the qp lets you find a
++  particular delivery.
++  http://iain.cx/qmail/patches.html#smtpd_pidqp
++* Jonathan de Boyne Pollard's any-to-cname patch
++  avoids qmail getting large amounts of DNS data we have no interest in and that may overflow our response
++  buffer.
++  http://www.memoryhole.net/qmail/#any-to-cname
++* Matthias Andree's qmail-rfc2821 patch
++  makes qmail rfc2821 compliant
++  http://www-dt.e-technik.uni-dortmund.de/~ma/qmail/patch-qmail-1.03-rfc2821.diff
++* Jonathan de Boyne Pollard's smtpd-502-to-500 patch
++  makes qmail rfc2821 compliant
++  https://notes.sagredo.eu/files/qmail/patches/smtpd-502-to-500.patch
++* Fabio Busatto's qmail-dnsbl patch
++  allows you to reject spam and virus looking at the sender's ip address.
++  Modified by Luca Franceschini to add support for whitelists, TXT and A queries, configurable return codes
++  451 or 553 with custom messages
++  http://qmail-dnsbl.sourceforge.net/
++* Scott Gifford's qmail-moreipme patch v. 0.6
++  prevents a problem caused by an MX or other mail routing directive instructing qmail to connect to
++  itself without realizing it's connecting to itself, saving CPU time.
++  http://www.suspectclass.com/sgifford/qmail/qmail-1.03-moreipme.README
++  http://www.suspectclass.com/sgifford/qmail/qmail-1.03-moreipme-0.6.patch
++* Alex Nee's qmail-hide-ip-headers patch
++  It will hide your Private or Public IP in the email Headers when you are sending Mail as a Relay Client.
++  https://notes.sagredo.eu/files/qmail/patches/qmail-hide-ip-headers.patch
++* John Saunders' qmail-date-localtime patch
++  causes the various qmail programs to generate date stamps in the local timezone.
++  https://notes.sagredo.eu/files/qmail/patches/qmail-date-localtime.patch
++* Dean Gaudet's qmail-liberal-lf patch v. 0.95
++  allow qmail-smtpd to accept messages that are terminated with a single \n instead of the required \r\n
++  sequence.
++  http://www.arctic.org/~dean/patches/qmail-0.95-liberal-lf.patch
++* Michael Samuel's maxrcpt patch
++  allows you to set a limit on how many recipients are specified for any one email message by setting
++  control/maxrcpt. RFC 2821 section 4.5.3.1 says that an MTA MUST allow at least 100 recipients for each
++  message, since this is one of the favourite tricks of the spammer.
++  http://copilotco.com/mail-archives/qmail.1997/msg03066.html
++* Inter7's qmail-eMPF patch
++  More info: http://www.qmailwiki.org/EMPF
++  eMPF follows a set of administrator-defined rules describing who can message whom.  With this,
++  companies can segregate various parts of their organizations email activities, as well as provide a
++  variety of security-enhancing services.
++* qregex (by  Andrew St. Jean http://www.arda.homeunix.net/downloads-qmail/, contributors: Jeremy Kitchen,
++  Alex Pleiner,
++  Thanos Massias. Original patch by Evan Borgstrom)
++  adds the ability to match address evelopes via Regular Expressions (REs) in the qmail-smtpd process.
++  Added new control file 'badhelonorelay', control/badmailto renamed control/badrcptto (Tx Luca Franceschini).
++* brtlimit
++  Luca Franceschini derived this patch from http://netdevice.com/qmail/patch/goodrcptto-12.patch
++  added control/brtlimit and BRTLIMIT variable to limit max invalid recipient errors before closing
++  the connection (man qmail-control)
++* validrcptto
++  https://notes.sagredo.eu/files/qmail/patches/validrcptto.README
++  Luca Franceschini grabbed the code from several patches with additional features:
++  http://qmail.jms1.net/patches/validrcptto cdb.shtml,
++  http://netdevice.com/qmail/patch/goodrcptto-ms-12.patch, http://patch.be/qmail/badrcptto.html
++  It works in conjunction with chkuser with both cdb and mysql accounts.
++* reject-relay-test by Russell Nelson
++  http://qmail.org/qmail-smtpd-relay-reject
++  It gets qmail to reject relay probes generated by so-called anti-spammers. These relay probes have
++  '!', '%' and '@' in the local (username) part of the address.
++* Luca Franceschini
++  added DISABLETLS environment variable, useful if you want to disable TLS on a desired port
++  added FORCEAUTHMAILFROM environment variable to REQUIRE that authenticated user and 'mail from' are identical
++  added SMTPAUTHMETHOD, SMTPAUTHUSER and SMTP_AUTH_USER env variables for external plugins (see
++  http://qmail-spp.sourceforge.net/doc/)
++* fixed little bug in 'mail from' address handling
++  patch by Andre Opperman at http://qmail.cr.yp.narkive.com/kBry6GJl/bug-in-qmail-smtpd-c-addrparse-function
++* Luca Franceschini's qlog patch
++  smtpd logging with fixed format. An entry 'qlogenvelope' is generated after accepting or rejecting
++  every recipients in the envelope phase.
++* Luca Franceschini's reject null senders patch
++  useful in special cases if you temporarily need to reject the null sender (although breaks RFC compatibility).
++  You just need to put 1 (actually any number different from 0) in your control/rejectnullsenders to reject
++  the null sender with 421 error message.
++* dnscname patch
++  Removes CNAME check in order to avoid getting large amounts of data of no interest in and that may
++  overflow the response buffer.
++  https://lists.gt.net/qmail/users/138190
++* Luca Franceschini's rcptcheck patch
++  (based on original patch from Jay Soffian (http://www.soffian.org/downloads/qmail/qmail-smtpd-doc.html)
++  Originally designed for the purpose of receipt validation, it can also be used to limit the numbr of
++  email a given IP and/or auth-user and/or domain can send in a given time interval. It has to be used
++  in conjuction with the rcptcheck-overlimit.sh LF's script
++  https://notes.sagredo.eu/files/qmail/rcptcheck-overlimit.sh
++  https://notes.sagredo.eu/files/qmail/patches/rcptcheck.patch
++* Reed Sandberg's qmail-channels patch
++  Allows you to add an arbitrary number of supplemental remote queues, each distinguished by a list of
++  recipient domains and separate throttling (concurrency) capabilities. This patch also allows dynamic
++  throttling of the concurrency control files so you can just send qmail-send a HUP signal instead of
++  restarting the service every time.
++  This patch is useful when some email providers complain of too many emails receveid at the same time
++  (in case of news letters for instance). Look here for more info
++  https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html#comment1328
++  Edit conf-channels before compiling: Total number of channels (queues) available for delivery. Must be at
++  least 2, and anything above 2 are considered supplemental channels.
++  http://www.thesmbexchange.com/eng/qmail-channels_patch.html
++* Endersys R&D team's qmail-remote-logging patch
++  gets qmail-remote to log sender, recipient and IP adddress all together in the "Delivery success/failure" line
++  https://web.archive.org/web/20120530051612/http://blog.endersys.com/2009/12/qmail-canonicalised-recipient-logging-and-more-patch/
++* notqmail.org's cve-2005-1513 patch
++  addresses a vulnerability issue spotted by Georgi Guninski in 2005
++  https://www.qualys.com/2020/05/19/cve-2005-1513/remote-code-execution-qmail.txt
++
++= Disclaimer
++This patch comes with the usual warranty: it works for me, it may not work for you,
++use at your own risk etc. etc. :)
++Comments, suggestions, criticisms are always welcome!
++
++= Usage
++
++* Install libdomainkeys
++wget https://notes.sagredo.eu/files/qmail/tar/libdomainkeys-0.69.tar.gz
++tar xzf libdomainkeys-0.69.tar.gz
++wget https://notes.sagredo.eu/files/qmail/patches/libdomainkeys/libdomainkeys-openssl-1.1.patch
++wget https://notes.sagredo.eu/files/qmail/patches/libdomainkeys-0.69.diff
++cd libdomainkeys-0.69
++chown -R root.root .
++patch -p1 < ../libdomainkeys-openssl-1.1.patch
++patch < ../libdomainkeys-0.69.diff
++make
++cp libdomainkeys.a /usr/lib
++
++* Install libsrs2
++wget https://notes.sagredo.eu/files/qmail/tar/libsrs2-1.0.18.tar.gz
++tar xzf libsrs2-1.0.18.tar.gz
++cd libsrs2-1.0.18
++./configure
++make
++make install
++ldconfig
++cd ../
++
++* Apply the patch and compile
++wget https://notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06.patch-latest.gz
++wget http://qmail.org/netqmail-1.06.tar.gz
++tar xzf netqmail-1.06.tar.gz
++cd netqmail-1.06
++chown -R root.root .
++gunzip -c ../roberto-netqmail-1.06.patch-latest.gz | patch
++make
++make setup check
++
++* You have to export SMTPAUTH in your run file if you want to do the auth
++
++* You have to export SURBL=1 in your run file if you want to enable SURBL
++
++* /var/qmail/control/cache must be owned by the user who runs qmail-smtpd, vpopmail.vchkpwd in my case.
++  Change the permissions according to your qmail configuration.
++
++=================================================================================================================
++
++= Changelog
++
++2020.07.29
++-dk-filter: corrected a bug where dk-filter was using DKIMDOMAIN unconditionally. Now it uses DKIMDOMAIN 
++ only if _SENDER is null (tx Manvendra Bhangui).
++
++2020.07.27
++-added cve-2005-1513 patch
++
++2020.04.25
++-qmail-smtpd.c: added rcptcount = 0; in smtp_rset function to prevent the maxrcpto error if control/maxrcpt limit
++ has been exceeded in multiple messages sent sequentially rather than in a single mail (tx Alexandre Fonceca).
++ More info here: https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html#comment1594
++
++2020.04.16
++-qmail-remote-logging patch added
++
++2020.04.10
++-DKIM patch updated to v. 1.28
++ * outgoing messages from null sender ("<>") will be signed as well with the domain in env variable DKIMDOMAIN
++ * declaring NODK env variable disables old domainkeys signature, while defining NODKIM disables DKIM.
++
++2020.01.11
++-qmail-tls patch updated to v. 20200107
++ * working client cert authentication with TLSv1.3 (Rolf Eike Beer)
++
++2019.12.08
++-BUG qmail-smtpd.c: now TLS is defined before chkuser.h call, to avoid errors on closing the db connection
++ (tx ChangHo.Na https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html#comment1469)
++
++2019.07.12
++-qmail-channels patch added
++ more info here http://www.thesmbexchange.com/eng/qmail-channels_patch.html
++-improved verbosity of die_read function in qmail-smtpd.c (qmail-smtpd: read failure)
++ more info here https://notes.sagredo.eu/files/qmail/patches/roberto-netqmail-1.06/die_read.patch
++
++2019.06.19
++-DKIM patch updated to v. 1.26
++ * BUG - honor body length tag in verification
++
++2019.05.24
++-qmail-tls updated to v. 20190517
++ * bug: qmail-smtpd ssl_free before tls_out error string (K. Wheeler)
++
++2019.05.23
++-DKIM patch updated to v. 1.25
++ * SIGSEGV - when the txt data for domainkeys is very large exposed a bug in the way realloc() was used incorrectly.
++ * On 32 bit systems, variable defined as time_t overflows. Now qmail-dkim will skip expiry check in such conditions.
++
++2019.04.25
++-bug fixed on qmail-smtpd.c: it was selecting the wrong openssl version on line 2331 (tx ChangHo.Na)
++
++2019.04.09
++-qmail-tls updated to v. 20190408
++ * make compatible with openssl 1.1.0 (Rolf Eike Beer, Dirk Engling, Alexander Hof)
++ * compiler warnings on char * casts (Kai Peter)
++
++2019.03.22
++-fixed a bug causing crashes with qmail-remote when using openssl-1.1 (tx Luca Franceschini)
++(https://notes.sagredo.eu/files/qmail//patches//roberto-netqmail-1.06/2019.03.22-fix.patch)
++
++2019.02.13
++-Port to openssl-1.1
++-DKIM patch updated to v. 1.24
++ * bug fix: restored signaturedomains/nosignaturedomains functionalities.
++
++2018.08.25
++-DKIM patch updated to v. 1.23
++ * fixed a bug where including round brackets in the From: field ouside the double quotes, i.e.
++   From: "Name Surname (My Company)" <name.surname@company.com>, results in a DKIMContext structure invalid
++   error (tx Mirko Buffoni).
++ * qmail-dkim and dkim were issuing a failure for emails which had multiple signature with at least one good
++   signature. Now qmail-dkim and dkim will issue a success if at least one good signature is found.
++
++2018.08.23
++-logging patch
++ * fixed a bug in logit and logit2 functions where after a RSET command and a subsequent brutal quit
++   of the smtp conversation '^]' by the client cause a segfault (tx Mirko Buffoni, more info here
++   https://notes.sagredo.eu/en/qmail-notes-185/patching-qmail-82.html#comment1132)
++-patch info moved to 'README.PATCH' file
++
++2018.04.03
++-DKIM patch updated to v. 1.22
++ * openssl 1.1.0 port
++ * various improvements, bug fixes
++
++2018.01.10
++-maildir++
++ * fixed a bug where the filesize part of the S=<filesize> component of the Maildir++ compatible filename
++   is wrong (tx MG). More info here: http://notes.sagredo.eu/en/qmail-notes-185/installing-dovecot-and-sieve-on-a-
++vpopmail-qmail-server-28.html#comment995
++-qmail-queue-extra
++ * removed, because it was causing more problems than advantages, as the domain of the log@yourdomain.tld
++   had to match the system domain inside control/me and shouldn't be a virtual domain as well.
++
++2017.10.11 (tx Luca Franceschini)
++-qlogfix
++ * log strings should terminate with \n to avoid trailing ^M using splogger
++ * bug reporting custom errors from qmail-queue in qlog
++-added dnscname patch
++-added rcptcheck patch
++
++2017.08.18
++-qmail-smtpd now retains authentication upon rset
++ (tx to Andreas http://notes.sagredo.eu/qmail-notes-185/smtp-auth-qmail-tls-forcetls-patch-for-qmail-84.html#comme
++nt750)
++
++2017-05-14
++-DKIM patch updated to v. 1.20
++ It now manages long TXT records, avoiding the rejection of some hotmail.com messages.
++
++2016-12-19
++-Several new patches and improvements added (thanks to Luca Franceschini)
++More info here http://notes.sagredo.eu/node/178
++ -qregex patch
++ -brtlimit patch
++ -validrcptto patch
++ -rbl patch (updates qmail-dnsbl patch)
++ -reject-relay-test patch
++ -added DISABLETLS environment variable, useful if you want to disable TLS on a desired port
++ -added FORCEAUTHMAILFROM environment variable to REQUIRE that authenticated user and 'mail from' are identical
++ -fixed little bug in 'mail from' address handling (patch by Andre Opperman at http://qmail.cr.yp.narkive.com/kBry
++  6GJl/bug-in-qmail-smtpd-c-addrparse-function)
++ -added SMTPAUTHMETHOD, SMTPAUTHUSER and SMTP_AUTH_USER env variables for external plugins
++ -qlog patch
++ -reject null senders patch
++ -bouncecontrolmime patch
++ -qmail-taps-extended (updates qmail-tap)
++
++2016-12-02
++-fixed BUG in qmail-remote.c: in case of remote server who doesn't allow EHLO the response for an alternative
++ HELO was checked twice, making the connection to die. (Thanks to Luca Franceschini)
++ Patch applied: http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/fix_sagredo_remotehelo.patch
++
++2016-09-19
++-qmail-tls patch updated to v. 20160918
++  * bug: qmail-remote accepting any dNSName, without checking that is matches (E. Surovegin)
++  * bug: documentation regarding RSA and DH keys (K. Peter, G. A. Bofill)
++
++2016-05-15
++-force-tls patch improved (a big thanks to Marcel Telka). Now qmail-smtpd avoids to write the auth verb if the
++ the STARTTLS command was not sent by the client
++
++2016-03-09
++-DKIM patch upgraded to v. 1.19
++ * verification will not fail when a dkim signature does not include the subject provided that the
++   UNSIGNED_SUBJECT environment variable is declared.
++
++2015-12-26
++-qmail-tls patch updated to v. 20151215
++ * typo in #if OPENSSL_VERSION_NUMBER for 2015-12-08 patch release (V. Smith)
++ * add ECDH to qmail-smtpd
++ * increase size of RSA and DH pregenerated keys to 2048 bits
++ * qmail-smtpd sets RELAYCLIENT if relaying allowed by cert
++ more info at http://inoa.net/qmail-tls/
++
++2015-12-15
++-DKIM patch by Manvendra Bhangui updated to v. 1.18
++
++2015-10-03
++-qmail-authentication: updated to v. 0.8.3
++
++2015-08-08
++-fixed a bug on qmail-remote.c that was causing the sending of an additionale ehlo greeting (thanks to Cristoph Gr
++over)
++
++2015-04-11
++-qmail-authentication: updated to v. 0.8.2
++-qmail-tls: upgraded to v. 20141216 (POODLE vulnerability fixed)
++
++2015-03-28
++-added qmail-eMPF patch
++
++2014-11-19
++-security fix: the SSLv3 connection is now switched off
++
++2014-11-15
++-modified the QUEUE_EXTRA variable in extra.h to improve the qmail-send's log
++
++2014-04-14
++-added maxrcpt patch
++
++2014-03-10
++-added qmail-0.95-liberal-lf patch
++
++2013-12-30
++-added qmail-srs
++-the character "=" is now considered valid in the sender address by chkuser in order to accept SRS
++
++2013-12-18
++-added qmail-date-localtime patch
++
++2013-12-14
++-added qmail-hide-ip patch
++
++2013-12-10
++-the original greetdelay by e.h. has been replaced with the improved patch by John Simpson. Now
++ communications trying to send commands before the greeting will be closed. Premature disconnections will be
++ logged as well.
++-CHKUSER_SENDER_FORMAT enabled to reject fake senders without any domain declared (like <foo>)
++-chkuser logging: I slightly modified the log line adding the variables' name just to facilitate its interpretation
++-added qmail-moreipme patch
++
++2013-12-07
++-added qmail-dnsbl patch
++
++2013-12-05
++-added two patches to make qmail rfc2821 compliant
++
++2013-11-23
++-added any-to-cname patch
++
++2013-09-27
++-DKIM patch upgraded to v. 1.17. Defined -DHAVE_SHA_256 while compiling dkimverify.cpp in the Makefile.
++ This solved an issue while verifying signatures using sha256.
++
++2013-09-16
++-Minor fixes to the DKIM patch.
++
++2013-09-13
++-DKIM patch upgraded to v. 1.16. The signing at qmail-remote level has been revised by its author.
++
++2013-08-25
++-qmail-qmqpc.c call to timeoutconn() needed a correction because the function signature was modified by the
++ outgoingip patch. Thanks to Robbie Walker (diff here http://notes.sagredo.eu/node/82#comment-373)
++
++2013-08-21
++-fixed a bug in hier.c which caused the installation not to build properly the queue/todo dir structure (thanks to
++ Scott Ramshaw)
++
++2013-08-18
++-DKIM-SURBL patch by Manvendra Bhangui updated to v. 1.14
++
++2013-08-12
++-DKIM patch upgraded to v. 1.12. The new patch adds surblfilter functionality.
++-added qmail-smtpd pid, qp log patch
++
++2013-08-08
++-qmail-SPF modified by Manvendra Bhangui to make it IPv6-mapped IPv4 addresses compliant. In order to have it
++ working with such addresses you have to patch tcpserver.c accordingly. You can use a patch fot ucspi-tcp6-0.98
++ by Manvendra Bhangui at http://notes.sagredo.eu/sites/notes.sagredo.eu/files/qmail/patches/tcpserver-ipv6mapped_ip
++ v4.patch or wait for v. 0.99 relase of ucspi-tcp6
++-added outgoingip patch
++-added qmail-bounce patch
++
++2013-03-31
++qmail-auth updated to latest v. 0.8.1 Added authentication by recipient domain for qmail-remote.
++Look at README.auth for further details
++
++2013-02-11
++some code adjustments in qmail-smtpd.c smtpd_ehlo() to restore total compatibility with esmtp-size patch
++
++2013-02-08
++qmail-auth updated to latest v. 0.7.6. Look at README.auth for further details
++
++2013-01-28
++fixed an issue on qmail-pop3d which was causing a double +OK after the pass command (thanks to Rakesh, Orbit
++and Simplex for helping in testing and troubleshooting)
++
++2013-01-06
++environment variable GREETDELAY renamed to SMTPD_GREETDELAY
++
++2012-10-31
++qmail-auth updated to latest v. 0.7.5. Look at README.auth for further details
++The qmail-forcetls patch was simplyfied accordingly.
++You MUST export SMTPAUTH="" in your run file now.
++
++2012-04-25
++-added qmail-remote CRLF (thanks to Pierre Lauriente for the help on testing and troubleshooting)
++The qmail-remote CRLF patch solved a problem of broken headers after sieve forwarding that was
++caused by a bad handling of the CR (carriage return) by qmail-remote.
++The issue is also reported here http://www.dt.e-technik.uni-dortmund.de/~ma/qmail-bugs.html
++
++2012.04.16
++-added qmail-tap
++
++2012.02.08
++-added smtp-size patch
++
++2012.01.29
++-added doublebounce-trim patch
++
++2011.12.12
++-file update_tmprsadh modified to chown the .pem files to vpopmail to avoid hang-ups during the smtp
++conversation on port 587 caused by permission problems.
++
++2011.10.06
++-qmail-remote.c: fixed. It was not going into tls on authentication (thanks to Krzysztof Gajdemski)
++-force-tls now quits if the starttls command is not provided when required (thanks to Jacekalex)
 diff -ruN ../netqmail-1.06-original/README.auth netqmail-1.06/README.auth
 --- ../netqmail-1.06-original/README.auth	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.auth	2016-11-22 21:03:57.103528399 +0100
++++ netqmail-1.06/README.auth	2019-02-27 20:57:13.379025191 +0100
 @@ -0,0 +1,154 @@
 +README qmail SMTP Authentication
@@ -2695,5 +2953,5 @@
 diff -ruN ../netqmail-1.06-original/README.dnsbl netqmail-1.06/README.dnsbl
 --- ../netqmail-1.06-original/README.dnsbl	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.dnsbl	2016-11-30 21:50:01.459033083 +0100
++++ netqmail-1.06/README.dnsbl	2019-02-27 20:57:13.379025191 +0100
 @@ -0,0 +1,18 @@
 +Code and logic from rblsmtpd and qmail-dnsbl patch http://qmail-dnsbl.sourceforge.net/
@@ -2717,5 +2975,5 @@
 diff -ruN ../netqmail-1.06-original/README.empf netqmail-1.06/README.empf
 --- ../netqmail-1.06-original/README.empf	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.empf	2016-11-22 21:03:57.103528399 +0100
++++ netqmail-1.06/README.empf	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,106 @@
 +config file is: /var/qmail/control/policy
@@ -2827,5 +3085,5 @@
 diff -ruN ../netqmail-1.06-original/README.exttodo netqmail-1.06/README.exttodo
 --- ../netqmail-1.06-original/README.exttodo	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.exttodo	2016-11-22 21:03:57.103528399 +0100
++++ netqmail-1.06/README.exttodo	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,114 @@
 +EXTTODO by Claudio Jeker <jeker@n-r-g.com> and 
@@ -2945,5 +3203,5 @@
 diff -ruN ../netqmail-1.06-original/README.liberal-lf netqmail-1.06/README.liberal-lf
 --- ../netqmail-1.06-original/README.liberal-lf	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.liberal-lf	2016-11-22 21:03:57.103528399 +0100
++++ netqmail-1.06/README.liberal-lf	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,39 @@
 +From dgaudet-list-qmail@arctic.org Fri Jan 17 17:50:19 1997
@@ -2988,5 +3246,5 @@
 diff -ruN ../netqmail-1.06-original/README.maxrcpt netqmail-1.06/README.maxrcpt
 --- ../netqmail-1.06-original/README.maxrcpt	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.maxrcpt	2016-11-22 21:03:57.104528366 +0100
++++ netqmail-1.06/README.maxrcpt	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,60 @@
 +maxrcpt patch for qmail-smtpd
@@ -3052,5 +3310,5 @@
 diff -ruN ../netqmail-1.06-original/README.moreipme netqmail-1.06/README.moreipme
 --- ../netqmail-1.06-original/README.moreipme	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.moreipme	2016-11-22 21:03:57.104528366 +0100
++++ netqmail-1.06/README.moreipme	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,154 @@
 +###########
@@ -3210,5 +3468,5 @@
 diff -ruN ../netqmail-1.06-original/README.qregex netqmail-1.06/README.qregex
 --- ../netqmail-1.06-original/README.qregex	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.qregex	2016-11-22 21:04:38.822137319 +0100
++++ netqmail-1.06/README.qregex	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,203 @@
 +QREGEX (v2) 20060423 - README April 23, 2006
@@ -3417,5 +3675,5 @@
 diff -ruN ../netqmail-1.06-original/README.rfc2821 netqmail-1.06/README.rfc2821
 --- ../netqmail-1.06-original/README.rfc2821	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.rfc2821	2016-11-22 21:03:57.104528366 +0100
++++ netqmail-1.06/README.rfc2821	2019-02-27 20:57:13.380025180 +0100
 @@ -0,0 +1,39 @@
 +This patch is Copyright (C) 2002 - 2003 by Matthias Andree. License below.
@@ -3460,5 +3718,5 @@
 diff -ruN ../netqmail-1.06-original/README.srs netqmail-1.06/README.srs
 --- ../netqmail-1.06-original/README.srs	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.srs	2016-11-22 21:03:57.104528366 +0100
++++ netqmail-1.06/README.srs	2019-02-27 20:57:13.381025169 +0100
 @@ -0,0 +1,93 @@
 +qmail SRS patch
@@ -3557,5 +3815,5 @@
 diff -ruN ../netqmail-1.06-original/README.surbl netqmail-1.06/README.surbl
 --- ../netqmail-1.06-original/README.surbl	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.surbl	2016-11-22 21:03:57.104528366 +0100
++++ netqmail-1.06/README.surbl	2019-02-27 20:57:13.381025169 +0100
 @@ -0,0 +1,34 @@
 +SURBL filter for netqmail
@@ -3595,5 +3853,5 @@
 diff -ruN ../netqmail-1.06-original/README.tap netqmail-1.06/README.tap
 --- ../netqmail-1.06-original/README.tap	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.tap	2016-11-22 21:04:38.822137319 +0100
++++ netqmail-1.06/README.tap	2019-02-27 20:57:13.381025169 +0100
 @@ -0,0 +1,34 @@
 +qmail provides the ability to make a copy of each email that flows through the system.
@@ -3633,10 +3891,10 @@
 diff -ruN ../netqmail-1.06-original/README.tls netqmail-1.06/README.tls
 --- ../netqmail-1.06-original/README.tls	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/README.tls	2016-11-22 21:03:57.104528366 +0100
-@@ -0,0 +1,100 @@
-+Frederik Vermeulen <qmail-tls akrul inoa.net> 20160918
++++ netqmail-1.06/README.tls	2020-01-10 21:46:22.909448586 +0100
+@@ -0,0 +1,98 @@
++Frederik Vermeulen <qmail-tls akrul inoa.net> 20200107
 +http://inoa.net/qmail-tls/
 +
-+This patch implements RFC 3207 (was RFC 2487) in qmail. 
++This patch implements RFC 3207 in qmail. 
 +This means you can get SSL or TLS encrypted and 
 +authenticated SMTP between the MTAs and from MUA to MTA. 
@@ -3644,7 +3902,7 @@
 +many since its first release on 1999-03-21).
 +
-+Usage: - install OpenSSL-1.0.2 http://www.openssl.org/ or later
-+         (any version since 0.9.6 is presumed to work)
-+       - apply patch to netqmail-1.06 http://qmail.org/netqmail
++Usage: - install OpenSSL-1.1.0 http://www.openssl.org/ or later
++         (any version since 0.9.8 is presumed to work)
++       - apply patch to netqmail-1.06 http://www.usenix.org.uk/mirrors/qmail/netqmail
 +         The patches to qmail-remote.c and qmail-smtpd.c can be applied 
 +         separately.
@@ -3709,6 +3967,4 @@
 +         - this patch could conflict with other patches (notably those
 +           replacing \n with \r\n, which is a bad idea on encrypted links).
-+         - some broken servers have a problem with TLSv1 compatibility.
-+           Uncomment the line where we set the SSL_OP_NO_TLSv1 option.
 +         - needs working /dev/urandom (or EGD for openssl versions >0.9.7)
 +           for seeding random number generator.
@@ -3737,5 +3993,5 @@
 diff -ruN ../netqmail-1.06-original/TARGETS netqmail-1.06/TARGETS
 --- ../netqmail-1.06-original/TARGETS	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/TARGETS	2016-11-22 21:04:20.043763470 +0100
++++ netqmail-1.06/TARGETS	2019-06-26 16:45:45.017718421 +0200
 @@ -1,3 +1,4 @@
 +dktest
@@ -3852,5 +4108,5 @@
  qmail-local.0
  qmail-lspawn.0
-@@ -382,6 +415,51 @@
+@@ -382,6 +415,54 @@
  addresses.0
  envelopes.0
@@ -3904,8 +4160,12 @@
 +dknewkey
 +dktest.8
++time_t_size.h
++channels.h
++
 diff -ruN ../netqmail-1.06-original/alloc.c netqmail-1.06/alloc.c
 --- ../netqmail-1.06-original/alloc.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/alloc.c	2016-11-22 21:03:57.105528332 +0100
-@@ -1,6 +1,6 @@
++++ netqmail-1.06/alloc.c	2020-07-27 13:06:47.995674192 +0200
+@@ -1,6 +1,7 @@
++#include <limits.h>
  #include "alloc.h"
  #include "error.h"
@@ -3915,7 +4175,18 @@
  
  #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
+@@ -15,6 +16,10 @@
+ unsigned int n;
+ {
+   char *x;
++  if (n >= (INT_MAX >> 3)) {
++    errno = error_nomem;
++    return 0;
++  }
+   n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
+   if (n <= avail) { avail -= n; return space + avail; }
+   x = malloc(n);
 diff -ruN ../netqmail-1.06-original/base64.c netqmail-1.06/base64.c
 --- ../netqmail-1.06-original/base64.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/base64.c	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/base64.c	2019-02-27 20:57:13.381025169 +0100
 @@ -0,0 +1,124 @@
 +#include "base64.h"
@@ -4045,5 +4316,5 @@
 diff -ruN ../netqmail-1.06-original/base64.h netqmail-1.06/base64.h
 --- ../netqmail-1.06-original/base64.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/base64.h	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/base64.h	2019-02-27 20:57:13.381025169 +0100
 @@ -0,0 +1,13 @@
 +#ifndef BASE64_H
@@ -4062,5 +4333,5 @@
 diff -ruN ../netqmail-1.06-original/base64sub.c netqmail-1.06/base64sub.c
 --- ../netqmail-1.06-original/base64sub.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/base64sub.c	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/base64sub.c	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,170 @@
 +/*
@@ -4236,5 +4507,5 @@
 diff -ruN ../netqmail-1.06-original/byte.h netqmail-1.06/byte.h
 --- ../netqmail-1.06-original/byte.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/byte.h	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/byte.h	2019-02-27 20:57:13.382025158 +0100
 @@ -3,6 +3,8 @@
  
@@ -4248,5 +4519,5 @@
 diff -ruN ../netqmail-1.06-original/byte_cspn.c netqmail-1.06/byte_cspn.c
 --- ../netqmail-1.06-original/byte_cspn.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/byte_cspn.c	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/byte_cspn.c	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,11 @@
 +#include "byte.h"
@@ -4263,5 +4534,5 @@
 diff -ruN ../netqmail-1.06-original/byte_rcspn.c netqmail-1.06/byte_rcspn.c
 --- ../netqmail-1.06-original/byte_rcspn.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/byte_rcspn.c	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/byte_rcspn.c	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,17 @@
 +#include "byte.h"
@@ -4284,5 +4555,5 @@
 diff -ruN ../netqmail-1.06-original/caldate.h netqmail-1.06/caldate.h
 --- ../netqmail-1.06-original/caldate.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/caldate.h	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/caldate.h	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,24 @@
 +/*
@@ -4312,5 +4583,5 @@
 diff -ruN ../netqmail-1.06-original/caltime.h netqmail-1.06/caltime.h
 --- ../netqmail-1.06-original/caltime.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/caltime.h	2016-11-22 21:03:57.105528332 +0100
++++ netqmail-1.06/caltime.h	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,30 @@
 +/*
@@ -4346,5 +4617,5 @@
 diff -ruN ../netqmail-1.06-original/case_startb.c netqmail-1.06/case_startb.c
 --- ../netqmail-1.06-original/case_startb.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/case_startb.c	2016-11-22 21:03:57.106528299 +0100
++++ netqmail-1.06/case_startb.c	2019-02-27 20:57:13.382025158 +0100
 @@ -0,0 +1,31 @@
 +#include "case.h"
@@ -4379,7 +4650,29 @@
 +}
 +/* end DKIM 1.10 */
+diff -ruN ../netqmail-1.06-original/channels.g netqmail-1.06/channels.g
+--- ../netqmail-1.06-original/channels.g	1970-01-01 01:00:00.000000000 +0100
++++ netqmail-1.06/channels.g	2019-06-26 16:39:31.572826981 +0200
+@@ -0,0 +1,18 @@
++#ifndef CHANNELS_H
++#define CHANNELS_H
++
++/* total number of channels including canonical "local" and "remote" channels */
++#define CHANNELS NUMCHANNELS
++
++/* supplemental channels are all channels less the canonical "local" and "remote" channels */
++#define SUPPL_CHANNELS (CHANNELS - 2)
++
++/* Not longer than 80 bytes, must also change qmail-upq.sh */
++#define QDIR_BASENAME "suppl"
++
++/* start supplemental channel fd numbers here */
++#define CHANNEL_FD_OFFSET 10
++
++
++#endif
++
 diff -ruN ../netqmail-1.06-original/chkspawn.c netqmail-1.06/chkspawn.c
 --- ../netqmail-1.06-original/chkspawn.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/chkspawn.c	2016-11-22 21:03:57.106528299 +0100
++++ netqmail-1.06/chkspawn.c	2019-02-27 20:57:13.382025158 +0100
 @@ -22,8 +22,8 @@
      _exit(1);
@@ -4395,6 +4688,6 @@
 diff -ruN ../netqmail-1.06-original/chkuser.c netqmail-1.06/chkuser.c
 --- ../netqmail-1.06-original/chkuser.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/chkuser.c	2016-11-22 21:04:19.987765257 +0100
-@@ -0,0 +1,1258 @@
++++ netqmail-1.06/chkuser.c	2019-08-05 19:11:16.583873852 +0200
+@@ -0,0 +1,1266 @@
 +
 +/*
@@ -4878,5 +5171,13 @@
 +                } else if (strcasecmp(starting_string, "DOMAIN") == 0) {
 +                        starting_value = 0;
-+                }
++/*
++  Edit by Roberto Puzzanghera
++  It seems like any other definition of starting_string ends up as "DOMAIN".
++  Instead, if starting_string is otherwise defined, we want to turn off chkuser,
++  just like if the starting_string is "NONE".
++ */
++                } else {
++			starting_value = -1;
++		}
 +        } else {
 +                starting_string = "";
@@ -5657,5 +5958,5 @@
 diff -ruN ../netqmail-1.06-original/chkuser.h netqmail-1.06/chkuser.h
 --- ../netqmail-1.06-original/chkuser.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/chkuser.h	2016-11-22 21:03:57.106528299 +0100
++++ netqmail-1.06/chkuser.h	2019-02-27 20:57:13.383025147 +0100
 @@ -0,0 +1,55 @@
 +
@@ -5716,5 +6017,5 @@
 diff -ruN ../netqmail-1.06-original/chkuser_settings.h netqmail-1.06/chkuser_settings.h
 --- ../netqmail-1.06-original/chkuser_settings.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/chkuser_settings.h	2016-11-28 17:35:36.567382036 +0100
++++ netqmail-1.06/chkuser_settings.h	2020-06-16 22:27:56.782600304 +0200
 @@ -0,0 +1,468 @@
 +/*
@@ -5929,5 +6230,5 @@
 + * aliases that have a -default extension
 + */
-+/* #define CHKUSER_ENABLE_ALIAS_DEFAULT */
++#define CHKUSER_ENABLE_ALIAS_DEFAULT
 +
 +
@@ -6080,5 +6381,5 @@
 +
 +/* #define CHKUSER_VAUTH_OPEN_CALL vauth_open   */
-+/* #define CHKUSER_VAUTH_OPEN_CALL vauth_open_update */
++#define CHKUSER_VAUTH_OPEN_CALL vauth_open_update
 +
 +/*
@@ -6100,5 +6401,5 @@
 + *
 + */
-+/* #define CHKUSER_DISABLE_VARIABLE "RELAYCLIENT" */
++#define CHKUSER_DISABLE_VARIABLE "RELAYCLIENT"
 +
 +
@@ -6188,5 +6489,5 @@
 diff -ruN ../netqmail-1.06-original/condredirect.c netqmail-1.06/condredirect.c
 --- ../netqmail-1.06-original/condredirect.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/condredirect.c	2016-11-22 21:03:57.107528266 +0100
++++ netqmail-1.06/condredirect.c	2019-02-27 20:57:13.384025136 +0100
 @@ -10,6 +10,8 @@
  #include "strerr.h"
@@ -6217,18 +6518,26 @@
 diff -ruN ../netqmail-1.06-original/conf-cc netqmail-1.06/conf-cc
 --- ../netqmail-1.06-original/conf-cc	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/conf-cc	2016-11-22 21:03:57.107528266 +0100
++++ netqmail-1.06/conf-cc	2020-01-10 21:52:13.080721081 +0100
 @@ -1,3 +1,3 @@
 -cc -O2
-+cc -O2 -g -DEXTERNAL_TODO -DTLS=20160918 -I/usr/local/ssl/include -I/home/vpopmail/include
++cc -O2 -g -DEXTERNAL_TODO -DTLS=20200107 -I/usr/local/ssl/include -I/home/vpopmail/include
  
  This will be used to compile .c files.
+diff -ruN ../netqmail-1.06-original/conf-channels netqmail-1.06/conf-channels
+--- ../netqmail-1.06-original/conf-channels	1970-01-01 01:00:00.000000000 +0100
++++ netqmail-1.06/conf-channels	2019-06-26 19:12:46.033685227 +0200
+@@ -0,0 +1,4 @@
++2
++
++Total number of channels (queues) available for delivery. Must be at
++least 2, and anything above 2 are considered supplemental channels.
 diff -ruN ../netqmail-1.06-original/conf-domainkeys netqmail-1.06/conf-domainkeys
 --- ../netqmail-1.06-original/conf-domainkeys	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/conf-domainkeys	2016-11-22 21:03:57.107528266 +0100
++++ netqmail-1.06/conf-domainkeys	2019-02-27 20:57:13.384025136 +0100
 @@ -0,0 +1 @@
 +-DDOMAIN_KEYS
 diff -ruN ../netqmail-1.06-original/conf-ld netqmail-1.06/conf-ld
 --- ../netqmail-1.06-original/conf-ld	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/conf-ld	2016-11-22 21:03:57.107528266 +0100
++++ netqmail-1.06/conf-ld	2019-02-27 20:57:13.384025136 +0100
 @@ -1,3 +1,3 @@
 -cc -s
@@ -6238,5 +6547,5 @@
 diff -ruN ../netqmail-1.06-original/conf-policy netqmail-1.06/conf-policy
 --- ../netqmail-1.06-original/conf-policy	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/conf-policy	2016-11-22 21:03:57.107528266 +0100
++++ netqmail-1.06/conf-policy	2019-02-27 20:57:13.384025136 +0100
 @@ -0,0 +1,17 @@
 +-DPOLICY_FILENAME="/var/qmail/control/policy" -DPOLICY_DEALLOCATE -DPOLICY_ENFORCE_AUTHENTICATION
@@ -6259,5 +6568,5 @@
 diff -ruN ../netqmail-1.06-original/conf-spawn netqmail-1.06/conf-spawn
 --- ../netqmail-1.06-original/conf-spawn	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/conf-spawn	2016-11-22 21:03:57.108528232 +0100
++++ netqmail-1.06/conf-spawn	2019-02-27 20:57:13.384025136 +0100
 @@ -1,4 +1,4 @@
 -120
@@ -6268,5 +6577,5 @@
 diff -ruN ../netqmail-1.06-original/config.h netqmail-1.06/config.h
 --- ../netqmail-1.06-original/config.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/config.h	2016-11-22 21:03:57.108528232 +0100
++++ netqmail-1.06/config.h	2019-02-27 20:57:13.384025136 +0100
 @@ -0,0 +1,10 @@
 +/* config.h.  Generated from config.h.in by configure.  */
@@ -6282,5 +6591,5 @@
 diff -ruN ../netqmail-1.06-original/control.c netqmail-1.06/control.c
 --- ../netqmail-1.06-original/control.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/control.c	2016-11-22 21:03:57.108528232 +0100
++++ netqmail-1.06/control.c	2019-02-27 20:57:13.384025136 +0100
 @@ -85,6 +85,82 @@
   return 1;
@@ -6368,5 +6677,5 @@
 diff -ruN ../netqmail-1.06-original/control.h netqmail-1.06/control.h
 --- ../netqmail-1.06-original/control.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/control.h	2016-11-22 21:03:57.108528232 +0100
++++ netqmail-1.06/control.h	2019-02-27 20:57:13.384025136 +0100
 @@ -3,8 +3,10 @@
  
@@ -6382,5 +6691,5 @@
 diff -ruN ../netqmail-1.06-original/date822fmt.c netqmail-1.06/date822fmt.c
 --- ../netqmail-1.06-original/date822fmt.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/date822fmt.c	2016-11-22 21:03:57.108528232 +0100
++++ netqmail-1.06/date822fmt.c	2019-02-27 20:57:13.385025125 +0100
 @@ -1,3 +1,4 @@
 +#include <time.h>
@@ -6449,6 +6758,6 @@
 diff -ruN ../netqmail-1.06-original/dk-filter.9 netqmail-1.06/dk-filter.9
 --- ../netqmail-1.06-original/dk-filter.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dk-filter.9	2016-11-22 21:03:57.108528232 +0100
-@@ -0,0 +1,102 @@
++++ netqmail-1.06/dk-filter.9	2020-04-10 11:08:43.313802048 +0200
+@@ -0,0 +1,98 @@
 +.TH dk-filter 8
 +.SH NAME
@@ -6472,7 +6781,7 @@
 +It uses the libdkim and OpenSSL libraries.  To sign a message, set the
 +.B DKIMSIGN
-+or
-+.B DKSIGIN
-+environment variables to the pathname of the private key that will be
++environment variable (for DKIM signing) or
++.B DKSIGN
++environment variable (for DK signing) to the pathname of the private key that will be
 +used to sign the message. If there is a % character in the environment
 +variable, it is removed and replaced by the domain name in the From: header.
@@ -6482,4 +6791,7 @@
 +After all substitutions, if the key file does not exist, the message will not be signed.
 +If there is no % and the file does not exist, the message will be rejected with error 35.
++The default private key QMAILHOME/control/domainkeys/default can be overriden by the
++\fBDKIM_DEFAULT_KEY\fR environment variable.
++
 +The selector (s=) will be taken from the basename of the file.
 +The private key should be created by 
@@ -6519,29 +6831,22 @@
 +.EE
 +
-+.B dk-filter
-+uses the domain found in the Sender: header to set the domain tag. If not it uses the From: header. You can override this by
-+setting 
-+.B DKIMDOMAIN
-+environment variable.
-+.B DKIMDOMAIN
-+can be set to an email address or a domain (without the at sign).
-+To verify a message, set the
-+.B DKIMVERIFY
-+or
-+.B DKVERIFY
-+environment variables
-+.B dk-filter
-+always inserts the 
-+.B DKIM-Status
-+or
-+.B DomainKey-Status
-+header, so that messages can be
-+rejected later at delivery time, or in the mail reader. In that case you may set
-+.B DKIMVERIFY
-+or
-+.B DKVERIFY
-+to an empty string.
-+.B dk-filter
-+does not use any signing practice byd default. You can override this by setting the SIGN_PRACTICE to ssp or adsp (lowercase).
++when signing \fBdk-filter\fR uses the domain found in the Return-Path, Sender, From headers to set
++the domain tag. If not it uses the value of \fBDKIMDOMAIN\fR environment
++variable. \fBDKIMDOMAIN\fR can be set to an email address or a domain (without the at sign).
++
++To verify a message, set the \fBDKIMVERIFY\fR or \fBDKVERIFY\fR environment variables.
++\fBdk-filter\fR always inserts the \fBDKIM-Status\fR or \fBDomainKey-Status\fR header, so
++that messages can be rejected later at delivery time, or in the mail reader. In that case
++you may set \fBDKIMVERIFY\fR or \fBDKVERIFY\fR to an empty string. The exit code of \fBdk-filter\fR
++can be fine tuned by setting \fBDKIMVERIFY\fR environment variable. See \fBdkim(8)\fR for a detailed
++description on setting the \fBDKIMVERIFY\fR environment variable.
++
++\fBdk-filter\fR does not use any signing practice by default. You can override this by setting
++the \fBSIGN_PRACTICE\fR to ssp or adsp (lowercase).
++
++If neither of these environment variables (\fBDKIMSIGN\fR, \fBDKSIGN\fR, \fBDKIMVERIFY\fR, \fBDKVERIFY\fR) are defined, \fBdk-filter\fR
++will do signing by default.
++
++You can set environment variable \fBNODK\fR to disable domainkeys and \fBNODKIM\fR to disable \fBDKIM\fR.
 +
 +.SH "EXIT CODES"
@@ -6555,8 +6860,32 @@
 diff -ruN ../netqmail-1.06-original/dk-filter.sh netqmail-1.06/dk-filter.sh
 --- ../netqmail-1.06-original/dk-filter.sh	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dk-filter.sh	2016-11-22 21:03:57.109528199 +0100
-@@ -0,0 +1,315 @@
++++ netqmail-1.06/dk-filter.sh	2020-07-29 15:59:13.351023490 +0200
+@@ -0,0 +1,367 @@
 +#
 +# $Log: dk-filter.sh,v $
++# Revision 1.22  2019-06-24 23:19:57+05:30  Cprogrammer
++# added code for -d option in DKIMSIGNOPTIONS
++#
++# Revision 1.21  2019-01-14 00:10:00+05:30  Cprogrammer
++# added -S, -f option to verify signatures with unsigned subject, unsigned from
++#
++# Revision 1.20  2017-03-09 16:38:15+05:30  Cprogrammer
++# FHS changes
++#
++# Revision 1.19  2016-05-17 23:11:42+05:30  Cprogrammer
++# fix for configurable control directory
++#
++# Revision 1.18  2014-03-12 08:50:48+05:30  Cprogrammer
++# bug - fixed signing when env variables DKSIGN or DKIMSIGN were set
++#
++# Revision 1.17  2013-09-03 23:04:30+05:30  Cprogrammer
++# set signing as default if both DKSIGN and DKIMSIGN are not defined
++#
++# Revision 1.16  2013-08-17 15:59:21+05:30  Cprogrammer
++# do not treat duplicate DomainKey-Signature as an error
++#
++# Revision 1.15  2013-08-17 15:02:06+05:30  Cprogrammer
++# fixed syntax errors and private key lookup
++#
 +# Revision 1.14  2011-02-10 22:47:01+05:30  Cprogrammer
 +# fixed exit code of dk-filter when doing verification
@@ -6604,5 +6933,5 @@
 +# Initial revision
 +#
-+# $Id: dk-filter.sh,v 1.14 2011-02-10 22:47:01+05:30 Cprogrammer Stab mbhangui $
++# $Id: dk-filter.sh,v 1.22 2019-06-24 23:19:57+05:30 Cprogrammer Exp mbhangui $
 +#
 +if [ -z "$QMAILREMOTE" -a -z "$QMAILLOCAL" ]; then
@@ -6614,13 +6943,26 @@
 +dkverify=0
 +dkimverify=0
-+if [ -z "$DKSIGN" -a -z "$DKVERIFY" ] ; then
-+	DKSIGN=QMAILHOME/control/domainkeys/%/default
-+	dksign=2
++if [ -z "$DEFAULT_DKIM_KEY" ] ; then
++	default_key=QMAILHOME/control/domainkeys/default
++else
++	default_key=$DEFAULT_DKIM_KEY
 +fi
-+if [ -z "$DKIMSIGN" -a -z "$DKIMVERIFY" ] ; then
-+	DKIMSIGN=QMAILHOME/control/domainkeys/%/default
-+	dkimsign=2
++if [ -z "$NODK" -a -x QMAILHOME/bin/dktest -a -z "$DKVERIFY" ] ; then
++	if [ -z "$DKSIGN" ] ; then
++		DKSIGN=QMAILHOME/control/domainkeys/%/default
++		dksign=2
++	elif [ " $DKSIGN" = " QMAILHOME/control/domainkeys/%/default" ] ; then
++		dksign=2
++	fi
 +fi
-+if [ ! -z "$DKSIGN" ] ; then
++if [ -z "$NODKIM" -a -x QMAILHOME/bin/dkim -a -z "$DKIMVERIFY" ] ; then
++	if [ -z "$DKIMSIGN" ] ; then
++		DKIMSIGN=QMAILHOME/control/domainkeys/%/default
++		dkimsign=2
++	elif [ " $DKIMSIGN" = " QMAILHOME/control/domainkeys/%/default" ] ; then
++		dkimsign=2
++	fi
++fi
++if [ -z "$NODK" -a -n "$DKSIGN" ] ; then
 +	if [ ! -f QMAILHOME/bin/dktest ] ; then
 +		echo "QMAILHOME/bin/dktest: No such file or directory" 1>&2
@@ -6632,5 +6974,7 @@
 +		percent_found=1
 +	fi
-+	if [ ! " $_SENDER" = " " ] ; then
++	if [ -n "$DKIMDOMAIN" ] && [ -z "$_SENDER" ] ; then
++		dkkeyfn=`echo $DKSIGN | sed s{%{$DKIMDOMAIN{g`
++	elif [ ! " $_SENDER" = " " ] ; then
 +		# replace '%' in filename with domain
 +		domain=`echo $_SENDER | cut -d@ -f2`
@@ -6640,5 +6984,5 @@
 +	fi
 +	if [ $dksign -eq 2 -a ! -f $dkkeyfn ] ; then
-+		dkkeyfn=QMAILHOME/control/domainkeys/default
++		dkkeyfn=$default_key
 +	fi
 +	if [ -f $dkkeyfn ] ; then
@@ -6652,5 +6996,5 @@
 +	dkselector=`basename $dkkeyfn`
 +fi
-+if [ ! -z "$DKIMSIGN" ] ; then
++if [ -z "$NODKIM" -a -n "$DKIMSIGN" ] ; then
 +	if [ ! -f QMAILHOME/bin/dkim ] ; then
 +		echo "QMAILHOME/bin/dkim: No such file or directory" 1>&2
@@ -6662,5 +7006,7 @@
 +		percent_found=1
 +	fi
-+	if [ ! " $_SENDER" = " " ] ; then
++	if [ -n "$DKIMDOMAIN" ] && [ -z "$_SENDER" ] ; then
++		dkimkeyfn=`echo $DKIMSIGN | sed s{%{$DKIMDOMAIN{g`
++	elif [ ! " $_SENDER" = " " ] ; then
 +		# replace '%' in filename with domain
 +		domain=`echo $_SENDER | cut -d@ -f2`
@@ -6670,5 +7016,5 @@
 +	fi
 +	if [ $dkimsign -eq 2 -a ! -f $dkimkeyfn ] ; then
-+		dkimkeyfn=QMAILHOME/control/domainkeys/default
++		dkimkeyfn=$default_key
 +	fi
 +	if [ -f $dkimkeyfn ] ; then
@@ -6678,9 +7024,9 @@
 +	fi
 +	if [ $dkimsign -eq 0 -a $percent_found -ne 1 ] ; then
-+		exit 32
++		exit 32 # private key does not exist
 +	fi
 +	dkimselector=`basename $dkimkeyfn`
 +fi
-+if [ ! -z "$DKVERIFY" ] ; then
++if [ -z "$NODK" -a -n "$DKVERIFY" ] ; then
 +	if [ ! -f QMAILHOME/bin/dktest ] ; then
 +		echo "QMAILHOME/bin/dktest: No such file or directory" 1>&2
@@ -6689,5 +7035,5 @@
 +	dkverify=1
 +fi
-+if [ ! -z "$DKIMVERIFY" ] ; then
++if [ -z "$NODKIM" -a -n "$DKIMVERIFY" ] ; then
 +	if [ ! -f QMAILHOME/bin/dkim ] ; then
 +		echo "QMAILHOME/bin/dkim: No such file or directory" 1>&2
@@ -6730,4 +7076,9 @@
 +		-c)
 +		dkimopts="$dkimopts -c $2"
++		shift
++		;;
++
++		-d)
++		dkimopts="$dkimopts -d $2"
 +		shift
 +		;;
@@ -6824,9 +7175,8 @@
 +	fi
 +	exec 0</tmp/dk.$$
-+	#QMAILHOME/bin/dktest -h -s $dkkeyfn
 +	eval $dkopts
 +	exit_val=$?
 +	# allow error due to duplicate DomainKey-Header
-+	if [ $exit_val -ne 0 -a $exit_val -ne 6 ] ; then
++	if [ $exit_val -ne 0 -a $exit_val -ne 12 ] ; then
 +		/bin/rm -f /tmp/dk.$$
 +		exit $exit_val
@@ -6843,5 +7193,12 @@
 +	fi
 +	exec 0</tmp/dk.$$
-+	QMAILHOME/bin/dkim -p $practice -v
++	dkimvargs="-p $practice"
++	if [ -n "$UNSIGNED_SUBJECT" ] ; then
++		dkimvargs="$dkimvargs -S"
++	fi
++	if [ -n "$UNSIGNED_FROM" ] ; then
++		dkimvargs="$dkimvargs -f"
++	fi
++	QMAILHOME/bin/dkim $dkimvargs -v
 +	ret=$?
 +	case $ret in
@@ -6874,6 +7231,6 @@
 diff -ruN ../netqmail-1.06-original/dkim.9 netqmail-1.06/dkim.9
 --- ../netqmail-1.06-original/dkim.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkim.9	2018-04-03 14:46:51.362411599 +0200
-@@ -0,0 +1,98 @@
++++ netqmail-1.06/dkim.9	2020-04-09 19:43:56.494473495 +0200
+@@ -0,0 +1,108 @@
 +.TH dkim 8
 +.SH NAME
@@ -6892,5 +7249,5 @@
 +
 +.EX
-+ (./dkim -s QMAILHOME/control/domainkeys/dog </tmp/testmsg; cat /tmp/testmsg)\
++ (./dkim -s INDIMAIL/control/domainkeys/dog </tmp/testmsg; cat /tmp/testmsg)\
 + | ./dkim -v
 +.EE
@@ -6924,5 +7281,5 @@
 +.TP
 +-l
-+include body length tag
++include body length tag when signing. Honor body length tag when verifying
 +.TP
 +-q
@@ -6934,4 +7291,7 @@
 +-f
 +issue error if not all message's From headers are in signature
++.TP
++-S
++Allow unsigned subject in signature
 +.TP
 +-h
@@ -6946,6 +7306,8 @@
 +-c \fIcanonicalization\fR
 +r for relaxed [DEFAULT], s - simple, t relaxed/simple, u - simple/relaxed
++
++.TP
 +-d \fIdomain\fR
-+the domain tag, if not provided, determined from the sender/from header
++the domain tag, if not provided, determined from the return-path/sender/from header
 +.TP
 +-i \fIidentity\fR
@@ -6967,4 +7329,9 @@
 +this help
 +
++.SH Return Value
++When signing, \fBdkim\fR returns 0 on success and non-zero on any failure. For verification, you can set the
++environment varable \fBDKIMVERIFY\fR. Refer to qmail-dkim(8) for a full description of  the \fBDKIMVERIFY\fR
++environment variable
++
 +.SH "SEE ALSO"
 +dktest(8),
@@ -6976,8 +7343,20 @@
 diff -ruN ../netqmail-1.06-original/dkim.c netqmail-1.06/dkim.c
 --- ../netqmail-1.06-original/dkim.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkim.c	2018-04-03 14:46:51.363411603 +0200
-@@ -0,0 +1,899 @@
++++ netqmail-1.06/dkim.c	2019-06-19 09:46:59.689809564 +0200
+@@ -0,0 +1,871 @@
 +/*
 + * $Log: dkim.c,v $
++ * Revision 1.23  2019-06-14 21:24:59+05:30  Cprogrammer
++ * BUG - honor body length tag in verification
++ *
++ * Revision 1.22  2019-01-13 10:10:27+05:30  Cprogrammer
++ * added missing usage string for allowing unsigned subject.
++ *
++ * Revision 1.21  2018-08-08 23:57:02+05:30  Cprogrammer
++ * issue success if at lease one one good signature is found
++ *
++ * Revision 1.20  2018-05-22 10:03:26+05:30  Cprogrammer
++ * changed return type of writeHeader() to void
++ *
 + * Revision 1.19  2016-03-01 16:23:38+05:30  Cprogrammer
 + * added -S option to allow email with unsigned subject
@@ -7109,4 +7488,6 @@
 +	fprintf(stderr, "t                    include a timestamp tag\n");
 +	fprintf(stderr, "h                    include Copied Headers\n");
++	fprintf(stderr, "f                    allow Unsigned From (default is to reject if From field is not signed)\n");
++	fprintf(stderr, "S                    allow Unsigned Subject (default is to reject if Subject field is not signed)\n");
 +	fprintf(stderr, "v                    verify the message\n");
 +	fprintf(stderr, "p <ssp|adsp>         0 - disable practice (default), 1- SSP, or 2 - ADSP verification\n");
@@ -7120,8 +7501,7 @@
 +	fprintf(stderr, "z <hash>             1 for sha1, 2 for sha256, 3 for both\n");
 +#endif
-+	fprintf(stderr, "f                    0 = From headers not included in the signature are not allowed\n");
-+	fprintf(stderr, "                     1 = allowed\n");
 +	fprintf(stderr, "y <selector>         the selector tag DEFAULT=private\n");
 +	fprintf(stderr, "s <privkeyfile>      sign the message using the private key in privkeyfile\n");
++	fprintf(stderr, "V                    set verbose mode\n");
 +	fprintf(stderr, "H                    this help\n");
 +	exit(1);
@@ -7135,6 +7515,5 @@
 +	ch = c;
 +	t = s;
-+	for (;;)
-+	{
++	for (;;) {
 +		if (!*t)
 +			break;
@@ -7187,5 +7566,5 @@
 + * Allows you to add the headers contain the results and DKIM ADSP
 + */
-+int writeHeader(int ret, int resDKIMSSP, int resDKIMADSP, int useSSP, int useADSP )
++void writeHeader(int ret, int resDKIMSSP, int resDKIMADSP, int useSSP, int useADSP )
 +{
 +	char           *dkimStatus, *sspStatus, *adspStatus;
@@ -7286,6 +7665,5 @@
 +		}
 +	}
-+	if (useADSP && resDKIMADSP != -1)
-+	{
++	if (useADSP && resDKIMADSP != -1) {
 +		switch(resDKIMADSP)
 +		{
@@ -7325,22 +7703,16 @@
 +		values[i] = 0;
 +	key = 0;
-+	for(ptr = list;*ptr;)
-+	{
++	for(ptr = list;*ptr;) {
 +		if ((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\r') || (*ptr == '\n')) /*- FWS */
 +			*ptr++ = 0;
 +		if (!key)
 +			key = ptr;
-+		if (*ptr == '=')
-+		{
++		if (*ptr == '=') {
 +			*ptr = 0;
-+			for (i = 0;letters[i];i++)
-+			{
-+				if (!strcmp(letters[i], key))
-+				{
++			for (i = 0;letters[i];i++) {
++				if (!strcmp(letters[i], key)) {
 +					ptr++;
-+					for (;*ptr;)
-+					{
-+						if ((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\r') || (*ptr == '\n'))
-+						{
++					for (;*ptr;) {
++						if ((*ptr == ' ') || (*ptr == '\t') || (*ptr == '\r') || (*ptr == '\n')) {
 +							ptr++;
 +							continue;
@@ -7353,8 +7725,6 @@
 +					if (*ptr)
 +						*ptr++ = 0;
-+					for(;tmp != values[i];tmp--) /*- RFC 4871 3.2 */
-+					{
-+						if ((*tmp == ' ') || (*tmp == '\t') || (*tmp == '\r') || (*tmp == '\n'))
-+						{
++					for(;tmp != values[i];tmp--) /*- RFC 4871 3.2 */ {
++						if ((*tmp == ' ') || (*tmp == '\t') || (*tmp == '\r') || (*tmp == '\n')) {
 +							*tmp = 0;
 +							continue;
@@ -7381,6 +7751,5 @@
 +
 +	*bTesting = 0;
-+	if (!(query = (char *) DKIM_MALLOC(strlen("_ssp._domainkey.") + strlen(domain) + 1)))
-+	{
++	if (!(query = (char *) DKIM_MALLOC(strlen("_ssp._domainkey.") + strlen(domain) + 1))) {
 +		fprintf(stderr, "malloc: %d: %s\n", strlen("_ssp._domainkey.") + strlen(domain) + 1,
 +			strerror(errno));
@@ -7390,20 +7759,16 @@
 +	results = dns_text(query);
 +	DKIM_MFREE(query);
-+	if (!strcmp(results, "e=temp;"))
-+	{
++	if (!strcmp(results, "e=temp;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_SSP_TEMPFAIL;
 +	} else
-+	if (!strcmp(results, "e=perm;"))
-+	{
++	if (!strcmp(results, "e=perm;")) {
 +		DKIM_MFREE(results);
 +		results = dns_text(domain);
-+		if (!strcmp(results, "e=temp;"))
-+		{
++		if (!strcmp(results, "e=temp;")) {
 +			DKIM_MFREE(results);
 +			return DKIM_SSP_TEMPFAIL;
 +		} else
-+		if (!strcmp(results, "e=perm;"))
-+		{
++		if (!strcmp(results, "e=perm;")) {
 +			DKIM_MFREE(results);
 +			return DKIM_SSP_SCOPE;
@@ -7411,6 +7776,5 @@
 +		bIsParentSSP = 1;
 +	}
-+	if (!ParseTagValues(results, tags, values))
-+	{
++	if (!ParseTagValues(results, tags, values)) {
 +		DKIM_MFREE(results);
 +		return DKIM_SSP_UNKNOWN;
@@ -7427,6 +7791,5 @@
 +	if (values[1] != NULL) {
 +		char           *s, *p;
-+		for (p = values[1], s = values[1]; *p; p++)
-+		{
++		for (p = values[1], s = values[1]; *p; p++) {
 +			if (*p == '|')
 +				*p = 0;
@@ -7460,16 +7823,13 @@
 +
 +	results = dns_text(domain);
-+	if (!strcmp(results, "e=perm;"))
-+	{
++	if (!strcmp(results, "e=perm;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_SCOPE;
 +	} else
-+	if (!strcmp(results, "e=temp;"))
-+	{
++	if (!strcmp(results, "e=temp;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_TEMPFAIL;
 +	}
-+	if (!(query = (char *) DKIM_MALLOC(strlen((char *) "_adsp._domainkey.") + strlen(domain) + 1)))
-+	{
++	if (!(query = (char *) DKIM_MALLOC(strlen((char *) "_adsp._domainkey.") + strlen(domain) + 1))) {
 +		fprintf(stderr, "malloc: %d: %s\n", strlen("_adsp._domainkey.") + strlen(domain) + 1,
 +			strerror(errno));
@@ -7479,16 +7839,13 @@
 +	results = dns_text(query);
 +	DKIM_MFREE(query);
-+	if (!strcmp(results, "e=perm;"))
-+	{
++	if (!strcmp(results, "e=perm;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_SCOPE;
 +	} else
-+	if (!strcmp(results, "e=temp;"))
-+	{
++	if (!strcmp(results, "e=temp;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_TEMPFAIL;
 +	}
-+	if (!ParseTagValues(results, tags, values))
-+	{
++	if (!ParseTagValues(results, tags, values)) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_UNKNOWN;
@@ -7541,6 +7898,5 @@
 +	strcpy(opts.szRequiredHeaders, "NonExistent");
 +	opts.pfnHeaderCallback = SignThisHeader;
-+	while (1)
-+	{
++	while (1) {
 +		if ((ch = getopt(argc, argv, "lqtfhHSvVp:b:c:d:i:s:x:y:z:")) == -1)
 +			break;
@@ -7548,4 +7904,5 @@
 +		{
 +		case 'l': /*- body length tag */
++			vopts.nHonorBodyLengthTag = 1;
 +			opts.nIncludeBodyLengthTag = 1;
 +			break;
@@ -7684,6 +8041,5 @@
 +	}
 +	if (bSign) { /*- sign */
-+		if (!PrivKeyFile)
-+		{
++		if (!PrivKeyFile) {
 +			fprintf(stderr, "Private Key not provided\n");
 +			usage();
@@ -7701,16 +8057,13 @@
 +			return (1);
 +		}
-+		if (fstat(PrivKeyFD, &statbuf) == -1)
-+		{
++		if (fstat(PrivKeyFD, &statbuf) == -1) {
 +			fprintf(stderr, "fstat: %s: %s\n", PrivKeyFile, strerror(errno));
 +			return (1);
 +		}
-+		if (!(PrivKey = (char *) DKIM_MALLOC(sizeof(char) * ((nPrivKeyLen = statbuf.st_size) + 1))))
-+		{
++		if (!(PrivKey = (char *) DKIM_MALLOC(sizeof(char) * ((nPrivKeyLen = statbuf.st_size) + 1)))) {
 +			fprintf(stderr, "malloc: %ld bytes: %s\n", statbuf.st_size + 1, strerror(errno));
 +			return (1);
 +		}
-+		if (read(PrivKeyFD, PrivKey, nPrivKeyLen) != nPrivKeyLen)
-+		{
++		if (read(PrivKeyFD, PrivKey, nPrivKeyLen) != nPrivKeyLen) {
 +			fprintf(stderr, "%s: read: %s\n", strerror(errno), program);
 +			return (1);
@@ -7718,13 +8071,10 @@
 +		close(PrivKeyFD);
 +		PrivKey[nPrivKeyLen] = '\0';
-+		if (DKIMSignInit(&ctxt, &opts) != DKIM_SUCCESS)
-+		{
++		if (DKIMSignInit(&ctxt, &opts) != DKIM_SUCCESS) {
 +			fprintf(stderr, "DKIMSignInit: failed to initialize signature %s\n", PrivKeyFile);
 +			return (1);
 +		}
-+		for (;;)
-+		{
-+			if ((ret = read(0, Buffer, sizeof(Buffer) - 1)) == -1)
-+			{
++		for (;;) {
++			if ((ret = read(0, Buffer, sizeof(Buffer) - 1)) == -1) {
 +				fprintf(stderr, "read: %s\n", strerror(errno));
 +				DKIMSignFree(&ctxt);
@@ -7733,6 +8083,5 @@
 +			if (!ret)
 +				break;
-+			if (DKIMSignProcess(&ctxt, Buffer, ret) == DKIM_INVALID_CONTEXT)
-+			{
++			if (DKIMSignProcess(&ctxt, Buffer, ret) == DKIM_INVALID_CONTEXT) {
 +				fprintf(stderr, "DKIMSignProcess: DKIMContext structure invalid for this operation\n");
 +				DKIMSignFree(&ctxt);
@@ -7740,12 +8089,10 @@
 +			}
 +		}
-+		if (DKIMSignGetSig2(&ctxt, PrivKey, &pSig) == DKIM_INVALID_CONTEXT)
-+		{
++		if (DKIMSignGetSig2(&ctxt, PrivKey, &pSig) == DKIM_INVALID_CONTEXT) {
 +			fprintf(stderr, "DKIMSignProcess: DKIMContext structure invalid for this operation\n");
 +			DKIMSignFree(&ctxt);
 +			return (1);
 +		}
-+		if (pSig)
-+		{
++		if (pSig) {
 +			fwrite(pSig, 1, strlen(pSig), stdout);
 +			fwrite("\n", 1, 1, stdout);
@@ -7766,8 +8113,6 @@
 +		vopts.nSubjectRequired = nAllowUnsignedSubject;
 +		DKIMVerifyInit(&ctxt, &vopts);		/*- this is always successful */
-+		for (;;)
-+		{
-+			if ((i = read(0, Buffer, sizeof(Buffer) - 1)) == -1)
-+			{
++		for (;;) {
++			if ((i = read(0, Buffer, sizeof(Buffer) - 1)) == -1) {
 +				fprintf(stderr, "read: %s\n", strerror(errno));
 +				DKIMVerifyFree(&ctxt);
@@ -7783,25 +8128,24 @@
 +				break;
 +		}
-+		if (!ret)
-+		{
-+			if ((ret = DKIMVerifyResults(&ctxt, &sCount, &sSize)) != DKIM_SUCCESS)
++		if (!ret) {
++			ret = DKIMVerifyResults(&ctxt, &sCount, &sSize);
++			if (ret != DKIM_SUCCESS && ret != DKIM_3PS_SIGNATURE && ret != DKIM_NEUTRAL)
 +				dkim_error(ret);
 +			if ((ret = DKIMVerifyGetDetails(&ctxt, &nSigCount, &pDetails, szPolicy)) != DKIM_SUCCESS)
 +				dkim_error(ret);
-+			else
-+			{
-+				for (ret = 0,i = 0; i < nSigCount; i++) {
++			else {
++				for (ret = DKIM_FAIL, i = 0; i < nSigCount; i++) {
 +					if (verbose)
 +						printf("Signature # %02d: ", i + 1);
-+					if (pDetails[i].nResult >= 0)
-+					{
++					if (pDetails[i].nResult >= 0) {
++						ret = 0;
 +						if (verbose)
 +							printf("Success\n");
 +						continue;
-+					} else
-+					{
-+						ret = pDetails[i].nResult;
++					} else {
++						if (ret == DKIM_FAIL)
++							ret = pDetails[i].nResult;
 +						if (verbose)
-+							printf("Failure %d\n", ret);
++							printf("Failure %d\n", pDetails[i].nResult);
 +					}
 +				}
@@ -7811,6 +8155,5 @@
 +		} 
 +		if (ret < 0 || ret == DKIM_3PS_SIGNATURE) {
-+			if (useADSP)
-+			{
++			if (useADSP) {
 +				char           *domain;
 +	
@@ -7826,6 +8169,5 @@
 +				ret = DKIM_NEUTRAL;
 +			} else
-+			if (useSSP)
-+			{
++			if (useSSP) {
 +				int             bTestingPractices = 0;
 +				char           *domain;
@@ -7848,14 +8190,11 @@
 +		DKIMVerifyFree(&ctxt);
 +		writeHeader(ret, resDKIMSSP, resDKIMADSP, useSSP, useADSP);
-+		if ((dkimverify = getenv("DKIMVERIFY")))
-+		{
-+			if (ret < 0)
-+			{
++		if ((dkimverify = getenv("DKIMVERIFY"))) {
++			if (ret < 0) {
 +				if (dkimverify[str_chr(dkimverify, 'F' - ret)])
 +					ret = 14; /*- return permanent error */
 +				if (dkimverify[str_chr(dkimverify, 'f' - ret)])
 +					ret = 88; /*- return temporary error */
-+			} else
-+			{
++			} else {
 +				if (dkimverify[str_chr(dkimverify, 'A' + ret)])
 +					ret = 14; /*- return permanent error */
@@ -7873,5 +8212,5 @@
 +getversion_dkim_c()
 +{
-+	static char    *x = (char *) "$Id: dkim.c,v 1.19 2016-03-01 16:23:38+05:30 Cprogrammer Exp mbhangui $";
++	static char    *x = (char *) "$Id: dkim.c,v 1.23 2019-06-14 21:24:59+05:30 Cprogrammer Exp mbhangui $";
 +
 +	x++;
@@ -7879,5 +8218,5 @@
 diff -ruN ../netqmail-1.06-original/dkim.h netqmail-1.06/dkim.h
 --- ../netqmail-1.06-original/dkim.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkim.h	2018-04-03 14:46:51.364411606 +0200
++++ netqmail-1.06/dkim.h	2019-02-27 20:57:13.386025114 +0100
 @@ -0,0 +1,193 @@
 +/*
@@ -8076,8 +8415,11 @@
 diff -ruN ../netqmail-1.06-original/dkimbase.cpp netqmail-1.06/dkimbase.cpp
 --- ../netqmail-1.06-original/dkimbase.cpp	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimbase.cpp	2018-04-03 14:46:51.363411603 +0200
-@@ -0,0 +1,336 @@
++++ netqmail-1.06/dkimbase.cpp	2019-06-19 09:46:20.131250010 +0200
+@@ -0,0 +1,339 @@
 +/*
 + * $Log: dkimbase.cpp,v $
++ * Revision 1.5  2019-06-14 21:24:03+05:30  Cprogrammer
++ * BUG - honor body length tag in verification
++ *
 + * Revision 1.4  2017-09-05 10:58:26+05:30  Cprogrammer
 + * removed compiler warnings
@@ -8242,5 +8584,5 @@
 +				// process body line
 +				int Result = ProcessBody(m_Line, m_LinePos, bEOF);
-+				if (Result != DKIM_SUCCESS) {
++				if (Result != DKIM_SUCCESS && Result != DKIM_FINISHED_BODY) {
 +					m_LinePos = 0;
 +					return Result;
@@ -8410,5 +8752,5 @@
 +getversion_dkimbase_cpp()
 +{
-+	static char    *x = (char *) "$Id: dkimbase.cpp,v 1.4 2017-09-05 10:58:26+05:30 Cprogrammer Exp mbhangui $";
++	static char    *x = (char *) "$Id: dkimbase.cpp,v 1.5 2019-06-14 21:24:03+05:30 Cprogrammer Exp mbhangui $";
 +
 +	x++;
@@ -8416,5 +8758,5 @@
 diff -ruN ../netqmail-1.06-original/dkimbase.h netqmail-1.06/dkimbase.h
 --- ../netqmail-1.06-original/dkimbase.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimbase.h	2018-04-03 14:46:51.363411603 +0200
++++ netqmail-1.06/dkimbase.h	2019-02-27 20:57:13.386025114 +0100
 @@ -0,0 +1,72 @@
 +/*
@@ -8492,6 +8834,6 @@
 diff -ruN ../netqmail-1.06-original/dkimdns.cpp netqmail-1.06/dkimdns.cpp
 --- ../netqmail-1.06-original/dkimdns.cpp	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimdns.cpp	2018-04-03 14:46:51.364411606 +0200
-@@ -0,0 +1,322 @@
++++ netqmail-1.06/dkimdns.cpp	2019-05-23 15:12:30.128092884 +0200
+@@ -0,0 +1,329 @@
 +/*
 + * $Log: dns.cpp,v $
@@ -8671,6 +9013,11 @@
 +				n = rrdlen - txtpos;
 +			if ((*txt_strlen + n + 1) > txtlen) {
-+				if (!(ptr = (char *) realloc(txt, (*txt_strlen + n) * 2)))
++				if (!(ptr = (char *) realloc(txt, (*txt_strlen + n) * 2))) {
++					free(txt);
++					txtlen = 0;
++					*txt_strlen = 0;
 +					return DNS_MEM;
++				}
++				txt = ptr;
 +				txtlen = (*txt_strlen + n) * 2;
 +			}
@@ -8706,5 +9053,5 @@
 +	total = 0;
 +	if (!dnresultlen) {
-+		if (!(dnresult = (char *) malloc ((2 * PACKETSZ) * sizeof(char))))
++		if (!(dnresult = (char *) malloc((2 * PACKETSZ) * sizeof(char))))
 +			return DNS_MEM;
 +		dnresultlen = 2 * PACKETSZ;
@@ -8721,4 +9068,5 @@
 +			if ((total + len + 1) >= dnresultlen) {
 +				if (!(ptr = (char *) realloc(dnresult, (total + len) * 2))) {
++					free(dnresult);
 +					dnresultlen = 0;
 +					if (txtlen) {
@@ -8728,4 +9076,5 @@
 +					return DNS_MEM;
 +				}
++				dnresult = ptr;
 +				dnresultlen = (total + len) * 2;
 +			}
@@ -8818,5 +9167,5 @@
 diff -ruN ../netqmail-1.06-original/dkimdns.h netqmail-1.06/dkimdns.h
 --- ../netqmail-1.06-original/dkimdns.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimdns.h	2018-04-03 14:46:51.364411606 +0200
++++ netqmail-1.06/dkimdns.h	2019-02-27 20:57:13.387025103 +0100
 @@ -0,0 +1,54 @@
 +/*
@@ -8876,5 +9225,5 @@
 diff -ruN ../netqmail-1.06-original/dkimfuncs.cpp netqmail-1.06/dkimfuncs.cpp
 --- ../netqmail-1.06-original/dkimfuncs.cpp	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimfuncs.cpp	2018-04-03 14:46:51.364411606 +0200
++++ netqmail-1.06/dkimfuncs.cpp	2019-02-27 20:57:13.387025103 +0100
 @@ -0,0 +1,236 @@
 +/*
@@ -8965,5 +9314,5 @@
 +
 +int             DKIM_CALL
-+DKIMSignGetSig(DKIMContext *pSignContext, char *szPrivKey, char *szSignature, unsigned int nSigLength)
++DKIMSignGetSig(DKIMContext *pSignContext, char *szPrivKey, char *szSignature, int nSigLength)
 +{
 +	CDKIMSign      *pSign = (CDKIMSign *) ValidateContext(pSignContext, true);
@@ -9068,5 +9417,5 @@
 +DKIMVersion()
 +{
-+	return (char *) "1.4";
++	return (char *) "1.5";
 +}
 +
@@ -9116,8 +9465,26 @@
 diff -ruN ../netqmail-1.06-original/dkimsign.cpp netqmail-1.06/dkimsign.cpp
 --- ../netqmail-1.06-original/dkimsign.cpp	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimsign.cpp	2018-04-03 14:46:51.365411610 +0200
-@@ -0,0 +1,1016 @@
++++ netqmail-1.06/dkimsign.cpp	2020-04-10 18:20:19.279077900 +0200
+@@ -0,0 +1,1029 @@
 +/*
 + * $Log: dkimsign.cpp,v $
++ * Revision 1.17  2020-04-10 21:36:20+05:30  Cprogrammer
++ * fixed BUG with domain assignment
++ *
++ * Revision 1.16  2020-04-09 21:21:04+05:30  Cprogrammer
++ * check for null domain after DKIMDOMAIN replacement
++ *
++ * Revision 1.15  2019-06-26 19:08:18+05:30  Cprogrammer
++ * added sBouncedAddr variable for X-Bounced-Address header added by qmail-send for bounces
++ *
++ * Revision 1.14  2019-06-24 22:22:15+05:30  Cprogrammer
++ * use DKIMDOMAIN only if Return-Path, From, Sender header are empty
++ *
++ * Revision 1.13  2018-08-25 18:01:59+05:30  Cprogrammer
++ * fixed dkim signing for From address containing company name
++ *
++ * Revision 1.12  2018-05-23 13:07:58+05:30  Cprogrammer
++ * fixed compiler warnings
++ *
 + * Revision 1.11  2017-09-05 10:59:03+05:30  Cprogrammer
 + * removed compiler warnings
@@ -9387,22 +9754,13 @@
 +CDKIMSign::GetHeaderParams(const string & sHdr)
 +{
-+	string::size_type pos1, pos2;
-+
++	if (_strnicmp(sHdr.c_str(), "X-Bounced-Address:", 18) == 0)
++		sBouncedAddr.assign(sHdr.c_str() + 21);
++	else
 +	if (_strnicmp(sHdr.c_str(), "X", 1) == 0)
 +		return;
-+	if (_strnicmp(sHdr.c_str(), "From:", 5) == 0) {
++	if (_strnicmp(sHdr.c_str(), "From:", 5) == 0)
 +		sFrom.assign(sHdr.c_str() + 5);
-+		pos1 = sFrom.find('(');
-+		pos2 = sFrom.find(')');
-+		if (pos1 != 0 && pos1 != string::npos && pos2 != 0 && pos2 != string::npos)
-+			sFrom.erase(pos1, pos2);
-+	}
-+	if (_strnicmp(sHdr.c_str(), "Sender:", 7) == 0) {
++	if (_strnicmp(sHdr.c_str(), "Sender:", 7) == 0)
 +		sSender.assign(sHdr.c_str() + 7);
-+		pos1 = sSender.find('(');
-+		pos2 = sSender.find(')');
-+		if (pos1 != 0 && pos1 != string::npos && pos2 != 0 && pos2 != string::npos)
-+			sSender.erase(pos1, pos2);
-+	}
 +	if (_strnicmp(sHdr.c_str(), "Return-Path:", 12) == 0)
 +		sReturnPath.assign(sHdr.c_str() + 12);
@@ -9452,5 +9810,5 @@
 +				nSignThisTag = 1;
 +				IsRequiredHeader(sTag);	// remove from required header list
-+			} 
++			}
 +			// is this in the list of headers that must be signed?
 +			else
@@ -9599,32 +9957,38 @@
 +	if (!sFrom.empty())
 +		sAddress.assign(sFrom);
++	else /* use indimail's X-Bounced-Address header to find the domain that injected the bounce */
++	if (!sBouncedAddr.empty())
++		sAddress.assign(sBouncedAddr);
 +	else
 +		return false;
-+	// simple for now, beef it up later
-+	// remove '<' and anything before it
++	/*-
++	 * simple for now, beef it up later
++	 * remove '<' and anything before it
++	 */
 +	pos = sAddress.find('<');
 +	if (pos != string::npos)
-+		sAddress.erase(0, pos);
-+	// remove '>' and anything after it
++		sAddress.erase(0, pos + 1);
++
++	/* remove '>' and anything after it */
 +	pos = sAddress.find('>');
 +	if (pos != string::npos)
 +		sAddress.erase(pos, string::npos);
-+	// look for '@' symbol
-+	pos = sAddress.find('@');
-+	if (pos == string::npos)
-+		return false;
++	/* look for '@' symbol */
 +	if (sDomain.empty()) {
-+		p = getenv("DKIMDOMAIN");
-+		if (p && *p)
-+		{
-+			if (!(at = strchr(p, '@')))
-+				at = p;
-+			else
-+				at++;
-+			sDomain.assign(at);
-+		} else
++		pos = sAddress.find('@');
++		if (pos != string::npos)
 +			sDomain.assign(sAddress.c_str() + pos + 1);
-+		RemoveSWSP(sDomain);
-+	}
++		if (sDomain.empty()) {
++			p = getenv("DKIMDOMAIN");
++			if (p && *p) {
++				if (!(at = strchr(p, '@')))
++					at = p;
++				else
++					at++;
++				sDomain.assign(at);
++			}
++		}
++	}
++	RemoveSWSP(sDomain);
 +	return true;
 +}
@@ -9895,18 +10259,16 @@
 +		for (sptr = ptr, len = 0;*sptr;sptr++) {
 +			if (*sptr == '%')
-+				len += (int) strlen(dptr);
++				len += (int) strlen(dptr) + 1;
 +			else
 +				len++;
 +		}
-+		if (!(buf = new char[len])) {
++		if (!(buf = new char[len]))
 +			return DKIM_OUT_OF_MEMORY;
-+		}
 +		for (cptr = buf, sptr = ptr; *sptr; sptr++) {
 +			if (*sptr == '%') {
-+				strncpy(cptr, dptr, (len = strlen(dptr)));
++				memcpy(cptr, dptr, (len = strlen(dptr)));
 +				cptr += len;
-+			} else {
++			} else
 +				*cptr++ = *sptr;
-+			}
 +		}
 +		*cptr = 0;
@@ -10130,5 +10492,5 @@
 +getversion_dkimsign_cpp()
 +{
-+	static char    *x = (char *) "$Id: dkimsign.cpp,v 1.11 2017-09-05 10:59:03+05:30 Cprogrammer Exp mbhangui $";
++	static char    *x = (char *) "$Id: dkimsign.cpp,v 1.17 2020-04-10 21:36:20+05:30 Cprogrammer Exp mbhangui $";
 +
 +	x++;
@@ -10136,8 +10498,14 @@
 diff -ruN ../netqmail-1.06-original/dkimsign.h netqmail-1.06/dkimsign.h
 --- ../netqmail-1.06-original/dkimsign.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimsign.h	2018-04-03 14:46:51.366411614 +0200
-@@ -0,0 +1,108 @@
++++ netqmail-1.06/dkimsign.h	2020-04-10 18:39:39.483427628 +0200
+@@ -0,0 +1,115 @@
 +/*
 + * $Log: dkimsign.h,v $
++ * Revision 1.5  2019-06-26 19:09:07+05:30  Cprogrammer
++ * added sBouncedAddr variable for X-Bounced-Address header added by qmail-send for bounces
++ *
++ * Revision 1.4  2017-09-05 10:59:20+05:30  Cprogrammer
++ * removed compiler warnings
++ *
 + * Revision 1.3  2017-08-09 22:03:09+05:30  Cprogrammer
 + * initialized EVP_MD_CTX variables
@@ -10225,4 +10593,5 @@
 +	string          sSelector;
 +	string          sReturnPath;
++	string          sBouncedAddr; /*- used for bounces */
 +	string          sDomain;
 +	string          sIdentity;	// for i= tag, if empty tag will not be included in sig
@@ -10248,8 +10617,23 @@
 diff -ruN ../netqmail-1.06-original/dkimverify.cpp netqmail-1.06/dkimverify.cpp
 --- ../netqmail-1.06-original/dkimverify.cpp	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimverify.cpp	2018-04-03 14:46:51.367411617 +0200
-@@ -0,0 +1,1285 @@
++++ netqmail-1.06/dkimverify.cpp	2019-06-19 09:47:20.017583230 +0200
+@@ -0,0 +1,1303 @@
 +/*
 + * $Log: dkimverify.cpp,v $
++ * Revision 1.23  2019-05-22 11:29:09+05:30  Cprogrammer
++ * fix for 32 bit systems where time_t is 4 bytes & encounters year 2038 issue
++ *
++ * Revision 1.22  2019-05-21 22:27:17+05:30  Cprogrammer
++ * increased buffer size
++ *
++ * Revision 1.21  2019-02-17 11:32:05+05:30  Cprogrammer
++ * made scope of sFromDomain static
++ *
++ * Revision 1.20  2018-12-14 11:05:20+05:30  Cprogrammer
++ * fixed 'conversion from 'int' to 'char' inside { }â for cross compiling on arm
++ *
++ * Revision 1.19  2018-08-08 23:56:27+05:30  Cprogrammer
++ * changed comment style
++ *
 + * Revision 1.18  2017-09-05 11:00:33+05:30  Cprogrammer
 + * removed extra whitespace
@@ -10329,4 +10713,5 @@
 +#include "config.h"
 +#endif
++#include "time_t_size.h"
 +#define _strnicmp strncasecmp
 +#define _stricmp strcasecmp
@@ -10340,5 +10725,5 @@
 +#include "dkimdns.h"
 +
-+#define MAX_SIGNATURES	10		// maximum number of DKIM signatures to process in a message
++#define MAX_SIGNATURES	10		/*- maximum number of DKIM signatures to process in a message */
 +
 +SignatureInfo::SignatureInfo(bool s)
@@ -10397,11 +10782,11 @@
 +
 +	for (;;) {
-+		// skip whitespace
++		/* skip whitespace */
 +		while (isswsp(*s))
 +			s++;
-+		// if at the end of the string, return success.  note: this allows a list with no entries
++		/* if at the end of the string, return success.  note: this allows a list with no entries */
 +		if (*s == '\0')
 +			return true;
-+		// get tag name
++		/*- get tag name -*/
 +		if (!isalpha(*s))
 +			return false;
@@ -10411,22 +10796,22 @@
 +		} while (isalnum(*s) || *s == '-');
 +		char           *endtag = s;
-+		// skip whitespace before equals
++		/*- skip whitespace before equals -*/
 +		while (isswsp(*s))
 +			s++;
-+		// next character must be equals
++		/*- next character must be equals -*/
 +		if (*s != '=')
 +			return false;
 +		s++;
-+		// null-terminate tag name
++		/*- null-terminate tag name -*/
 +		*endtag = '\0';
-+		// skip whitespace after equals
++		/*- skip whitespace after equals -*/
 +		while (isswsp(*s))
 +			s++;
-+		// get tag value
++		/*- get tag value -*/
 +		char           *value = s;
 +		while (*s != ';' && ((*s == '\t' || *s == '\r' || *s == '\n') || (*s >= ' ' && *s <= '~')))
 +			s++;
 +		char           *e = s;
-+		// make sure the next character is the null terminator (which means we're done) or a semicolon (not done)
++		/*- make sure the next character is the null terminator (which means we're done) or a semicolon (not done) -*/
 +		bool            done = false;
 +		if (*s == '\0')
@@ -10437,13 +10822,13 @@
 +			s++;
 +		}
-+		// skip backwards past any trailing whitespace
++		/*- skip backwards past any trailing whitespace -*/
 +		while (e > value && isswsp(e[-1]))
 +			e--;
-+		// null-terminate tag value
++		/*- null-terminate tag value -*/
 +		*e = '\0';
-+		// check to see if we want this tag
++		/*- check to see if we want this tag -*/
 +		for (unsigned i = 0; wanted[i] != NULL; i++) {
 +			if (strcmp(wanted[i], tag) == 0) {
-+				// return failure if we already have a value for this tag (duplicates not allowed)
++				/*- return failure if we already have a value for this tag (duplicates not allowed) -*/
 +				if (values[i] != NULL)
 +					return false;
@@ -10457,5 +10842,5 @@
 +}
 +
-+// Convert hex char to value (0-15)
++/*- Convert hex char to value (0-15) -*/
 +char
 +tohex(char ch)
@@ -10510,5 +10895,5 @@
 +DecodeBase64(char *ptr)
 +{
-+	static const char base64_table[256] =
++	static const signed char base64_table[256] =
 +		{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
 +		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
@@ -10553,5 +10938,5 @@
 +WildcardMatch(const char *p, const char *s)
 +{
-+	// special case: An empty "g=" value never matches any addresses
++	/*- special case: An empty "g=" value never matches any addresses -*/
 +	if (*p == '\0')
 +		return false;
@@ -10582,8 +10967,8 @@
 +		char           *from = s;
 +		char           *to = s;
-+		char           *lt = NULL;	// pointer to less than character (<) which starts the address if found
++		char           *lt = NULL;	/*- pointer to less than character (<) which starts the address if found */
 +		while (*from != '\0') {
 +			if (*from == '(') {
-+				// skip over comment
++				/*- skip over comment -*/
 +				from++;
 +				for (int depth = 1; depth != 0; from++) {
@@ -10602,23 +10987,18 @@
 +			}
 +			else
-+			if (*from == ')') {
-+				// ignore closing parenthesis outside of comment
++			if (*from == ')') /*- ignore closing parenthesis outside of comment -*/
 +				from++;
-+			}
-+
 +			else
 +			if (*from == ',' || *from == ';') {
-+				// comma/selicolon ends the address
++				/*- comma/selicolon ends the address -*/
 +				from++;
 +				break;
 +			}
 +			else
-+			if (*from == ' ' || *from == '\t' || *from == '\r' || *from == '\n') {
-+				// ignore whitespace
++			if (*from == ' ' || *from == '\t' || *from == '\r' || *from == '\n') /*- ignore whitespace -*/
 +				from++;
-+			}
 +			else
 +			if (*from == '"') {
-+				// copy the contents of a quoted string
++				/*- copy the contents of a quoted string -*/
 +				from++;
 +				while (*from != '\0') {
@@ -10635,9 +11015,9 @@
 +			else
 +			if (*from == '\\' && from[1] != '\0') {
-+				// copy quoted-pair
++				/*- copy quoted-pair -*/
 +				*to++ = *from++;
 +				*to++ = *from++;
 +			} else {
-+				// copy any other char
++				/*- copy any other char -*/
 +				*to = *from++;
 +				// save pointer to '<' for later...
@@ -10648,5 +11028,5 @@
 +		}
 +		*to = '\0';
-+		// if there's < > get what's inside
++		/*- if there's < > get what's inside -*/
 +		if (lt != NULL) {
 +			start = lt + 1;
@@ -10655,5 +11035,5 @@
 +				*gt = '\0';
 +		} else {
-+			// look for and strip group name
++			/*- look for and strip group name -*/
 +			char           *colon = strchr(start, ':');
 +			if (colon != NULL) {
@@ -10686,5 +11066,5 @@
 +}
 +
-+// Init - save the options
++/*- Init - save the options -*/
 +int
 +CDKIMVerify::Init(DKIMVerifyOptions *pOptions)
@@ -10703,5 +11083,5 @@
 +}
 +
-+// GetResults - return the pass/fail/neutral verification result
++/*- GetResults - return the pass/fail/neutral verification result -*/
 +int
 +CDKIMVerify::GetResults(int *sCount, int *sSize)
@@ -10711,12 +11091,10 @@
 +	int             TestingFailures = 0;
 +	int             RealFailures = 0;
-+	list <string>   SuccessfulDomains;	// can contain duplicates
-+	/* get the From address's domain if we might need it */
-+	string          sFromDomain;
++	list <string>   SuccessfulDomains;	/* can contain duplicates */
++	string          sFromDomain; /*- get the From address's domain if we might need it -*/
 +
 +	for (list < SignatureInfo >::iterator i = Signatures.begin(); i != Signatures.end(); ++i) {
 +		if (i->Status == DKIM_SUCCESS) {
-+			if (!i->BodyHashData.empty()) {
-+				// check the body hash
++			if (!i->BodyHashData.empty()) { /*- check the body hash -*/
 +				unsigned char   md[EVP_MAX_MD_SIZE];
 +				unsigned        len = 0;
@@ -10727,8 +11105,7 @@
 +#endif
 +				if (!res || len != i->BodyHashData.length() || memcmp(i->BodyHashData.data(), md, len) != 0) {
-+					// body hash mismatch
-+					// if the selector is in testing mode...
-+					if (i->m_pSelector->Testing) {
-+						i->Status = DKIM_SIGNATURE_BAD_BUT_TESTING;	// todo: make a new error code for this?
++					/* body hash mismatch */
++					if (i->m_pSelector->Testing) { /* if the selector is in testing mode... */
++						i->Status = DKIM_SIGNATURE_BAD_BUT_TESTING;	/* todo: make a new error code for this? */
 +						TestingFailures++;
 +					} else {
@@ -10739,8 +11116,8 @@
 +				}
 +			} else {
-+				// hash CRLF separating the body from the signature
++				/* hash CRLF separating the body from the signature */
 +				i->Hash("\r\n", 2);
 +			}
-+			// check the header hash
++			/*- check the header hash -*/
 +			string          sSignedSig = i->Header;
 +			string          sSigValue = sSignedSig.substr(sSignedSig.find(':') + 1);
@@ -10756,5 +11133,5 @@
 +			if (i->HeaderCanonicalization == DKIM_CANON_NOWSP) {
 +				RemoveSWSP(sSignedSig);
-+				// convert "DKIM-Signature" to lower case
++				/* convert "DKIM-Signature" to lower case */
 +				sSignedSig.replace(0, 14, "dkim-signature", 14);
 +			}
@@ -10776,5 +11153,5 @@
 +				SuccessfulDomains.push_back(i->Domain);
 +			} else {
-+				// if the selector is in testing mode...
++				/* if the selector is in testing mode... */
 +				if (i->m_pSelector->Testing) {
 +					i->Status = DKIM_SIGNATURE_BAD_BUT_TESTING;
@@ -10789,6 +11166,6 @@
 +			|| i->Status == DKIM_SELECTOR_ALGORITHM_MISMATCH
 +			|| i->Status == DKIM_SELECTOR_KEY_REVOKED) {
-+			// treat these as failures
-+			// todo: maybe see if the selector is in testing mode?
++			/*- treat these as failures -*/
++			/*- todo: maybe see if the selector is in testing mode? -*/
 +			RealFailures++;
 +		}
@@ -10797,5 +11174,5 @@
 +		for (list < string >::iterator i = HeaderList.begin(); i != HeaderList.end(); ++i) {
 +			if (_strnicmp(i->c_str(), "From", 4) == 0) {
-+				// skip over whitespace between the header name and :
++				/*- skip over whitespace between the header name and : -*/
 +				const char     *s = i->c_str() + 4;
 +				while (*s == ' ' || *s == '\t')
@@ -10812,9 +11189,11 @@
 +		}
 +	}
-+	// if a signature from the From domain verified successfully, return success now
-+	// without checking the sender signing practices
++	/*-
++	 * if a signature from the From domain verified successfully,
++	 * return success now without checking the sender signing practices
++	 */
 +	if (SuccessCount > 0 && !sFromDomain.empty()) {
 +		for (list < string >::iterator i = SuccessfulDomains.begin(); i != SuccessfulDomains.end(); ++i) {
-+			// see if the successful domain is the same as or a parent of the From domain
++			/* see if the successful domain is the same as or a parent of the From domain */
 +			if (i->length() > sFromDomain.length())
 +				continue;
@@ -10870,13 +11249,13 @@
 +
 +
-+// ProcessHeaders - Look for DKIM-Signatures and start processing them
++/*- ProcessHeaders - Look for DKIM-Signatures and start processing them -*/
 +int
 +CDKIMVerify::ProcessHeaders(void)
 +{
 +
-+	// look for DKIM-Signature header(s)
++	/*- look for DKIM-Signature header(s) -*/
 +	for (list < string >::iterator i = HeaderList.begin(); i != HeaderList.end(); ++i) {
 +		if (_strnicmp(i->c_str(), "DKIM-Signature", 14) == 0) {
-+			// skip over whitespace between the header name and :
++			/*- skip over whitespace between the header name and : -*/
 +			const char     *s = i->c_str() + 14;
 +			while (*s == ' ' || *s == '\t')
@@ -10905,8 +11284,8 @@
 +			return (sig.Status);
 +		} else {
-+			// check the granularity
++			/*- check the granularity -*/
 +			if (!WildcardMatch(sel.Granularity.c_str(), sig.IdentityLocalPart.c_str()))
-+				sig.Status = DKIM_SELECTOR_GRANULARITY_MISMATCH;	// this error causes the signature to fail
-+			// check the hash algorithm
++				sig.Status = DKIM_SELECTOR_GRANULARITY_MISMATCH;	/* this error causes the signature to fail */
++			/*- check the hash algorithm -*/
 +#ifdef HAVE_EVP_SHA256
 +			if ((sig.m_nHash == DKIM_HASH_SHA1 && !sel.AllowSHA1) || (sig.m_nHash == DKIM_HASH_SHA256 && !sel.AllowSHA256))
@@ -10914,6 +11293,6 @@
 +			if ((sig.m_nHash == DKIM_HASH_SHA1 && !sel.AllowSHA1))
 +#endif
-+				sig.Status = DKIM_SELECTOR_ALGORITHM_MISMATCH;	// causes signature to fail
-+			// check for same domain
++				sig.Status = DKIM_SELECTOR_ALGORITHM_MISMATCH;	/* causes signature to fail */
++			/*- check for same domain -*/
 +			if (sel.SameDomain && _stricmp(sig.Domain.c_str(), sig.IdentityDomain.c_str()) != 0)
 +				sig.Status = DKIM_BAD_SYNTAX;
@@ -10921,5 +11300,5 @@
 +		if (sig.Status != DKIM_SUCCESS)
 +			continue;
-+		// initialize the hashes
++		/*- initialize the hashes -*/
 +#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 +#ifdef HAVE_EVP_SHA256
@@ -10949,5 +11328,5 @@
 +#endif
 +#endif
-+		// compute the hash of the header
++		/*- compute the hash of the header -*/
 +		vector < list < string >::reverse_iterator > used;
 +		for (vector < string >::iterator x = sig.SignedHeaders.begin(); x != sig.SignedHeaders.end(); ++x) {
@@ -10955,5 +11334,5 @@
 +			for (i = HeaderList.rbegin(); i != HeaderList.rend(); ++i) {
 +				if (_strnicmp(i->c_str(), x->c_str(), x->length()) == 0) {
-+					// skip over whitespace between the header name and :
++					/*- skip over whitespace between the header name and : -*/
 +					const char     *s = i->c_str() + x->length();
 +					while (*s == ' ' || *s == '\t')
@@ -10965,5 +11344,5 @@
 +			if (i != HeaderList.rend()) {
 +				used.push_back(i);
-+				// hash this header
++				/*- hash this header -*/
 +				if (sig.HeaderCanonicalization == DKIM_CANON_SIMPLE)
 +					sig.Hash(i->c_str(), i->length());
@@ -10976,5 +11355,5 @@
 +					string          sTemp = *i;
 +					RemoveSWSP(sTemp);
-+					// convert characters before ':' to lower case
++					/*- convert characters before ':' to lower case -*/
 +					for (char *s = (char *)sTemp.c_str(); *s != '\0' && *s != ':'; s++) {
 +						if (*s >= 'A' && *s <= 'Z')
@@ -10986,14 +11365,12 @@
 +			}
 +		}
-+		if (sig.BodyHashData.empty()) {
-+			// hash CRLF separating headers from body
++		if (sig.BodyHashData.empty()) /*- hash CRLF separating headers from body -*/
 +			sig.Hash("\r\n", 2);
-+		}
 +		if (!m_AllowUnsignedFromHeaders) {
-+			// make sure the message has no unsigned From headers
++			/*- make sure the message has no unsigned From headers -*/
 +			list<string>::reverse_iterator i;
 +			for( i = HeaderList.rbegin(); i != HeaderList.rend(); ++i ) {
 +				if( _strnicmp(i->c_str(), "From", 4 ) == 0 ) {
-+					// skip over whitespace between the header name and :
++					/*- skip over whitespace between the header name and : -*/
 +					const char *s = i->c_str()+4;
 +					while (*s == ' ' || *s == '\t')
@@ -11001,5 +11378,5 @@
 +					if (*s == ':') {
 +						if (find(used.begin(), used.end(), i) == used.end()) {
-+							// this From header was not signed
++							/*- this From header was not signed -*/
 +							break;
 +						}
@@ -11008,5 +11385,5 @@
 +			}
 +			if (i != HeaderList.rend()) {
-+				// treat signature as invalid
++				/*- treat signature as invalid -*/
 +				sig.Status = DKIM_UNSIGNED_FROM;
 +				continue;
@@ -11035,5 +11412,5 @@
 +	do {
 +		if (*s < '0' || *s > '9')
-+			return false;		// returns false for an initial '\0'
++			return false;	/*- returns false for an initial '\0' */
 +		temp = temp * 10 + (*s - '0');
 +		if (temp < last)
@@ -11050,10 +11427,10 @@
 +
 +
-+// ParseDKIMSignature - Parse a DKIM-Signature header field
++/*- ParseDKIMSignature - Parse a DKIM-Signature header field -*/
 +int
 +CDKIMVerify::ParseDKIMSignature(const string &sHeader, SignatureInfo &sig)
 +{
 +
-+	// save header for later
++	/*- save header for later -*/
 +	sig.Header = sHeader;
 +	string          sValue = sHeader.substr(sHeader.find(':') + 1);
@@ -11064,19 +11441,18 @@
 +	if (!ParseTagValueList((char *) sValue.c_str(), tags, values))
 +		return DKIM_BAD_SYNTAX;
-+	// check signature version
++	/*- check signature version -*/
 +	if (values[0] != NULL) {
 +		if (strcmp(values[0], "1") == 0 || strcmp(values[0], "0.5") == 0 || strcmp(values[0], "0.4") == 0
 +			|| strcmp(values[0], "0.3") == 0 || strcmp(values[0], "0.2") == 0) {
 +			sig.Version = DKIM_SIG_VERSION_02_PLUS;
-+		} else {
-+		// unknown version
++		} else /*- unknown version -*/
 +			return DKIM_STAT_INCOMPAT;
-+		}
 +	} else {
-+		// Note:  DKIM Interop 1 pointed out that v= is now required, but we do
-+		// not enforce that in order to verify signatures made by older drafts.
-+
-+		// prior to 0.2, there MUST NOT have been a v=
-+		// (optionally) support these signatures, for backwards compatibility
++		/*-
++		 * Note:  DKIM Interop 1 pointed out that v= is now required, but we do
++		 * not enforce that in order to verify signatures made by older drafts.
++		 * prior to 0.2, there MUST NOT have been a v=
++		 * (optionally) support these signatures, for backwards compatibility
++		 */
 +		if (true) {
 +			sig.Version = DKIM_SIG_VERSION_PRE_02;
@@ -11085,27 +11461,26 @@
 +		}
 +	}
-+	// signature MUST have a=, b=, d=, h=, s=
++	/*- signature MUST have a=, b=, d=, h=, s= -*/
 +	if (values[1] == NULL || values[2] == NULL || values[3] == NULL || values[4] == NULL || values[5] == NULL)
 +		return DKIM_BAD_SYNTAX;
-+	// algorithm can be "rsa-sha1" or "rsa-sha256"
++	/*- algorithm can be "rsa-sha1" or "rsa-sha256" -*/
 +	if (strcmp(values[1], "rsa-sha1") == 0) {
 +		sig.m_nHash = DKIM_HASH_SHA1;
 +	}
 +#ifdef HAVE_EVP_SHA256
-+	else if (strcmp(values[1], "rsa-sha256") == 0) {
++	else
++	if (strcmp(values[1], "rsa-sha256") == 0)
 +		sig.m_nHash = DKIM_HASH_SHA256;
-+	}
 +#endif
-+	else {
-+		return DKIM_BAD_SYNTAX;	// todo: maybe create a new error code for unknown algorithm
-+	}
-+	// make sure the signature data is not empty
++	else
++		return DKIM_BAD_SYNTAX;	/* todo: maybe create a new error code for unknown algorithm */
++	/*- make sure the signature data is not empty -*/
 +	unsigned SigDataLen = DecodeBase64(values[2]);
 +	if (SigDataLen == 0)
 +		return DKIM_BAD_SYNTAX;
 +	sig.SignatureData.assign(values[2], SigDataLen);
-+	// check for body hash
++	/*- check for body hash -*/
 +	if (values[12] == NULL) {
-+		// use the old single hash way for backwards compatibility
++		/*- use the old single hash way for backwards compatibility -*/
 +		if (sig.Version != DKIM_SIG_VERSION_PRE_02)
 +			return DKIM_BAD_SYNTAX;
@@ -11116,24 +11491,23 @@
 +		sig.BodyHashData.assign(values[12], BodyHashLen);
 +	}
-+	// domain must not be empty
++	/*- domain must not be empty -*/
 +	if (*values[3] == '\0')
 +		return DKIM_BAD_SYNTAX;
 +	sig.Domain = values[3];
-+	// signed headers must not be empty (more verification is done later)
++	/*- signed headers must not be empty (more verification is done later) -*/
 +	if (*values[4] == '\0')
 +		return DKIM_BAD_SYNTAX;
-+	// selector must not be empty
++	/*- selector must not be empty -*/
 +	if (*values[5] == '\0')
 +		return DKIM_BAD_SYNTAX;
 +	sig.Selector = values[5];
-+	// canonicalization
++	/*- canonicalization -*/
 +	if (values[6] == NULL) {
 +		sig.HeaderCanonicalization = sig.BodyCanonicalization = DKIM_CANON_SIMPLE;
 +	}
 +	else
-+	if (sig.Version == DKIM_SIG_VERSION_PRE_02 && strcmp(values[6], "nowsp") == 0) {
-+	// for backwards compatibility
++	if (sig.Version == DKIM_SIG_VERSION_PRE_02 && strcmp(values[6], "nowsp") == 0) /*- for backwards compatibility -*/
 +		sig.HeaderCanonicalization = sig.BodyCanonicalization = DKIM_CANON_NOWSP;
-+	} else {
++	else {
 +		char           *slash = strchr(values[6], '/');
 +		if (slash != NULL)
@@ -11154,12 +11528,12 @@
 +			return DKIM_BAD_SYNTAX;
 +	}
-+	// identity
++	/*- identity -*/
 +	if (values[7] == NULL) {
 +		sig.IdentityLocalPart.erase();
 +		sig.IdentityDomain = sig.Domain;
 +	} else {
-+		// quoted-printable decode the value
++		/*- quoted-printable decode the value -*/
 +		DecodeQuotedPrintable(values[7]);
-+		// must have a '@' separating the local part from the domain
++		/*- must have a '@' separating the local part from the domain -*/
 +		char           *at = strchr(values[7], '@');
 +		if (at == NULL)
@@ -11168,9 +11542,9 @@
 +		char           *ilocalpart = values[7];
 +		char           *idomain = at + 1;
-+		// i= domain must be the same as or a subdomain of the d= domain
++		/*- i= domain must be the same as or a subdomain of the d= domain -*/
 +		int idomainlen = strlen(idomain);
 +		int ddomainlen = strlen(values[3]);
 +
-+		// todo: maybe create a new error code for invalid identity domain
++		/*- todo: maybe create a new error code for invalid identity domain -*/
 +		if (idomainlen < ddomainlen)
 +			return DKIM_BAD_SYNTAX;
@@ -11182,5 +11556,5 @@
 +		sig.IdentityDomain = idomain;
 +	}
-+	// body count
++	/*- body count -*/
 +	if (values[8] == NULL || !m_HonorBodyLengthTag) {
 +		sig.BodyLength = -1;
@@ -11189,8 +11563,8 @@
 +			return DKIM_BAD_SYNTAX;
 +	}
-+	// query methods
++	/*- query methods -*/
 +	if (values[9] != NULL) {
 +
-+		// make sure "dns" is in the list
++		/*- make sure "dns" is in the list -*/
 +		bool            HasDNS = false;
 +		char           *s = strtok_r(values[9], ":", &saveptr);
@@ -11205,11 +11579,15 @@
 +			return DKIM_BAD_SYNTAX;	// todo: maybe create a new error code for unknown query method
 +	}
-+	// signature time
++#if SIZEOF_TIME_T  == 8
++	/*- signature time -*/
 +	time_t          SignedTime = -1;
++#else
++	long long       SignedTime = -1;
++#endif
 +	if (values[10] != NULL) {
 +		if (!ParseUnsigned(values[10], (unsigned long *) &SignedTime))
 +			return DKIM_BAD_SYNTAX;
 +	}
-+	// expiration time
++	/*- expiration time -*/
 +	if (values[11] == NULL) {
 +		sig.ExpireTime = -1;
@@ -11218,16 +11596,26 @@
 +			return DKIM_BAD_SYNTAX;
 +		if (sig.ExpireTime != -1) {
-+			// the value of x= MUST be greater than the value of t= if both are present
++			/*- the value of x= MUST be greater than the value of t= if both are present -*/
++#if SIZEOF_TIME_T  == 8
 +			if (SignedTime != -1 && sig.ExpireTime <= SignedTime)
 +				return DKIM_BAD_SYNTAX;
-+			// todo: if possible, use the received date/time instead of the current time
++#else
++			if (SignedTime != -1 && (long long) sig.ExpireTime <= SignedTime)
++				return DKIM_BAD_SYNTAX;
++#endif
++			/*- todo: if possible, use the received date/time instead of the current time -*/
 +			time_t curtime = time(NULL);
++#if SIZEOF_TIME_T  == 8
 +			if (curtime > sig.ExpireTime)
 +				return DKIM_SIGNATURE_EXPIRED;
++#else /*- handle year 2038 the best we can, beyond which one has to upgrade to a 64 bit os */
++			if (curtime < 2147483648 && curtime > sig.ExpireTime)
++				return DKIM_SIGNATURE_EXPIRED;
++#endif
 +		}
 +	}
-+	// parse the signed headers list
++	/*- parse the signed headers list -*/
 +	bool            HasFrom = false, HasSubject = false;
-+	RemoveSWSP(values[4]);		// header names shouldn't have spaces in them so this should be ok...
++	RemoveSWSP(values[4]);		/*- header names shouldn't have spaces in them so this should be ok... */
 +	char           *s = strtok_r(values[4], ":", &saveptr);
 +	while (s != NULL) {
@@ -11241,12 +11629,12 @@
 +	}
 +	if (!HasFrom)
-+		return DKIM_BAD_SYNTAX;	// todo: maybe create a new error code for h= missing From
++		return DKIM_BAD_SYNTAX;	/*- todo: maybe create a new error code for h= missing From */
 +	if (m_SubjectIsRequired && !HasSubject)
-+		return DKIM_BAD_SYNTAX;	// todo: maybe create a new error code for h= missing Subject
++		return DKIM_BAD_SYNTAX;	/*- todo: maybe create a new error code for h= missing Subject */
 +	return DKIM_SUCCESS;
 +}
 +
 +
-+// ProcessBody - Process message body data
++/*- ProcessBody - Process message body data -*/
 +int
 +CDKIMVerify::ProcessBody(char *szBuffer, int nBufLength, bool bEOF)
@@ -11330,9 +11718,9 @@
 +		return DKIM_SELECTOR_INVALID;
 +	if (values[0] != NULL) {
-+
-+		// make sure the version is "DKIM1"
++		/*- make sure the version is "DKIM1" -*/
 +		if (strcmp(values[0], "DKIM1") != 0)
-+			return DKIM_SELECTOR_INVALID;	// todo: maybe create a new error code for unsupported selector version
-+		// make sure v= is the first tag in the response    // todo: maybe don't enforce this, it seems unnecessary
++			return DKIM_SELECTOR_INVALID;	/*- todo: maybe create a new error code for unsupported selector version */
++		/*- make sure v= is the first tag in the response  */
++		/*- todo: maybe don't enforce this, it seems unnecessary */
 +		for (unsigned int j = 1; j < sizeof (values) / sizeof (values[0]); j++) {
 +			if (values[j] != NULL && values[j] < values[0]) {
@@ -11341,8 +11729,8 @@
 +		}
 +	}
-+	// selector MUST have p= tag
++	/*- selector MUST have p= tag -*/
 +	if (values[4] == NULL)
 +		return DKIM_SELECTOR_INVALID;
-+	// granularity
++	/*- granularity -*/
 +	if (values[1] == NULL)
 +		Granularity = "*";
@@ -11350,5 +11738,5 @@
 +	else
 +		Granularity = values[1];
-+	// hash algorithm
++	/*- hash algorithm -*/
 +	if (values[2] == NULL) {
 +		AllowSHA1 = true;
@@ -11359,5 +11747,5 @@
 +#endif
 +	} else {
-+		// MUST include "sha1" or "sha256"
++		/*- MUST include "sha1" or "sha256" -*/
 +		char           *s = strtok_r(values[2], ":", &saveptr);
 +		while (s != NULL) {
@@ -11375,15 +11763,15 @@
 +		if (!AllowSHA1)
 +#endif
-+			return DKIM_SELECTOR_INVALID;	// todo: maybe create a new error code for unsupported hash algorithm
-+	}
-+	// key type
++			return DKIM_SELECTOR_INVALID;	/*- todo: maybe create a new error code for unsupported hash algorithm */
++	}
++	/*- key type -*/
 +	if (values[3] != NULL) {
-+		// key type MUST be "rsa"
++		/*- key type MUST be "rsa" -*/
 +		if (strcmp(values[3], "rsa") != 0)
 +			return DKIM_SELECTOR_INVALID;
 +	}
-+	// service type
++	/*- service type -*/
 +	if (values[5] != NULL) {
-+		// make sure "*" or "email" is in the list
++		/*- make sure "*" or "email" is in the list -*/
 +		bool            ServiceTypeMatch = false;
 +		char           *s = strtok_r(values[5], ":", &saveptr);
@@ -11398,5 +11786,5 @@
 +			return DKIM_SELECTOR_INVALID;
 +	}
-+	// flags
++	/*- flags -*/
 +	if (values[6] != NULL) {
 +		char           *s = strtok_r(values[6], ":", &saveptr);
@@ -11411,9 +11799,9 @@
 +		}
 +	}
-+#define M_ToConstUCharPtr(p)       reinterpret_cast<const unsigned char*>(p)          // Cast to unsigned char*
++#define M_ToConstUCharPtr(p)       reinterpret_cast<const unsigned char*>(p) /* Cast to unsigned char* */
 +	/*- public key data */
 +	unsigned        PublicKeyLen = DecodeBase64(values[4]);
 +	if (PublicKeyLen == 0)
-+		return DKIM_SELECTOR_KEY_REVOKED;	// this error causes the signature to fail
++		return DKIM_SELECTOR_KEY_REVOKED; /*- this error causes the signature to fail */
 +	else {
 +		EVP_PKEY       *pkey;
@@ -11447,9 +11835,8 @@
 +}
 +
-+// GetSelector - Get a DKIM selector for a domain
++/*- GetSelector - Get a DKIM selector for a domain -*/
 +SelectorInfo &CDKIMVerify::GetSelector(const string &sSelector, const string &sDomain)
 +{
-+
-+	// see if we already have this selector
++	/*- see if we already have this selector -*/
 +	for (list < SelectorInfo >::iterator i = Selectors.begin(); i != Selectors.end(); ++i) {
 +		if (_stricmp(i->Selector.c_str(), sSelector.c_str()) == 0 && _stricmp(i->Domain.c_str(), sDomain.c_str()) == 0) {
@@ -11462,5 +11849,5 @@
 +	sFQDN += "._domainkey.";
 +	sFQDN += sDomain;
-+	char            Buffer[1024];
++	char            Buffer[4096];
 +	int             DNSResult;
 +
@@ -11487,5 +11874,5 @@
 +}
 +
-+// GetDetails - Get DKIM verification details (per signature)
++/*- GetDetails - Get DKIM verification details (per signature) -*/
 +int
 +CDKIMVerify::GetDetails(int *nSigCount, DKIMVerifyDetails ** pDetails)
@@ -11508,8 +11895,8 @@
 +CDKIMVerify::GetDomain(void)
 +{
-+	string          sFromDomain;
++	static string   sFromDomain;
 +	for (list <string>::iterator i = HeaderList.begin(); i != HeaderList.end(); ++i) {
 +		if (_strnicmp(i->c_str(), "From", 4) == 0) {
-+			// skip over whitespace between the header name and :
++			/*- skip over whitespace between the header name and : -*/
 +			const char     *s = i->c_str() + 4;
 +			while (*s == ' ' || *s == '\t')
@@ -11531,5 +11918,5 @@
 +getversion_dkimverify_cpp()
 +{
-+	static char    *x = (char *) "$Id: dkimverify.cpp,v 1.18 2017-09-05 11:00:33+05:30 Cprogrammer Exp mbhangui $";
++	static char    *x = (char *) "$Id: dkimverify.cpp,v 1.23 2019-05-22 11:29:09+05:30 Cprogrammer Exp mbhangui $";
 +
 +	x++;
@@ -11537,8 +11924,14 @@
 diff -ruN ../netqmail-1.06-original/dkimverify.h netqmail-1.06/dkimverify.h
 --- ../netqmail-1.06-original/dkimverify.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dkimverify.h	2018-04-03 14:46:51.367411617 +0200
-@@ -0,0 +1,139 @@
++++ netqmail-1.06/dkimverify.h	2019-06-19 09:47:30.665464671 +0200
+@@ -0,0 +1,150 @@
 +/*
 + * $Log: dkimverify.h,v $
++ * Revision 1.9  2019-06-14 21:25:11+05:30  Cprogrammer
++ * BUG - honor body length tag in verification. Changed data type for BodyLength
++ *
++ * Revision 1.8  2019-05-22 11:30:06+05:30  Cprogrammer
++ * fix for 32 bit systems where time_t is 4 bytes & encounters year 2038 issue
++ *
 + * Revision 1.7  2017-08-31 17:07:45+05:30  Cprogrammer
 + * fixed g++ compiler warning
@@ -11586,4 +11979,5 @@
 +
 +#include "dkimbase.h"
++#include "time_t_size.h"
 +#include <vector>
 +
@@ -11624,10 +12018,14 @@
 +	string          CanonicalizedData;
 +	vector <string> SignedHeaders;
-+	int             BodyLength;
++	long            BodyLength;
 +	unsigned        HeaderCanonicalization;
 +	unsigned        BodyCanonicalization;
++#if SIZEOF_TIME_T  == 8
 +	time_t          ExpireTime;
-+	int             VerifiedBodyCount;
-+	unsigned        UnverifiedBodyCount;
++#else
++	long long       ExpireTime;
++#endif
++	long            VerifiedBodyCount;
++	long            UnverifiedBodyCount;
 +#if OPENSSL_VERSION_NUMBER >= 0x10100000L
 +	EVP_MD_CTX     *m_Hdr_ctx = NULL;
@@ -11680,5 +12078,5 @@
 diff -ruN ../netqmail-1.06-original/dknewkey.sh netqmail-1.06/dknewkey.sh
 --- ../netqmail-1.06-original/dknewkey.sh	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dknewkey.sh	2016-11-22 21:03:57.112528099 +0100
++++ netqmail-1.06/dknewkey.sh	2019-02-27 20:57:13.389025081 +0100
 @@ -0,0 +1,27 @@
 +#
@@ -11711,5 +12109,5 @@
 diff -ruN ../netqmail-1.06-original/dktest.9 netqmail-1.06/dktest.9
 --- ../netqmail-1.06-original/dktest.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dktest.9	2016-11-22 21:03:57.112528099 +0100
++++ netqmail-1.06/dktest.9	2019-02-27 20:57:13.389025081 +0100
 @@ -0,0 +1,86 @@
 +.TH dktest 8
@@ -11801,6 +12199,6 @@
 diff -ruN ../netqmail-1.06-original/dktest.c netqmail-1.06/dktest.c
 --- ../netqmail-1.06-original/dktest.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dktest.c	2016-11-22 21:03:57.112528099 +0100
-@@ -0,0 +1,431 @@
++++ netqmail-1.06/dktest.c	2020-04-09 19:44:51.053935329 +0200
+@@ -0,0 +1,434 @@
 +/*
 + * $Log: dktest.c,v $
@@ -12204,4 +12602,7 @@
 +			status = "bad sender (g=)";
 +			break;
++		case DK_STAT_DUPLICATE:
++			status = "duplicate signature";
++			break;
 +		}
 +#if 0
@@ -12236,5 +12637,5 @@
 diff -ruN ../netqmail-1.06-original/dktrace.c netqmail-1.06/dktrace.c
 --- ../netqmail-1.06-original/dktrace.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dktrace.c	2016-11-22 21:03:57.112528099 +0100
++++ netqmail-1.06/dktrace.c	2019-02-27 20:57:13.389025081 +0100
 @@ -0,0 +1,277 @@
 +/*
@@ -12517,5 +12918,5 @@
 diff -ruN ../netqmail-1.06-original/dktrace.h netqmail-1.06/dktrace.h
 --- ../netqmail-1.06-original/dktrace.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dktrace.h	2016-11-22 21:03:57.112528099 +0100
++++ netqmail-1.06/dktrace.h	2019-02-27 20:57:13.389025081 +0100
 @@ -0,0 +1,26 @@
 +/* $Id: dktrace.h,v 1.3 2005/06/27 18:47:57 ted46045 Exp $ */
@@ -12547,5 +12948,5 @@
 diff -ruN ../netqmail-1.06-original/dns.c netqmail-1.06/dns.c
 --- ../netqmail-1.06-original/dns.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/dns.c	2018-04-02 11:45:03.323768372 +0200
++++ netqmail-1.06/dns.c	2019-04-09 20:53:51.981528338 +0200
 @@ -1,4 +1,3 @@
 -#include <stdio.h>
@@ -12710,5 +13111,5 @@
     case DNS_MEM: return DNS_MEM;
     case DNS_SOFT: return DNS_SOFT;
-@@ -254,25 +318,46 @@
+@@ -254,25 +318,49 @@
     if (r == DNS_SOFT) return DNS_SOFT;
     if (r == 1)
@@ -12757,9 +13158,11 @@
   if (!stralloc_0(&glue)) return DNS_MEM;
   if (glue.s[0]) {
--   ix.pref = 0;
++#ifndef IX_FQDN
+    ix.pref = 0;
++#endif
     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 +376,16 @@
+@@ -291,9 +379,16 @@
     ix.ip = ip;
     ix.pref = pref;
@@ -12779,5 +13182,5 @@
  }
  
-@@ -313,7 +405,7 @@
+@@ -313,7 +408,7 @@
  {
   int r;
@@ -12788,13 +13191,15 @@
   int i;
   int j;
-@@ -325,7 +417,6 @@
+@@ -325,7 +420,9 @@
   if (!stralloc_copy(&glue,sa)) return DNS_MEM;
   if (!stralloc_0(&glue)) return DNS_MEM;
   if (glue.s[0]) {
--   ix.pref = 0;
++#ifndef IX_FQDN
+    ix.pref = 0;
++#endif
     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;
-@@ -396,3 +487,49 @@
+@@ -396,3 +493,49 @@
   alloc_free(mx);
   return flagsoft;
@@ -12848,5 +13253,5 @@
 diff -ruN ../netqmail-1.06-original/dns.h netqmail-1.06/dns.h
 --- ../netqmail-1.06-original/dns.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/dns.h	2016-11-22 21:03:57.113528065 +0100
++++ netqmail-1.06/dns.h	2019-02-27 20:57:13.390025070 +0100
 @@ -10,5 +10,6 @@
  int dns_mxip();
@@ -12858,5 +13263,5 @@
 diff -ruN ../netqmail-1.06-original/dnsfq.c netqmail-1.06/dnsfq.c
 --- ../netqmail-1.06-original/dnsfq.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/dnsfq.c	2016-11-22 21:03:57.113528065 +0100
++++ netqmail-1.06/dnsfq.c	2019-02-27 20:57:13.390025070 +0100
 @@ -5,15 +5,19 @@
  #include "dnsdoe.h"
@@ -12896,5 +13301,5 @@
 diff -ruN ../netqmail-1.06-original/dnsptr.c netqmail-1.06/dnsptr.c
 --- ../netqmail-1.06-original/dnsptr.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/dnsptr.c	2016-11-22 21:03:57.113528065 +0100
++++ netqmail-1.06/dnsptr.c	2019-02-27 20:57:13.390025070 +0100
 @@ -6,22 +6,28 @@
  #include "dns.h"
@@ -12932,5 +13337,5 @@
 diff -ruN ../netqmail-1.06-original/dnstxt.c netqmail-1.06/dnstxt.c
 --- ../netqmail-1.06-original/dnstxt.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/dnstxt.c	2016-11-22 21:03:57.113528065 +0100
++++ netqmail-1.06/dnstxt.c	2019-02-27 20:57:13.390025070 +0100
 @@ -0,0 +1,32 @@
 +#include "substdio.h"
@@ -12968,6 +13373,6 @@
 diff -ruN ../netqmail-1.06-original/domainkeys.h netqmail-1.06/domainkeys.h
 --- ../netqmail-1.06-original/domainkeys.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/domainkeys.h	2018-03-31 15:08:54.373109416 +0200
-@@ -0,0 +1,378 @@
++++ netqmail-1.06/domainkeys.h	2020-04-09 19:45:10.589742433 +0200
+@@ -0,0 +1,379 @@
 +/* This file is automatically created from the corresponding .c file */
 +/* Do not change this file; change the .c file instead. */
@@ -13037,4 +13442,5 @@
 +  DK_STAT_INTERNAL, /* cannot call this routine in this context.  Internal error. */
 +  DK_STAT_GRANULARITY, /* Granularity mismatch: sender doesn't match g= option. */
++  DK_STAT_DUPLICATE, /* Duplicate Domainkey-Header */
 +} DK_STAT;
 +
@@ -13350,5 +13756,5 @@
 diff -ruN ../netqmail-1.06-original/forward.c netqmail-1.06/forward.c
 --- ../netqmail-1.06-original/forward.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/forward.c	2016-11-22 21:03:57.114528032 +0100
++++ netqmail-1.06/forward.c	2019-02-27 20:57:13.391025058 +0100
 @@ -6,11 +6,11 @@
  #include "strerr.h"
@@ -13384,5 +13790,5 @@
 diff -ruN ../netqmail-1.06-original/global.h netqmail-1.06/global.h
 --- ../netqmail-1.06-original/global.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/global.h	2016-11-22 21:03:57.114528032 +0100
++++ netqmail-1.06/global.h	2019-02-27 20:57:13.391025058 +0100
 @@ -0,0 +1,51 @@
 +/* GLOBAL.H - RSAREF types and constants */
@@ -13437,846 +13843,23 @@
 +
 +#endif /* end _GLOBAL_H_ */
-diff -ruN ../netqmail-1.06-original/goodrcptto-12.patch netqmail-1.06/goodrcptto-12.patch
---- ../netqmail-1.06-original/goodrcptto-12.patch	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/goodrcptto-12.patch	2004-11-09 20:12:53.000000000 +0100
-@@ -0,0 +1,834 @@
-+This is a goodrcptto patch for qmail-1.03 or netqmail-1.05:
-+http://netdevice.com/qmail/patch/goodrcptto-12.patch
-+See http://cr.yp.to/qmail.html or http://qmail.org/netqmail/.
-+
-+A qmail server will normally accept email for any recipient address at a domain.
-+This patch causes the server to reject single recipient email to an invalid
-+recipient, and filter out the invalid recipients from multiple recipient email,
-+while accepting the message for the valid recipients.
-+This occurs during the initial SMTP conversation for a reduction in disk I/O.
-+The server rejects attempts to queue messages to non existent recipients, and
-+joe job bounces to forged recipients, preventing them from becoming double
-+bounces.
-+To prevent dictionary attacks, the transmission channel is closed after the
-+number of bad recipients set in control/brtlimit or BRTLIMIT, two by default.
-+Repeated attempts from the same IPs may be handled by a cron that looks at the
-+logs and updates tcprules accordingly.
-+
-+A goodrcptto list and or moregoodrcptto database is maintained.
-+Relay and accept clients are not held to the address check, control/brtlimit or
-+BRTLIMIT.
-+If you need to wildcard domains, list them one per line like @example.net
-+in control/goodrcptto only.
-+Recipient addresses like name@example.com may be included in control/goodrcptto,
-+but the check will run fastest if you put these into control/moregoodrcptto,
-+then into control/moregoodrcptto.cdb using qmail-newmgrt.
-+A check against a 50,000 address moregoodrcptto.cdb is virtually instantaneous
-+on a 300Mhz machine.
-+
-+A user may want to participate in mailing list discussions, but doesn't want
-+spam or off list replies to her now public address.
-+Set ACCEPTCLIENT="" for the IPs of the mailing list servers with tcprules, and
-+put the recipient address in control/protectedgood instead.
-+
-+For an example of how to automate this process, see the parent directory for an
-+interactive user run script where one can remotely add, remove or list their
-+disposable alias addresses, and the mail server cron that keeps the
-+moregoodrcptto.cdb up to date.
-+The patch assumes a Dave Sill type of installation with regards to extra control
-+files concurrencyincoming and defaultdelivery, see http://lifewithqmail.org.
-+
-+Use http@ to get the patch onto your box, tab characters must be preserved.
-+Here are examples of how to patch.
-+
-+Solaris:
-+# gzip -cd qmail-1.03.tar.gz |tar -xf - ;cd qmail-1.03
-+# gpatch </path/to/goodrcptto-12.patch
-+or
-+# gzip -cd netqmail-1.05.tar.gz |tar -xf - ;cd netqmail-1.05
-+# sh -c "cat collate.sh |sed -e s/patch/gpatch/ >collate.sh"
-+# ./collate.sh ;cd netqmail-1.05
-+# gpatch </path/to/goodrcptto-12.patch
-+
-+Others:
-+# gzip -cd qmail-1.03.tar.gz |tar -xf - ;cd qmail-1.03
-+# patch </path/to/goodrcptto-12.patch
-+or
-+# gzip -cd netqmail-1.05.tar.gz |tar -xf - ;cd netqmail-1.05
-+# ./collate.sh ;cd netqmail-1.05
-+# patch </path/to/goodrcptto-12.patch
-+
-+Log example:
-+2003-06-08 12:56:28.951415500 qmail-smtpd: !ok 29791 Bad recipient user nonexistent@example.com from DealsonWheels@321sm.com by 205.235.78.101 (HELO mx4.321sm.com).
-+
-+2003-06-08 01: Original version, based on John Levine's badrcptto patch:
-+               http://www.iecc.com/bad-rcpt-noisy-patch.txt
-+2003-06-15 02: Added support for domain wildcarding.
-+2003-06-15 03: Running qmail-showctl also shows good recipient addresses.
-+2003-07-01 04: The pid for the connection is included in the log.
-+2003-07-11 05: Experimental.
-+2003-07-13 06: Experimental.
-+2003-07-20 07: Removed the message block on a mix of good and bad recipients.
-+               Allowed for only using a goodrcptto list.
-+               Corrected an error in the qmail-showctl.c patch.
-+2003-09-02 08: Added publicly known recipient address protection using an
-+               ACCEPTCLIENT tcprules variable.
-+2003-10-04 09: Running qmail-showctl also shows protected recipient addresses.
-+2003-11-07 10: Discontinued the non logging version of goodrcptto.
-+               Added dictionary attack prevention within qmail-smtpd using
-+               control/brtlimit and or BRTLIMIT.
-+               Updated the qmail-smtpd.8 man page patch regarding ACCEPTCLIENT,
-+               control/brtlimit and BRTLIMIT.
-+               Updated the qmail-control.9 man page patch regarding brtlimit,
-+               concurrencyincoming, defaultdelivery, goodrcptto, moregoodrcptto
-+               and protectedgood.
-+2004-02-14 11: Code cleanup and standardization with tcpserver logging at 
-+               getpid.
-+               This single patch works with both qmail-1.03 and netqmail-1.05.
-+               The brtcount is continued across rsets.
-+2004-03-05 12: No changes, matched version number with goodrcptto-ms-12.patch.
-+
-+Eben Pratt, goodrcptto at netdevice dot com
-+_____
-+
-+diff -ur qmail-1.03.orig/Makefile qmail-1.03/Makefile
-+--- qmail-1.03.orig/Makefile	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/Makefile	Sat Feb 14 02:41:03 2004
-+@@ -803,7 +803,7 @@
-+ 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 \
-++qmail-smtpd sendmail tcp-env qmail-newmrh qmail-newmgrt 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 \
-+@@ -930,8 +930,8 @@
-+ 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 \
-++qmail-smtpd.0 tcp-env.0 qmail-newmrh.0 qmail-newmgrt.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 \
-+@@ -1241,6 +1241,31 @@
-+ uint32.h substdio.h
-+ 	./compile qmail-newmrh.c
-+ 
-++qmail-newmgrt: \
-++load qmail-newmgrt.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-newmgrt 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-newmgrt.0: \
-++qmail-newmgrt.8
-++	nroff -man qmail-newmgrt.8 > qmail-newmgrt.0
-++
-++qmail-newmgrt.8: \
-++qmail-newmgrt.9 conf-break conf-spawn
-++	cat qmail-newmgrt.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-newmgrt.8
-++
-++qmail-newmgrt.o: \
-++compile qmail-newmgrt.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-newmgrt.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
-+@@ -1767,7 +1792,7 @@
-+ 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-lspawn.8 qmail-newmrh.9 qmail-newmgrt.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 \
-+@@ -1774,7 +1799,7 @@
-+ 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-lspawn.c qmail-newmrh.c qmail-newmgrt.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 \
-+diff -ur qmail-1.03.orig/TARGETS qmail-1.03/TARGETS
-+--- qmail-1.03.orig/TARGETS	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/TARGETS	Sat Feb 14 02:41:03 2004
-+@@ -257,6 +257,8 @@
-+ tcp-env.o
-+ remoteinfo.o
-+ tcp-env
-++qmail-newmgrt.o
-++qmail-newmgrt
-+ qmail-newmrh.o
-+ qmail-newmrh
-+ config
-+@@ -352,6 +354,8 @@
-+ qmail-qmtpd.0
-+ qmail-smtpd.0
-+ tcp-env.0
-++qmail-newmgrt.8
-++qmail-newmgrt.0
-+ qmail-newmrh.8
-+ qmail-newmrh.0
-+ qreceipt.0
-+diff -ur qmail-1.03.orig/conf-spawn qmail-1.03/conf-spawn
-+--- qmail-1.03.orig/conf-spawn	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/conf-spawn	Sat Feb 14 02:41:03 2004
-+@@ -1,4 +1,4 @@
-+-120
-++255
-+ 
-+ This is a silent concurrency limit. You can't set it above 255. On some
-+ systems you can't set it above 125. qmail will refuse to compile if the
-+diff -ur qmail-1.03.orig/hier.c qmail-1.03/hier.c
-+--- qmail-1.03.orig/hier.c	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/hier.c	Sat Feb 14 02:41:03 2004
-+@@ -109,6 +109,7 @@
-+   c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
-+   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
-+   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
-++  c(auto_qmail,"bin","qmail-newmgrt",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-pw2u",auto_uido,auto_gidq,0711);
-+@@ -221,6 +222,8 @@
-+   c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644);
-++  c(auto_qmail,"man/man8","qmail-newmgrt.8",auto_uido,auto_gidq,0644);
-++  c(auto_qmail,"man/cat8","qmail-newmgrt.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644);
-+diff -ur qmail-1.03.orig/install-big.c qmail-1.03/install-big.c
-+--- qmail-1.03.orig/install-big.c	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/install-big.c	Sat Feb 14 02:41:03 2004
-+@@ -109,6 +109,7 @@
-+   c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
-+   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
-+   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
-++  c(auto_qmail,"bin","qmail-newmgrt",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
-+   c(auto_qmail,"bin","qmail-pw2u",auto_uido,auto_gidq,0711);
-+@@ -221,6 +222,8 @@
-+   c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644);
-++  c(auto_qmail,"man/man8","qmail-newmgrt.8",auto_uido,auto_gidq,0644);
-++  c(auto_qmail,"man/cat8","qmail-newmgrt.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644);
-+   c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644);
-+diff -ur qmail-1.03.orig/qmail-control.9 qmail-1.03/qmail-control.9
-+--- qmail-1.03.orig/qmail-control.9	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/qmail-control.9	Sat Feb 14 02:41:03 2004
-+@@ -21,6 +21,7 @@
-+ Comments are allowed
-+ in
-+ .IR badmailfrom ,
-++.IR goodrcptto ,
-+ .IR locals ,
-+ .IR percenthack ,
-+ .IR qmqpservers ,
-+@@ -43,8 +44,11 @@
-+ .I badmailfrom	\fR(none)	\fRqmail-smtpd
-+ .I bouncefrom	\fRMAILER-DAEMON	\fRqmail-send
-+ .I bouncehost	\fIme	\fRqmail-send
-++.I brtlimit	\fR2	\fRqmail-smtpd
-++.I concurrencyincoming	\fR40	\fRtcpserver
-+ .I concurrencylocal	\fR10	\fRqmail-send
-+ .I concurrencyremote	\fR20	\fRqmail-send
-++.I defaultdelivery	\fR(none)	\fRqmail-start
-+ .I defaultdomain	\fIme	\fRqmail-inject
-+ .I defaulthost	\fIme	\fRqmail-inject
-+ .I databytes	\fR0	\fRqmail-smtpd
-+@@ -51,13 +55,16 @@
-+ .I doublebouncehost	\fIme	\fRqmail-send
-+ .I doublebounceto	\fRpostmaster	\fRqmail-send
-+ .I envnoathost	\fIme	\fRqmail-send
-++.I goodrcptto	\fR(none)	\fRqmail-smtpd
-+ .I helohost	\fIme	\fRqmail-remote
-+ .I idhost	\fIme	\fRqmail-inject
-+ .I localiphost	\fIme	\fRqmail-smtpd
-+ .I locals	\fIme	\fRqmail-send
-++.I moregoodrcptto	\fR(none)	\fRqmail-smtpd
-+ .I morercpthosts	\fR(none)	\fRqmail-smtpd
-+ .I percenthack	\fR(none)	\fRqmail-send
-+ .I plusdomain	\fIme	\fRqmail-inject
-++.I protectedgood	\fR(none)	\fRqmail-showctl
-+ .I qmqpservers	\fR(none)	\fRqmail-qmqpc
-+ .I queuelifetime	\fR604800	\fRqmail-send
-+ .I rcpthosts	\fR(none)	\fRqmail-smtpd
-+diff -ur qmail-1.03.orig/qmail-newmgrt.9 qmail-1.03/qmail-newmgrt.9
-+--- qmail-1.03.orig/qmail-newmgrt.9	Thu Jan  1 00:00:00 1970
-++++ qmail-1.03/qmail-newmgrt.9	Sat Feb 14 02:41:04 2004
-+@@ -0,0 +1,41 @@
-++.TH qmail-newmgrt 8
-++.SH NAME
-++qmail-newmgrt \- prepare moregoodrcptto for qmail-smtpd
-++.SH SYNOPSIS
-++.B qmail-newmgrt
-++.SH DESCRIPTION
-++.B qmail-newmgrt
-++reads the instructions in
-++.B QMAILHOME/control/moregoodrcptto
-++and writes them into
-++.B QMAILHOME/control/moregoodrcptto.cdb
-++in a binary format suited
-++for quick access by
-++.BR qmail-smtpd .
-++
-++If there is a problem with
-++.BR control/moregoodrcptto ,
-++.B qmail-newmgrt
-++complains and leaves
-++.B control/moregoodrcptto.cdb
-++alone.
-++
-++.B qmail-newmgrt
-++ensures that
-++.B control/moregoodrcptto.cdb
-++is updated atomically,
-++so
-++.B qmail-smtpd
-++never has to wait for
-++.B qmail-newmgrt
-++to finish.
-++However,
-++.B qmail-newmgrt
-++makes no attempt to protect against two simultaneous updates of
-++.BR control/moregoodrcptto.cdb .
-++
-++The binary
-++.B control/moregoodrcptto.cdb
-++format is portable across machines.
-++.SH "SEE ALSO"
-++qmail-smtpd(8)
-+diff -ur qmail-1.03.orig/qmail-newmgrt.c qmail-1.03/qmail-newmgrt.c
-+--- qmail-1.03.orig/qmail-newmgrt.c	Thu Jan  1 00:00:00 1970
-++++ qmail-1.03/qmail-newmgrt.c	Sat Feb 14 02:41:04 2004
-+@@ -0,0 +1,70 @@
-++#include "strerr.h"
-++#include "stralloc.h"
-++#include "substdio.h"
-++#include "getln.h"
-++#include "exit.h"
-++#include "readwrite.h"
-++#include "open.h"
-++#include "auto_qmail.h"
-++#include "cdbmss.h"
-++
-++#define FATAL "qmail-newmgrt: fatal: "
-++
-++void die_read()
-++{
-++  strerr_die2sys(111,FATAL,"unable to read control/moregoodrcptto: ");
-++}
-++void die_write()
-++{
-++  strerr_die2sys(111,FATAL,"unable to write to control/moregoodrcptto.tmp: ");
-++}
-++
-++char inbuf[1024];
-++substdio ssin;
-++
-++int fd;
-++int fdtemp;
-++
-++struct cdbmss cdbmss;
-++stralloc line = {0};
-++int match;
-++
-++void main()
-++{
-++  umask(033);
-++  if (chdir(auto_qmail) == -1)
-++    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");
-++
-++  fd = open_read("control/moregoodrcptto");
-++  if (fd == -1) die_read();
-++
-++  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf);
-++
-++  fdtemp = open_trunc("control/moregoodrcptto.tmp");
-++  if (fdtemp == -1) die_write();
-++
-++  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_write();
-++
-++  for (;;) {
-++    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
-++    case_lowerb(line.s,line.len);
-++    while (line.len) {
-++      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
-++      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
-++      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
-++      if (line.s[0] != '#')
-++       if (cdbmss_add(&cdbmss,line.s,line.len,"",0) == -1)
-++         die_write();
-++      break;
-++    }
-++    if (!match) break;
-++  }
-++
-++  if (cdbmss_finish(&cdbmss) == -1) die_write();
-++  if (fsync(fdtemp) == -1) die_write();
-++  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
-++  if (rename("control/moregoodrcptto.tmp","control/moregoodrcptto.cdb") == -1)
-++    strerr_die2sys(111,FATAL,"unable to move control/moregoodrcpto.tmp to control/moregoodrcptto.cdb");
-++
-++  _exit(0);
-++}
-+diff -ur qmail-1.03.orig/qmail-showctl.c qmail-1.03/qmail-showctl.c
-+--- qmail-1.03.orig/qmail-showctl.c	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/qmail-showctl.c	Sat Feb 14 02:41:04 2004
-+@@ -142,6 +142,8 @@
-+   direntry *d;
-+   struct stat stmrh;
-+   struct stat stmrhcdb;
-++  struct stat stmgrt;
-++  struct stat stmgrtcdb;
-+ 
-+   substdio_puts(subfdout,"qmail home directory: ");
-+   substdio_puts(subfdout,auto_qmail);
-+@@ -217,9 +219,12 @@
-+   do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM.");
-+   do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is ");
-+   do_str("bouncehost",1,"bouncehost","Bounce host name is ");
-++  do_int("brtlimit","2","Transmission channel close after "," bad recipients");
-++  do_int("concurrencyincoming","1","Incoming concurrency is ","");
-+   do_int("concurrencylocal","10","Local concurrency is ","");
-+   do_int("concurrencyremote","20","Remote concurrency is ","");
-+   do_int("databytes","0","SMTP DATA limit is "," bytes");
-++  do_str("defaultdelivery",1,"defaultdelivery","Default mailbox is "); 
-+   do_str("defaultdomain",1,"defaultdomain","Default domain name is ");
-+   do_str("defaulthost",1,"defaulthost","Default host name is ");
-+   do_str("doublebouncehost",1,"doublebouncehost","2B recipient host: ");
-+@@ -235,8 +240,8 @@
-+   do_lst("qmqpservers","No QMQP servers.","QMQP server: ",".");
-+   do_int("queuelifetime","604800","Message lifetime in the queue is "," seconds");
-+ 
-+-  if (do_lst("rcpthosts","SMTP clients may send messages to any recipient.","SMTP clients may send messages to recipients at ","."))
-+-    do_lst("morercpthosts","No effect.","SMTP clients may send messages to recipients at ",".");
-++  if (do_lst("rcpthosts","SMTP relay clients may send to any recipient.","SMTP relay clients may send to recipients at ","."))
-++    do_lst("morercpthosts","No effect.","SMTP relay clients may send to recipients at ",".");
-+   else
-+     do_lst("morercpthosts","No rcpthosts; morercpthosts is irrelevant.","No rcpthosts; doesn't matter that morercpthosts has ",".");
-+   /* XXX: check morercpthosts.cdb contents */
-+@@ -255,6 +260,27 @@
-+       else
-+         substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
-+ 
-++  if (do_lst("goodrcptto","Oops? moregoodrcptto must exist if this doesn't.","SMTP clients may send to ","."))
-++    do_lst("moregoodrcptto","No effect.","SMTP clients may send to ",".");
-++  else
-++    do_lst("moregoodrcptto","Oops? goodrcptto must exist if this doesn't.","SMTP clients may send to ",".");
-++  /* XXX: check moregoodrcptto.cdb contents */
-++  substdio_puts(subfdout,"\nmoregoodrcptto.cdb: ");
-++  if (stat("moregoodrcptto",&stmgrt) == -1)
-++    if (stat("moregoodrcptto.cdb",&stmgrtcdb) == -1)
-++      substdio_puts(subfdout,"(Default.) No effect.\n");
-++    else
-++      substdio_puts(subfdout,"Oops! moregoodrcptto.cdb exists but moregoodrcptto doesn't.\n");
-++  else
-++    if (stat("moregoodrcptto.cdb",&stmgrtcdb) == -1)
-++      substdio_puts(subfdout,"Oops! moregoodrcptto exists but moregoodrcptto.cdb doesn't.\n");
-++    else
-++      if (stmgrt.st_mtime > stmgrtcdb.st_mtime)
-++        substdio_puts(subfdout,"Oops! moregoodrcptto.cdb is older than moregoodrcptto.\n");
-++      else
-++        substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
-++
-++  do_lst("protectedgood","No accept client addresses.","SMTP accept clients may send to ",".");
-+   do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
-+   do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
-+   do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
-+@@ -265,19 +291,21 @@
-+   while (d = readdir(dir)) {
-+     if (str_equal(d->d_name,".")) continue;
-+     if (str_equal(d->d_name,"..")) continue;
-+-    if (str_equal(d->d_name,"bouncefrom")) continue;
-+-    if (str_equal(d->d_name,"bouncehost")) continue;
-+     if (str_equal(d->d_name,"badmailfrom")) continue;
-+     if (str_equal(d->d_name,"bouncefrom")) continue;
-+     if (str_equal(d->d_name,"bouncehost")) continue;
-++    if (str_equal(d->d_name,"brtlimit")) continue;
-++    if (str_equal(d->d_name,"concurrencyincoming")) continue;
-+     if (str_equal(d->d_name,"concurrencylocal")) continue;
-+     if (str_equal(d->d_name,"concurrencyremote")) continue;
-+     if (str_equal(d->d_name,"databytes")) continue;
-++    if (str_equal(d->d_name,"defaultdelivery")) continue;
-+     if (str_equal(d->d_name,"defaultdomain")) continue;
-+     if (str_equal(d->d_name,"defaulthost")) continue;
-+     if (str_equal(d->d_name,"doublebouncehost")) continue;
-+     if (str_equal(d->d_name,"doublebounceto")) continue;
-+     if (str_equal(d->d_name,"envnoathost")) continue;
-++    if (str_equal(d->d_name,"goodrcptto")) continue;
-+     if (str_equal(d->d_name,"helohost")) continue;
-+     if (str_equal(d->d_name,"idhost")) continue;
-+     if (str_equal(d->d_name,"localiphost")) continue;
-+@@ -285,8 +313,11 @@
-+     if (str_equal(d->d_name,"me")) continue;
-+     if (str_equal(d->d_name,"morercpthosts")) continue;
-+     if (str_equal(d->d_name,"morercpthosts.cdb")) continue;
-++    if (str_equal(d->d_name,"moregoodrcptto")) continue;
-++    if (str_equal(d->d_name,"moregoodrcptto.cdb")) continue;
-+     if (str_equal(d->d_name,"percenthack")) continue;
-+     if (str_equal(d->d_name,"plusdomain")) continue;
-++    if (str_equal(d->d_name,"protectedgood")) continue;
-+     if (str_equal(d->d_name,"qmqpservers")) continue;
-+     if (str_equal(d->d_name,"queuelifetime")) continue;
-+     if (str_equal(d->d_name,"rcpthosts")) continue;
-+diff -ur qmail-1.03.orig/qmail-smtpd.8 qmail-1.03/qmail-smtpd.8
-+--- qmail-1.03.orig/qmail-smtpd.8	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/qmail-smtpd.8	Sat Feb 14 02:41:04 2004
-+@@ -50,6 +50,20 @@
-+ meaning every address at
-+ .IR host .
-+ .TP 5
-++.I brtlimit
-++Number of bad recipients before closing the transmission channel.
-++.B qmail-smtpd
-++will close the transmission channel after 
-++reaching the number of bad recipients in
-++.IR brtlimit .
-++
-++If the environment variable
-++.B BRTLIMIT 
-++is set, it overrides
-++.IR brtlimit .
-++
-++Default and minimum: 2.
-++.TP 5
-+ .I databytes
-+ Maximum number of bytes allowed in a message,
-+ or 0 for no limit.
-+@@ -77,6 +91,50 @@
-+ is set, it overrides
-+ .IR databytes .
-+ .TP 5
-++.I goodrcptto 
-++Allowed RCPT addresses.
-++.B qmail-smtpd
-++will reject
-++any envelope recipient address not listed in
-++.I goodrcptto
-++or
-++.IR moregoodrcptto .
-++A line in
-++.I goodrcptto 
-++may be of the form
-++.BR @\fIhost ,
-++meaning every address at
-++.IR host .
-++
-++.I goodrcptto
-++format:
-++
-++.EX
-++   @heaven.af.mil
-++   box@heaven.af.mil
-++.EE 
-++
-++Exceptions:
-++If the environment variable
-++.B RELAYCLIENT
-++is set,
-++.B qmail-smtpd
-++will ignore
-++.I goodrcptto
-++and
-++.IR moregoodrcptto ,
-++and will append the value of
-++.B RELAYCLIENT
-++to each incoming recipient address.
-++If the environment variable
-++.B ACCEPTCLIENT
-++is set,
-++.B qmail-smtpd
-++will ignore
-++.I goodrcptto
-++and
-++.IR moregoodrcptto .
-++.TP 5
-+ .I localiphost
-+ Replacement host name for local IP addresses.
-+ Default:
-+@@ -97,6 +155,38 @@
-+ This is done before
-+ .IR rcpthosts .
-+ .TP 5
-++.I moregoodrcptto
-++Extra allowed RCPT addresses.
-++If
-++.I goodrcptto 
-++and
-++.I moregoodrcptto
-++both exist,
-++.I moregoodrcptto
-++is effectively appended to
-++.IR goodrcptto .
-++
-++.I moregoodrcptto
-++format:
-++
-++.EX
-++   box@heaven.af.mil
-++.EE
-++
-++You must run
-++.B qmail-newmgrt
-++whenever
-++.I moregoodrcptto
-++changes.
-++
-++Rule of thumb:
-++Put your
-++.BR @\fIhost
-++wildcarded domains into
-++.IR goodrcptto ,
-++and the rest into
-++.IR moregoodrcptto .
-++.TP 5
-+ .I morercpthosts
-+ Extra allowed RCPT domains.
-+ If
-+@@ -150,7 +240,7 @@
-+ .EE
-+ 
-+ Envelope recipient addresses without @ signs are
-+-always allowed through.
-++allowed through if added to goodrcptto or moregoodrcptto.
-+ .TP 5
-+ .I smtpgreeting
-+ SMTP greeting message.
-+@@ -174,6 +264,7 @@
-+ tcp-environ(5),
-+ qmail-control(5),
-+ qmail-inject(8),
-++qmail-newmgrt(8),
-+ qmail-newmrh(8),
-+ qmail-queue(8),
-+ qmail-remote(8)
-+diff -ur qmail-1.03.orig/qmail-smtpd.c qmail-1.03/qmail-smtpd.c
-+--- qmail-1.03.orig/qmail-smtpd.c	Mon Jun 15 06:53:16 1998
-++++ qmail-1.03/qmail-smtpd.c	Sat Feb 14 03:12:49 2004
-+@@ -23,11 +23,19 @@
-+ #include "timeoutread.h"
-+ #include "timeoutwrite.h"
-+ #include "commands.h"
-++#include "cdb.h"
-+ 
-+ #define MAXHOPS 100
-+ unsigned int databytes = 0;
-+ int timeout = 1200;
-+ 
-++char *remoteip;
-++char *remotehost;
-++char *remoteinfo;
-++char *local;
-++char *relayclient;
-++char *acceptclient;
-++
-+ int safewrite(fd,buf,len) int fd; char *buf; int len;
-+ {
-+   int r;
-+@@ -42,12 +50,39 @@
-+ void flush() { substdio_flush(&ssout); }
-+ void out(s) char *s; { substdio_puts(&ssout,s); }
-+ 
-++char sserrbuf[512];
-++substdio sserr = SUBSTDIO_FDBUF(safewrite,2,sserrbuf,sizeof sserrbuf);
-++
-++char strnum[FMT_ULONG];
-++void log(s) char *s; { substdio_putsflush(&sserr,s); }
-++void logs(s1,s2,s3) char *s1; char *s2; char *s3; {
-++  substdio_putsflush(&sserr,s1);
-++  substdio_putsflush(&sserr,s2);
-++  substdio_putsflush(&sserr,s3);
-++}
-++void pid() { log("qmail-smtpd: !ok "); strnum[fmt_ulong(strnum,getpid())] = 0; log(strnum); }
-++
-+ 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 die_alarm() {
-++  pid(); logs(" Connection to ",remoteip," timed out.\n");
-++  out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1);
-++}
-++void die_nomem() {
-++  pid(); logs(" Out of memory while connected to ",remoteip,"!\n");
-++  out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1);
-++}
-++void die_control() {
-++  pid(); log(" Unable to read controls!\n");
-++  out("421 unable to read controls (#4.3.0)\r\n"); flush(); _exit(1);
-++}
-++void die_ipme() {
-++  pid(); log(" Unable to figure out my IP addresses!\n");
-++  out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1);
-++}
-++void straynewline() {
-++  pid(); logs(" Stray newline from ",remoteip,".\n");
-++  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"); }
-+@@ -76,12 +111,6 @@
-+   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 */
-+ 
-+@@ -96,6 +125,11 @@
-+ int bmfok = 0;
-+ stralloc bmf = {0};
-+ struct constmap mapbmf;
-++int grtok = 0;
-++stralloc grt = {0};
-++struct constmap mapgrt;
-++int fdmgrt;
-++int brtlimit = 0;
-+ 
-+ void setup()
-+ {
-+@@ -117,6 +151,19 @@
-+   if (bmfok)
-+     if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
-+  
-++  grtok = control_readfile(&grt,"control/goodrcptto",0);
-++  if (grtok == -1) die_control();
-++  if (grtok)
-++    if (!constmap_init(&mapgrt,grt.s,grt.len,0)) die_nomem();
-++
-++  fdmgrt = open_read("control/moregoodrcptto.cdb");
-++  if (fdmgrt == -1) if (errno != error_noent) die_control();
-++
-++  if (control_readint(&brtlimit,"control/brtlimit") == -1) die_control();
-++  x = env_get("BRTLIMIT");
-++  if (x) { scan_ulong(x,&u); brtlimit = u; };
-++  if (brtlimit <= 1) brtlimit = 2;
-++
-+   if (control_readint(&databytes,"control/databytes") == -1) die_control();
-+   x = env_get("DATABYTES");
-+   if (x) { scan_ulong(x,&u); databytes = u; }
-+@@ -131,6 +178,7 @@
-+   if (!remotehost) remotehost = "unknown";
-+   remoteinfo = env_get("TCPREMOTEINFO");
-+   relayclient = env_get("RELAYCLIENT");
-++  acceptclient = env_get("ACCEPTCLIENT");
-+   dohelo(remotehost);
-+ }
-+ 
-+@@ -197,6 +245,16 @@
-+   return 1;
-+ }
-+ 
-++void err_brt(s1,s2,s3,s4) char *s1; char *s2; char *s3; char *s4; {
-++  pid(); log(s1); log(s2); log(s3); log(s4); log(" by ");
-++  log(remoteip); log(" (HELO "); log(helohost.s); log(").\n");
-++}
-++
-++void die_attack() {
-++  pid(); logs(" Too many bad recipients from ",remoteip,", closing connection.\n");
-++  out("421 service shutting down and closing transmission channel (#4.3.0)\r\n"); flush(); _exit(1);
-++}
-++
-+ int bmfcheck()
-+ {
-+   int j;
-+@@ -208,6 +266,24 @@
-+   return 0;
-+ }
-+ 
-++int grtcheck()
-++{
-++  int g;
-++  case_lowerb(addr.s,addr.len);
-++  if (grtok) {
-++    if (constmap(&mapgrt,addr.s,addr.len - 1)) return 1;
-++    g = byte_rchr(addr.s,addr.len,'@');
-++    if (g < addr.len)
-++      if (constmap(&mapgrt,addr.s + g,addr.len - g - 1)) return 1;  
-++  }
-++  if (fdmgrt != -1) {
-++    uint32 dlen;
-++    g = cdb_seek(fdmgrt, addr.s, addr.len - 1, &dlen);
-++    if (g) return g;
-++  }
-++  return 0;
-++}
-++
-+ int addrallowed()
-+ {
-+   int r;
-+@@ -221,6 +297,7 @@
-+ int flagbarf; /* defined if seenmail */
-+ stralloc mailfrom = {0};
-+ stralloc rcptto = {0};
-++int brtcount;
-+ 
-+ void smtp_helo(arg) char *arg;
-+ {
-+@@ -250,7 +327,10 @@
-+ void smtp_rcpt(arg) char *arg; {
-+   if (!seenmail) { err_wantmail(); return; }
-+   if (!addrparse(arg)) { err_syntax(); return; }
-+-  if (flagbarf) { err_bmf(); return; }
-++  if (flagbarf) {
-++    err_brt(" Bad envelope sender ",mailfrom.s," to ",addr.s);
-++    err_bmf(); return;
-++  }
-+   if (relayclient) {
-+     --addr.len;
-+     if (!stralloc_cats(&addr,relayclient)) die_nomem();
-+@@ -257,7 +337,23 @@
-+     if (!stralloc_0(&addr)) die_nomem();
-+   }
-+   else
-+-    if (!addrallowed()) { err_nogateway(); return; }
-++    if (!addrallowed()) {
-++      err_brt(" Bad recipient host ",addr.s," from ",mailfrom.s);
-++      if (++brtcount == brtlimit) die_attack();
-++      err_nogateway(); return;
-++    }
-++    else
-++      if (!acceptclient) {
-++        if (!grtcheck()) {
-++          if (str_equal(mailfrom.s,"")) {
-++            err_brt(" Forged recipient user ",addr.s," from ","null");
-++          }
-++          else
-++            err_brt(" Bad recipient user ",addr.s," from ",mailfrom.s);
-++          if (++brtcount == brtlimit) die_attack();
-++          out("550 sorry, no mailbox here by that name (#5.1.1)\r\n"); return;
-++        }
-++      }
-+   if (!stralloc_cats(&rcptto,"T")) die_nomem();
-+   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
-+   if (!stralloc_0(&rcptto)) die_nomem();
 diff -ruN ../netqmail-1.06-original/hier.c netqmail-1.06/hier.c
 --- ../netqmail-1.06-original/hier.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/hier.c	2018-01-04 22:33:49.406411066 +0100
-@@ -32,6 +32,7 @@
++++ netqmail-1.06/hier.c	2019-06-26 16:39:31.573826970 +0200
+@@ -4,6 +4,9 @@
+ #include "fmt.h"
+ #include "fifo.h"
+ 
++#include <stdio.h>
++#include "channels.h"
++
+ char buf[100 + FMT_ULONG];
+ 
+ void dsplit(base,uid,mode)
+@@ -29,9 +32,12 @@
+ 
+ void hier()
+ {
++  int cc;
++
    h(auto_qmail,auto_uido,auto_gidq,0755);
  
@@ -14286,5 +13869,5 @@
    d(auto_qmail,"bin",auto_uido,auto_gidq,0755);
    d(auto_qmail,"boot",auto_uido,auto_gidq,0755);
-@@ -55,6 +56,8 @@
+@@ -55,10 +61,20 @@
    d(auto_qmail,"queue/bounce",auto_uids,auto_gidq,0700);
  
@@ -14295,5 +13878,17 @@
    dsplit("queue/local",auto_uids,0700);
    dsplit("queue/remote",auto_uids,0700);
-@@ -89,6 +92,7 @@
+ 
++  for (cc = 0;cc < SUPPL_CHANNELS;++cc)
++  {
++      char adbuf[100];
++
++      sprintf(adbuf,"queue/" QDIR_BASENAME "%d", cc);
++      dsplit(adbuf,auto_uids,0700);
++  }
++
+   d(auto_qmail,"queue/lock",auto_uidq,auto_gidq,0750);
+   z(auto_qmail,"queue/lock/tcpto",1024,auto_uidr,auto_gidq,0644);
+   z(auto_qmail,"queue/lock/sendmutex",0,auto_uids,auto_gidq,0600);
+@@ -89,6 +105,7 @@
    c(auto_qmail,"doc","TEST.receive",auto_uido,auto_gidq,0644);
    c(auto_qmail,"doc","REMOVE.sendmail",auto_uido,auto_gidq,0644);
@@ -14303,5 +13898,5 @@
    c(auto_qmail,"doc","PIC.local2ext",auto_uido,auto_gidq,0644);
    c(auto_qmail,"doc","PIC.local2local",auto_uido,auto_gidq,0644);
-@@ -104,13 +108,26 @@
+@@ -104,13 +121,26 @@
    c(auto_qmail,"bin","qmail-start",auto_uido,auto_gidq,0700);
    c(auto_qmail,"bin","qmail-getpw",auto_uido,auto_gidq,0711);
@@ -14330,5 +13925,5 @@
    c(auto_qmail,"bin","qmail-inject",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","predate",auto_uido,auto_gidq,0755);
-@@ -127,6 +144,7 @@
+@@ -127,6 +157,7 @@
    c(auto_qmail,"bin","qmail-qmqpd",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","qmail-qmtpd",auto_uido,auto_gidq,0755);
@@ -14338,5 +13933,5 @@
    c(auto_qmail,"bin","tcp-env",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","qreceipt",auto_uido,auto_gidq,0755);
-@@ -143,6 +161,9 @@
+@@ -143,6 +174,9 @@
    c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755);
@@ -14348,5 +13943,5 @@
    c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644);
    c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644);
-@@ -198,6 +219,18 @@
+@@ -198,6 +232,18 @@
    c(auto_qmail,"man/cat1","tcp-env.0",auto_uido,auto_gidq,0644);
  
@@ -14369,5 +13964,5 @@
 diff -ruN ../netqmail-1.06-original/hmac_md5.c netqmail-1.06/hmac_md5.c
 --- ../netqmail-1.06-original/hmac_md5.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/hmac_md5.c	2016-11-22 21:03:57.114528032 +0100
++++ netqmail-1.06/hmac_md5.c	2019-02-27 20:57:13.391025058 +0100
 @@ -0,0 +1,76 @@
 +#include "global.h"
@@ -14449,5 +14044,5 @@
 diff -ruN ../netqmail-1.06-original/hmac_md5.h netqmail-1.06/hmac_md5.h
 --- ../netqmail-1.06-original/hmac_md5.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/hmac_md5.h	2016-11-22 21:03:57.114528032 +0100
++++ netqmail-1.06/hmac_md5.h	2019-02-27 20:57:13.391025058 +0100
 @@ -0,0 +1,11 @@
 +
@@ -14464,6 +14059,40 @@
 diff -ruN ../netqmail-1.06-original/install-big.c netqmail-1.06/install-big.c
 --- ../netqmail-1.06-original/install-big.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/install-big.c	2016-11-22 21:04:38.822137319 +0100
-@@ -89,6 +89,7 @@
++++ netqmail-1.06/install-big.c	2019-06-26 16:39:31.574826959 +0200
+@@ -4,6 +4,9 @@
+ #include "fmt.h"
+ #include "fifo.h"
+ 
++#include <stdio.h>
++#include "channels.h"
++
+ char buf[100 + FMT_ULONG];
+ 
+ void dsplit(base,uid,mode)
+@@ -29,6 +32,8 @@
+ 
+ void hier()
+ {
++  int cc;
++
+   h(auto_qmail,auto_uido,auto_gidq,0755);
+ 
+   d(auto_qmail,"control",auto_uido,auto_gidq,0755);
+@@ -59,6 +64,14 @@
+   dsplit("queue/local",auto_uids,0700);
+   dsplit("queue/remote",auto_uids,0700);
+ 
++  for (cc = 0;cc < SUPPL_CHANNELS;++cc)
++  {
++      char adbuf[100];
++
++      sprintf(adbuf,"queue/" QDIR_BASENAME "%d", cc);
++      dsplit(adbuf,auto_uids,0700);
++  }
++
+   d(auto_qmail,"queue/lock",auto_uidq,auto_gidq,0750);
+   z(auto_qmail,"queue/lock/tcpto",1024,auto_uidr,auto_gidq,0644);
+   z(auto_qmail,"queue/lock/sendmutex",0,auto_uids,auto_gidq,0600);
+@@ -89,6 +102,7 @@
    c(auto_qmail,"doc","TEST.receive",auto_uido,auto_gidq,0644);
    c(auto_qmail,"doc","REMOVE.sendmail",auto_uido,auto_gidq,0644);
@@ -14473,5 +14102,5 @@
    c(auto_qmail,"doc","PIC.local2ext",auto_uido,auto_gidq,0644);
    c(auto_qmail,"doc","PIC.local2local",auto_uido,auto_gidq,0644);
-@@ -108,9 +109,13 @@
+@@ -108,9 +122,13 @@
    c(auto_qmail,"bin","qmail-rspawn",auto_uido,auto_gidq,0711);
    c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
@@ -14487,5 +14116,5 @@
    c(auto_qmail,"bin","qmail-inject",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","predate",auto_uido,auto_gidq,0755);
-@@ -133,6 +138,7 @@
+@@ -133,6 +151,7 @@
    c(auto_qmail,"bin","qsmhook",auto_uido,auto_gidq,0755);
    c(auto_qmail,"bin","qbiff",auto_uido,auto_gidq,0755);
@@ -14497,5 +14126,5 @@
 diff -ruN ../netqmail-1.06-original/ip.h netqmail-1.06/ip.h
 --- ../netqmail-1.06-original/ip.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/ip.h	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ip.h	2019-02-27 20:57:13.392025048 +0100
 @@ -2,6 +2,7 @@
  #define IP_H
@@ -14508,5 +14137,5 @@
 diff -ruN ../netqmail-1.06-original/ipalloc.h netqmail-1.06/ipalloc.h
 --- ../netqmail-1.06-original/ipalloc.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/ipalloc.h	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ipalloc.h	2019-02-27 20:57:13.392025048 +0100
 @@ -3,7 +3,15 @@
  
@@ -14527,5 +14156,5 @@
 diff -ruN ../netqmail-1.06-original/ipme.c netqmail-1.06/ipme.c
 --- ../netqmail-1.06-original/ipme.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/ipme.c	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ipme.c	2019-02-27 20:57:13.392025048 +0100
 @@ -14,23 +14,65 @@
  #include "ipalloc.h"
@@ -14742,5 +14371,5 @@
 diff -ruN ../netqmail-1.06-original/ipme.h netqmail-1.06/ipme.h
 --- ../netqmail-1.06-original/ipme.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/ipme.h	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ipme.h	2019-02-27 20:57:13.392025048 +0100
 @@ -4,7 +4,7 @@
  #include "ip.h"
@@ -14754,5 +14383,5 @@
 diff -ruN ../netqmail-1.06-original/ipmeprint.c netqmail-1.06/ipmeprint.c
 --- ../netqmail-1.06-original/ipmeprint.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/ipmeprint.c	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ipmeprint.c	2019-02-27 20:57:13.392025048 +0100
 @@ -3,12 +3,15 @@
  #include "ip.h"
@@ -14794,5 +14423,5 @@
 diff -ruN ../netqmail-1.06-original/ipmetest.c netqmail-1.06/ipmetest.c
 --- ../netqmail-1.06-original/ipmetest.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/ipmetest.c	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/ipmetest.c	2019-02-27 20:57:13.392025048 +0100
 @@ -0,0 +1,38 @@
 +#include "subfd.h"
@@ -14836,5 +14465,5 @@
 diff -ruN ../netqmail-1.06-original/macros.h netqmail-1.06/macros.h
 --- ../netqmail-1.06-original/macros.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/macros.h	2016-11-22 21:03:57.115527999 +0100
++++ netqmail-1.06/macros.h	2019-02-27 20:57:13.392025048 +0100
 @@ -0,0 +1,25 @@
 +/*
@@ -14865,5 +14494,5 @@
 diff -ruN ../netqmail-1.06-original/maildirflags.c netqmail-1.06/maildirflags.c
 --- ../netqmail-1.06-original/maildirflags.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirflags.c	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirflags.c	2019-02-27 20:57:13.392025048 +0100
 @@ -0,0 +1,23 @@
 +/*
@@ -14892,5 +14521,5 @@
 diff -ruN ../netqmail-1.06-original/maildirgetquota.c netqmail-1.06/maildirgetquota.c
 --- ../netqmail-1.06-original/maildirgetquota.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirgetquota.c	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirgetquota.c	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,50 @@
 +/*
@@ -14946,5 +14575,5 @@
 diff -ruN ../netqmail-1.06-original/maildirgetquota.h netqmail-1.06/maildirgetquota.h
 --- ../netqmail-1.06-original/maildirgetquota.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirgetquota.h	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirgetquota.h	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,30 @@
 +#ifndef	maildirgetquota_h
@@ -14980,5 +14609,5 @@
 diff -ruN ../netqmail-1.06-original/maildirmisc.h netqmail-1.06/maildirmisc.h
 --- ../netqmail-1.06-original/maildirmisc.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirmisc.h	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirmisc.h	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,145 @@
 +#ifndef	maildirmisc_h
@@ -15129,5 +14758,5 @@
 diff -ruN ../netqmail-1.06-original/maildiropen.c netqmail-1.06/maildiropen.c
 --- ../netqmail-1.06-original/maildiropen.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildiropen.c	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildiropen.c	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,133 @@
 +/*
@@ -15266,5 +14895,5 @@
 diff -ruN ../netqmail-1.06-original/maildirparsequota.c netqmail-1.06/maildirparsequota.c
 --- ../netqmail-1.06-original/maildirparsequota.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirparsequota.c	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirparsequota.c	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,44 @@
 +/*
@@ -15314,5 +14943,5 @@
 diff -ruN ../netqmail-1.06-original/maildirquota.c netqmail-1.06/maildirquota.c
 --- ../netqmail-1.06-original/maildirquota.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirquota.c	2016-11-22 21:03:57.116527965 +0100
++++ netqmail-1.06/maildirquota.c	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,685 @@
 +/*
@@ -16003,5 +15632,5 @@
 diff -ruN ../netqmail-1.06-original/maildirquota.h netqmail-1.06/maildirquota.h
 --- ../netqmail-1.06-original/maildirquota.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/maildirquota.h	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/maildirquota.h	2019-02-27 20:57:13.393025036 +0100
 @@ -0,0 +1,45 @@
 +#ifndef	maildirquota_h
@@ -16052,5 +15681,5 @@
 diff -ruN ../netqmail-1.06-original/md5.h netqmail-1.06/md5.h
 --- ../netqmail-1.06-original/md5.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/md5.h	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/md5.h	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,49 @@
 +/* MD5.H - header file for MD5C.C
@@ -16105,5 +15734,5 @@
 diff -ruN ../netqmail-1.06-original/md5c.c netqmail-1.06/md5c.c
 --- ../netqmail-1.06-original/md5c.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/md5c.c	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/md5c.c	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,334 @@
 +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
@@ -16443,5 +16072,5 @@
 diff -ruN ../netqmail-1.06-original/mess822.h netqmail-1.06/mess822.h
 --- ../netqmail-1.06-original/mess822.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/mess822.h	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/mess822.h	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,55 @@
 +/*
@@ -16502,5 +16131,5 @@
 diff -ruN ../netqmail-1.06-original/mess822_ok.c netqmail-1.06/mess822_ok.c
 --- ../netqmail-1.06-original/mess822_ok.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/mess822_ok.c	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/mess822_ok.c	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,55 @@
 +/*
@@ -16561,5 +16190,5 @@
 diff -ruN ../netqmail-1.06-original/numlib.h netqmail-1.06/numlib.h
 --- ../netqmail-1.06-original/numlib.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/numlib.h	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/numlib.h	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,45 @@
 +#ifndef	numlib_h
@@ -16610,5 +16239,5 @@
 diff -ruN ../netqmail-1.06-original/overmaildirquota.c netqmail-1.06/overmaildirquota.c
 --- ../netqmail-1.06-original/overmaildirquota.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/overmaildirquota.c	2016-11-22 21:03:57.117527932 +0100
++++ netqmail-1.06/overmaildirquota.c	2019-02-27 20:57:13.394025025 +0100
 @@ -0,0 +1,41 @@
 +/*
@@ -16655,5 +16284,5 @@
 diff -ruN ../netqmail-1.06-original/policy.c netqmail-1.06/policy.c
 --- ../netqmail-1.06-original/policy.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/policy.c	2016-11-22 21:03:57.118527899 +0100
++++ netqmail-1.06/policy.c	2019-02-27 20:57:13.395025014 +0100
 @@ -0,0 +1,1210 @@
 +/*
@@ -17869,5 +17498,5 @@
 diff -ruN ../netqmail-1.06-original/policy.h netqmail-1.06/policy.h
 --- ../netqmail-1.06-original/policy.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/policy.h	2016-11-22 21:03:57.118527899 +0100
++++ netqmail-1.06/policy.h	2019-02-27 20:57:13.395025014 +0100
 @@ -0,0 +1,6 @@
 +#ifndef __POLICY_H_
@@ -17879,5 +17508,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-clean.c netqmail-1.06/qmail-clean.c
 --- ../netqmail-1.06-original/qmail-clean.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-clean.c	2016-11-22 21:03:57.118527899 +0100
++++ netqmail-1.06/qmail-clean.c	2019-02-27 20:57:13.395025014 +0100
 @@ -73,22 +73,26 @@
     if (line.len < 7) { respond("x"); continue; }
@@ -17914,5 +17543,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-control.9 netqmail-1.06/qmail-control.9
 --- ../netqmail-1.06-original/qmail-control.9	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-control.9	2016-11-28 17:36:57.350660496 +0100
++++ netqmail-1.06/qmail-control.9	2019-02-27 20:57:13.395025014 +0100
 @@ -20,7 +20,11 @@
  
@@ -17991,5 +17620,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-dk.9 netqmail-1.06/qmail-dk.9
 --- ../netqmail-1.06-original/qmail-dk.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-dk.9	2018-04-03 14:46:51.371411632 +0200
++++ netqmail-1.06/qmail-dk.9	2019-02-27 20:57:13.395025014 +0100
 @@ -0,0 +1,164 @@
 +.TH qmail-dk 8
@@ -18159,5 +17788,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-dk.c netqmail-1.06/qmail-dk.c
 --- ../netqmail-1.06-original/qmail-dk.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-dk.c	2018-04-03 14:46:51.372411636 +0200
++++ netqmail-1.06/qmail-dk.c	2019-02-27 20:57:13.396025003 +0100
 @@ -0,0 +1,866 @@
 +/*
@@ -19029,6 +18658,6 @@
 diff -ruN ../netqmail-1.06-original/qmail-dkim.9 netqmail-1.06/qmail-dkim.9
 --- ../netqmail-1.06-original/qmail-dkim.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-dkim.9	2018-04-03 14:46:51.372411636 +0200
-@@ -0,0 +1,321 @@
++++ netqmail-1.06/qmail-dkim.9	2020-04-09 19:45:28.421566373 +0200
+@@ -0,0 +1,322 @@
 +.TH qmail-dkim 8
 +.SH NAME
@@ -19061,5 +18690,5 @@
 +variable, it is removed and replaced by the domain name in the From: header.
 +If, after substituting the %, that file does not exist, the % character will be
-+removed. If the private key file does not exist and does not have a % character,
++removed. If a private key file does not exist and does not have a % character,
 +the message will be rejected with error 35. The selector (s=) will be taken from
 +the basename of the file. The private key should be created by 
@@ -19107,9 +18736,6 @@
 +.BR DKIMSIGNOPTIONS.
 +.B qmail-dkim
-+uses the domain found in the Sender: header to set the domain tag. If not it uses the
-+From: header. You can override this by setting 
-+.B DKIMDOMAIN
-+environment variable.
-+.B DKIMDOMAIN
++uses the domain found in the Return-Path, Sender, From headers to set the domain tag.
++If not it uses the \fBDKIMDOMAIN\fR environment variable. \fBDKIMDOMAIN\fR
 +can be set to an email address or a domain (without the at sign).
 +
@@ -19120,9 +18746,10 @@
 +letter, where A is the first return status (DKIM_SUCCESS), B is the
 +second (DKIM_FINISHED_BODY), etc.  The letter should be uppercase if you
-+want a permanent error to be returned, and lowercase if
-+you want a temporary error to be returned (exit code 88). If you omit the letter,
-+\fBqmail-dkim\fR will not issue any error inspite of DKIM verification failure. It
-+will return success and the email will get delivered. The complete set of letters
-+with the corresponding return status is given below
++want a permanent error to be returned, and lowercase if you want a temporary
++error to be returned (exit code 88). If you omit the letter, qmail-dkim will
++not issue any error inspite of DKIM verification failure. It will return
++success and the email will get delivered.
++
++The complete set of letters with the corresponding return status is given below
 +
 + A - DKIM_SUCCESS                        - Function executed successfully
@@ -19191,5 +18818,7 @@
 +.B DKIMVERIFY
 +to an empty string. If you want to check all message's From header in signature set the
-+\fBUNSIGNED_FROM\fR environment variable to an empty string.
++\fBUNSIGNED_FROM\fR environment variable to an empty string. If you want to check messages
++without signed subject header, set \fBUNSIGNED_SUBJECT\fR environment variable. If you want
++to honor body lengh tag (l=), set \fBHONOR_BODYLENGTHTAG\fR environment variable.
 +
 +qmail-dkim supports signing practice which can be additonall checked when a signature
@@ -19211,5 +18840,5 @@
 +set the environment variable 
 +.BR DKIMPRACTICE="ST" .
-+If you want automatic behaviour, set DKIMADSPERROR to an empty string. In this case ADSP/SSP will be used when return code
++If you want automatic behaviour, set DKIMPRACTICE to an empty string. In this case ADSP/SSP will be used when return code
 +matches "FGHIJKLMNPQRSTUVWX".
 +.B qmail-dkim
@@ -19266,5 +18895,5 @@
 +containing a list of domains which you know are sure not to sign messages using DKIM.
 +If a message comes from a domain listed in
-+.IR signaturedomains ,
++.IR nosignaturedomains ,
 +and does not have a DKIM-Signature header, 
 +.B qmail-dkim
@@ -19278,6 +18907,6 @@
 +Typically, you would sign messages generated on-host by setting
 +.B DKIMSIGN
-+in the environment before running an email program.  DKIMSIGN will be carried
-+through qmail's sendmail emulation through 
++in the environment before running an \fBqmail-smtpd\fR(8) or \fBsendmail(1)\fR / \fBqmail-inject\fR(8).  DKIMSIGN will be carried
++through qmail-smtpd or through qmail's sendmail emulation through 
 +.B qmail-inject
 +to
@@ -19336,4 +18965,5 @@
 +qmail-header(5),
 +dknewkey(8),
++dkim(8),
 +dktest(8),
 +qmail-inject(8),
@@ -19354,8 +18984,26 @@
 diff -ruN ../netqmail-1.06-original/qmail-dkim.c netqmail-1.06/qmail-dkim.c
 --- ../netqmail-1.06-original/qmail-dkim.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-dkim.c	2018-04-03 14:46:51.373411639 +0200
-@@ -0,0 +1,1388 @@
++++ netqmail-1.06/qmail-dkim.c	2019-06-19 09:48:44.632641078 +0200
+@@ -0,0 +1,1417 @@
 +/*
 + * $Log: qmail-dkim.c,v $
++ * Revision 1.53  2019-06-14 21:26:37+05:30  Cprogrammer
++ * added env variable HONOR_BODYLENGTHTAG to honor body length tag during verification
++ *
++ * Revision 1.52  2019-02-18 22:18:12+05:30  Cprogrammer
++ * allow DKIMVERIFY env variable in place of DKIMPRACTICE when SIGN_PRACTICE="local"
++ *
++ * Revision 1.51  2019-02-17 11:38:51+05:30  Cprogrammer
++ * set original DKIM error for SIGN_PRACTICE=local
++ *
++ * Revision 1.50  2019-02-15 21:25:04+05:30  Cprogrammer
++ * skip nosignaturedomains if domain is present in signaturedomains
++ *
++ * Revision 1.49  2018-08-08 23:58:01+05:30  Cprogrammer
++ * issue success if at lease one one good signature is found
++ *
++ * Revision 1.48  2017-09-05 12:37:16+05:30  Cprogrammer
++ * added missing DKIM_MFREE()
++ *
 + * Revision 1.47  2016-06-03 09:57:59+05:30  Cprogrammer
 + * moved qmail-multi to sbin
@@ -19819,5 +19467,5 @@
 +
 +#include <openssl/evp.h>
-+#define DKIM_MALLOC(s)     OPENSSL_malloc(s)
++#define DKIM_MALLOC(n)     OPENSSL_malloc(n)
 +#define DKIM_MFREE(s)      OPENSSL_free(s); s = NULL;
 +char           *dns_text(char *);
@@ -19958,12 +19606,13 @@
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_SCOPE;
-+	}
-+	else
++	} else
 +	if (!str_diff(results, "e=temp;")) {
 +		DKIM_MFREE(results);
 +		return DKIM_ADSP_TEMPFAIL;
 +	}
-+	if (!(query = DKIM_MALLOC(str_len("_adsp._domainkey.") + str_len(domain) + 1)))
++	if (!(query = DKIM_MALLOC(str_len("_adsp._domainkey.") + str_len(domain) + 1))) {
++		DKIM_MFREE(results);
 +		die(51, 0);
++	}
 +	sprintf(query, "_adsp._domainkey.%s", domain);
 +	results = dns_text(query);
@@ -20290,13 +19939,17 @@
 +
 +int
-+checkPractice(int dkimRet)
++checkPractice(int dkimRet, int useADSP, int useSSP)
 +{
 +	char           *ptr;
 +
-+	if (!(ptr = env_get("DKIMPRACTICE")))
-+		return (0);
-+	else
++	if (!(ptr = env_get("DKIMPRACTICE"))) {
++		/*- if SIGN_PRACTICE="local" then you can use DKIMVERIFY env variable too */
++		if (!useADSP && !useSSP) 
++			dkimpractice = dkimverify; /*- DKIMVERIFY env variable */
++		else
++			return (0);
++	} else
 +		dkimpractice = ptr;
-+	if (!*ptr) {
++	if (!*dkimpractice) {
 +		if (dkimRet < 0 || dkimRet == DKIM_3PS_SIGNATURE)
 +			return (1);
@@ -20525,6 +20178,5 @@
 +			useADSP = 1;
 +			accept3ps = 1;
-+		}
-+		else
++		} else
 +		if (!str_diffn("ssp", x, 3)) {
 +			useSSP = 1;
@@ -20548,4 +20200,5 @@
 +			vopts.nAllowUnsignedFromHeaders = 1;
 +		vopts.nSubjectRequired = env_get("UNSIGNED_SUBJECT") ? 0 : 1;
++		vopts.nHonorBodyLengthTag = env_get("HONOR_BODYLENGTHTAG") ? 0 : 1;
 +		DKIMVerifyInit(&ctxt, &vopts);		/*- this is always successful */
 +	}
@@ -20611,8 +20264,10 @@
 +					maybe_die_dkim(ret);
 +				else
-+				for (ret = DKIM_SUCCESS,i = 0; i < nSigCount; i++) {
-+					if (pDetails[i].nResult < 0) {
-+						ret = pDetails[i].nResult;
-+						break; /*- don't know if it is right to break */
++				for (ret = DKIM_FAIL,i = 0; i < nSigCount; i++) {
++					if (pDetails[i].nResult >= 0) {
++						ret = 0;
++					} else {
++						if (ret == DKIM_FAIL)
++							ret = pDetails[i].nResult;
 +					}
 +				}
@@ -20621,6 +20276,7 @@
 +			}
 +			/*- what to do if DKIM Verification fails */
-+			if (checkPractice(ret)) {
++			if (checkPractice(ret, useADSP, useSSP)) {
 +				char           *domain;
++				int             skip_nosignature_domain = 0;
 +
 +				origRet = ret;
@@ -20635,5 +20291,6 @@
 +						len += ((token_len = str_len(p)) + 1); /*- next domain */
 +						if (!case_diffb(p, token_len, domain)) {
-+							ret = DKIM_FAIL;
++							ret = origRet;
++							skip_nosignature_domain = 1;
 +							useADSP = 0;
 +							useSSP = 0;
@@ -20642,19 +20299,21 @@
 +						p = sigdomains.s + len;
 +					}
-+					if (!(p = env_get("NOSIGNATUREDOMAINS"))) {
-+						if (control_readfile(&nsigdomains, "nosignaturedomains", 0) == -1)
-+							die(55, 2);
-+					} else
-+					if (!stralloc_copys(&nsigdomains, p))
-+						die(51, 2);
-+					for (len = 0, p = nsigdomains.s;len < nsigdomains.len;) {
-+						len += ((token_len = str_len(p)) + 1); /*- next domain */
-+						if (*p == '*' || !case_diffb(p, token_len, domain)) {
-+							ret = DKIM_NEUTRAL;
-+							useADSP = 0;
-+							useSSP = 0;
-+							break;
++					if (!skip_nosignature_domain) {
++						if (!(p = env_get("NOSIGNATUREDOMAINS"))) {
++							if (control_readfile(&nsigdomains, "nosignaturedomains", 0) == -1)
++								die(55, 2);
++						} else
++						if (!stralloc_copys(&nsigdomains, p))
++							die(51, 2);
++						for (len = 0, p = nsigdomains.s;len < nsigdomains.len;) {
++							len += ((token_len = str_len(p)) + 1); /*- next domain */
++							if (*p == '*' || !case_diffb(p, token_len, domain)) {
++								ret = DKIM_NEUTRAL;
++								useADSP = 0;
++								useSSP = 0;
++								break;
++							}
++							p = nsigdomains.s + len;
 +						}
-+						p = nsigdomains.s + len;
 +					}
 +				}
@@ -20677,5 +20336,5 @@
 +					int             bTestingPractices = 0;
 +					char           *domain;
-+	
++
 +					if ((domain = DKIMVerifyGetDomain(&ctxt)))
 +						resDKIMSSP = checkSSP(domain, &bTestingPractices);
@@ -20740,5 +20399,5 @@
 +getversion_qmail_dkim_c()
 +{
-+	static char    *x = "$Id: qmail-dkim.c,v 1.37 2013-01-24 22:37:22+05:30 Cprogrammer Exp mbhangui $";
++	static char    *x = "$Id: qmail-dkim.c,v 1.49 2018-08-08 23:58:01+05:30 Cprogrammer Exp mbhangui $";
 +
 +	x++;
@@ -20746,5 +20405,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-inject.c netqmail-1.06/qmail-inject.c
 --- ../netqmail-1.06-original/qmail-inject.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-inject.c	2016-11-22 21:03:57.120527832 +0100
++++ netqmail-1.06/qmail-inject.c	2019-02-27 20:57:13.397024992 +0100
 @@ -22,6 +22,7 @@
  #include "auto_qmail.h"
@@ -20798,5 +20457,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-local.c netqmail-1.06/qmail-local.c
 --- ../netqmail-1.06-original/qmail-local.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/qmail-local.c	2018-01-01 12:10:21.981102868 +0100
++++ netqmail-1.06/qmail-local.c	2019-02-27 20:57:13.398024981 +0100
 @@ -28,6 +28,7 @@
  #include "myctime.h"
@@ -20877,5 +20536,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-lspawn.c netqmail-1.06/qmail-lspawn.c
 --- ../netqmail-1.06-original/qmail-lspawn.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-lspawn.c	2016-11-22 21:03:57.120527832 +0100
++++ netqmail-1.06/qmail-lspawn.c	2019-02-27 20:57:13.398024981 +0100
 @@ -1,4 +1,5 @@
  #include "fd.h"
@@ -20906,5 +20565,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-newmvrt.c netqmail-1.06/qmail-newmvrt.c
 --- ../netqmail-1.06-original/qmail-newmvrt.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-newmvrt.c	2016-11-22 21:04:20.041763530 +0100
++++ netqmail-1.06/qmail-newmvrt.c	2019-02-27 20:57:13.398024981 +0100
 @@ -0,0 +1,70 @@
 +#include "strerr.h"
@@ -20980,5 +20639,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-pop3d.c netqmail-1.06/qmail-pop3d.c
 --- ../netqmail-1.06-original/qmail-pop3d.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/qmail-pop3d.c	2016-11-22 21:03:57.121527799 +0100
++++ netqmail-1.06/qmail-pop3d.c	2019-02-27 20:57:13.398024981 +0100
 @@ -16,6 +16,11 @@
  #include "readwrite.h"
@@ -21140,5 +20799,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-pw2u.c netqmail-1.06/qmail-pw2u.c
 --- ../netqmail-1.06-original/qmail-pw2u.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-pw2u.c	2016-11-22 21:03:57.121527799 +0100
++++ netqmail-1.06/qmail-pw2u.c	2019-02-27 20:57:13.398024981 +0100
 @@ -1,3 +1,4 @@
 +#include <unistd.h>
@@ -21148,5 +20807,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-qmqpc.c netqmail-1.06/qmail-qmqpc.c
 --- ../netqmail-1.06-original/qmail-qmqpc.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-qmqpc.c	2016-11-22 21:03:57.121527799 +0100
++++ netqmail-1.06/qmail-qmqpc.c	2019-02-27 20:57:13.398024981 +0100
 @@ -102,6 +102,8 @@
  char *server;
@@ -21169,5 +20828,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-qmtpd.c netqmail-1.06/qmail-qmtpd.c
 --- ../netqmail-1.06-original/qmail-qmtpd.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-qmtpd.c	2016-11-22 21:03:57.121527799 +0100
++++ netqmail-1.06/qmail-qmtpd.c	2019-02-27 20:57:13.399024970 +0100
 @@ -1,3 +1,5 @@
 +#include <unistd.h>
@@ -21178,5 +20837,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-qstat.sh netqmail-1.06/qmail-qstat.sh
 --- ../netqmail-1.06-original/qmail-qstat.sh	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-qstat.sh	2016-11-22 21:03:57.121527799 +0100
++++ netqmail-1.06/qmail-qstat.sh	2019-02-27 20:57:13.399024970 +0100
 @@ -1,7 +1,7 @@
  cd QMAIL
@@ -21191,5 +20850,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-queue.8 netqmail-1.06/qmail-queue.8
 --- ../netqmail-1.06-original/qmail-queue.8	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/qmail-queue.8	2016-12-05 19:24:19.597680897 +0100
++++ netqmail-1.06/qmail-queue.8	2019-02-27 20:57:13.399024970 +0100
 @@ -46,6 +46,13 @@
  will invoke the contents of
@@ -21208,5 +20867,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-queue.c netqmail-1.06/qmail-queue.c
 --- ../netqmail-1.06-original/qmail-queue.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-queue.c	2016-12-05 19:24:19.597680897 +0100
++++ netqmail-1.06/qmail-queue.c	2019-02-27 20:57:13.399024970 +0100
 @@ -16,6 +16,8 @@
  #include "auto_uids.h"
@@ -21360,5 +21019,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-remote.8 netqmail-1.06/qmail-remote.8
 --- ../netqmail-1.06-original/qmail-remote.8	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-remote.8	2016-11-22 21:03:57.122527765 +0100
++++ netqmail-1.06/qmail-remote.8	2019-02-27 20:57:13.399024970 +0100
 @@ -100,6 +100,73 @@
  After this letter comes a human-readable description of
@@ -21643,5 +21302,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-remote.c netqmail-1.06/qmail-remote.c
 --- ../netqmail-1.06-original/qmail-remote.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-remote.c	2017-08-28 17:51:47.068287985 +0200
++++ netqmail-1.06/qmail-remote.c	2020-04-16 11:23:31.333050380 +0200
 @@ -28,6 +28,7 @@
  #include "timeoutconn.h"
@@ -21716,5 +21375,5 @@
    if (flagcritical) out("Possible duplicate! ");
 +#ifdef TLS
-+  if (ssl_err_str) { out(ssl_err_str); out(" "); }
++  if (ssl_err_str) { out((char *)ssl_err_str); out(" "); }
 +#endif
    out("(#4.4.2)\n");
@@ -21813,5 +21472,5 @@
  {
    int i; 
-@@ -179,6 +284,11 @@
+@@ -179,6 +284,16 @@
  char *prepend;
  char *append;
@@ -21819,11 +21478,16 @@
 +#ifdef TLS
 +  /* shouldn't talk to the client unless in an appropriate state */
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++  OSSL_HANDSHAKE_STATE state = ssl ? SSL_get_state(ssl) : TLS_ST_BEFORE;
++  if (state & TLS_ST_OK || (!smtps && state & TLS_ST_BEFORE))
++#else
 +  int state = ssl ? ssl->state : SSL_ST_BEFORE;
 +  if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE))
++#endif
 +#endif
    substdio_putsflush(&smtpto,"QUIT\r\n");
    /* waiting for remote side is just too ridiculous */
    out(prepend);
-@@ -186,6 +296,30 @@
+@@ -186,6 +301,30 @@
    out(append);
    out(".\n");
@@ -21856,5 +21520,5 @@
  }
  
-@@ -201,6 +335,16 @@
+@@ -201,6 +340,16 @@
      if (ch == '.')
        substdio_put(&smtpto,".",1);
@@ -21873,5 +21537,5 @@
        r = substdio_get(&ssin,&ch,1);
        if (r == 0) perm_partialline();
-@@ -214,30 +358,432 @@
+@@ -214,30 +363,436 @@
    substdio_flush(&smtpto);
  }
@@ -21885,5 +21549,5 @@
 +void tls_quit(const char *s1, const char *s2)
 +{
-+  out(s1); if (s2) { out(": "); out(s2); } TLS_QUIT;
++  out((char *)s1); if (s2) { out(": "); out((char *)s2); } TLS_QUIT;
 +}
 +# define tls_quit_error(s) tls_quit(s, ssl_error())
@@ -21949,5 +21613,5 @@
 +    if (!len) {
 +      if (!servercert) return 0;
-+      out("ZNo TLS achieved while "); out(servercert);
++      out("ZNo TLS achieved while "); out((char *)servercert);
 +      out(" exists"); smtptext.len = 0; TLS_QUIT;
 +    }
@@ -21980,4 +21644,8 @@
 +    SSL_CTX_use_RSAPrivateKey_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM);
 +# undef CLIENTCERT
++
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L
++  SSL_CTX_set_post_handshake_auth(ctx, 1);
++#endif
 +
 +  myssl = SSL_new(ctx);
@@ -22011,5 +21679,5 @@
 +      if (!servercert) return 0;
 +      out("ZSTARTTLS rejected while ");
-+      out(servercert); out(" exists"); TLS_QUIT;
++      out((char *)servercert); out(" exists"); TLS_QUIT;
 +    }
 +    smtptext.len = 0;
@@ -22063,5 +21731,5 @@
 +      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;
++        const ASN1_STRING *s = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
 +        if (s) { peer.len = s->length; peer.s = s->data; }
 +      }
@@ -22319,5 +21987,32 @@
    for (i = 0;i < reciplist.len;++i) {
      substdio_puts(&smtpto,"RCPT TO:<");
-@@ -297,19 +843,14 @@
+@@ -246,15 +801,23 @@
+     substdio_flush(&smtpto);
+     code = smtpcode();
+     if (code >= 500) {
+-      out("h"); outhost(); out(" does not like recipient.\n");
++      /* added by Endersys R&D Team */
++      out("h<From:"); outsafe(&sender); out(" To:"); outsafe(&reciplist.sa[i]); out("> ");  outhost(); out(" does not like recipient.\n");
+       outsmtptext(); zero();
+     }
+     else if (code >= 400) {
+-      out("s"); outhost(); out(" does not like recipient.\n");
++      /* added by Endersys R&D Team */
++      out("s<From:"); outsafe(&sender); out(" To:"); outsafe(&reciplist.sa[i]);  out("> ");  outhost(); out(" does not like recipient.\n");
+       outsmtptext(); zero();
+     }
+     else {
+-      out("r"); zero();
++       /*
++       * James Raftery <james@now.ie>
++       * Log _real_ envelope recipient, post canonicalisation.
++       * and modified by Endersys R&D Team
++       */
++
++      out("r<From:"); outsafe(&sender); out(" To:"); outsafe(&reciplist.sa[i]); out("> "); zero();
+       flagbother = 1;
+     }
+   }
+@@ -297,19 +860,14 @@
    if (!stralloc_cats(saout,"@")) temp_nomem();
   
@@ -22341,5 +22036,5 @@
    if (control_readint(&timeout,"control/timeoutremote") == -1) temp_control();
    if (control_readint(&timeoutconnect,"control/timeoutconnect") == -1)
-@@ -324,48 +865,108 @@
+@@ -324,48 +882,108 @@
      case 1:
        if (!constmap_init(&maproutes,routes.s,routes.len,1)) temp_nomem(); break;
@@ -22469,5 +22164,5 @@
    if (ipme_init() != 1) temp_oserr();
   
-@@ -414,10 +1015,13 @@
+@@ -414,10 +1032,13 @@
      smtpfd = socket(AF_INET,SOCK_STREAM,0);
      if (smtpfd == -1) temp_oserr();
@@ -22487,5 +22182,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-rspawn.c netqmail-1.06/qmail-rspawn.c
 --- ../netqmail-1.06-original/qmail-rspawn.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-rspawn.c	2016-11-22 21:03:57.123527732 +0100
++++ netqmail-1.06/qmail-rspawn.c	2019-02-27 20:57:13.400024959 +0100
 @@ -1,3 +1,4 @@
 +#include "env.h"
@@ -22516,6 +22211,22 @@
 diff -ruN ../netqmail-1.06-original/qmail-send.9 netqmail-1.06/qmail-send.9
 --- ../netqmail-1.06-original/qmail-send.9	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-send.9	2016-11-22 21:03:57.123527732 +0100
-@@ -51,7 +51,9 @@
++++ netqmail-1.06/qmail-send.9	2019-06-26 16:45:05.514152928 +0200
+@@ -16,6 +16,15 @@
+ .B qmail-send
+ leaves it in the queue and tries the addresses again later.
+ 
++.B Supplemental queues
++allow more than one queue for remote recipients. (CHANNELS - 2) supplemental queues total, because one queue is always
++designated for local deliveries and a second queue is always available for remote deliveries that
++don't match any of the domains listed in the supplemental queue control files.
++This makes it possible to divide remote deliveries into distinct queues at different concurrency
++levels and can be used as a throttling mechanism based on domain.
++Supplemental queues are managed by the supplsX and concurrencysupplX control files, where X is an integer from
++0 to (CHANNELS - 3).
++
+ .B qmail-send
+ prints a readable record of its activities to descriptor 0.
+ It writes commands to
+@@ -51,7 +60,13 @@
  .B qmail-send
  receives a HUP signal,
@@ -22524,9 +22235,29 @@
 +.IR concurrencylocal ,
 +.IR concurrencyremote ,
-+.IR locals
++.IR locals,
++.IR supplsX,
++.IR concurrencylocal,
++.IR concurrencyremote,
++.IR concurrencysupplX
  and
  .IR virtualdomains .
  .TP 5
-@@ -115,6 +117,10 @@
+@@ -93,6 +108,15 @@
+ is limited at compile time to
+ SPAWN.
+ .TP 5
++.I concurrencysupplX
++Maximum number of simultaneous delivery attempts via supplemental
++channel X, where X is an integer starting at 0.
++Default: 20.
++If 0, deliveries via channel X will be put on hold.
++.I concurrencysupplX
++is limited at compile time to
++SPAWN.
++.TP 5
+ .I doublebouncehost
+ Double-bounce host.
+ Default:
+@@ -115,6 +139,10 @@
  (If that bounces,
  .B qmail-send
@@ -22539,16 +22270,44 @@
  .I envnoathost
  Presumed domain name for addresses without @ signs.
+@@ -147,6 +175,12 @@
+ is listed in
+ .IR locals .
+ .TP 5
++.I supplsX
++List of domain names that the current host
++will deliver on supplemental channel X where X is an integer starting at 0,
++one per line.
++No default.
++.TP 5
+ .I percenthack
+ List of domain names where the percent hack is applied.
+ If
+@@ -164,7 +198,9 @@
+ handles
+ .I percenthack
+ before
+-.IR locals .
++.I locals
++and
++.IR supplsX.
+ .TP 5
+ .I queuelifetime
+ Number of seconds
 diff -ruN ../netqmail-1.06-original/qmail-send.c netqmail-1.06/qmail-send.c
 --- ../netqmail-1.06-original/qmail-send.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-send.c	2016-11-22 21:03:57.124527699 +0100
-@@ -31,6 +31,7 @@
++++ netqmail-1.06/qmail-send.c	2019-06-26 16:42:40.004753618 +0200
+@@ -31,6 +31,11 @@
  #include "constmap.h"
  #include "fmtqfn.h"
  #include "readsubdir.h"
 +#include "srs.h"
++
++#include "auto_spawn.h"
++
++#include "channels.h"
  
  /* critical timing feature #1: if not triggered, do not busy-loop */
  /* critical timing feature #2: if triggered, respond within fixed time */
-@@ -44,6 +45,8 @@
+@@ -44,6 +49,8 @@
  
  int lifetime = 604800;
@@ -22559,5 +22318,5 @@
  struct constmap mappercenthack;
  stralloc locals = {0};
-@@ -55,6 +58,7 @@
+@@ -55,17 +62,20 @@
  stralloc bouncehost = {0};
  stralloc doublebounceto = {0};
@@ -22567,5 +22326,25 @@
  char strnum2[FMT_ULONG];
  char strnum3[FMT_ULONG];
-@@ -82,9 +86,6 @@
+ 
+-#define CHANNELS 2
+-char *chanaddr[CHANNELS] = { "local/", "remote/" };
+-char *chanstatusmsg[CHANNELS] = { " local ", " remote " };
+-char *tochan[CHANNELS] = { " to local ", " to remote " };
+-int chanfdout[CHANNELS] = { 1, 3 };
+-int chanfdin[CHANNELS] = { 2, 4 };
+-int chanskip[CHANNELS] = { 10, 20 };
++char *chanaddr[CHANNELS];
++char *chanstatusmsg[CHANNELS];
++char *tochan[CHANNELS];
++int chanfdout[CHANNELS];
++int chanfdin[CHANNELS];
++int chanskip[CHANNELS];
++struct constmap mapsuppl[SUPPL_CHANNELS];
++stralloc suppls[SUPPL_CHANNELS];
++stralloc newsuppls[SUPPL_CHANNELS];
+ 
+ int flagexitasap = 0; void sigterm() { flagexitasap = 1; }
+ int flagrunasap = 0; void sigalrm() { flagrunasap = 1; }
+@@ -82,12 +92,10 @@
  
  datetime_sec recent;
@@ -22577,5 +22356,9 @@
  stralloc fn2 = {0};
  char fnmake_strnum[FMT_ULONG];
-@@ -96,7 +97,7 @@
++stralloc fname = {0};
+ 
+ void fnmake_init()
+ {
+@@ -96,7 +104,7 @@
  }
  
@@ -22586,5 +22369,37 @@
  void fnmake_foop(id) unsigned long id; { fn.len = fmtqfn(fn.s,"foop/",id,0); }
  void fnmake_split(id) unsigned long id; { fn.len = fmtqfn(fn.s,"",id,1); }
-@@ -262,6 +263,8 @@
+@@ -117,6 +125,7 @@
+ {
+   int i;
+   int j;
++  int c;
+   char *x;
+   static stralloc addr = {0};
+   int at;
+@@ -159,6 +168,13 @@
+  
+   if (!stralloc_cat(&rwline,&addr)) return 0;
+   if (!stralloc_0(&rwline)) return 0;
++
++  for (c = 0;c < SUPPL_CHANNELS;++c)
++  {
++      if (constmap(&mapsuppl[c],addr.s + at + 1,addr.len - at - 1))
++          return c + 3;
++  }
++
+   return 2;
+ }
+ 
+@@ -228,7 +244,8 @@
+ 
+ substdio sstoqc; char sstoqcbuf[1024];
+ substdio ssfromqc; char ssfromqcbuf[1024];
+-stralloc comm_buf[CHANNELS] = { {0}, {0} };
++
++stralloc comm_buf[CHANNELS];
+ int comm_pos[CHANNELS];
+ 
+ void comm_init()
+@@ -262,6 +279,8 @@
   while (!stralloc_copys(&comm_buf[c],"")) nomem();
   ch = delnum;
@@ -22595,5 +22410,14 @@
   while (!stralloc_cats(&comm_buf[c],fn.s)) nomem();
   while (!stralloc_0(&comm_buf[c])) nomem();
-@@ -683,15 +686,39 @@
+@@ -382,7 +401,7 @@
+ /* this file is too long ----------------------------------- PRIORITY QUEUES */
+ 
+ prioq pqdone = {0}; /* -todo +info; HOPEFULLY -local -remote */
+-prioq pqchan[CHANNELS] = { {0}, {0} };
++prioq pqchan[CHANNELS];
+ /* pqchan 0: -todo +info +local ?remote */
+ /* pqchan 1: -todo +info ?local +remote */
+ prioq pqfail = {0}; /* stat() failure; has to be pqadded again */
+@@ -683,15 +702,39 @@
    }
   if (str_equal(sender.s,"#@[]"))
@@ -22638,5 +22462,5 @@
     qmail_put(&qqt,newfield_date.s,newfield_date.len);
     qmail_puts(&qqt,"From: ");
-@@ -740,9 +767,17 @@
+@@ -740,9 +783,17 @@
       qmail_fail(&qqt);
     else
@@ -22657,5 +22481,28 @@
       if (r == -1)
         qmail_fail(&qqt);
-@@ -906,41 +941,42 @@
+@@ -780,8 +831,8 @@
+ ;
+ 
+ unsigned long masterdelid = 1;
+-unsigned int concurrency[CHANNELS] = { 10, 20 };
+-unsigned int concurrencyused[CHANNELS] = { 0, 0 };
++unsigned int concurrency[CHANNELS];
++unsigned int concurrencyused[CHANNELS];
+ struct del *d[CHANNELS];
+ stralloc dline[CHANNELS];
+ char delbuf[2048];
+@@ -808,9 +859,9 @@
+  for (c = 0;c < CHANNELS;++c)
+   {
+    flagspawnalive[c] = 1;
+-   while (!(d[c] = (struct del *) alloc(concurrency[c] * sizeof(struct del))))
++   while (!(d[c] = (struct del *) alloc(auto_spawn * sizeof(struct del))))
+      nomem();
+-   for (i = 0;i < concurrency[c];++i)
++   for (i = 0;i < auto_spawn;++i)
+     { d[c][i].used = 0; d[c][i].recip.s = 0; }
+    dline[c].s = 0;
+    while (!stralloc_copys(&dline[c],"")) nomem();
+@@ -906,41 +957,42 @@
       dline[c].len = REPORTMAX;
       /* qmail-lspawn and qmail-rspawn are responsible for keeping it short */
@@ -22665,6 +22512,7 @@
      {
       delnum = (unsigned int) (unsigned char) dline[c].s[0];
+-     if ((delnum < 0) || (delnum >= concurrency[c]) || !d[c][delnum].used)
 +     delnum += (unsigned int) ((unsigned int) dline[c].s[1]) << 8;
-      if ((delnum < 0) || (delnum >= concurrency[c]) || !d[c][delnum].used)
++     if ((delnum < 0) || (delnum >= auto_spawn) || !d[c][delnum].used)
         log1("warning: internal error: delivery report out of range\n");
       else
@@ -22708,5 +22556,5 @@
  	   --jo[d[c][delnum].j].numtodo;
  	   break;
-@@ -1215,8 +1251,10 @@
+@@ -1215,8 +1267,10 @@
  
  /* this file is too long ---------------------------------------------- TODO */
@@ -22720,5 +22568,5 @@
  char todobuf[SUBSTDIO_INSIZE];
  char todobufinfo[512];
-@@ -1224,7 +1262,7 @@
+@@ -1224,7 +1278,7 @@
  
  void todo_init()
@@ -22729,5 +22577,5 @@
   trigger_set();
  }
-@@ -1236,7 +1274,7 @@
+@@ -1236,7 +1290,7 @@
  {
   if (flagexitasap) return;
@@ -22738,5 +22586,5 @@
  }
  
-@@ -1253,8 +1291,7 @@
+@@ -1253,8 +1307,7 @@
   char ch;
   int match;
@@ -22748,5 +22596,5 @@
   unsigned long uid;
   unsigned long pid;
-@@ -1265,32 +1302,26 @@
+@@ -1265,32 +1318,26 @@
  
   if (flagexitasap) return;
@@ -22790,5 +22638,21 @@
   fnmake_todo(id);
  
-@@ -1438,10 +1469,148 @@
+@@ -1363,12 +1410,9 @@
+        log1("\n");
+        break;
+      case 'T':
+-       switch(rewrite(todoline.s + 1))
+-	{
+-	 case 0: nomem(); goto fail;
+-	 case 2: c = 1; break;
+-	 default: c = 0; break;
+-        }
++       c = rewrite(todoline.s + 1);
++       if (c == 0) { nomem(); goto fail; }
++       c--;
+        if (fdchan[c] == -1)
+ 	{
+ 	 fnmake_chanaddr(id,c);
+@@ -1438,17 +1482,175 @@
     if (fdchan[c] != -1) close(fdchan[c]);
  }
@@ -22845,20 +22709,24 @@
 +
 + for (c = 0;c < CHANNELS;++c) flagchan[c] = 0;
-+ switch(*s++) {
-+  case 'L':
-+    flagchan[0] = 1;
-+    break;
-+  case 'R':
-+    flagchan[1] = 1;
-+    break;
-+  case 'B':
-+    flagchan[0] = 1;
-+    flagchan[1] = 1;
-+    break;
-+  case 'X':
-+    break;
-+  default:
-+    log1("warning: qmail-send unable to understand qmail-todo\n");
-+    return;
++
++ for (c = 0;c < CHANNELS;++c)
++ {
++  if (!*s)
++  {
++     log1("warning: qmail-send unable to understand qmail-todo\n");
++     return;
++  }
++
++  switch(*s++) {
++   case '0':
++     flagchan[c] = 0;
++     break;
++   case '1':
++     flagchan[c] = 1;
++     break;
++   default:
++     log1("warning: qmail-send unable to understand qmail-todo\n");
++     return;
++  }
 + }
 + 
@@ -22934,10 +22802,25 @@
  /* this file is too long ---------------------------------------------- MAIN */
  
- int getcontrols() { if (control_init() == -1) return 0;
-+ if (control_readint(&bouncemaxbytes,"control/bouncemaxbytes") == -1) return 0;   
+-int getcontrols() { if (control_init() == -1) return 0;
++int getcontrols() {
++ int c;
++ int ck = 0;
++
++ if (control_init() == -1) return 0;
++ if (control_readint(&bouncemaxbytes,"control/bouncemaxbytes") == -1) return 0;
   if (control_readint(&lifetime,"control/queuelifetime") == -1) return 0;
   if (control_readint(&concurrency[0],"control/concurrencylocal") == -1) return 0;
   if (control_readint(&concurrency[1],"control/concurrencyremote") == -1) return 0;
-@@ -1449,6 +1618,8 @@
++
++ for (c = 2,ck = 0;c < CHANNELS;++c)
++ {
++     strnum2[fmt_uint(strnum2,ck++)] = 0;
++     if (!stralloc_copys(&fname,"control/concurrencysuppl")) return 0;
++     if (!stralloc_cats(&fname,strnum2)) return 0;
++     if (!stralloc_0(&fname)) return 0;
++     if (control_readint(&concurrency[c],fname.s) == -1) return 0;
++ }
++
+  if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) return 0;
   if (control_rldef(&bouncefrom,"control/bouncefrom",0,"MAILER-DAEMON") != 1) return 0;
   if (control_rldef(&bouncehost,"control/bouncehost",1,"bouncehost") != 1) return 0;
@@ -22948,5 +22831,50 @@
   if (!stralloc_cats(&doublebounceto,"@")) return 0;
   if (!stralloc_cat(&doublebounceto,&doublebouncehost)) return 0;
-@@ -1478,6 +1649,10 @@
+@@ -1467,6 +1669,21 @@
+    case 0: if (!constmap_init(&mapvdoms,"",0,1)) return 0; break;
+    case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) return 0; break;
+   }
++
++ for (c = 0;c < SUPPL_CHANNELS;++c)
++ {
++     strnum2[fmt_uint(strnum2,c)] = 0;
++     if (!stralloc_copys(&fname,"control/suppls")) return 0;
++     if (!stralloc_cats(&fname,strnum2)) return 0;
++     if (!stralloc_0(&fname)) return 0;
++     switch (control_readfile(&suppls[c],fname.s,0))
++     {
++         case -1: return 0;
++         case 0: if (!constmap_init(&mapsuppl[c],"",0,0)) return 0; break;
++         case 1: if (!constmap_init(&mapsuppl[c],suppls[c].s,suppls[c].len,0)) return 0; break;
++     }
++ }
++
+  return 1; }
+ 
+ stralloc newlocals = {0};
+@@ -1475,9 +1692,33 @@
+ void regetcontrols()
+ {
+  int r;
++ int c;
++ int ck = 0;
++
++ if (control_readint(&concurrency[0],"control/concurrencylocal") == -1)
++  { log1("alert: unable to reread control/concurrencylocal\n"); return; }
++ if (control_readint(&concurrency[1],"control/concurrencyremote") == -1)
++  { log1("alert: unable to reread control/concurrencyremote\n"); return; }
++
++ for (c = 2,ck = 0;c < CHANNELS;++c)
++ {
++     strnum2[fmt_uint(strnum2,ck++)] = 0;
++     if (!stralloc_copys(&fname,"control/concurrencysuppl"))
++         { log3("alert: unable to reread ",fname.s,"\n"); return; }
++     if (!stralloc_cats(&fname,strnum2))
++         { log3("alert: unable to reread ",fname.s,"\n"); return; }
++     if (!stralloc_0(&fname))
++         { log3("alert: unable to reread ",fname.s,"\n"); return; }
++     if (control_readint(&concurrency[c],fname.s) == -1)
++         { log3("alert: unable to reread ",fname.s,"\n"); return; }
++ }
  
   if (control_readfile(&newlocals,"control/locals",1) != 1)
@@ -22959,5 +22887,34 @@
   if (r == -1)
    { log1("alert: unable to reread control/virtualdomains\n"); return; }
-@@ -1504,6 +1679,9 @@
+@@ -1495,6 +1736,28 @@
+   }
+  else
+    while (!constmap_init(&mapvdoms,"",0,1)) nomem();
++
++ for (c = 0;c < SUPPL_CHANNELS;++c)
++ {
++     strnum2[fmt_uint(strnum2,c)] = 0;
++     if (!stralloc_copys(&fname,"control/suppls")) nomem();
++     if (!stralloc_cats(&fname,strnum2)) nomem();
++     if (!stralloc_0(&fname)) nomem();
++     r = control_readfile(&newsuppls[c],fname.s,0);
++     if (r == -1)
++      { log3("alert: qmail-todo: unable to reread ", fname.s, "\n"); return; }
++
++     constmap_free(&mapsuppl[c]);
++
++     if (r)
++      {
++       while (!stralloc_copy(&suppls[c],&newsuppls[c])) nomem();
++       while (!constmap_init(&mapsuppl[c],suppls[c].s,suppls[c].len,0)) nomem();
++      }
++     else
++       while (!constmap_init(&mapsuppl[c],"",0,0)) nomem();
++ }
++
+ }
+ 
+ void reread()
+@@ -1504,6 +1767,9 @@
     log1("alert: unable to reread controls: unable to switch to home directory\n");
     return;
@@ -22969,5 +22926,119 @@
   while (chdir("queue") == -1)
    {
-@@ -1544,7 +1722,7 @@
+@@ -1512,6 +1778,104 @@
+   }
+ }
+ 
++
++static int static_i = 0;
++static int static_j = 0;
++static void channels_init(void)
++{
++    chanaddr[0] = "local/";
++    chanaddr[1] = "remote/";
++    for (static_i=2,static_j=0;static_i<CHANNELS;static_i++,static_j++)
++    {
++        stralloc fnc = {0};
++        strnum2[fmt_uint(strnum2,static_j)] = 0;
++        if (!stralloc_copys(&fname,QDIR_BASENAME)) nomem();
++        if (!stralloc_cats(&fname,strnum2)) nomem();
++        if (!stralloc_cats(&fname,"/")) nomem();
++        if (!stralloc_0(&fname)) nomem();
++        if (!stralloc_copy(&fnc,&fname)) nomem();
++        chanaddr[static_i] = fnc.s;
++    }
++
++    chanstatusmsg[0] = " local ";
++    chanstatusmsg[1] = " remote ";
++    for (static_i=2,static_j=0;static_i<CHANNELS;static_i++,static_j++)
++    {
++        stralloc fnc = {0};
++        strnum2[fmt_uint(strnum2,static_j)] = 0;
++        if (!stralloc_copys(&fname," " QDIR_BASENAME)) nomem();
++        if (!stralloc_cats(&fname,strnum2)) nomem();
++        if (!stralloc_cats(&fname," ")) nomem();
++        if (!stralloc_0(&fname)) nomem();
++        if (!stralloc_copy(&fnc,&fname)) nomem();
++        chanstatusmsg[static_i] = fnc.s;
++    }
++
++    tochan[0] = " to local ";
++    tochan[1] = " to remote ";
++    static_j = 0;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        stralloc fnc = {0};
++        strnum2[fmt_uint(strnum2,static_j++)] = 0;
++        if (!stralloc_copys(&fname," to " QDIR_BASENAME)) nomem();
++        if (!stralloc_cats(&fname,strnum2)) nomem();
++        if (!stralloc_cats(&fname," ")) nomem();
++        if (!stralloc_0(&fname)) nomem();
++        if (!stralloc_copy(&fnc,&fname)) nomem();
++        tochan[static_i] = fnc.s;
++    }
++
++    chanfdout[0] = 1;
++    chanfdout[1] = 3;
++    static_j = 1+CHANNEL_FD_OFFSET;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        chanfdout[static_i] = static_j;
++        static_j+=2;
++    }
++
++    chanfdin[0] = 2;
++    chanfdin[1] = 4;
++    static_j = 2+CHANNEL_FD_OFFSET;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        chanfdin[static_i] = static_j;
++        static_j+=2;
++    }
++
++    chanskip[0] = 10;
++    chanskip[1] = 20;
++    static_j = 20;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        chanskip[static_i] = static_j;
++    }
++
++    for (static_i=0;static_i<CHANNELS;static_i++)
++        comm_buf[static_i].s = 0;
++
++    for (static_i=0;static_i<CHANNELS;static_i++)
++        pqchan[static_i].p = 0;
++
++    concurrency[0] = 10;
++    concurrency[1] = 20;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        concurrency[static_i] = 20;
++    }
++
++    for (static_i=0;static_i<CHANNELS;static_i++)
++        concurrencyused[static_i] = 0;
++
++    for (static_i=0;static_i<SUPPL_CHANNELS;static_i++)
++        suppls[static_i].s = 0;
++
++    for (static_i=0;static_i<SUPPL_CHANNELS;static_i++)
++        newsuppls[static_i].s = 0;
++
++}
++
+ void main()
+ {
+  int fd;
+@@ -1522,6 +1886,8 @@
+  struct timeval tv;
+  int c;
+ 
++ channels_init();
++
+  if (chdir(auto_qmail) == -1)
+   { log1("alert: cannot start: unable to switch to home directory\n"); _exit(111); }
+  if (!getcontrols())
+@@ -1544,7 +1910,7 @@
   numjobs = 0;
   for (c = 0;c < CHANNELS;++c)
@@ -22978,5 +23049,5 @@
     int r;
     do
-@@ -1552,7 +1730,13 @@
+@@ -1552,7 +1918,13 @@
     while ((r == -1) && (errno == error_intr));
     if (r < 1)
@@ -22992,5 +23063,5 @@
     numjobs += concurrency[c];
    }
-@@ -1568,7 +1752,11 @@
+@@ -1568,7 +1940,11 @@
   todo_init();
   cleanup_init();
@@ -23006,5 +23077,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-showctl.c netqmail-1.06/qmail-showctl.c
 --- ../netqmail-1.06-original/qmail-showctl.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-showctl.c	2016-11-28 19:39:45.341600337 +0100
++++ netqmail-1.06/qmail-showctl.c	2019-02-27 20:57:13.401024948 +0100
 @@ -15,6 +15,7 @@
  #include "auto_patrn.h"
@@ -23126,5 +23197,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-smtpd.8 netqmail-1.06/qmail-smtpd.8
 --- ../netqmail-1.06-original/qmail-smtpd.8	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-smtpd.8	2016-12-18 19:08:22.496459855 +0100
++++ netqmail-1.06/qmail-smtpd.8	2019-02-27 20:57:13.402024937 +0100
 @@ -14,6 +14,15 @@
  see
@@ -23450,5 +23521,5 @@
 diff -ruN ../netqmail-1.06-original/qmail-smtpd.c netqmail-1.06/qmail-smtpd.c
 --- ../netqmail-1.06-original/qmail-smtpd.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/qmail-smtpd.c	2017-11-07 17:45:04.599607652 +0100
++++ netqmail-1.06/qmail-smtpd.c	2020-04-25 15:15:28.957053097 +0200
 @@ -12,6 +12,9 @@
  #include "ip.h"
@@ -23461,5 +23532,5 @@
  #include "scan.h"
  #include "byte.h"
-@@ -23,44 +26,178 @@
+@@ -23,44 +26,180 @@
  #include "timeoutread.h"
  #include "timeoutwrite.h"
@@ -23467,44 +23538,6 @@
 +#include "dns.h"
 +#include "wait.h"
-+/* start chkuser code */
-+#include "chkuser.h"
-+/* end chkuser code */
-+#include "spf.h"
-+/* rbl: start */
-+#include "strsalloc.h"
-+/* rbl: end */
-+
-+#define AUTHSLEEP 5
- 
- #define MAXHOPS 100
-+
-+#define BMCHECK_BMF 0
-+#define BMCHECK_BMFNR 1
-+#define BMCHECK_BMT 2
-+#define BMCHECK_BMTNR 3
-+#define BMCHECK_BHELO 4
-+#define BMCHECK_BHELONR 5
-+
-+static char strnum[FMT_ULONG];
- unsigned int databytes = 0;
-+unsigned int greetdelay = 0;
-+unsigned int drop_pre_greet = 0;
- int timeout = 1200;
-+int maxrcpt = -1;
-+unsigned int spfbehavior = 0;
-+
-+/* rejectrelaytest: start */
-+unsigned int rejectrelaytest = 0;
-+/* rejecrelayttest: end */
-+/* rejectnullsenders: start */
-+unsigned int rejnsmf = 0;
-+/* rejectnullsenders: end */
-+
-+const char *protocol = "SMTP";
-+
-+/* spf ipv6 fix */
-+char *remoteip4;
-+/* end spf ipv6 fix */
-+
++
++/* chkuser.h will check if TLS_H is defined, so this has to come before chkuser.h */
 +#ifdef TLS
 +#include <sys/stat.h>
@@ -23517,4 +23550,44 @@
 +int forcetls = 1;
 +#endif
++
++/* start chkuser code */
++#include "chkuser.h"
++/* end chkuser code */
++#include "spf.h"
++/* rbl: start */
++#include "strsalloc.h"
++/* rbl: end */
++
++#define AUTHSLEEP 5
+ 
+ #define MAXHOPS 100
++
++#define BMCHECK_BMF 0
++#define BMCHECK_BMFNR 1
++#define BMCHECK_BMT 2
++#define BMCHECK_BMTNR 3
++#define BMCHECK_BHELO 4
++#define BMCHECK_BHELONR 5
++
++static char strnum[FMT_ULONG];
+ unsigned int databytes = 0;
++unsigned int greetdelay = 0;
++unsigned int drop_pre_greet = 0;
+ int timeout = 1200;
++int maxrcpt = -1;
++unsigned int spfbehavior = 0;
++
++/* rejectrelaytest: start */
++unsigned int rejectrelaytest = 0;
++/* rejecrelayttest: end */
++/* rejectnullsenders: start */
++unsigned int rejnsmf = 0;
++/* rejectnullsenders: end */
++
++static const char *protocol = "SMTP";
++
++/* spf ipv6 fix */
++char *remoteip4;
++/* end spf ipv6 fix */
  
  int safewrite(fd,buf,len) int fd; char *buf; int len;
@@ -23555,5 +23628,5 @@
 -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 die_read() { logit("read failed"); _exit(1); }
++void die_read(char *reason) { logit2("read failed", reason); flush(); _exit(1); }
 +void die_alarm() { qlogenvelope("rejected","alarmtimeout","","451"); logit("timeout"); out("451 timeout (#4.4.2)\r\n"); flush(); _exit(1); }
 +void die_nomem() { qlogenvelope("rejected","outofmemory","","421"); out("421 out of memory (#4.3.0)\r\n"); flush(); _exit(1); }
@@ -23649,5 +23722,5 @@
  void smtp_greet(code) char *code;
  {
-@@ -76,11 +213,33 @@
+@@ -76,11 +215,33 @@
    smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
  }
@@ -23683,5 +23756,5 @@
  stralloc helohost = {0};
  char *fakehelo; /* pointer into helohost, or 0 */
-@@ -91,11 +250,101 @@
+@@ -91,11 +252,101 @@
    fakehelo = case_diffs(remotehost,helohost.s) ? helohost.s : 0;
  }
@@ -23786,5 +23859,5 @@
  void setup()
  {
-@@ -109,21 +358,110 @@
+@@ -109,21 +360,110 @@
    if (liphostok == -1) die_control();
    if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
@@ -23898,5 +23971,5 @@
    if (!local) local = env_get("TCPLOCALIP");
    if (!local) local = "unknown";
-@@ -131,10 +469,67 @@
+@@ -131,10 +471,67 @@
    if (!remotehost) remotehost = "unknown";
    remoteinfo = env_get("TCPREMOTEINFO");
@@ -23967,5 +24040,5 @@
  
  int addrparse(arg)
-@@ -155,6 +550,7 @@
+@@ -155,6 +552,7 @@
      terminator = ' ';
      arg += str_chr(arg,':');
@@ -23975,5 +24048,5 @@
    }
  
-@@ -197,6 +593,8 @@
+@@ -197,6 +595,8 @@
    return 1;
  }
@@ -23984,5 +24057,5 @@
  {
    int j;
-@@ -207,68 +605,1102 @@
+@@ -207,76 +607,1108 @@
      if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1;
    return 0;
@@ -24459,57 +24532,48 @@
 +}
 +
-+void logit(message) const char* message;
++/* logging patch */
++
++void safeloglen(const char* string, const int len) {
++    if (string && len) {
++        if (!stralloc_catb(&log_buf, string, len-1)) die_nomem();
++    } else {
++        if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
++    }
++}
++
++void safelog(const char* string) {
++    if (string) {
++        if (!stralloc_cats(&log_buf, string)) die_nomem();
++    } else {
++        if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
++    }
++}
++
++void logit(const char* message) {
++    logit2(message, (const char*)0);
++}
++
++void logit2(const char* message, const char* reason)
 +{
 +  if (!stralloc_copys(&log_buf, "qmail-smtpd: ")) die_nomem();
-+  if (!stralloc_cats(&log_buf, message)) die_nomem();
++  safelog(message);
++  if (reason) {
++      if (!stralloc_cats(&log_buf, " (")) die_nomem();
++      if (!stralloc_cats(&log_buf, reason)) die_nomem();
++      if (!stralloc_cats(&log_buf, ")")) die_nomem();
++  }
 +  if (!stralloc_catb(&log_buf, ": ", 2)) die_nomem();
-+  if (mailfrom.s) {
-+      if (!stralloc_catb(&log_buf, mailfrom.s, mailfrom.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
++  safeloglen(mailfrom.s, mailfrom.len);
 +  if (!stralloc_catb(&log_buf, " from ", 6)) die_nomem();
-+  if (!stralloc_cats(&log_buf, remoteip)) die_nomem();
++  safelog(remoteip);
 +  if (!stralloc_catb(&log_buf, " to ", 4)) die_nomem();
-+  if (addr.s) {
-+      if (!stralloc_catb(&log_buf, addr.s, addr.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
++  safeloglen(addr.s, addr.len);
 +  if (!stralloc_catb(&log_buf, " helo ", 6)) die_nomem();
-+  if (helohost.s) {
-+      if (!stralloc_catb(&log_buf, helohost.s, helohost.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
++  safeloglen(helohost.s, helohost.len);
 +  if (!stralloc_catb(&log_buf, "\n", 1)) die_nomem();
 +  substdio_putflush(&sserr, log_buf);
 +}
 +
-+void logit2(message, reason)
-+const char* message;
-+const char* reason;
-+{
-+  if (!stralloc_copys(&log_buf,"qmail-smtpd: ")) die_nomem();
-+  if (!stralloc_cats(&log_buf, message)) die_nomem();
-+  if (!stralloc_cats(&log_buf, " (")) die_nomem();
-+  if (!stralloc_cats(&log_buf, reason)) die_nomem();
-+  if (!stralloc_cats(&log_buf, "): ")) die_nomem();
-+  if (mailfrom.s) {
-+      if (!stralloc_catb(&log_buf, mailfrom.s, mailfrom.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
-+  if (!stralloc_cats(&log_buf," from ")) die_nomem();
-+  if (!stralloc_cats(&log_buf, remoteip)) die_nomem();
-+  if (!stralloc_cats(&log_buf, " to ")) die_nomem();
-+  if (addr.s) {
-+      if (!stralloc_catb(&log_buf, addr.s, addr.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
-+  if (!stralloc_cats(&log_buf, " helo ")) die_nomem();
-+  if (helohost.s) {
-+      if (!stralloc_catb(&log_buf, helohost.s, helohost.len-1)) die_nomem();
-+  } else
-+      if (!stralloc_catb(&log_buf, "(null)", 6)) die_nomem();
-+  if (!stralloc_catb(&log_buf, "\n", 1)) die_nomem();
-+  substdio_putflush(&sserr, log_buf);
-+}
++/* end logging patch */
 +
 +int mailfrom_size(arg) char *arg;
@@ -24543,5 +24607,5 @@
 +  if (!remoteinfo) {
 +    remoteinfo = fuser.s;
-+    if (!env_unset("TCPREMOTEINFO")) die_read();
++    if (!env_unset("TCPREMOTEINFO")) die_read("TCPREMOTEINFO");
 +    if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
 +  }
@@ -24577,5 +24641,5 @@
 +  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
 +  if ((!flagbarfbhelo) && (bhelonrok) && (!relayclient)) flagbarfbhelo = bmcheck(BMCHECK_BHELONR);
-+}
+ }
 +char size_buf[FMT_ULONG];
 +void smtp_size()
@@ -24583,5 +24647,5 @@
 +  size_buf[fmt_ulong(size_buf,(unsigned long) databytes)] = 0;
 +  out("250 SIZE "); out(size_buf); out("\r\n");
- }
++}
 +
 +/* ESMTP extensions are published here */
@@ -24620,4 +24684,8 @@
 +  seenmail = 0; /* seenauth = 0; RFC 5321: retain authentication */
 +  mailfrom.len = 0; rcptto.len = 0;
++  /* prevents the maxrcpto error if control/maxrcpt limit has been exceeded in the same email, but not in multiple messages sequentially */
++  rcptcount = 0;
++  envelopepos = 1;
++  /* end rcptcount adjustment */
    out("250 flushed\r\n");
  }
@@ -24669,5 +24737,5 @@
 +/* qregex: start */
 +  /*
-+  flagbarf = bmfcheck();
+   flagbarf = bmfcheck();
 +  */
 +  flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
@@ -24683,5 +24751,5 @@
 +/* qregex: start */
 +  /*
-   flagbarf = bmfcheck();
++  flagbarf = bmfcheck();
 +  */
 +  flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
@@ -25091,6 +25159,8 @@
    r = timeoutread(timeout,fd,buf,len);
    if (r == -1) if (errno == error_timeout) die_alarm();
-   if (r <= 0) die_read();
-@@ -277,6 +1709,9 @@
+-  if (r <= 0) die_read();
++  if (r <= 0) die_read("hang up before quit cmd");
+   return r;
+ }
  
  char ssinbuf[1024];
@@ -25102,5 +25172,5 @@
  struct qmail qqt;
  unsigned int bytestooverflow = 0;
-@@ -300,7 +1735,7 @@
+@@ -300,7 +1732,7 @@
    int flagmaybex; /* 1 if this line might match RECEIVED, if fih */
    int flagmaybey; /* 1 if this line might match \r\n, if fih */
@@ -25111,5 +25181,5 @@
    *hops = 0;
    flaginheader = 1;
-@@ -322,17 +1757,16 @@
+@@ -322,17 +1754,16 @@
      }
      switch(state) {
@@ -25132,5 +25202,5 @@
          state = 0;
          break;
-@@ -351,10 +1785,73 @@
+@@ -351,10 +1782,73 @@
    }
  }
@@ -25206,5 +25276,5 @@
    out("250 ok ");
    accept_buf[fmt_ulong(accept_buf,(unsigned long) when)] = 0;
-@@ -363,22 +1860,32 @@
+@@ -363,22 +1857,32 @@
    accept_buf[fmt_ulong(accept_buf,qp)] = 0;
    out(accept_buf);
@@ -25241,5 +25311,5 @@
    hops = (hops >= MAXHOPS);
    if (hops) qmail_fail(&qqt);
-@@ -386,34 +1893,631 @@
+@@ -386,36 +1890,662 @@
    qmail_put(&qqt,rcptto.s,rcptto.len);
   
@@ -25282,5 +25352,5 @@
 +    if (!stralloc_readyplus(&authin,1)) die_nomem(); /* XXX */
 +    i = substdio_get(&ssin,authin.s + authin.len,1);
-+    if (i != 1) die_read();
++    if (i != 1) die_read("authgetl");
 +    if (authin.s[authin.len] == '\n') break;
 +    ++authin.len;
@@ -25461,13 +25531,13 @@
 +      relayclient = "";
 +      remoteinfo = user.s;
-+      if (!env_unset("TCPREMOTEINFO")) die_read();
++      if (!env_unset("TCPREMOTEINFO")) die_read("TCPREMOTEINFO");
 +      if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
 +      if (!env_put2("RELAYCLIENT",relayclient)) die_nomem();
 +
-+      if (!env_unset("SMTPAUTHMETHOD")) die_read();
++      if (!env_unset("SMTPAUTHMETHOD")) die_read("SMTPAUTHMETHOD");
 +      if (!env_put2("SMTPAUTHMETHOD", authcmds[i].text)) die_nomem();
-+      if (!env_unset("SMTPAUTHUSER")) die_read();
++      if (!env_unset("SMTPAUTHUSER")) die_read("SMTPAUTHUSER");
 +      if (!env_put2("SMTPAUTHUSER",user.s)) die_nomem();
-+      if (!env_unset("SMTP_AUTH_USER")) die_read();
++      if (!env_unset("SMTP_AUTH_USER")) die_read("SMTP_AUTH_USER");
 +      if (!env_put2("SMTP_AUTH_USER",user.s)) die_nomem();
 +
@@ -25495,23 +25565,36 @@
 +RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen)
 +{
++  RSA *rsa;
++
 +  if (!export) keylen = 2048;
 +  if (keylen == 2048) {
 +    FILE *in = fopen("control/rsa2048.pem", "r");
 +    if (in) {
-+      RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL);
++      rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL);
 +      fclose(in);
 +      if (rsa) return rsa;
 +    }
 +  }
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++  BIGNUM *e; /*exponent */
++  e = BN_new();
++  BN_set_word(e, RSA_F4);
++  if (RSA_generate_key_ex(rsa, keylen, e, NULL) == 1)
++    return rsa;
++  return NULL;
++#else
 +  return RSA_generate_key(keylen, RSA_F4, NULL, NULL);
++#endif
 +}
 +
 +DH *tmp_dh_cb(SSL *ssl, int export, int keylen)
 +{
++  DH *dh;
++
 +  if (!export) keylen = 2048;
 +  if (keylen == 2048) {
 +    FILE *in = fopen("control/dh2048.pem", "r");
 +    if (in) {
-+      DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL);
++      dh = PEM_read_DHparams(in, NULL, NULL, NULL);
 +      fclose(in);
 +      if (dh) return dh;
@@ -25526,9 +25609,15 @@
 +    }
 +  }
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++  if((dh = DH_new()) && (DH_generate_parameters_ex(dh, keylen, DH_GENERATOR_2, NULL) == 1))
++    return dh;
++  return NULL;
++#else
 +  return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL);
-+} 
++#endif
++}
 +
 +/* don't want to fail handshake if cert isn't verifiable */
-+int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
++int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) { return 1; }
 +
 +void tls_nogateway()
@@ -25545,5 +25634,5 @@
 +  out(" (#4.3.0)\r\n"); flush();
 +}
-+void tls_err(const char *s) { tls_out(s, ssl_error()); if (smtps) die_read(); }
++void tls_err(const char *s) { tls_out(s, ssl_error()); if (smtps) die_read("tls_err"); }
 +
 +# define CLIENTCA "control/clientca.pem"
@@ -25572,5 +25661,5 @@
 +      if (sk) {
 +        SSL_set_client_CA_list(ssl, sk);
-+        SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
++        SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_cb);
 +        break;
 +      }
@@ -25583,5 +25672,5 @@
 +  if (ssl_timeoutrehandshake(timeout, ssl_rfd, ssl_wfd, ssl) <= 0) {
 +    const char *err = ssl_error_str();
-+    tls_out("rehandshake failed", err); die_read();
++    tls_out("rehandshake failed", err); die_read("rehandshake failed");
 +  }
 +
@@ -25600,5 +25689,5 @@
 +    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;
++      const ASN1_STRING *s = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, n));
 +      if (s) { email.len = s->length; email.s = s->data; }
 +    }
@@ -25640,4 +25729,5 @@
 +  X509_STORE *store;
 +  X509_LOOKUP *lookup;
++  int session_id_context = 1; /* anything will do */
 +
 +  SSL_library_init();
@@ -25650,9 +25740,20 @@
 +  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
 +
++  /* renegotiation should include certificate request */
++  SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
++
++  /* never bother the application with retries if the transport is blocking */
++  SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
++
++  /* relevant in renegotiation */
++  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
++  if (!SSL_CTX_set_session_id_context(ctx, (void *)&session_id_context,
++                                        sizeof(session_id_context))) 
++    { SSL_CTX_free(ctx); tls_err("failed to set session_id_context"); 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);
@@ -25661,5 +25762,4 @@
 +    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK |
 +                                X509_V_FLAG_CRL_CHECK_ALL);
-+#endif
 +
 +#if OPENSSL_VERSION_NUMBER >= 0x10002000L
@@ -25668,6 +25768,5 @@
 +#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);
++  SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
 +
 +  /* a new SSL object, with the rest added to it directly to avoid copying */
@@ -25705,5 +25804,5 @@
 +    /* 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();
++    tls_out("connection failed", err); ssl_free(myssl); die_read("tls connection failed");
 +  }
 +  ssl = myssl;
@@ -25878,9 +25977,18 @@
    smtp_greet("220 ");
    out(" ESMTP\r\n");
-   if (commands(&ssin,&smtpcommands) == 0) die_read();
+-  if (commands(&ssin,&smtpcommands) == 0) die_read();
++  if (commands(&ssin,&smtpcommands) == 0) die_read("commands");
+   die_nomem();
+ }
 diff -ruN ../netqmail-1.06-original/qmail-start.c netqmail-1.06/qmail-start.c
 --- ../netqmail-1.06-original/qmail-start.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail-start.c	2016-11-22 21:03:57.125527665 +0100
-@@ -8,6 +8,9 @@
++++ netqmail-1.06/qmail-start.c	2019-06-26 16:39:31.578826915 +0200
+@@ -4,10 +4,15 @@
+ #include "fork.h"
+ #include "auto_uids.h"
+ 
++#include "channels.h"
++
+ char *(qsargs[]) = { "qmail-send", 0 };
  char *(qcargs[]) = { "qmail-clean", 0 };
  char *(qlargs[]) = { "qmail-lspawn", "./Mailbox", 0 };
@@ -25892,5 +26000,5 @@
  void die() { _exit(111); }
  
-@@ -18,13 +21,28 @@
+@@ -18,19 +23,51 @@
  int pi4[2];
  int pi5[2];
@@ -25905,12 +26013,21 @@
 +#endif
 +
++int suppl_pi[SUPPL_CHANNELS*2][2];
++
 +void close23456() { 
++  int c;
 +  close(2); close(3); close(4); close(5); close(6); 
 +#ifdef EXTERNAL_TODO
 +  close(7); close(8);
 +#endif
++  for (c=1+CHANNEL_FD_OFFSET;c<=SUPPL_CHANNELS*2+CHANNEL_FD_OFFSET;c++)
++  {
++      close(c);
++  }
 +}
  
  void closepipes() {
++  int c;
++
    close(pi1[0]); close(pi1[1]); close(pi2[0]); close(pi2[1]);
    close(pi3[0]); close(pi3[1]); close(pi4[0]); close(pi4[1]);
@@ -25920,8 +26037,22 @@
 +	close(pi9[0]); close(pi9[1]); close(pi10[0]); close(pi10[1]);
 +#endif
++
++  for (c=0;c<SUPPL_CHANNELS*2;c++)
++  {
++      close(suppl_pi[c][0]);
++      close(suppl_pi[c][1]);
++  }
  }
  
  void main(argc,argv)
-@@ -40,6 +58,10 @@
+ int argc;
+ char **argv;
+ {
++  int c, cc;
++
+   if (chdir("/") == -1) die();
+   umask(077);
+   if (prot_gid(auto_gidq) == -1) die();
+@@ -40,6 +77,14 @@
    if (fd_copy(4,0) == -1) die();
    if (fd_copy(5,0) == -1) die();
@@ -25931,8 +26062,12 @@
 +  if (fd_copy(8,0) == -1) die();
 +#endif
++  for (c=1+CHANNEL_FD_OFFSET;c<=SUPPL_CHANNELS*2+CHANNEL_FD_OFFSET;c++)
++  {
++      if (fd_copy(c,0) == -1) die();
++  }
  
    if (argv[1]) {
      qlargs[1] = argv[1];
-@@ -70,6 +92,12 @@
+@@ -70,6 +115,16 @@
    if (pipe(pi4) == -1) die();
    if (pipe(pi5) == -1) die();
@@ -25944,8 +26079,12 @@
 +  if (pipe(pi10) == -1) die();
 +#endif
++  for (c=0;c<SUPPL_CHANNELS*2;c++)
++  {
++      if (pipe(suppl_pi[c]) == -1) die();
++  }
   
    switch(fork()) {
      case -1: die();
-@@ -106,6 +134,34 @@
+@@ -106,6 +161,57 @@
        die();
    }
@@ -25978,9 +26117,32 @@
 +  }
 +#endif
-+ 
++
++  for (c=0,cc=0;c<SUPPL_CHANNELS;++c,cc+=2)
++  {
++      switch(fork()) {
++        case -1: die();
++        case 0:
++          if (prot_uid(auto_uidr) == -1) die();
++          /* Does not increment cc in parent process */
++          if (fd_copy(0,suppl_pi[cc++][0]) == -1) die();
++          if (fd_copy(1,suppl_pi[cc][1]) == -1) die();
++          close23456();
++          closepipes();
++          /*if (str_equal(channel_types[c],"remote"))
++          {*/
++              execvp(*qrargs,qrargs);
++          /*}
++           else
++          {
++             execvp(*qlargs,qlargs);
++          }*/
++          die();
++      }
++  }
++
    if (prot_uid(auto_uids) == -1) die();
    if (fd_copy(0,1) == -1) die();
    if (fd_copy(1,pi1[1]) == -1) die();
-@@ -114,6 +170,10 @@
+@@ -114,6 +220,17 @@
    if (fd_copy(4,pi4[0]) == -1) die();
    if (fd_copy(5,pi5[1]) == -1) die();
@@ -25990,4 +26152,11 @@
 +  if (fd_copy(8,pi8[0]) == -1) die();
 +#endif
++
++  for (cc=0,c=1+CHANNEL_FD_OFFSET;c<=SUPPL_CHANNELS*2+CHANNEL_FD_OFFSET;c++)
++  {
++      if (fd_copy(c++,suppl_pi[cc++][1]) == -1) die();
++      if (fd_copy(c,suppl_pi[cc++][0]) == -1) die();
++  }
++
    closepipes();
    execvp(*qsargs,qsargs);
@@ -25995,6 +26164,6 @@
 diff -ruN ../netqmail-1.06-original/qmail-todo.c netqmail-1.06/qmail-todo.c
 --- ../netqmail-1.06-original/qmail-todo.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qmail-todo.c	2016-11-22 21:03:57.126527632 +0100
-@@ -0,0 +1,703 @@
++++ netqmail-1.06/qmail-todo.c	2019-06-26 16:39:31.579826904 +0200
+@@ -0,0 +1,791 @@
 +#include <sys/types.h>
 +#include <sys/stat.h>
@@ -26022,4 +26191,6 @@
 +#include "trigger.h"
 +
++#include "channels.h"
++
 +/* critical timing feature #1: if not triggered, do not busy-loop */
 +/* critical timing feature #2: if triggered, respond within fixed time */
@@ -26030,4 +26201,5 @@
 +#define SLEEP_SYSFAIL 123
 +
++
 +stralloc percenthack = {0};
 +struct constmap mappercenthack;
@@ -26037,10 +26209,12 @@
 +struct constmap mapvdoms;
 +stralloc envnoathost = {0};
++stralloc fname = {0};
 +
 +char strnum[FMT_ULONG];
 +
-+/* XXX not good, if qmail-send.c changes this has to be updated */
-+#define CHANNELS 2
-+char *chanaddr[CHANNELS] = { "local/", "remote/" };
++struct constmap mapsuppl[SUPPL_CHANNELS];
++stralloc suppls[SUPPL_CHANNELS];
++stralloc newsuppls[SUPPL_CHANNELS];
++char *chanaddr[CHANNELS];
 +
 +datetime_sec recent;
@@ -26097,4 +26271,5 @@
 +  int i;
 +  int j;
++  int c;
 +  char *x;
 +  static stralloc addr = {0};
@@ -26139,4 +26314,11 @@
 +  if (!stralloc_cat(&rwline,&addr)) return 0;
 +  if (!stralloc_0(&rwline)) return 0;
++
++  for (c = 0;c < SUPPL_CHANNELS;++c)
++  {
++      if (constmap(&mapsuppl[c],addr.s + at + 1,addr.len - at - 1))
++          return c + 3;
++  }
++
 +  return 2;
 +}
@@ -26206,13 +26388,22 @@
 +}
 +
-+void comm_write(unsigned long id, int local, int remote)
++void comm_write(unsigned long id, int flagchan[])
 +{
 +  int pos;
-+  char *s;
++  char s[CHANNELS+1];
++  int c;
 +  
-+  if(local && remote) s="B";
-+  else if(local) s="L";
-+  else if(remote) s="R";
-+  else s="X";
++  for (c = 0;c < CHANNELS;++c)
++  {
++      if (flagchan[c])
++      {
++          s[c] = '1';
++      }
++      else
++      {
++          s[c] = '0';
++      }
++  }
++  s[c] = 0;
 +  
 +  pos = comm_buf.len;
@@ -26496,10 +26687,7 @@
 +       break;
 +     case 'T':
-+       switch(rewrite(todoline.s + 1))
-+	{
-+	 case 0: nomem(); goto fail;
-+	 case 2: c = 1; break;
-+	 default: c = 0; break;
-+        }
++       c = rewrite(todoline.s + 1);
++       if (c == 0) { nomem(); goto fail; }
++       c--;
 +       if (fdchan[c] == -1)
 +	{
@@ -26553,5 +26741,5 @@
 +  }
 +
-+ comm_write(id, flagchan[0], flagchan[1]);
++ comm_write(id, flagchan);
 + 
 + return;
@@ -26568,4 +26756,6 @@
 +int getcontrols(void)
 +{
++ int c;
++
 + if (control_init() == -1) return 0;
 + if (control_rldef(&envnoathost,"control/envnoathost",1,"envnoathost") != 1) return 0;
@@ -26584,4 +26774,19 @@
 +   case 1: if (!constmap_init(&mapvdoms,vdoms.s,vdoms.len,1)) return 0; break;
 +  }
++
++ for (c = 0;c < SUPPL_CHANNELS;++c)
++ {
++     strnum[fmt_uint(strnum,c)] = 0;
++     if (!stralloc_copys(&fname,"control/suppls")) return 0;
++     if (!stralloc_cats(&fname,strnum)) return 0;
++     if (!stralloc_0(&fname)) return 0;
++     switch (control_readfile(&suppls[c],fname.s,0))
++     {
++         case -1: return 0;
++         case 0: if (!constmap_init(&mapsuppl[c],"",0,0)) return 0; break;
++         case 1: if (!constmap_init(&mapsuppl[c],suppls[c].s,suppls[c].len,0)) return 0; break;
++     }
++ }
++
 + return 1;
 +}
@@ -26593,4 +26798,5 @@
 +{
 + int r;
++ int c;
 +
 + if (control_readfile(&newlocals,"control/locals",1) != 1)
@@ -26613,4 +26819,26 @@
 + else
 +   while (!constmap_init(&mapvdoms,"",0,1)) nomem();
++
++ for (c = 0;c < SUPPL_CHANNELS;++c)
++ {
++     strnum[fmt_uint(strnum,c)] = 0;
++     if (!stralloc_copys(&fname,"control/suppls")) nomem();
++     if (!stralloc_cats(&fname,strnum)) nomem();
++     if (!stralloc_0(&fname)) nomem();
++     r = control_readfile(&newsuppls[c],fname.s,0);
++     if (r == -1)
++      { log3("alert: qmail-todo: unable to reread ", fname.s, "\n"); return; }
++
++     constmap_free(&mapsuppl[c]);
++
++     if (r)
++      {
++       while (!stralloc_copy(&suppls[c],&newsuppls[c])) nomem();
++       while (!constmap_init(&mapsuppl[c],suppls[c].s,suppls[c].len,0)) nomem();
++      }
++     else
++       while (!constmap_init(&mapsuppl[c],"",0,0)) nomem();
++ }
++
 +}
 +
@@ -26630,4 +26858,31 @@
 +}
 +
++static int static_i = 0;
++static int static_j = 0;
++void channels_init(void)
++{
++    for (static_i=0;static_i<SUPPL_CHANNELS;static_i++)
++        suppls[static_i].s = 0;
++
++    for (static_i=0;static_i<SUPPL_CHANNELS;static_i++)
++        newsuppls[static_i].s = 0;
++
++    chanaddr[0] = "local/";
++    chanaddr[1] = "remote/";
++    static_j = 0;
++    for (static_i=2;static_i<CHANNELS;static_i++)
++    {
++        stralloc fnc = {0};
++        strnum[fmt_uint(strnum,static_j++)] = 0;
++        if (!stralloc_copys(&fname,QDIR_BASENAME)) nomem();
++        if (!stralloc_cats(&fname,strnum)) nomem();
++        if (!stralloc_cats(&fname,"/")) nomem();
++        if (!stralloc_0(&fname)) nomem();
++        if (!stralloc_copy(&fnc,&fname)) nomem();
++        chanaddr[static_i] = fnc.s;
++    }
++}
++
++
 +void main()
 +{
@@ -26639,4 +26894,6 @@
 + int r;
 + char c;
++
++ channels_init();
 +
 + if (chdir(auto_qmail) == -1)
@@ -26700,7 +26957,18 @@
 +}
 +
+diff -ruN ../netqmail-1.06-original/qmail-upq.sh netqmail-1.06/qmail-upq.sh
+--- ../netqmail-1.06-original/qmail-upq.sh	1998-06-15 12:53:16.000000000 +0200
++++ netqmail-1.06/qmail-upq.sh	2019-06-26 16:39:31.579826904 +0200
+@@ -1,6 +1,6 @@
+ cd QMAIL
+ cd queue
+-for dir in mess info local remote
++for dir in mess info local remote suppl*
+ do
+   ( cd $dir; find . -type f -print ) | (
+     cd $dir
 diff -ruN ../netqmail-1.06-original/qmail.c netqmail-1.06/qmail.c
 --- ../netqmail-1.06-original/qmail.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/qmail.c	2016-11-22 21:03:57.126527632 +0100
++++ netqmail-1.06/qmail.c	2019-02-27 20:57:13.404024915 +0100
 @@ -23,22 +23,32 @@
  {
@@ -26800,5 +27068,5 @@
 diff -ruN ../netqmail-1.06-original/qmail.h netqmail-1.06/qmail.h
 --- ../netqmail-1.06-original/qmail.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/qmail.h	2016-11-22 21:03:57.126527632 +0100
++++ netqmail-1.06/qmail.h	2019-02-27 20:57:13.404024915 +0100
 @@ -3,11 +3,13 @@
  
@@ -26817,5 +27085,5 @@
 diff -ruN ../netqmail-1.06-original/qregex.c netqmail-1.06/qregex.c
 --- ../netqmail-1.06-original/qregex.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qregex.c	2016-11-22 21:03:57.126527632 +0100
++++ netqmail-1.06/qregex.c	2019-02-27 20:57:13.405024904 +0100
 @@ -0,0 +1,239 @@
 +/*
@@ -27060,5 +27328,5 @@
 diff -ruN ../netqmail-1.06-original/qregex.h netqmail-1.06/qregex.h
 --- ../netqmail-1.06-original/qregex.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/qregex.h	2016-11-22 21:03:57.126527632 +0100
++++ netqmail-1.06/qregex.h	2019-02-27 20:57:13.405024904 +0100
 @@ -0,0 +1,24 @@
 +/*
@@ -27088,5 +27356,5 @@
 diff -ruN ../netqmail-1.06-original/readwrite.h netqmail-1.06/readwrite.h
 --- ../netqmail-1.06-original/readwrite.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/readwrite.h	2016-11-22 21:03:57.126527632 +0100
++++ netqmail-1.06/readwrite.h	2019-02-27 20:57:13.405024904 +0100
 @@ -1,7 +1,6 @@
  #ifndef READWRITE_H
@@ -27100,5 +27368,5 @@
 diff -ruN ../netqmail-1.06-original/received.c netqmail-1.06/received.c
 --- ../netqmail-1.06-original/received.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/received.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/received.c	2019-02-27 20:57:13.405024904 +0100
 @@ -21,6 +21,9 @@
    return 0;
@@ -27128,5 +27396,5 @@
 diff -ruN ../netqmail-1.06-original/remoteinfo.c netqmail-1.06/remoteinfo.c
 --- ../netqmail-1.06-original/remoteinfo.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/remoteinfo.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/remoteinfo.c	2019-02-27 20:57:13.405024904 +0100
 @@ -44,12 +44,12 @@
    s = socket(AF_INET,SOCK_STREAM,0);
@@ -27147,5 +27415,5 @@
 diff -ruN ../netqmail-1.06-original/scan.h netqmail-1.06/scan.h
 --- ../netqmail-1.06-original/scan.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/scan.h	2018-03-31 14:54:40.767441567 +0200
++++ netqmail-1.06/scan.h	2019-02-27 20:57:13.405024904 +0100
 @@ -2,6 +2,7 @@
  #define SCAN_H
@@ -27158,5 +27426,5 @@
 diff -ruN ../netqmail-1.06-original/scan_ulong.c netqmail-1.06/scan_ulong.c
 --- ../netqmail-1.06-original/scan_ulong.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/scan_ulong.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/scan_ulong.c	2019-02-27 20:57:13.405024904 +0100
 @@ -9,3 +9,43 @@
      { result = result * 10 + c; ++pos; }
@@ -27205,5 +27473,5 @@
 diff -ruN ../netqmail-1.06-original/scan_xlong.c netqmail-1.06/scan_xlong.c
 --- ../netqmail-1.06-original/scan_xlong.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/scan_xlong.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/scan_xlong.c	2019-02-27 20:57:13.405024904 +0100
 @@ -0,0 +1,47 @@
 +/*
@@ -27256,5 +27524,5 @@
 diff -ruN ../netqmail-1.06-original/select.h2 netqmail-1.06/select.h2
 --- ../netqmail-1.06-original/select.h2	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/select.h2	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/select.h2	2019-02-27 20:57:13.405024904 +0100
 @@ -1,6 +1,12 @@
  #ifndef SELECT_H
@@ -27272,5 +27540,5 @@
 diff -ruN ../netqmail-1.06-original/socket_v4mappedprefix.c netqmail-1.06/socket_v4mappedprefix.c
 --- ../netqmail-1.06-original/socket_v4mappedprefix.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/socket_v4mappedprefix.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/socket_v4mappedprefix.c	2019-02-27 20:57:13.406024893 +0100
 @@ -0,0 +1,9 @@
 +/*
@@ -27285,5 +27553,5 @@
 diff -ruN ../netqmail-1.06-original/socket_v6any.c netqmail-1.06/socket_v6any.c
 --- ../netqmail-1.06-original/socket_v6any.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/socket_v6any.c	2016-11-22 21:03:57.127527599 +0100
++++ netqmail-1.06/socket_v6any.c	2019-02-27 20:57:13.406024893 +0100
 @@ -0,0 +1,9 @@
 +/*
@@ -27298,5 +27566,5 @@
 diff -ruN ../netqmail-1.06-original/softwarelicense1-1.html netqmail-1.06/softwarelicense1-1.html
 --- ../netqmail-1.06-original/softwarelicense1-1.html	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/softwarelicense1-1.html	2016-11-22 21:03:57.128527565 +0100
++++ netqmail-1.06/softwarelicense1-1.html	2019-02-27 20:57:13.406024893 +0100
 @@ -0,0 +1,59 @@
 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
@@ -27361,5 +27629,5 @@
 diff -ruN ../netqmail-1.06-original/spawn-filter.9 netqmail-1.06/spawn-filter.9
 --- ../netqmail-1.06-original/spawn-filter.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/spawn-filter.9	2016-11-22 21:03:57.128527565 +0100
++++ netqmail-1.06/spawn-filter.9	2019-02-27 20:57:13.406024893 +0100
 @@ -0,0 +1,103 @@
 +.TH spawn-filter 8
@@ -27468,6 +27736,6 @@
 diff -ruN ../netqmail-1.06-original/spawn-filter.c netqmail-1.06/spawn-filter.c
 --- ../netqmail-1.06-original/spawn-filter.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/spawn-filter.c	2016-11-22 21:03:57.128527565 +0100
-@@ -0,0 +1,546 @@
++++ netqmail-1.06/spawn-filter.c	2020-04-09 19:45:45.390398843 +0200
+@@ -0,0 +1,506 @@
 +/*
 + * netqmail-version without spam filter
@@ -27635,30 +27903,8 @@
 +static int      run_mailfilter(char *, char *, char **);
 +int             wildmat_internal(char *, char *);
-+static int      check_size(char *);
 +
 +static int      remotE;
 +stralloc        sender = { 0 };
 +stralloc        recipient = { 0 };
-+
-+static int
-+check_size(char *size)
-+{
-+	char           *x;
-+	unsigned long   databytes = -1, msgsize;
-+
-+	if (!(x = env_get("DATABYTES")))
-+	{
-+		if (control_readulong(&databytes, "databytes") == -1)
-+			report(111, "spawn-filter: Unable to read databytes: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
-+	} else
-+		scan_ulong(x, &databytes);
-+	if (databytes == -1)
-+		return (0);
-+	scan_ulong(size, &msgsize);
-+	if (msgsize > databytes)
-+		return(1);
-+	else
-+		return(0);
-+}
 +
 +static void
@@ -27926,7 +28172,5 @@
 +main(int argc, char **argv)
 +{
-+	char           *ptr, *mailprog, *domain, *errStr = 0, *size = "0", *qqeh, *ext;
-+	char            sizebuf[FMT_ULONG];
-+	struct stat     statbuf;
++	char           *ptr, *mailprog, *domain, *ext;
 +	int             len;
 +
@@ -27939,16 +28183,9 @@
 +	{
 +		mailprog = "bin/qmail-local";
++		ext = argv[6];
 +		domain = argv[7];
-+		ext = argv[6];
-+		qqeh = argv[10];
 +		remotE = 0;
 +		if (!env_unset("QMAILREMOTE"))
 +			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
-+		if (!fstat(0, &statbuf)) 
-+		{
-+			sizebuf[fmt_ulong(sizebuf, statbuf.st_size)] = 0;
-+			size = sizebuf;
-+		} else
-+			size = "0";
 +		/*- sender */
 +		if (!stralloc_copys(&sender, argv[8]))
@@ -27956,14 +28193,11 @@
 +		if (!stralloc_0(&sender))
 +			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
-+		if (!env_unset("QMAILREMOTE"))
-+			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
 +		/*- recipient */
-+		if (*ext) /*- EXT */
-+		{
++		if (*ext) { /*- EXT */
 +			if (!stralloc_copys(&recipient, ext))
 +				report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
 +		} else /*- user */
-+			if (!stralloc_copys(&recipient, argv[2]))
-+				report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
++		if (!stralloc_copys(&recipient, argv[2]))
++			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
 +		if (!stralloc_cats(&recipient, "@"))
 +			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
@@ -27977,7 +28211,4 @@
 +		mailprog = "bin/qmail-remote";
 +		domain = argv[1];
-+		ext = argv[5];
-+		qqeh = argv[3];
-+		size = argv[4];
 +		remotE = 1;
 +		if (!env_unset("QMAILLOCAL"))
@@ -27989,5 +28220,5 @@
 +			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
 +		/*- recipient */
-+		if (!stralloc_copys(&recipient, argv[5]))
++		if (!stralloc_copys(&recipient, argv[3]))
 +			report(111, "spawn-filter: out of mem: ", error_str(errno), ". (#4.3.0)", 0, 0, 0);
 +		if (!stralloc_0(&recipient))
@@ -28000,7 +28231,4 @@
 +	if (chdir(auto_qmail) == -1)
 +		report(111, "spawn-filter: Unable to switch to ", auto_qmail, ": ", error_str(errno), ". (#4.3.0)", 0);
-+	/*- DATABYTES Check */
-+	if (check_size(size))
-+		report(100, "sorry, that message size exceeds my databytes limit (#5.3.4)", 0, 0, 0, 0, 0);
 +	run_mailfilter(domain, mailprog, argv);
 +	report(111, "spawn-filter: could not exec ", mailprog, ": ", error_str(errno), ". (#4.3.0)", 0);
@@ -28018,5 +28246,5 @@
 diff -ruN ../netqmail-1.06-original/spawn.c netqmail-1.06/spawn.c
 --- ../netqmail-1.06-original/spawn.c	2007-11-30 21:22:54.000000000 +0100
-+++ netqmail-1.06/spawn.c	2016-11-22 21:03:57.128527565 +0100
++++ netqmail-1.06/spawn.c	2019-02-27 20:57:13.407024882 +0100
 @@ -1,4 +1,4 @@
 -#include <sys/types.h>
@@ -28097,5 +28325,5 @@
 diff -ruN ../netqmail-1.06-original/spf.c netqmail-1.06/spf.c
 --- ../netqmail-1.06-original/spf.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/spf.c	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/spf.c	2019-02-27 20:57:13.407024882 +0100
 @@ -0,0 +1,877 @@
 +#include "stralloc.h"
@@ -28978,5 +29206,5 @@
 diff -ruN ../netqmail-1.06-original/spf.h netqmail-1.06/spf.h
 --- ../netqmail-1.06-original/spf.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/spf.h	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/spf.h	2019-02-27 20:57:13.407024882 +0100
 @@ -0,0 +1,20 @@
 +#ifndef SPF_H
@@ -29002,5 +29230,5 @@
 diff -ruN ../netqmail-1.06-original/spfquery.c netqmail-1.06/spfquery.c
 --- ../netqmail-1.06-original/spfquery.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/spfquery.c	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/spfquery.c	2019-02-27 20:57:13.407024882 +0100
 @@ -0,0 +1,84 @@
 +#include "substdio.h"
@@ -29090,5 +29318,5 @@
 diff -ruN ../netqmail-1.06-original/srs.c netqmail-1.06/srs.c
 --- ../netqmail-1.06-original/srs.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/srs.c	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/srs.c	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,166 @@
 +#include <sys/types.h>
@@ -29260,5 +29488,5 @@
 diff -ruN ../netqmail-1.06-original/srs.h netqmail-1.06/srs.h
 --- ../netqmail-1.06-original/srs.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/srs.h	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/srs.h	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,9 @@
 +#ifndef SRS_H
@@ -29273,5 +29501,5 @@
 diff -ruN ../netqmail-1.06-original/srsfilter.c netqmail-1.06/srsfilter.c
 --- ../netqmail-1.06-original/srsfilter.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/srsfilter.c	2016-11-22 21:03:57.129527532 +0100
++++ netqmail-1.06/srsfilter.c	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,137 @@
 +#include "sig.h"
@@ -29414,6 +29642,7 @@
 diff -ruN ../netqmail-1.06-original/ssl_timeoutio.c netqmail-1.06/ssl_timeoutio.c
 --- ../netqmail-1.06-original/ssl_timeoutio.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/ssl_timeoutio.c	2016-11-22 21:03:57.129527532 +0100
-@@ -0,0 +1,95 @@
++++ netqmail-1.06/ssl_timeoutio.c	2020-01-10 21:51:32.057157279 +0100
+@@ -0,0 +1,126 @@
++#ifdef TLS
 +#include "select.h"
 +#include "error.h"
@@ -29488,7 +29717,35 @@
 +int ssl_timeoutrehandshake(int t, int rfd, int wfd, SSL *ssl)
 +{
-+  int r;
-+
-+  SSL_renegotiate(ssl);
++  int r=0;
++
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L
++  if (SSL_version(ssl) >= TLS1_3_VERSION){
++    if(SSL_verify_client_post_handshake(ssl) != 1)
++      return -EPROTO;
++  } else
++#endif
++  {
++    r =  SSL_renegotiate(ssl);
++    if (r<=0) return r;
++  }
++
++#if OPENSSL_VERSION_NUMBER >= 0x10001000L
++  char buf[1]; /* dummy read buffer */
++  struct timeval tv;
++  fd_set fds;
++  r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
++  if (r <=0) return r;
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L
++  if (SSL_version(ssl) >= TLS1_3_VERSION) return r;
++#endif
++
++  tv.tv_sec = (time_t)t; tv.tv_usec = 0;
++  FD_ZERO(&fds);  FD_SET(rfd, &fds);
++  if ((r = select(rfd + 1, &fds, NULL, NULL, &tv)>0) && FD_ISSET(rfd, &fds)){
++    r = SSL_read(ssl, buf, 1);
++    if (SSL_get_error(ssl, r) == SSL_ERROR_WANT_READ) r = 1; /*ignore */
++  }
++  if (r <=0) return r;
++#else
 +  r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
 +  if (r <= 0 || ssl->type == SSL_ST_CONNECT) return r;
@@ -29496,4 +29753,5 @@
 +  /* this is for the server only */
 +  ssl->state = SSL_ST_ACCEPT;
++#endif
 +  return ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
 +}
@@ -29511,7 +29769,8 @@
 +  return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len);
 +}
++#endif
 diff -ruN ../netqmail-1.06-original/ssl_timeoutio.h netqmail-1.06/ssl_timeoutio.h
 --- ../netqmail-1.06-original/ssl_timeoutio.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/ssl_timeoutio.h	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/ssl_timeoutio.h	2019-04-07 13:05:52.192763950 +0200
 @@ -0,0 +1,21 @@
 +#ifndef SSL_TIMEOUTIO_H
@@ -29521,6 +29780,6 @@
 +
 +/* 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"
++#if OPENSSL_VERSION_NUMBER < 0x00908000L
++# error "Need OpenSSL version at least 0.9.8"
 +#endif
 +
@@ -29538,5 +29797,5 @@
 diff -ruN ../netqmail-1.06-original/str.h netqmail-1.06/str.h
 --- ../netqmail-1.06-original/str.h	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/str.h	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/str.h	2019-02-27 20:57:13.408024870 +0100
 @@ -2,6 +2,11 @@
  #define STR_H
@@ -29565,5 +29824,5 @@
 diff -ruN ../netqmail-1.06-original/str_cpyb.c netqmail-1.06/str_cpyb.c
 --- ../netqmail-1.06-original/str_cpyb.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/str_cpyb.c	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/str_cpyb.c	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,53 @@
 +/*
@@ -29622,5 +29881,5 @@
 diff -ruN ../netqmail-1.06-original/str_cspn.c netqmail-1.06/str_cspn.c
 --- ../netqmail-1.06-original/str_cspn.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/str_cspn.c	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/str_cspn.c	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,40 @@
 +/*
@@ -29666,5 +29925,5 @@
 diff -ruN ../netqmail-1.06-original/strpidt.c netqmail-1.06/strpidt.c
 --- ../netqmail-1.06-original/strpidt.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/strpidt.c	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/strpidt.c	2019-02-27 20:57:13.408024870 +0100
 @@ -0,0 +1,26 @@
 +/*
@@ -29696,5 +29955,5 @@
 diff -ruN ../netqmail-1.06-original/strsalloc.c netqmail-1.06/strsalloc.c
 --- ../netqmail-1.06-original/strsalloc.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/strsalloc.c	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/strsalloc.c	2019-02-27 20:57:13.409024860 +0100
 @@ -0,0 +1,7 @@
 +#include "alloc.h"
@@ -29707,5 +29966,5 @@
 diff -ruN ../netqmail-1.06-original/strsalloc.h netqmail-1.06/strsalloc.h
 --- ../netqmail-1.06-original/strsalloc.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/strsalloc.h	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/strsalloc.h	2019-02-27 20:57:13.409024860 +0100
 @@ -0,0 +1,12 @@
 +#ifndef STRSALLOC_H
@@ -29723,5 +29982,5 @@
 diff -ruN ../netqmail-1.06-original/strtimet.c netqmail-1.06/strtimet.c
 --- ../netqmail-1.06-original/strtimet.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/strtimet.c	2016-11-22 21:03:57.130527499 +0100
++++ netqmail-1.06/strtimet.c	2019-02-27 20:57:13.409024860 +0100
 @@ -0,0 +1,26 @@
 +/*
@@ -29753,6 +30012,6 @@
 diff -ruN ../netqmail-1.06-original/surblfilter.9 netqmail-1.06/surblfilter.9
 --- ../netqmail-1.06-original/surblfilter.9	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/surblfilter.9	2016-11-22 21:03:57.130527499 +0100
-@@ -0,0 +1,80 @@
++++ netqmail-1.06/surblfilter.9	2019-06-19 09:49:02.553441531 +0200
+@@ -0,0 +1,82 @@
 +.TH surblfilter 8
 +.SH NAME
@@ -29789,4 +30048,5 @@
 +whitelist recipients by having the email addresses in \fIsurblrcpt\fR control file. You can
 +change the name of this control file by setting \fBSURBLRCPT\fR environment variable.
++
 +.PP
 +\fBsurblfilter\fR uses the control file \fIsurbldomainwhite\fR to whitelist a domain.
@@ -29797,8 +30057,9 @@
 +
 +.PP
-+\fBsurblfilter\fR caches results in QMAILHOME/control/cache. The filename represents the domain.
-+If a file as permission 0600, it means that the domain was blacklisted. The entries are
-+cached for a default of 300 seconds. You can change this by setting \fIcachelifetime\fR
-+control file. This directory should be owned by the uid set for running qmail-smtpd(8).
++\fBsurblfilter\fR caches results in @controldir@/cache directory. The filename of files in this
++directory represents the domain. If a file has permission 0600, it means that the domain was
++blacklisted. The entries are cached for a default of 300 seconds. You can change this by
++setting \fBCACHELIFETIME\fR environment variable or setting this value in \fBcacheliftime\fR
++control file. The cache directory should be owned by the uid of the running qmail-smtpd(8).
 +
 +\fBsurblfilter\fR removes all leading host names, subdomains, www., randomized subdomains, etc. In
@@ -29837,6 +30098,6 @@
 diff -ruN ../netqmail-1.06-original/surblfilter.c netqmail-1.06/surblfilter.c
 --- ../netqmail-1.06-original/surblfilter.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/surblfilter.c	2017-05-10 21:54:26.719100696 +0200
-@@ -0,0 +1,881 @@
++++ netqmail-1.06/surblfilter.c	2020-04-09 19:46:02.374231173 +0200
+@@ -0,0 +1,882 @@
 +/*
 + * $Log: surblfilter.c,v $
@@ -30058,24 +30319,24 @@
 +dns_text(char *dn)
 +{
-+        u_char          response[PACKETSZ + PACKETSZ + 1];      /* response */
++	u_char          response[PACKETSZ + PACKETSZ + 1];	/* response */
 +	int             responselen;			/* buffer length */
-+	int             rc;				/* misc variables */
++	int             rc;						/* misc variables */
 +	int             ancount, qdcount;		/* answer count and query count */
 +	u_short         type, rdlength;			/* fields of records returned */
 +	u_char         *eom, *cp;
-+	u_char          buf[PACKETSZ + 1];		/* we're storing a TXT record here, not just a DNAME */
++	u_char          buf[PACKETSZ + PACKETSZ + 1];		/* we're storing a TXT record here, not just a DNAME */
 +	u_char         *bufptr;
 +
-+        for (rc = 0, responselen = PACKETSZ;rc < 2;rc++) {
-+                if ((responselen = res_query(dn, C_IN, T_TXT, response, responselen)) < 0) {
-+                        if (h_errno == TRY_AGAIN)
-+                                return strdup("e=temp;");
-+                        else
-+                                return strdup("e=perm;");
-+                }
-+                if (responselen <= PACKETSZ)
-+                        break;
++	for (rc = 0, responselen = PACKETSZ;rc < 2;rc++) {
++		if ((responselen = res_query(dn, C_IN, T_TXT, response, responselen)) < 0) {
++			if (h_errno == TRY_AGAIN)
++				return strdup("e=temp;");
++			else
++				return strdup("e=perm;");
++		}
++		if (responselen <= PACKETSZ)
++			break;
 +		else
-+                if (responselen >= (2 * PACKETSZ))
++		if (responselen >= (2 * PACKETSZ))
 +			return strdup("e=perm;");
 +	}
@@ -30108,5 +30369,5 @@
 +
 +			cnt = *cp++;		/* http://crynwr.com/rfc1035/rfc1035.html#3.3.14. */
-+                        if (bufptr - buf + cnt + 1 >= (2 * PACKETSZ))
++			if (bufptr - buf + cnt + 1 >= (2 * PACKETSZ))
 +				return strdup("e=perm;");
 +			if (cp + cnt > eom)
@@ -30200,5 +30461,5 @@
 +		return (-1);
 +	}
-+	if (!stralloc_copys(&cachefile, "control/cache", 13))
++	if (!stralloc_copyb(&cachefile, "control/cache", 13))
 +		die_nomem();
 +	if (!stralloc_0(&cachefile))
@@ -30720,7 +30981,8 @@
 +	x++;
 +}
++
 diff -ruN ../netqmail-1.06-original/surblqueue.sh netqmail-1.06/surblqueue.sh
 --- ../netqmail-1.06-original/surblqueue.sh	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/surblqueue.sh	2016-11-22 21:03:57.131527465 +0100
++++ netqmail-1.06/surblqueue.sh	2019-02-27 20:57:13.409024860 +0100
 @@ -0,0 +1,33 @@
 +#!/bin/sh
@@ -30759,5 +31021,5 @@
 diff -ruN ../netqmail-1.06-original/tai.h netqmail-1.06/tai.h
 --- ../netqmail-1.06-original/tai.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/tai.h	2016-11-22 21:03:57.131527465 +0100
++++ netqmail-1.06/tai.h	2019-02-27 20:57:13.409024860 +0100
 @@ -0,0 +1,34 @@
 +/*
@@ -30797,5 +31059,5 @@
 diff -ruN ../netqmail-1.06-original/tcp-env.c netqmail-1.06/tcp-env.c
 --- ../netqmail-1.06-original/tcp-env.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/tcp-env.c	2016-11-22 21:03:57.131527465 +0100
++++ netqmail-1.06/tcp-env.c	2019-02-27 20:57:13.410024849 +0100
 @@ -10,6 +10,7 @@
  #include "scan.h"
@@ -30844,7 +31106,19 @@
         case_lowers(remotename.s);
         if (!env_put2("TCPREMOTEHOST",remotename.s)) die();
+diff -ruN ../netqmail-1.06-original/time_t_size.c netqmail-1.06/time_t_size.c
+--- ../netqmail-1.06-original/time_t_size.c	1970-01-01 01:00:00.000000000 +0100
++++ netqmail-1.06/time_t_size.c	2019-05-23 15:12:30.140092743 +0200
+@@ -0,0 +1,8 @@
++#include <stdio.h>
++#include <time.h>
++int
++main()
++{
++	printf("#define SIZEOF_TIME_T %d\n", sizeof(time_t));
++	return (0);
++}
 diff -ruN ../netqmail-1.06-original/timeoutconn.c netqmail-1.06/timeoutconn.c
 --- ../netqmail-1.06-original/timeoutconn.c	1998-06-15 12:53:16.000000000 +0200
-+++ netqmail-1.06/timeoutconn.c	2016-11-22 21:03:57.131527465 +0100
++++ netqmail-1.06/timeoutconn.c	2019-02-27 20:57:13.410024849 +0100
 @@ -10,9 +10,10 @@
  #include "byte.h"
@@ -30875,6 +31149,7 @@
 diff -ruN ../netqmail-1.06-original/tls.c netqmail-1.06/tls.c
 --- ../netqmail-1.06-original/tls.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/tls.c	2016-11-22 21:03:57.131527465 +0100
-@@ -0,0 +1,25 @@
++++ netqmail-1.06/tls.c	2019-04-09 20:56:31.139694929 +0200
+@@ -0,0 +1,27 @@
++#ifdef TLS
 +#include "exit.h"
 +#include "error.h"
@@ -30902,7 +31177,8 @@
 +  return (errno == error_timeout) ? "timed out" : error_str(errno);
 +}
++#endif
 diff -ruN ../netqmail-1.06-original/tls.h netqmail-1.06/tls.h
 --- ../netqmail-1.06-original/tls.h	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/tls.h	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/tls.h	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,16 @@
 +#ifndef TLS_H
@@ -30924,5 +31200,5 @@
 diff -ruN ../netqmail-1.06-original/tryulong64.c netqmail-1.06/tryulong64.c
 --- ../netqmail-1.06-original/tryulong64.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/tryulong64.c	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/tryulong64.c	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,47 @@
 +/*
@@ -30975,5 +31251,5 @@
 diff -ruN ../netqmail-1.06-original/uint64.h1 netqmail-1.06/uint64.h1
 --- ../netqmail-1.06-original/uint64.h1	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/uint64.h1	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/uint64.h1	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,12 @@
 +/*
@@ -30991,5 +31267,5 @@
 diff -ruN ../netqmail-1.06-original/uint64.h2 netqmail-1.06/uint64.h2
 --- ../netqmail-1.06-original/uint64.h2	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/uint64.h2	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/uint64.h2	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,12 @@
 +/*
@@ -31007,5 +31283,5 @@
 diff -ruN ../netqmail-1.06-original/update_tmprsadh.sh netqmail-1.06/update_tmprsadh.sh
 --- ../netqmail-1.06-original/update_tmprsadh.sh	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/update_tmprsadh.sh	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/update_tmprsadh.sh	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,22 @@
 +#!/bin/sh
@@ -31033,5 +31309,5 @@
 diff -ruN ../netqmail-1.06-original/wildmat.c netqmail-1.06/wildmat.c
 --- ../netqmail-1.06-original/wildmat.c	1970-01-01 01:00:00.000000000 +0100
-+++ netqmail-1.06/wildmat.c	2016-11-22 21:03:57.132527432 +0100
++++ netqmail-1.06/wildmat.c	2019-02-27 20:57:13.410024849 +0100
 @@ -0,0 +1,173 @@
 +/*-** wildmat.c.orig	Wed Dec  3 11:46:31 1997
