G. Pape

qconfirm - How it works

Handling incoming mail messages
Handling outgoing mail messages

Incoming mail messages

The qconfirm-check program processes incoming mail messages on local delivery, and conditionally requests a delivery confirmation from the sender. It operates either sender-based, or message-based.

Sender mode

qconfirm-check checks for each message if the envelope sender of this message is allowed to send mail to the user owning the .qmail file it was invoked from.

If qconfirm-check already knows this envelope sender, or was told to accept mails from this sender, it immediately exits with 0, and so allows the mail to be processed further in the .qmail file. If not, qconfirm-check injects a confirmation request message to the envelope sender asking for a reply, and exits 111 to defer the message temporarily. The message will stay in the qmail queue and will be tried to be delivered in a little while.

qconfirm-check then defers this message on future delivery attempts and all other messages from the same envelope sender temporarily without injecting another confirmation request message until a reply to the confirmation request message is received (Exception: see the -t option). If queuelifetime has expired for a message before a reply to the confirmation request was received, the message is bounced and never delivered to the recipient.

Envelope sender address id

To check if the envelope sender is allowed, qconfirm-check creates an id based on the envelope sender mail address as follows:

The sender mail address is split into two parts, the local part and the host part. For example if the sender mail address is floyd@smarden.org, the local part is floyd, the host part is smarden.org. These two parts are concatenated in reverse order with a "=-" in between, any uppercase letter is converted to lowercase, and finally each dot, slash, and apostrophe is replaced by a colon. So the id for floyd@smarden.org is smarden:org=-floyd.

Matching envelope sender address id

qconfirm-check matches the id created from the envelope sender address against a file in the directory ~/.qconfirm/ok/ the same way qmail matches .qmail files for extension addresses. For example, the address floyd-extension@smarden.org with the id smarden:org=-floyd-extension is matched by the following files in the ~/.qconfirm/ok/ directory:
If at least one of these files exists in the ~/.qconfirm/ok/ directory, the message is allowed to be processed further in the .qmail file. If qconfirm-check runs with the -b option, the same matching takes place for the .qconfirm/bad/ directory.

Extended envelope sender domain matching

qconfirm-check by default additionally checks the host part of the id with a wild-card similar to qmail-smtpd's rcpthosts. For example, the address floyd-list@list.smarden.org with the id list:smarden:org=-floyd-list is matched by the following files:
Extended domain matching is applied after matching the envelope sender address id.

Sending the confirmation request

If the envelope sender isn't matched to be allowed, qconfirm-check creates a random key, creates a file with the filename "id" in the ~/.qconfirm/pending/ directory containing the key, and creates a .qmail-qconfirm-key file in the user's home directory to handle the reply to the confirmation request. qconfirm-check injects the confirmation request message to the envelope sender address with the from header user-qconfirm-key@host.

qconfirm-check creates a special Message-ID for the confirmation request message it sends so that delivery confirmation request message can be processed automatically. The Message-ID is constructed using the Message-ID of the mail message the delivery confirmation is requested for, by prepending the string ``confirm-'', and appending the host part of the mail address qconfirm is configured for. E.g.: qconfirm runs for <floyd@smarden.org> and sends a delivery confirmation request message for a message with the Message-ID <abcde@sender.mid>. The Message-ID of the confirmation request message is <confirm-abcde@sender.mid@smarden.org>.

Handling the reply to the confirmation request

The reply to the confirmation request messages goes to the address user-qconfirm-key@host and so is handled by the .qmail-qconfirm-key file. qconfirm-check automatically has set up a program delivery to qconfirm-accept in this .qmail file. So if a mail to this address is received, qconfirm-accept is invoked. qconfirm-accept then moves the file with the filename "id" from the ~/.qconfirm/pending/ directory to the ~/.qconfirm/ok/ directory, writes the message (the reply to the confirmation request) to this file, and removes the .qmail-qconfirm-key file it was invoked from.

The next time qmail tries to deliver a temporarily deferred or a new message from this envelope sender, qconfirm-check matches the sender to be allowed and allows the message to be processed further in the .qmail file. If the file in the ~/.qconfirm/ok/ directory that matched the envelope sender is not empty, qconfirm-check optionally injects a confirmation acknowledgement message to the envelope sender, including the contents of the file at the bottom of the message, and then truncates this file to the size 0.

Handling bounces from confirmation requests

qconfirm can be configured to process bounces from confirmation request messages, and so to reduce the amount of doublebounces reaching the postmaster's mailboxes. See Handling bounce messages for details.

Message mode

If qconfirm-check is running in message mode, each single message must go through the confirmation process. The id qconfirm-check uses for identifying a message is not created from the envelope sender but is the inode number of the message stored in the qmail mail queue.

Outgoing mail messages

Additionally to configuring qconfirm-check to handle local delivery to a mailbox, it's possible to configure the qconfirm-inject program for sending mail originated from the mail address qconfirm is running for. qconfirm-inject overrides the envelope sender address and Message-ID of an outgoing mail message so that delivery notification (bounces) for this mail are handled through the qconfirm-notice program, and follow-ups can be detected by qconfirm-check-mid, and so accepted without requesting a delivery confirmation.

The qconfirm-notice program can validate delivery notifications, is capable of detecting delivery confirmation request messages, and automatically confirming delivery on such requests.

Envelope sender

qconfirm-inject overrides the envelope sender of outgoing mail messages with a variable envelope return path (VERP). E.g., if floyd@smarden.org has configured qconfirm for outgoing mail, and sends a mail message to <burdon@example.org> through qconfirm-inject, the envelope sender will be set to <floyd-qnotice-xxxxxxx-burdon=example.org@smarden.org>, where xxxxxxx is a seven characters long random string.

A dot-qmail file with a program delivery to qconfirm-notice has been set up to handle delivery notification messages to such addresses.

Whenever qconfirm-notice processes a delivery notification message, it check if the dot-qmail file it was invoked from is in use for long enough. If so, qconfirm-notice creates a new seven characters long random string, creates a new dot-qmail file with this random string, and tells qconfirm-inject to use the new random string from now on. Obsolete dot-qmail files for delivery notifications are removed automatically.


qconfirm-inject overrides the Message-ID of outgoing mail messages. The Message-ID's host part contains two random strings, one for qconfirm-check-mid to detect follow-ups, and one for qconfirm-notice to reliably identify delivery confirmation request messages.

The configuration file conf/QCONFIRM_MID has been set up in the qconfirm directory, containing the seven characters long random string to detect follow-ups. A 14 characters long random string to identify confirmation request messages is created for each outgoing message.

qconfirm-inject keeps track of the Message-IDs of mail messages it has sent in the .qconfirm/notice/ directory for some time. qconfirm-notice checks the Message-IDs of potential configuration request messages against files on this directory before sending a delivery confirmation message.

Gerrit Pape <pape@smarden.org>
$Id: technical.html,v 1.12 2003/11/29 11:42:33 pape Exp $