Some open-source projects made by Frank DENIS.


A bridge between Qmail and the Sophos antivirus

The Qmail virus scanner (QScan) is a mail filter for Qmail that scans incoming messages using the Sophos Antivirus engine, immediately rejecting infected content.


qmail-smtpd and qmail-qmtpd feed qscan with two streams as data is received from a remote client:

After sanity checks, qscan spawns ripmime and qmail-queue-old. The message is read from qmail-smtpd and asynchronously dispatched to ripmime and qmail-queue-old.

ripmime fills /var/qmail/qscan/uid/ with found attachments, and qmail-queue-old stores the original data in a temporary queue.

ripmime is then killed, while qmail-queue-old stays on hold, waiting for envelope data.

If /var/qmail/scan/uid/ is not empty, the current concurrency is evaluated by reading the number of directories in /var/qmail/scan/ . If the concurrency is above the max one, the client is placed on hold until the number decreases. If the number is still high after one minute, a 99 error code (temporary error) is returned, so that the remote client will retry later. Please note that there’s a little race, as no locking is made when evaluating the number of active scanners. In a real world, it’s not harmful, and it keeps the code simple.

As soon as possible, the sweep virus scanned is spawned to walk into the /var/qmail/scan/uid directory. qscan read the output of the sweep command to check for alerts.

If a system call fails, or if a child unexpectedly dies, qscan removes the MIME extraction folder and exits with error code 99.

If a virus is reported, qscan send the report to syslog, removes the MIME extraction folder and exits with error code 39 (reported as a permanent error by qmail-smtpd) .

In both cases, an early closed pipe causes qmail-queue-old to clean its own queue.

If the message can safely be delivered, qscan transparently bridges the envelope from qmail-smtpd to qmail-queue-old.

Once the envelope has been fed, qmail-send is triggered and injects it in the Qmail’s todo queue.