[Top] [All Lists]

Re: rfc2821bis-01 Issue 18: Usability of 1yz replies

2007-04-23 12:26:59

Hector, thank you for wanting to dig further into the code. See below.

Hector Santos wrote:

Tony Hansen wrote:
In order to help put this issue to bed, I'd like to get more input from
actual SMTP deployments.

Are you looking for CONTINUATION or NON-CONTINUATION lines?

The issue is the *set* of response lines that come back in response to a
command. This consists of all CONTINUATION lines followed by one
NON-CONTINUATION lines. So the answer is "yes" to both.

But with Exim, per specification Exim definitely uses the first
*non-continuation* reply code. Below is the loop in the function
smtp_read_response() with loop break based on the first non-dash line
encountered. The behavior is also documented as such in the comment block:

You missed the most important piece of information, the END of the function:

return buffer[0] == okdigit;

THIS is where it determines which code is important. And buffer is
pointing at the BEGINNING of the concatenated list of all CONTINUATION
and the NON-CONTINUATION response lines.

Smail uses the *first* code.

Looking for source. Do you have a URL?

hMailServer appears to use the *first* code.

Per specification, it looks for the first NON-CONTINUATION reply code,
however, this code is buggy and shouldn't be included in your test.  It
only looks for hard coded "250" values and it only supports 1 extra
multiple line from what I can see.  This would be the least of its
problems.  Throw this one out.

We're both wrong on this one. The state machine of hMailServer *skips*
over *all* continuation lines. It then uses the reply code in the *last*
response line.

qmail uses the *first* code.

Yes it does - but it should noted it is doesn't care for continuation
lines which is obvious broken code and n violation of the formal
reply-code[sp] specification.

unsigned long smtpcode()
  unsigned char ch;
  unsigned long code;

  if (!stralloc_copys(&smtptext,"")) temp_nomem();

  get(&ch); code = ch - '0';
  get(&ch); code = code * 10 + (ch - '0');
  get(&ch); code = code * 10 + (ch - '0');
  for (;;) {
    if (ch != '-') break;   <---------- BREAK ON NON-DASH
    while (ch != '\n') get(&ch);
  while (ch != '\n') get(&ch);

  return code;  <--- return first code -- BROKEN CODE!

It simply isn't following specs.  Do you wish to encourage this behavior?

Excuse me: It's looping over all continuation lines, stopping on the
first non-continuation line, and then returning the code for those
response lines.

That is definitely following the spec that we've been arguing over. Yes,
it takes a couple of short cuts, only looking for the dash to decide if
it should continue or not and ignoring bad input lines that don't have
either a space or dash in the 4th character of the line, but otherwise
it's following the use-first-code interpretation of the specs.

postfix appears to use the *last* code.
jsmtp uses the *last* code.

Courier generally uses the *first* code. In some cases it actually
treats 1yz, 2yz and 3yz as equivalent and will totally miss any
subsequent 4yz/5yz.

What about the first non-continuation for its reply?

I repeat, it generally uses the *first* code in a multiline response. It
correctly stops when it reaches the non-continuation line, but it's the
*first* code that's important to it.

The use of the first response code appears to be used just as often as
the last response code. The codes in between seem to be universally

IMO, that is not a valid conclusion.

With the exception of one package (QMAIL) which is clearly violating
821/2821 formal specifications, at least one of the codes (hMailServer)
is very SMTP-buggy and is not worth any consideration.  You were
incorrect with Exim and it isn't clear if analysis  s considering mixed
non-continuation codes which is already conflictive with the
specification.  You also didn't analyze a good bit of other popular main
stream packages in the market, including none of the major MUAs which we
have tested.

As I said above, your analysis of both Exim and qmail is flawed; my
conclusions on those remains.

The MUAs are only one piece of the MUA->MTA->...->MTA->MDA SMTP flow.
That they tend to use the last code is a datapoint.

We've also heard about a couple other major MTAs, PMDF and Sun Messaging
Server, that use the first code.

My conclusions stand: there is code out there that is in popular use
that will BREAK if the reply code on the first continuation line is
different from the final non-continuation line.

Part of the rules we are following for moving to draft standard is that
we MUST look at how current code has interpreted the proposed standard.

In this particular case, allowing anything other than the same code for
the first continuation line and the last non-continuation line will
break code. Lots of the code.

Making it a SHOULD would allow future implementations to break lots of
code that exists today. That is not a viable output of moving to draft

IMO, his is precisely the reason why it should be SHOULD and not a

A MUST encourages broken code behavior by falsely encouraging poor
logic and pre 2821bis non-compliant logic that it is OK to read the
first code because there is NEW presumption that the codes will be

Calling the interpretation of using the first reply code "poor logic and
non-compliant" is an not borne out.

By using a MUST you are saying that FUTURE clients should use a
persistent reply code when in fact it is very conceivable that it
might encounter a failure.


The solution is quite simple - follow the 25 year old spec of looking
for the first non-continuation line.

Nothing has changed with respect to looking for the first
non-continuation line for when to stop looking for response lines.

Maybe Postels conservative/liberal axiom should apply:

    Servers SHOULD send persistent reply codes, however, clients
    SHOULD be aware for mixed reply codes scenarios and SHOULD
    only react to the first non-continuation reply code.

This is consistent with Postel's rule, it is consistent with past,
present and future considerations, backward compatible and it is not a
functional change on the specs. On the other hand, a MUST will attempt
to enforce change. The MUST should not imply that CLIENT should begin
enforcing persistent reply codes or just rely on the first line. It
encourage incorrect designs of not ignoring continuation lines.

The point again is that it has been POSSIBLE for 25 years and a MUST
would be changing that now and also encourage designs that may not be

A MUST will support and codify current behavior. A SHOULD will not and
can not. Therefore a MUST is necessary to move 2821bis to draft standard.

        Tony Hansen

<Prev in Thread] Current Thread [Next in Thread>