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

[xmpp] the stream negotiation process



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Earlier today I rewrote the section of 3920bis on stream features,
expanding it to cover the stream negotiation process in general. Thanks
to Jehan Pagès for pointing out to me in private conversation that this
topic was underspecified. My provisional text follows. I will review
this again next, but as always feedback is welcome.

######

5.2.  Stream Negotiation

5.2.1.  Overview

   Because the receiving entity for a stream acts as a gatekeeper to the
   domains it services, it imposes certain conditions for connecting as
   a client or as a peer server.  At a minimum, the initiating entity
   needs to authenticate with the receiving entity before it is allowed
   to send stanzas to the receiving entity, typically using SASL as
   described under Section 7.  However, the receiving entity can require
   other conditions in addition to authentication, such as encryption
   using TLS as described under Section 6.  The receiving entity informs
   the initiating entity about such conditions by communicating STREAM
   FEATURES: the set of particular protocol interactions that are
   mandatory for the initiating entity to complete before the receiving
   entity will accept XML stanzas from the initiating entity (e.g.,
   authentication), as well as any protocol interactions that are
   voluntary but that might improve the handling of an XML stream (e.g.,
   establishment of application-layer compression).

   The existence of such conditions implies that streams need to be
   negotiated, and the order of layers (TCP, then TLS, then SASL, then
   XMPP; see Section 14.5) implies that stream negotiation is a well-
   defined process.  Furthermore, stream features can be either
   mandatory or voluntary; this imposes further structure on the
   negotiation process.  Finally, for security reasons, the parties to a
   stream need to discard knowledge that they gained during the
   negotiation process after successfully completing the protocol
   interactions defined for certain features (e.g., TLS and SASL); this
   is done by flushing the old stream context and exchanging new stream
   headers over the existing TCP connection.

5.2.2.  Stream Features Format

   If the initiating entity includes the 'version' attribute set to a
   value of at least "1.0" in the initial stream header, after sending
   the response stream header the receiving entity MUST send a
   <features/> child element (prefixed by the streams namespace prefix)
   to the initiating entity in order to announce any conditions for
   continuation of the stream negotiation process.  Each condition takes
   the form of a child element of the <features/> element, qualified by
   a namespace that is different from the streams namespace and the
   default namespace.

   If negotiation of a particular stream feature is mandatory, the
   stream feature advertisement MUST include an empty <required/> child
   element.

   If negotiation of a particular stream feature is voluntary, the
   stream feature advertisement MAY include an empty <optional/> child
   element.  However, because every stream feature defaults to
   voluntary, the inclusion of an empty <optional/> child element is not
   necessary to indicate that a stream feature is voluntary.

   For security reasons, certain stream features necessitate the
   initiating entity to send a new initial stream header upon successful
   negotiation of the feature (e.g., TLS and SASL).  If a stream restart
   is necessary for any given feature, the <optional/> or <required/>
   child element MUST include a boolean 'restart' attribute with a value
   of "true" or "1" (this optional attribute defaults to false).
   Although it is expected that stream restarts will be necessary only
   for mandatory features, voluntary features are also allowed to
   necessitate restarts.

   Aside from the <optional/> child element, <required/> child element,
   and 'restart' attribute, the syntax and semantics of each particular
   feature are defined by an appropriate specification of that feature;
   several such features are defined in this document but stream
   features can be defined by other documents, as well.

   A <features/> element that contains at least one mandatory feature
   indicates that the stream negotiation is not complete and that the
   initiating entity MUST negotiate further features.

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

   A <features/> element MAY contain more than one mandatory feature.
   This means that the initiating entity can choose among the mandatory
   features.  For example, perhaps a future technology will perform
   roughly the same function as TLS, so the receiving entity might
   advertise support for both TLS and the future technology.

   A <features/> element that contains only voluntary features indicates
   that the stream negotiation is complete and that the initiating
   entity is cleared to send XML stanzas, but that the initiating entity
   MAY negotiate further features if desired.

   R: <stream:features>
        <session xmlns='urn:ietf:params:xml:ns:xmpp-session'>
          <optional/>
        </session>
        <compression xmlns='http://jabber.org/features/compress'>
          <method>zlib</method>
          <method>lzw</method>
          <optional/>
        </compression>
      </stream:features>

   A <features/> element that contains both mandatory and voluntary
   features indicates that the negotiation is not complete but but that
   the initiating entity MAY complete the voluntary feature(s) before it
   attempts to negotiate the mandatory feature(s).

   R: <stream:features>
        <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
          <required/>
        </bind>
        <compression xmlns='http://jabber.org/features/compress'>
          <method>zlib</method>
          <method>lzw</method>
          <optional/>
        </compression>
      </stream:features>

   An empty <features/> element indicates that the stream negotiation is
   complete and that the initiating entity is cleared to send XML
   stanzas.

   R: <stream:features/>

      Note: The order of child elements contained in any given
      <features/> element is not significant.

   If the initiating entity does not understand or support a feature
   that has been advertised, it MUST still inspect the feature
   advertisement to determine if negotiation of the feature is
   mandatory.  If negotiation of an unsupported feature is mandatory and
   the receiving entity has offered no other mandatory features at that
   stage of the negotiation process, then the initiating entity MUST
   abort the stream negotiation process and SHOULD return an
   <unsupported-feature/> stream error to the receiving entity.  If
   negotiation of an unsupported feature is voluntary, the entity MUST
   silently ignore the associated feature advertisement and proceed with
   the stream negotiation process.

      Note: Implementations based on an earlier revision of this
      specification do not include the <optional/> child element and
      they include the <required/> child element only in the case of the
      STARTTLS feature.  Entities MUST accept stream feature
      advertisements without the child elements, and MUST consider
      negotiation of such features to be voluntary.

5.2.3.  Restarts

   On successful negotiation of a feature that requires a stream
   restart, both parties MUST consider the previous stream to be
   replaced but MUST NOT terminate the underlying TCP connection;
   instead, the parties MUST reuse the existing connection, which might
   be in a new state (e.g., encrypted as a result of TLS negotiation).
   The initiating entity then MUST send a new initial stream header,
   which SHOULD be preceded by an XML declaration as described under
   Section 12.5.  When the receiving entity receives the new initial
   stream header, it MUST generate a new stream ID (instead of re-using
   the old stream ID) before sending a new response stream header (which
   SHOULD be preceded by an XML declaration as described under
   Section 12.5).

5.2.4.  Resending Features

   After completing negotiation of any stream feature (even stream
   features that do not require a stream restart), the receiving entity
   MUST send an updated list of stream features to the initiating
   entity, where the list MAY be empty if there are no further features
   to be advertised.

   At any time after stream establishment and before closing of the
   stream, the receiving entity MAY send additional or modified stream
   feature advertisements to the initiating entity (e.g., because a new
   feature has been enabled).

5.2.5.  Completion of Stream Negotiation

   The receiving entity indicates completion of the stream negotiation
   process by sending to the initiating entity either an empty
   <features/> element or a <features/> element that contains only
   voluntary features.  Once stream negotiation is complete, the
   initiating entity is cleared to send XML stanzas over the stream for
   as long as the stream is maintained by both parties.

   The initiating entity MUST NOT attempt to send XML stanzas
   (Section 9) over the stream until stream negotiation has been
   completed.  However, if it does attempt to do so, the receiving
   entity MUST NOT accept such stanzas and MUST return a <not-
   authorized/> stream error.  This rule applies to XML stanzas only
   (i.e., <message/>, <presence/>, and <iq/> elements qualified by the
   default namespace) and not to XML elements used for stream
   negotiation (e.g., elements used to complete TLS negotiation
   (Section 6) or SASL negotiation (Section 7)).

5.2.6.  State Chart

   We summarize the foregoing rules in the following non-normative state
   chart, presented from the perspective of the initiating entity.


     +------------+
     |  open TCP  |
     | connection |
     +------------+
           |
    +---------------+
    | send initial  |<-------------------------------------------+
    | stream header |                                            |
    +---------------+                                            |
           |                                                     |
   +------------------+                                          |
   | receive response |                                          |
   | stream header    |                                          |
   +------------------+                                          |
           |                                                     |
    +----------------+                                           |
    | receive stream |                                           |
    | features       |                                           |
    +----------------+                                           |
           |                                                     |
        {empty?} ---> {all voluntary?} ---> {some mandatory?}    |
           |      no        |           no         |             |
           | yes            | yes                  |             |
           |                |                      |             |
           |          +---------------+     +----------------+   |
           |          | MAY negotiate |     | MUST negotiate |   |
           |          | any feature   |     | one feature    |   |
           |          +---------------+     +----------------+   |
           |                |                      |             |
           |                +--->-------+---<------+             |
           |                            |                        |
           |                    [restart required?] ------------>+
           |                            |              yes
           |                        no  |
           |                            |
           |                     +-------------+
           |                     | negotiation |
           +-------------------->| complete    |
                                 +-------------+

######

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkrGn+MACgkQNL8k5A2w/vzDUQCg45C5e2YNky1nzmaa3+C72N9f
0PIAoOzrVqmXXgh1QPbFRyOsv7qyLJe3
=ZwmO
-----END PGP SIGNATURE-----

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