Some of what is said about qmail is wrong.

You've come to this page because you've made an erroneous claim about Dan Bernstein's qmail, similar to one (or more) of the following précis (which are expanded in full further on):

These are the Frequently Given Answers to these claims.

These claims are highly inaccurate.

The myth about supporting bare LFs being a requirement

Postel's Robustness Principle states that one should be "liberal in what [one] accept[s], and conservative in what [one] send[s]". qmail-smtpd violates this by not accepting message bodies that contain "bare" linefeed characters (i.e. ones without a preceding carriage return character). This causes interoperability problems and is wrong.

In fact, qmail is avoiding interoperability problems and is right.

This myth directly contradicts RFC 2821 § 2.3.7, which is unequivocal and explicit on how SMTP servers are required to behave:

SMTP commands and [...] message data, are transmitted in "lines". Lines consist of zero or more data characters terminated by the sequence ASCII character CR (hex value 0D) followed immediately by ASCII character LF (hex value 0A). [...] Conforming implementations MUST NOT recognize or generate any other character or character sequence as a line terminator.

So, first of all, if qmail-smtpd were to accept message data containing bare linefeeds, it would not be conformant with RFC 2821.

RFC 2821 is also reasonably clear (albeit somewhat understated) that it is the cases where bare linefeeds are silently accepted that the interoperability problems actually occur:

The custom of accepting lines ending only in LF, as a concession to non-conforming behavior on the part of some UNIX systems, has proven to cause more interoperability problems than it solves, and SMTP server systems MUST NOT do this, even in the name of improved robustness. In particular, the sequence LF.LF (bare line feeds, without carriage returns) MUST NOT be treated as equivalent to CRLF.CRLF as the end of mail data indication.

Far from creating interoperability problems, by enforcing the correct and only format for line termination in SMTP, qmail is actually avoiding them.

Silently handling SMTP Relay clients, that do not implement the protocol correctly, is actually a cause of problems rather than a solution for them. As has been pointed out by many others, Gresham's Law trumps Postel's Principle. Accommodating different line termination sequences in clients (which can only be done heuristically) leads to correct server implementations being driven out by incorrect ones.

Moreover, such accommodation leads to data corruption. Data that would, by a correct implementation of the protocol, be transferred exactly as they stand are instead converted, by the incorrect Postel Principle implementations, into different data as they are (erroneously) taken to be line termination sequences. (For example: Bare CRs in message data that do not represent the ends of lines are corrupted by being converted into CRLF sequences by Postel Principle implementations that attempt to accommodate one particular kind of broken client.)

Furthermore, employing heuristics to spot non-conforming line termination sequences introduces the risk of false positives when detecting the end of mail data indication, which will result in truncation of the message and may also (in some cases) result in spurious extra messages and actions. (For example: Consider a message whose body just happens to contain a message data terminator and a series of SMTP commands, all delimited by bare LFs.) With servers that implement the protocol incorrectly, using such heuristics, a client has no knowledge of exactly what any particular server will take to be a line termination sequence, and so has no way to correctly perform the necessary "dot stuffing" on any sequence that might possibly be recognised by the server as the end of mail data indicator. With correct implementations, however, "dot stuffing" is symmetric and reliable.

Randall C. Gellens <RANDY@MPA15AB.MV.UNISYS.COM> writing on the IETF's discussion forum for SMTP expressed these points (and more) succinctly:

Patching conforming implementations to adapt to broken ones propagates garbage.

Mark Crispin <MRC@CAC.Washington.EDU> writing in the Usenet alt.comp.qmail.misc newsgroup adds:

Actually, Postel's principle is misstated. I knew Jon personally. He never advocated forcing implementations to accept bogus protocol, and it is a perverson of Jon's legacy to claim otherwise.

A final note: It is ironic that RFC 1123, often quoted as the reference for Postel's Robustness Principle by proponents of this myth (even though RFC 793 is in fact the correct reference), actually itself describes the sort of "interoperability headache" that results if one is not strict about correct line termination sequences, in § 3.3 where it describes the interoperability problems caused by a multiplicity of line termination sequences in TELNET.

The myth about qmail-queue's Received: headers being non-standard

qmail-queue prepends to messages Received: headers that don't conform to the standard. This causes problems.

This myth is, simply, wrong. Its proponents clearly haven't read and understood the standards. Ironically, it is often they who are the real causes of the problems being referred to.

Contrary to the myth, qmail is in fact entirely conformant to the standards in this regard. The syntax for Received: headers is given in RFC 2822 § 3.6.7 as

received = "Received:" name-val-list ";" date-time CRLF
name-val-list = [CFWS] [name-val-pair *(CFWS name-val-pair)]
name-val-pair = item-name CFWS item-value
and Received: headers are described in the accompanying text as containing
a (possibly empty) list of name/value pairs followed by a semicolon and a date-time specification

Given both this and the definition of CFWS (from RFC 2822 § 3.2.3), a typical Received: header inserted by qmail-queue boils down to merely an empty list, a semi-colon, and a datestamp, such as

Received: ; 2003-07-11 04:07:01 +0000
since the other information is, syntactically, a comment that is parsed as being equivalent to whitespace. Such a header is syntactically correct according to the grammar.

The real causes of the problems alluded to are generally one of two categories of people:

The people in the second category often incorrectly require Received: headers to contain certain specific name/value pairs in a certain specific order, and complain about "errors" if they encounter Received: headers with the pairs in a different sequence, or Received: headers without the pairs that they are expecting, or Received: headers with no name/value pairs at all (despite the clear note in the standard that it is possible for the list of pairs to be empty).

In particular, they often erroneously think that only SMTP transactions may ever be the cause of Received: headers being prepended to messages, and so expect all Received: headers to contain from and by pairs, in that order. Sometimes they write SMTP Relay servers that reject messages that contain any Received: headers that do not meet these restrictions. (It is ironic, given the claim of this myth about lack of standards conformance, that whereas qmail does conform to standards, these SMTP Relay servers do not, because they are in clear violation of an explicit prohibition in RFC 2821 § 3.8.2.)

But, in fact, as RFC 822 § 4.3 states, the purpose of trace fields such as Received: headers is to provide an

audit trail of message handling
not merely to provide a list of the SMTP Relay servers that have received the message, as some of the proponents of this particular myth think. Not only is it legitimate to provide an audit trail that covers more of the message handling than just SMTP Relay receipt, but doing so is actually in line with the very intention of having trace fields.

qmail firmly embraces this intention. It provides an audit trail that not only includes trace information indicating receipt by an SMTP Relay server, but also provides details of the message handling within the MTS as well, allowing mail administrators to cross-check the audit trail in the message headers against process execution logs and system user ID databases if required.

Indeed, as many mail administrators who have had to trace message handling problems will attest, the detailed audit trail information that qmail provides in trace headers is very useful.

The myth about mailboxes that contain the '!' character

Mail to mailboxes containing '!' bounces into the admin mailbox.

This is one of the myths about qmail that ORBS published.

qmail does not bounce messages addressed to mailboxes containing the '!' character "into the admin mailbox". As any qmail user will tell you, it bounces them back to the envelope sender as undeliverable.

(This is unless, of course, you have very strange ideas about user naming, and actually have users with names containing '!'. In that case, qmail will deliver the messages to those users' mailboxes and not bounce them at all.)

This is what qmail does with all undeliverable messages. It's also the correct thing to do.

The myth about supposed "denial of service attacks"

qmail effectively issues a denial of service attack when it delivers mail.

This is another of the myths about qmail that ORBS published.

This myth, that qmail generates "denial of service attacks" by trying to open multiple SMTP connections to a single host when it has multiple messages to send to it, is almost too foolish for words. The default remote concurrency limit of qmail (which can be overridden, of course) is 20 simultaneous SMTP conversations across the board (i.e. in total). Any SMTP server that can be taken down by the simple expedient of making 20 simultaneous TCP connection requests to it (which presumes that qmail isn't delivering mail anywhere else and is concentrating upon that one server) shouldn't be connected to Internet at all.

It's also worth noting the irony that it is qmail that actually has such a remote concurrency control mechanism. Other MTS softwares have no such limits.

For example: exim, for example, as its manual explains, doesn't have a centralised queue manager like qmail does and so no centralised concurrency control mechanism. It only limits SMTP session concurrency within each individual delivery process. So if, say, 100 messages are separately injected into the system at once, then in the default "out of the box" configuration exim will run 100 separate parallel delivery processes, each performing a separate SMTP conversation with the target server.

In contrast, in its default "out of the box" configuration qmail will only open a maximum of 20 separate parallel SMTP conversations in such a situation.

In any case, transmitting queued mail is not a "denial of service". Rather, it is using the service for its intended purpose.


© Copyright 2003-2003 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp is preserved.