[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xmpp] the stream negotiation process



On Fri, Oct 23, 2009 at 1:08 AM, Peter Saint-Andre <stpeter at stpeter.im> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

My apologies for the long post...

On 10/21/09 8:45 AM, Peter Saint-Andre wrote:
> On 10/20/09 1:58 AM, Dave Cridland wrote:
>
> <snip/>
>
> Dave, let me see if I can summarize your perspective...

Because I am working to publish revised versions of 3920bis and 3921bis
by the I-D cutoff date on Monday, I shall assume that my summary is
accurate. :) 

> 1. Negotiation of all stream features is optional. If the receiving
> entity considers negotiation of a given feature to be mandatory, it will
> advertise only that feature; and if the initiating entity does not
> negotiate that feature (e.g., by attempting to send stanzas before it is
> allowed to do so), then the receiving entity will return an error to the
> initiating entity. Therefore, we have no need to specify over the wire
> if a given stream feature must be negotiated at any given stage of the
> stream negotiation process.

For TLS, we felt the need in RFC 3920 to define a method whereby the
server could flag negotiation of TLS as mandatory to negotiate ("MTN")
in order to enforce local service policies. The discussions since then
have always assumed that we need a way to flag (some) features as MTN.

And that's the assumption being questioned here :-)
 
The thread here has attempted to define MTN in a standardized way,
rather than assuming that MTN will be explicit in the definition of some
features (TLS) but not others (everything else), implicit in the
definition of a given feature (SASL is always mandatory) or implicit via
the inclusion of a given feature and only that feature at a particular
point in the stream negotiation process (what Mr. Cridland appears to be
suggesting).

I think the following are very different:

(a) As the first stream features, inform the initating entity that TLS
is MTN.

  <stream:features>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
      <required/>
    </starttls>
  </stream:features>

(b) At some point in the stream negotiation process, inform the
initiating entity that SASL is MTN.

  <stream:features>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
      <mechanism>DIGEST-MD5</mechanism>
      <mechanism>PLAIN</mechanism>
    </mechanisms>
  </stream:features>

(c) As the last stream features (after resource binding), inform the
initiating entity that stream compression is voluntary to negotiate ("VTN").

  <stream:features>
    <compression xmlns='http://jabber.org/features/compress'>
      <method>zlib</method>
      <method>lzw</method>
    </compression>
  </stream:features>

If we say that a feature is MTN if it is the only feature advertised at
a particular point in the stream negotiation process, then (c) would
mean compression is MTN after resource binding. Because that is
non-sensical, I must conclude that all features are VTN unless
explicitly defined otherwise (i.e., we cannot deduce that a feature is
MTN simply by the absence of other features in that particular instance
of stream features advertisement).

As far as I can see, the need here isn't for individual features to be MTN or VTN, but a way for the server to indicate its readiness for normal XMPP IM. From what I have seen, the algorithm clients (and servers) tend to use is to negotiate all negotiable features they are able and configured to negotiate, and as the last step they bind a resource. At this point they assume the server is ready for XMPP IM. This seems reasonable enough, and I have not seen clients actually testing individual features for being MTN or VTN.

While what I just said applies to C2S, the process used by other initiating entities isn't any different. The initiating entities are only interested in the stream's readiness for their purposes, not about individual features being MTN or VTN (or non-negotiable; not all features are negotiable).
 
The initiating entity can implicitly know that a given feature is MTN
(we "just know" that SASL is MTN because you must authenticate) or the
receiving entity can explicitly inform the intitiating entity (we don't
"just know" and therefore need a way for the receiving entity to inform
the initiating entity that Feature X is MTN).

I don't like these things to be implicit (the stream feature approach is
open-ended and we don't know what features people might define in the
future), which is why I think that we need some kind of method for
explicitly signalling that a feature is MTN. We have two options:

1. Place the burden on each stream feature. Therefore we might end up
with things like this:

  <stream:features>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
      <required/>
    </starttls>
  </stream:features>

vs.

  <stream:features>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
                mandatory='true'>
      <mechanism>DIGEST-MD5</mechanism>
      <mechanism>PLAIN</mechanism>
    </mechanisms>
  </stream:features>

vs.

  <stream:features>
    <compression xmlns='http://jabber.org/features/compress'>
      <method>zlib</method>
      <method>lzw</method>
      <you-gotta-negotiate-this/>
    </compression>
  </stream:features>

2. Define a generalized data structure that can be re-used by all stream
features.

  <stream:features>
    <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
      <stream:usage mandatory='true'/>
    </starttls>
  </stream:features>

  <stream:features>
    <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
      <mechanism>DIGEST-MD5</mechanism>
      <mechanism>PLAIN</mechanism>
      <stream:usage mandatory='true'/>
    </mechanisms>
  </stream:features>

  <stream:features>
    <compression xmlns='http://jabber.org/features/compress'>
      <method>zlib</method>
      <method>lzw</method>
      <stream:usage mandatory='true'/>
    </compression>
  </stream:features>

Option #2 is a lot cleaner, it can be re-used by any stream feature that
people might define in the future, it simplifies processing by the
initiating entity, and it reduces the chance of nasty surprises (e.g.,
disconnections because the initiating entity assumed that Feature X was
VTN while the receiving entity assumed that Feature X was MTN).

If the MTN vs. VTN distinction was really necessary, I would agree.
 
> 2. Whether a stream restart is mandatory is defined by the stream
> feeature and does not need to be specified on the wire. All that 3920bis
> needs to say is that the definition of a stream feature must specify
> whether stream restarts are necessary after negotiation of that feature.

Here again, I think it would be helpful to be explicit about whether a
restart is needed or not. In general, stream restarts apply to any
protocol in which the entities need to discard information received in
an insecure manner before the given feature was negotiated. Right now
that is true only for TLS and for SASL-with-security-layers. It is
probably unlikely that we will define new technologies that also force
stream restarts (since they would essentially be replacements for TLS or
for SASL-with-security-layers), so I am not as worked up about defining
an explicit signalling method here. However, it seems to me that if we
are defining an explicit signalling method for MTN vs. VTN then we might
as well define one for restarts while we're at it. I will update -03
along these lines and flag this as an item for discussion on the list
and in Hiroshima.

If the MTN vs. VTN distinction was really necessary, this would be still be arguable.
 
There is one more issue that is still unclear in -02: how to handle
stream feature advertisements that contain multiple features. The
following combinations are possible:

(a) 1+ features, all of which are MTN.
(b) 1+ features, 1 or 1+ (but not all) of which are MTN.
(c) 1+ features, none of which are MTN.

In the case of (a) I think the initiating just picks one MTN feature to
negotiate based on local preferences.

In the case of (b) I think the initiating entity can negotiate one of
the VTN features (say, in-band registration instead of SASL) or one of
the MTN features, but it needs to negotiate something.

So, basically as far as the initiating entity is concerned, there is no distinction between (a) and (b). The initiating entity will do the same thing for either case: Pick any one feature it likes.
 
In the case of (c) I think the initiating entity can negotiate any of
the features or none of the features.

And only (c) really matters. That is, all that matters is a signal that negotiation is complete. Currently, for C2S this is assumed to be the case after resource binding, and for S2S this is assumed to be the case after auth (SASL or dialback). Your goal seems to be making this explicit. Wouldn't a simple stream feature making this explicit be enough? What would an MTN/VTN flag on each feature buy us that a <negitiation-complete/> (or more appropriately <xmpp-im/>, etc) feature will not?
 
I tried to capture this in the state chart, but I've made a few edits to
the chart since -02 and those will show up in -03.

Peter

- --
Peter Saint-Andre
https://stpeter.im/

--
Waqas Hussain


Note Well: Messages sent to this mailing list are the opinions of the senders and do not imply endorsement by the IETF.