logo
logo

Andrew Richards
• The Free Stuff!

qmail-verify (OLD VERSION - v1.22)

This version of qmail-verify is the subject of a security advisory: Please upgrade to the latest version instead

On this page: • Introduction   • License   • Status/Warranty   • Documentation   • Download   • Installation   • Setup / Configuration   • Migrating from realrcptto   • Compatibility   • Gotchas   • Security   • Programming Notes   • Archives

Introduction

This patchset adds a feature to qmail-smtpd's behaviour, enabled by environment variables: Each recipient specified in the SMTP session (RCPT command) may be verified to see if it is a valid address on the system. A new daemon, qmail-verify is used by qmail-smtpd to determine if addresses are valid; qmail-smtpd communicates with qmail-verify using UDP.

This is an update to Paul Jarc's realrcptto patch. The major changes are:

License

I have used Paul Jarc's code as a basis for this patchset. He raises no objections to this patch. In turn, he has used code from qmail (by Dan Bernstein), who has recently placed qmail in the public domain (see Dan's page on Information for Distributors).

Status / Warranty

No warranty, express or implied is given - USE THIS SOFTWARE ENTIRELY AT YOUR OWN RISK. You will need to satisfy yourself as to the suitability of this software before deploying it in a production environment.

Documentation

The documentation for this package consists of this web page and the included man pages (the qmail-smtpd man page is an updated version of the original):

Download

[NB old version] Version 1.22, is available in plaintext or gzipped (.gz), but note that this version is subject to a security advisory: Please use the latest version instead.

Installation

Proceed as follows:

Setup / Configuration

You need to setup a 'service' for qmail-verify.
You need to enable recipient verification in qmail-smtpd.

If you're comfortable with qmail, daemontools etc. you can probably just skim-read this section; if you need a bit more detail, then this section should provide it...

In detail:

Setting up qmail-verify as a 'service':

Enabling recipient verification in qmail-smtpd:

Migrating from realrcptto

It is fairly straightforward to move between these two approaches to recipient verification.

For qmail-verify to do any recipient verification, environment variables VERIFY or VERIFYDEFER must be enabled (exist).

Recipient verification with realrcptto (the version named qmail-1.03-realrcptto-2006.12.10.patch) is enabled by default. Additionally, QMAILRRTDENYALL can be used to modify its behaviour.

QMAILRRTDENYALL is similar to qmail-verify's VERIFYDEFER environment variable: Both invoke the same behaviour (refusal at DATA stage), but their setup is slightly different: QMAILRRTDENYALL needs to be set to 1, VERIFYDEFER just needs to be set.

If you're moving from realrcptto to qmail-verify, you should check your tcpserver cdb source file (if in use) (typically /etc/tcp.smtp):

Now rebuild the corresponding cdb file. Alternatively if you're not using a cdb file for tcpserver, you need to enable VERIFY in the tcpserver/qmail-smtpd startup script instead (or VERIFYDEFER if QMAILRRTDENYALL="1" is set in the script) to enable recipient verification (see above). Remember to rebuild your cdb file having made these changes.

Compatibility

Please let me know if you successfully install qmail-verify on systems not listed below (see the end of the installation section on this page).

Compatibility with qmail, netqmail: The qmail-verify patch should apply cleanly to the following:

Compatibility with Unix / Linux: qmail 1.03 / netqmail 1.05 / netqmail 1.06 with the qmail-verify patch has been reported to compile successfully on the following:

Linux:

Unix:

Compatibility with common patches: In trying a few typical qmail patches, I note that they may clash in qmail-smtpd.c, qmail-smtpd.8 or Makefile. In patches I looked at (inluding SMTP AUTH patches, qmail-virusscan and qmail-dk) this will mean some work to finish off the patching by hand: This is however pretty straightforward - alternatively that's bread & butter work for qmail consultants such as the author of this patchset...

Gotchas

If you have a qmail system using .qmail-default files for your domains, qmail-verify will consider all addresses in the domain 'valid' (since you have provided explicit delivery instructions for all the domain's addresses by using a .qmail-default). This includes products such as vpopmail - which may have .qmail-default files like:

| /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox

One workaround may be to remove .qmail-default files that are there purely to cause a bounce, instead leaving this task to qmail (and qmail-verify); but check that this doesn't confuse the back-end package.

Sean Newton gives an update here regarding vpopmail & qmail-admin: I just discovered yesterday that qmailadmin is one of the apps that cares a lot about .qmail-default files: It errors out when attempting to administer domains if it doesn't see a .qmail-default file. The fix was a few tweaks to user.c to make it treat the absence of .qmail-default as being equivalent to having read one that said " bounce-no-mailbox\n". The space and the \n are both significant. - find his patch for user.c here - "this will render a qmailadmin-1.2.11 tarball perfectly qmail-verify happy."

Security

Here are some notes relating to security with this patchset, these notes are unlikely to be exhaustive:

It is conceivable that an attacker or spammer could abuse a system patched using this patchset to mount dictionary attacks. To vary how a qmail-verify patched system responds, you should make sure you understand the difference between the VERIFY and VERIFYDEFER environment variables that control the behaviour of qmail-smtpd; the former is likely to be more attractive to an attacker/spammer.

On the other hand, with this patchset you have a greater degree of certainty that messages in the queue for local users are destined for real mailboxes.

This patchset deliberately splits the functionality of the original realrcptto patch such that the address verification part runs as a separate daemon, qmail-verify (running as root), with qmail-smtpd still able to run as user qmaild. This also means that the changes to qmail-smtpd are minimal.

There is no attempt made to check that the replies to the queries to qmail-verify are genuine: It is conceivable that an attacker might wish to generate spoof UDP replies to tell qmail-smtpd that an address is valid. For this to occur, the attacker would either need to be a 'local' user to generate such 'replies' on the loopback interface (default configuration), or qmail-verify would need to be running on an external interface. In the latter case it should be possible to block the qmail-verify port at a firewall.

All that said however, such an attack is of limited use, since qmail will still bounce the message at delivery time for an invalid recipient.

Programming Notes

I've tried to ensure that the changes to qmail-smtpd.c are minimal, this along with the desire to keep qmail-smtpd running as user qmaild forming the rationale behind updating the realrcptto patch.

Although I initially used pipes to split the functionality, I replaced this with a UDP client/server setup (with help from John Levine) which was simpler, cleaner and more flexible in how it can be deployed.

In the interests of future extensibility I've created a couple of new files with new functions that may be of use to other similar "call-out" type features. These files are sockbits.h, sockbits.c, udpbits.h, udpbits.c, the new functions being query_skt() and connect_udp(). With this structure it should also be more straightforward to replace UDP with (say) Unix domain sockets if that is preferred, either for qmail-verify functionality or for other call-out functions.

qmail-verify.c has some commented-out debug statements, primarily to show - if desired - where in the code qmail-verify decides that an address is valid or not.

qmail-verify.h has ADDR_NOK_TEMP defined, although at present this is not used. This is for possible future use, to indicate that an address is temporarily invalid.

John Levine added code to show the "Controlling user" which is useful for logging esp. from qmail-verify (it can also be enabled in verifyrcpt.c, you'll need to add e.g. eout statements). This doesn't trim trailing 'extension' components to the address, relating to .qmail-abc files - evident when using virtualdomains.

Archives

This link will take you to the newest version which also includes links to other versions.

This page last updated: AR, 13th May 2020.