Subject: Re: Minutes from DRUMS WG, 42nd IETF

From: "D. J. Bernstein" <[email-masked]>
Date: 9 Oct 1998 00:01:05 -0000

Barry Leiba writes:
> At issue is whether
> implementations that always reply 252 to any VRFY command may be
> considered compliant.

The overwhelming majority opinion on the mailing list is ``Yes.''

> Consensus is for 821bis to specify that VRFY SHOULD (not MUST) be implemented

That permits always-return-252, right?

> Consensus is to leave QUIT as a "MUST send".

Unacceptable. There may be a disk error after DATA.

  [ RSET BLAH BLAH BLAH ]
> servers SHOULD reject them.

Absurd. Please read P. J. Plauger's essay on malloc().

> * There was discussion about allowing the underscore character in domain
>   names.  Currently the document says that servers MUST reject invalid 
>   characters in domain names.

This rule was never approved by DRUMS, so it must be removed.

> there is no consensus to change the 821bis spec.

You are implying by omission that there was no consensus _for_ the rule.
It is an abuse of power for the document editor to make changes without
DRUMS approval.

---Dan
1000 recipients, 28.8 modem, 10 seconds. http://pobox.com/~djb/qmail/mini.html

---

From: Eliot Lear <[email-masked]>
Date: Tue, 13 Oct 1998 12:01:14 -0700

> Unacceptable. There may be a disk error after DATA.

I think we need to be more specific.  I believe people had in mind the
case where that final <CRLF> "." <CRLF> had been sent, where the server
is safe to assume the message has been transmitted in its entirety, and
is awaiting other messages or a "QUIT".

> Absurd. Please read P. J. Plauger's essay on malloc().

What's absurd is your risky violation of an existing standard, and the
idea that you would promote such an idea.  But heck, it's your code. 
But rather than debate this point why don't you create an EHLO option
that allows you to do what you want to do, in a way that avoids
conflicting with standards?

> This rule was never approved by DRUMS, so it must be removed.

Nonsense.  Who is DRUMS, but the working group?

Anyway, the idea behind the rule was to restrict the client from
transmitting pure garbage.  Given Rob Elz's comments its pretty clear to
me that we need to rethink the wording.
--
Eliot Lear
[email-masked]

---

From: "D. J. Bernstein" <[email-masked]>
Date: 13 Oct 1998 22:58:18 -0000

> > > Currently the document says that servers MUST reject invalid

Please pay attention.

As I said, this rule was never approved by DRUMS.

What Leiba says in the ``minutes'' is that there wasn't consensus
_against_ the rule. This implies by omission that there also wasn't
consensus _for_ the rule. (Already clear from the list discussions.)

When there is no consensus, 821bis must match 821. It is an abuse of
power for the document editor to make changes without group approval.

---Dan

---

From: "D. J. Bernstein" <[email-masked]>
Date: 13 Oct 1998 22:48:24 -0000

Everyone agrees that it is a violation of RFC 821 for the client to send
"RSET ", or "RSET BLAH BLAH BLAH", or "MAIL FROM: <[email-masked]>".

However, RFC 821 does _not_ require that the server reject these things.
In reality, every server allows a wide variety of syntax extensions, to
reduce implementation costs and to interoperate with existing clients.

Everyone agrees that sending bad syntax should continue to be a
violation of 821bis. But there is certainly _not_ consensus that
_accepting_ bad syntax should be a violation of 821bis:

   220 mathieu.sendmail.com ESMTP Sendmail 8.9.1/8.9.1 ...
   RSET BLAH BLAH BLAH
   250 Reset state

From an engineering perspective, it makes no sense to require that
servers reject "RSET BLAH BLAH BLAH". There is no dispute that this
imposes implementation costs and deployment costs. The only alleged
benefit does not stand up under scrutiny; any future use of arguments
for RSET can be implemented just as easily under a different name.

According to Leiba's so-called ``minutes,'' the ``consensus'' at the
meeting was to change ``MUST reject'' to ``SHOULD reject.'' It isn't
clear from this brief description whether ``MAY reject'' was discussed.
``SHOULD reject'' is an absurd result in this situation, for the reasons
explained in P. J. Plauger's essay on malloc().

Eliot Lear writes:
> What's absurd is your risky violation of an existing standard,

You are fundamentally confused. I am not _sending_ RSET BLAH BLAH BLAH.
I am merely _accepting_ RSET BLAH BLAH BLAH, just like sendmail.

Please correct your mistakes for the record.

---Dan

---

From: Eliot Lear <[email-masked]>
Date: Tue, 20 Oct 1998 15:28:44 -0700

> You are fundamentally confused. I am not _sending_ RSET BLAH BLAH BLAH.

Then I stand corrected.  I also appreciate you clarifying your position.

Is it your position, therefore, that if one of the primary the goals of
the document is to encourage conformance to the standard, then
separating the grammars into send and accept is a mistake, given that it
forces the standards body to either accept bad behavior or require that
such behavior be rejected?
--
Eliot Lear
[email-masked]

---

From: "D. J. Bernstein" <[email-masked]>
Date: 23 Oct 1998 06:03:27 -0000

Eliot Lear writes:
> the document is to encourage conformance to the standard,

_My_ goal is to help future implementors.

> then separating the grammars into send and accept is a mistake,

Huh? Are you suggesting that the upper limits of safe message creation
are an exact match for the lower limits of safe message parsing?

That is factually incorrect. Interoperability problems exist.

(For example, some message generators will print the year 2000 as 100.
Some message parsers will be confused by that.)

As for ``grammars'': Competent writers don't put religious restrictions
on their writing tools.

> given that it

Telling implementors the truth doesn't mean ``accepting bad behavior.''

Furthermore, there is a big difference between _allowing_ implementors
to reject something and _requiring_ that they reject it.

---Dan

---

From: Robert Elz <[email-masked]>
Date: Sat, 24 Oct 1998 13:32:44 +1000

Date:        23 Oct 1998 06:03:27 -0000
    From:        "D. J. Bernstein" <[email-masked]>
    Message-ID:  <[email-masked]>

  | Furthermore, there is a big difference between _allowing_ implementors
  | to reject something and _requiring_ that they reject it.

Yes, there is, and it is fundamental.   Allowing implementors to reject
something means that in most cases they don't.   In practice that then
alows the other end to get away with something which is not quite legal
(or blatantly illegal) "no-one rejects this, so what is the harm?"
Then, when someone actually decides to enforce the restriction they're
permitted to enforce according to the standard, they suffer from being
incompatible with all of the other implementations that assume the rule
will not be enforced.

If we want genuine interoperability, so we don't keep having to document
all the hidden extras, the stuff that you have to know to actually make
an implementation that works in practice, we have exactly two options.

Either we allow the behaviour (make it legal), or we make it illegal
and require that that be enforced by conforming implementations (so
enough actually will enforce it that no-one can assume the rule doesn't
matter).

kre

---

From: "D. J. Bernstein" <[email-masked]>
Date: 24 Oct 1998 05:25:07 -0000

Robert Elz writes:
> something means that in most cases they don't.

Nobody does complete syntax checks in SMTP servers. Nobody ever will.
It's too expensive.

> In practice that then

The history of Internet mail interoperability problems does not support
your views.

For example, Windows CE didn't deliberately try to ``get away with''
unbracketed RCPT commands. Microsoft simply didn't know any better.

The solution is education. That's why I set up web pages explaining
SMTP, the header format, and Internet mail generally:

   http://pobox.com/~djb/proto/smtp.html
   http://pobox.com/~djb/proto/immhf.html
   http://pobox.com/~djb/proto/im.html

It's also possible to predict interoperability problems, and avoid them
during protocol design, by the principle discussed in

   http://pobox.com/~djb/proto/design.html

However, we're stuck with the SMTP design for the foreseeable future.

---Dan

---

From: Robert Elz <[email-masked]>
Date: Sun, 25 Oct 1998 03:55:25 +1100

Date:        24 Oct 1998 05:25:07 -0000
    From:        "D. J. Bernstein" <[email-masked]>
    Message-ID:  <[email-masked]>

  | For example, Windows CE didn't deliberately try to ``get away with''
  | unbracketed RCPT commands. Microsoft simply didn't know any better.

I didn't mean to imply that implementors would deliberately cheat,
but that they would make errors, and if those errors aren't detected
by their interoperability tests, then they don't get corrected early.
Once widely distributed, fixing them is too hard, it is generally
easier just to tell the few (must be only a few or the interop tests
would have discovered the problem earlier) who do enforce the rules
that they are going to have to relax to interoperate.

Education is certainly a partial answer, it will help, but it can
never solve this problem.  There are two many implementors, who,
pressed for time, implement by skimming the standards (and any other
doc) and implementing by guesswork and testing.   Further, we can
only educate about what we know about - a few years ago no-one would
have bothered telling people to stick the <> in RCPT TO, that was
just too obvious...    But if sendmail had checked that they were
present and rejected the address if not, there's no way a problem like
that could have been left unnoticed.

Last, almost all syntax checks are trivially cheap to include.   The
only costly part is making sure that you know what needs to be checked,
and if we have the standard expressly point out as much as we can, that
cost largely vanishes.   While there are undoutably implementation costs
associated with adding the extra code, it is mostly so insignificant as
to be irrelevant (checking for '<' and '>' in RCPT TO, or for a \r\n
immediately after RSET, etc, each takes one line, and one test case
to validate.)   Compared with the costs of ensuring stable storage for
queued messages, or doing the stray DNS lookups people do these days to
attempt to avoid spam, the run time costs of these checks are trivial.

kre

---

From: "D. J. Bernstein" <[email-masked]>
Date: 24 Oct 1998 19:41:00 -0000

Robert Elz writes:
> Last, almost all syntax checks are trivially cheap to include.

A complete syntax check is horrendously expensive.

You say that it takes one line of code to check for < and > after RCPT.
But what about hundreds of other ways to violate the SMTP syntax? You
aren't stopping _future_ interoperability problems.

I agree that Microsoft wouldn't have screwed up in an alternate universe
where sendmail checked for < and > after RCPT. But we don't live in that
universe! Adding those checks _now_ to sendmail doesn't fix the problem.
It exacerbates the problem.

> the run time costs of these checks

Computer time is a red herring. The issue is implementor time.

> There are two many implementors, who,
> pressed for time, implement by skimming the standards

So why do you keep making the problem worse? Time wouldn't be a problem
if the ``standards'' weren't full of garbage!

My web pages cover the same material as RFC 821 and RFC 822---plus many
more examples, descriptions of interoperability problems, and practical
advice---in half the space. The structure of the presentation matches
the structure of a typical implementation. The goal is to help future
implementors. I used to think that this was also the goal of DRUMS.

---Dan

---

From: [email-masked] (Kai Henningsen)
Date: 25 Oct 1998 11:28:00 +0200

> that they are going to have to relax to interoperate.

Here's an example of what happens (from the README of the berolist mailing  
list software):

> --enable-ntsmtp
> 	Use \r\n as newline in SMTP commands - some NT-based SMTP servers
> 	apparently require this, while a few others complain about it.
> 	Generally, if your SMTP server is running NT, you'll probably need
> 	this, if it's running something reasonable, you probably won't.

Aaargh!

MfG Kai

---

From: Robert Elz <[email-masked]>
Date: Mon, 26 Oct 1998 06:29:28 +1100

Date:        24 Oct 1998 19:41:00 -0000
    From:        "D. J. Bernstein" <[email-masked]>
    Message-ID:  <[email-masked]>

  | You say that it takes one line of code to check for < and > after RCPT.
  | But what about hundreds of other ways to violate the SMTP syntax? You
  | aren't stopping _future_ interoperability problems.

We are unlikely to stop every possible problem, that's true, but by being as
rigorous as we can in the spec, and strongly encouraging implementations to
enforce the spec (ie: adding MUST wherever we reasonably can) will certainly
help.

  | I agree that Microsoft wouldn't have screwed up in an alternate universe
  | where sendmail checked for < and > after RCPT. But we don't live in that
  | universe! Adding those checks _now_ to sendmail doesn't fix the problem.
  | It exacerbates the problem.

Yes, it would, but this thread wasn't about checking <> in RCPT TO, it was
about checking for \r\n after RSET (etc).   As best I can work it out, adding
those checks doesn't cause any kind of problem, and just might, sometime in the
future, prevent some kind of interoperability problem.

Even on <> I'd not object to putting in the spec a requirement to check
that they're present, but also adding a note adding that some popular
implementations will fail if you do (hence advising implementors right now
that actually doing it is probably not advisable) - the object being to
gradually be able to move towards correct behaviour.

  | Computer time is a red herring. The issue is implementor time.

Oh good, I'm glay we agree on that - from your previous message it wasn't
clear which you intended (so I had to cover both, I wasn't intending to
set up a straw man just to shoot it down - further, if anything, spending the
computer time is the harder to justify, that's the standard GIGO argument,
whether it is worth the run time cost to check for things which aren't supposed
to happen, and deal with them if they do, or whether it is better to allow
occasional bogus input to produce undefined behaviour - it is good that we
don't have to get into that one).

For implementor time we need to distinguish between individual implementor
time, and collective implementor time.   Personally, I consider the time
needed to be spent by any particular implementor to implement what ought be
checked by the implementation close to irrelevant - it is probably even
beneficial, as it forces the implementor to consider lots more border cases
than they migt otherwise.

What's more important is the collective implementation time - the time that
everyone needs to waste dealing with all the bogus implementation nonsense
that we get because implementors have been able to get away will all kinds of
trash, because other implementations didn't bother complaining about.
That's the true cost to worry about.

This would be a much smaller problem if we had a good e-mail (SMTP and 822)
reference implementation that everyone could test against.   Unfortunately,
the 821/822 "reference implementation" is sendmail, which is truly atrocious
for the task.  In its defence of course, sendmail was never intended to be a
reference implementation.

  | So why do you keep making the problem worse? Time wouldn't be a problem
  | if the ``standards'' weren't full of garbage!

I think you over-estimate the average programmer.   I know you work in an
academic environment, you must come into contact with average students.
I can't imagine that the US is too different from Australia there (esp as we
have a tendancy to copy almost anything form the US).   Just maybe Maths is
a little different (because of not being seen quite so much as a quick route
to a good income the way computing is), but here at least your average student
expects to be spoon fed (not the best ones, true, just the average ones).
They don't want to read anything more than they have to - no matter how
concise.   If there's a short-cut they see, they'll take it - anything to get
a result that seems to work with as little effort as possible.   That is
where your average implementor community comes from...

The way to force implementations to work correctly is to make them fail in
practice if they aren't correct.   If they fail, the implementor will be
forced to work out why, and fix it.   If they work (or seem to work), than
"that's close enough"...

kre

ps: Do recall that what I am arguing for is for the standard to say either one
of "servers MUST reject RSET with any parameters" or "servers MUST NOT object
to parameters on RSET".   I prefer the former, but it's a marginal thing.
What I want is predictable behaviour.    If you want to argue for the latter,
then go ahead, I won't be a part of that argument, others can participate if
they desire.   What I don't want is "servers can object or not object as it
suits them" (or "servers SHOULD check" or "servers MAY check").   (RSET
here means all of RSET DATA NOOP, and anything else similar that's around,
though I guess the rule could vary for the different commands).

---

From: Robert Elz <[email-masked]>
Date: Mon, 26 Oct 1998 06:42:11 +1100

Date:        Mon, 26 Oct 1998 06:29:28 +1100
    From:        Robert Elz <[email-masked]>
    Message-ID:  <[email-masked]>

I don't much like replying to my own messages, but I finally went and
looked at some of Dan's web pages...

What I said was...

  |   | So why do you keep making the problem worse? Time wouldn't be a problem
  |   | if the ``standards'' weren't full of garbage!
  | 
  | I think you over-estimate the average programmer.  ...
  | They don't want to read anything more than they have to - no matter how
  | concise.   If there's a short-cut they see, they'll take it ...

It seems I needn't have bothered, as Dan clearly agrees.   From one of
his web pages...

>> So you want to design a protocol?
>> I'll let you in on an evil secret: most implementors will never
>> read your spec. 

>> Instead, they'll look at some common examples and write the most
>> obvious code that works for those examples. 

Exactly.   I agree.   So exactly why would be not have a problem is the
standards weren't ``full of garbage'' ??   What we must have is for broken
code to fail to work, then it gets fixed by the implementors.

kre