with the receiving entity, it SHOULD signal that fact by
including a <required/> element as a child of the <starttls/>
element).
4. The initiating entity issues the STARTTLS command (i.e., a
<starttls/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-tls’ namespace) to instruct the
receiving entity that it wishes to begin a TLS negotiation to
secure the stream.
5. The receiving entity MUST reply with either a <proceed/> element
or a <failure/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-tls’ namespace. If the failure case
occurs, the receiving entity MUST terminate both the XML stream
and the underlying TCP connection. If the proceed case occurs,
the entities MUST attempt to complete the TLS negotiation over
the TCP connection and MUST NOT send any further XML data until
the TLS negotiation is complete.
6. The initiating entity and receiving entity attempt to complete a
TLS negotiation in accordance with [TLS].
7. If the TLS negotiation is unsuccessful, the receiving entity MUST
terminate the TCP connection. If the TLS negotiation is
successful, the initiating entity MUST initiate a new stream by
sending an opening XML stream header to the receiving entity (it
is not necessary to send a closing </stream> tag first, since the
receiving entity and initiating entity MUST consider the original
stream to be closed upon successful TLS negotiation).
8. Upon receiving the new stream header from the initiating entity,
the receiving entity MUST respond by sending a new XML stream
header to the initiating entity along with the available features
(but not including the STARTTLS feature).
5.3. Client-to-Server Example
The following example shows the data flow for a client securing a
stream using STARTTLS (note: the alternate steps shown below are
provided to illustrate the protocol for failure cases; they are not
exhaustive and would not necessarily be triggered by the data sent in
the example).
Step 1: Client initiates stream to server:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 2: Server responds by sending a stream tag to client:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
id=’c2s_123’
from=’example.com’
version=’1.0’>
Step 3: Server sends the STARTTLS extension to client along with
authentication mechanisms and any other stream features:
<stream:features>
<starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’>
<required/>
</starttls>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
Step 4: Client sends the STARTTLS command to server:
<starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
Step 5: Server informs client that it is allowed to proceed:
<proceed xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
Step 5 (alt): Server informs client that TLS negotiation has failed
and closes both stream and TCP connection:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
</stream:stream>
Step 6: Client and server attempt to complete TLS negotiation over
the existing TCP connection.
Step 7: If TLS negotiation is successful, client initiates a new
stream to server:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 7 (alt): If TLS negotiation is unsuccessful, server closes TCP
connection.
Step 8: Server responds by sending a stream header to client along
with any available stream features:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
from=’example.com’
id=’c2s_234’
version=’1.0’>
<stream:features>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
<mechanism>EXTERNAL</mechanism>
</mechanisms>
</stream:features>
Step 9: Client continues with SASL negotiation (Section 6).
5.4. Server-to-Server Example
The following example shows the data flow for two servers securing a
stream using STARTTLS (note: the alternate steps shown below are
provided to illustrate the protocol for failure cases; they are not
exhaustive and would not necessarily be triggered by the data sent in
the example).
Step 1: Server1 initiates stream to Server2:
<stream:stream
xmlns=’jabber:server’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 2: Server2 responds by sending a stream tag to Server1:
<stream:stream
xmlns=’jabber:server’
xmlns:stream=’http://etherx.jabber.org/streams’
from=’example.com’
id=’s2s_123’
version=’1.0’>
Step 3: Server2 sends the STARTTLS extension to Server1 along with
authentication mechanisms and any other stream features:
<stream:features>
<starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’>
<required/>
</starttls>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
</mechanisms>
</stream:features>
Step 4: Server1 sends the STARTTLS command to Server2:
<starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
Step 5: Server2 informs Server1 that it is allowed to proceed:
<proceed xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
Step 5 (alt): Server2 informs Server1 that TLS negotiation has failed
and closes stream:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/>
</stream:stream>
Step 6: Server1 and Server2 attempt to complete TLS negotiation via
TCP.
Step 7: If TLS negotiation is successful, Server1 initiates a new
stream to Server2:
<stream:stream
xmlns=’jabber:server’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 7 (alt): If TLS negotiation is unsuccessful, Server2 closes TCP
connection.
Step 8: Server2 responds by sending a stream header to Server1 along
with any available stream features:
<stream:stream
xmlns=’jabber:server’
xmlns:stream=’http://etherx.jabber.org/streams’
from=’example.com’
id=’s2s_234’
version=’1.0’>
<stream:features>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
<mechanism>EXTERNAL</mechanism>
</mechanisms>
</stream:features>
Step 9: Server1 continues with SASL negotiation (Section 6).
6. Use of SASL
6.1. Overview
XMPP includes a method for authenticating a stream by means of an
XMPP-specific profile of the Simple Authentication and Security Layer
(SASL) protocol [SASL]. SASL provides a generalized method for
adding authentication support to connection-based protocols, and XMPP
uses a generic XML namespace profile for SASL that conforms to the
profiling requirements of [SASL].
The following rules apply:
1. If the SASL negotiation occurs between two servers,
communications MUST NOT proceed until the Domain Name System
(DNS) hostnames asserted by the servers have been resolved (see
Server-to-Server Communications (Section 14.4)).
2. If the initiating entity is capable of SASL negotiation, it MUST
include the ’version’ attribute set to a value of at least "1.0"
in the initial stream header.
3. If the receiving entity is capable of SASL negotiation, it MUST
advertise one or more authentication mechanisms within a
<mechanisms/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace in reply to the
opening stream tag received from the initiating entity (if the
opening stream tag included the ’version’ attribute set to a
value of at least "1.0").
4. During SASL negotiation, an entity MUST NOT send any white space
characters (matching production [3] content of [XML]) within the
root stream element as separators between elements (any white
space characters shown in the SASL examples below are included
for the sake of readability only); this prohibition helps to
ensure proper security layer byte precision.
5. Any XML character data contained within the XML elements used
during SASL negotiation MUST be encoded using base64, where the
encoding adheres to the definition in Section 3 of RFC 3548
[BASE64].
6. If provision of a "simple username" is supported by the selected
SASL mechanism (e.g., this is supported by the DIGEST-MD5 and
CRAM-MD5 mechanisms but not by the EXTERNAL and GSSAPI
mechanisms), during authentication the initiating entity SHOULD
provide as the simple username its sending domain (IP address or
fully qualified domain name as contained in a domain identifier)
in the case of server-to-server communications or its registered
account name (user or node name as contained in an XMPP node
identifier) in the case of client-to-server communications.
7. If the initiating entity wishes to act on behalf of another
entity and the selected SASL mechanism supports transmission of
an authorization identity, the initiating entity MUST provide an
authorization identity during SASL negotiation. If the
initiating entity does not wish to act on behalf of another
entity, it MUST NOT provide an authorization identity. As
specified in [SASL], the initiating entity MUST NOT provide an
authorization identity unless the authorization identity is
different from the default authorization identity derived from
the authentication identity as described in [SASL]. If provided,
the value of the authorization identity MUST be of the form
<domain> (i.e., a domain identifier only) for servers and of the
form <node@domain> (i.e., node identifier and domain identifier)
for clients.
8. Upon successful SASL negotiation that involves negotiation of a
security layer, the receiving entity MUST discard any knowledge
obtained from the initiating entity which was not obtained from
the SASL negotiation itself.
9. Upon successful SASL negotiation that involves negotiation of a
security layer, the initiating entity MUST discard any knowledge
obtained from the receiving entity which was not obtained from
the SASL negotiation itself.
10. See Mandatory-to-Implement Technologies (Section 14.7) regarding
mechanisms that MUST be supported.
6.2. Narrative
When an initiating entity authenticates with a receiving entity using
SASL, the steps involved are as follows:
1. The initiating entity requests SASL authentication by including
the ’version’ attribute in the opening XML stream header sent to
the receiving entity, with the value set to "1.0".
2. After sending an XML stream header in reply, the receiving entity
advertises a list of available SASL authentication mechanisms;
each of these is a <mechanism/> element included as a child
within a <mechanisms/> container element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace, which in turn is a
child of a <features/> element in the streams namespace. If Use
of TLS (Section 5) needs to be established before a particular
authentication mechanism may be used, the receiving entity MUST
NOT provide that mechanism in the list of available SASL
authentication mechanisms prior to TLS negotiation. If the
initiating entity presents a valid certificate during prior TLS
negotiation, the receiving entity SHOULD offer the SASL EXTERNAL
mechanism to the initiating entity during SASL negotiation (refer
to [SASL]), although the EXTERNAL mechanism MAY be offered under
other circumstances as well.
3. The initiating entity selects a mechanism by sending an <auth/>
element qualified by the ’urn:ietf:params:xml:ns:xmpp-sasl’
namespace to the receiving entity and including an appropriate
value for the ’mechanism’ attribute. This element MAY contain
XML character data (in SASL terminology, the "initial response")
if the mechanism supports or requires it; if the initiating
entity needs to send a zero-length initial response, it MUST
transmit the response as a single equals sign ("="), which
indicates that the response is present but contains no data.
4. If necessary, the receiving entity challenges the initiating
entity by sending a <challenge/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace to the initiating
entity; this element MAY contain XML character data (which MUST
be computed in accordance with the definition of the SASL
mechanism chosen by the initiating entity).
5. The initiating entity responds to the challenge by sending a
<response/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace to the receiving
entity; this element MAY contain XML character data (which MUST
be computed in accordance with the definition of the SASL
mechanism chosen by the initiating entity).
6. If necessary, the receiving entity sends more challenges and the
initiating entity sends more responses.
This series of challenge/response pairs continues until one of three
things happens:
1. The initiating entity aborts the handshake by sending an <abort/>
element qualified by the ’urn:ietf:params:xml:ns:xmpp-sasl’
namespace to the receiving entity. Upon receiving an <abort/>
element, the receiving entity SHOULD allow a configurable but
reasonable number of retries (at least 2), after which it MUST
terminate the TCP connection; this enables the initiating entity
(e.g., an end-user client) to tolerate incorrectly-provided
credentials (e.g., a mistyped password) without being forced to
reconnect.
2. The receiving entity reports failure of the handshake by sending
a <failure/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace to the initiating
entity (the particular cause of failure SHOULD be communicated in
an appropriate child element of the <failure/> element as defined
under SASL Errors (Section 6.4)). If the failure case occurs,
the receiving entity SHOULD allow a configurable but reasonable
number of retries (at least 2), after which it MUST terminate the
TCP connection; this enables the initiating entity (e.g., an
end-user client) to tolerate incorrectly-provided credentials
(e.g., a mistyped password) without being forced to reconnect.
3. The receiving entity reports success of the handshake by sending
a <success/> element qualified by the
’urn:ietf:params:xml:ns:xmpp-sasl’ namespace to the initiating
entity; this element MAY contain XML character data (in SASL
terminology, "additional data with success") if required by the
chosen SASL mechanism. Upon receiving the <success/> element,
the initiating entity MUST initiate a new stream by sending an
opening XML stream header to the receiving entity (it is not
necessary to send a closing </stream> tag first, since the
receiving entity and initiating entity MUST consider the original
stream to be closed upon sending or receiving the <success/>
element). Upon receiving the new stream header from the
initiating entity, the receiving entity MUST respond by sending a
new XML stream header to the initiating entity, along with any
available features (but not including the STARTTLS and SASL
features) or an empty <features/> element (to signify that no
additional features are available); any such additional features
not defined herein MUST be defined by the relevant extension to
XMPP.
6.3. SASL Definition
The profiling requirements of [SASL] require that the following
information be supplied by a protocol definition:
service name: "xmpp"
initiation sequence: After the initiating entity provides an opening
XML stream header and the receiving entity replies in kind, the
receiving entity provides a list of acceptable authentication
methods. The initiating entity chooses one method from the list
and sends it to the receiving entity as the value of the
’mechanism’ attribute possessed by an <auth/> element, optionally
including an initial response to avoid a round trip.
exchange sequence: Challenges and responses are carried through the
exchange of <challenge/> elements from receiving entity to
initiating entity and <response/> elements from initiating entity
to receiving entity. The receiving entity reports failure by
sending a <failure/> element and success by sending a <success/>
element; the initiating entity aborts the exchange by sending an
<abort/> element. Upon successful negotiation, both sides
consider the original XML stream to be closed and new stream
headers are sent by both entities.
security layer negotiation: The security layer takes effect
immediately after sending the closing ">" character of the
<success/> element for the receiving entity, and immediately after
receiving the closing ">" character of the <success/> element for
the initiating entity. The order of layers is first [TCP], then
[TLS], then [SASL], then XMPP.
use of the authorization identity: The authorization identity may be
used by xmpp to denote the non-default <node@domain> of a client
or the sending <domain> of a server.
6.4. SASL Errors
The following SASL-related error conditions are defined:
o <aborted/> -- The receiving entity acknowledges an <abort/>
element sent by the initiating entity; sent in reply to the
<abort/> element.
o <incorrect-encoding/> -- The data provided by the initiating
entity could not be processed because the [BASE64] encoding is
incorrect (e.g., because the encoding does not adhere to the
definition in Section 3 of [BASE64]); sent in reply to a
<response/> element or an <auth/> element with initial response
data.
o <invalid-authzid/> -- The authzid provided by the initiating
entity is invalid, either because it is incorrectly formatted or
because the initiating entity does not have permissions to
authorize that ID; sent in reply to a <response/> element or an
<auth/> element with initial response data.
o <invalid-mechanism/> -- The initiating entity did not provide a
mechanism or requested a mechanism that is not supported by the
receiving entity; sent in reply to an <auth/> element.
o <mechanism-too-weak/> -- The mechanism requested by the initiating
entity is weaker than server policy permits for that initiating
entity; sent in reply to a <response/> element or an <auth/>
element with initial response data.
o <not-authorized/> -- The authentication failed because the
initiating entity did not provide valid credentials (this includes
but is not limited to the case of an unknown username); sent in
reply to a <response/> element or an <auth/> element with initial
response data.
o <temporary-auth-failure/> -- The authentication failed because of
a temporary error condition within the receiving entity; sent in
reply to an <auth/> element or <response/> element.
6.5. Client-to-Server Example
The following example shows the data flow for a client authenticating
with a server using SASL, normally after successful TLS negotiation
(note: the alternate steps shown below are provided to illustrate the
protocol for failure cases; they are not exhaustive and would not
necessarily be triggered by the data sent in the example).
Step 1: Client initiates stream to server:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 2: Server responds with a stream tag sent to client:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
id=’c2s_234’
from=’example.com’
version=’1.0’>
Step 3: Server informs client of available authentication mechanisms:
<stream:features>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
Step 4: Client selects an authentication mechanism:
<auth xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’
mechanism=’DIGEST-MD5’/>
Step 5: Server sends a [BASE64] encoded challenge to client:
<challenge xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
The decoded challenge is:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
Step 5 (alt): Server returns error to client:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<incorrect-encoding/>
</failure>
</stream:stream>
Step 6: Client sends a [BASE64] encoded response to the challenge:
<response xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
</response>
The decoded response is:
username="somenode",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.com",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
Step 7: Server sends another [BASE64] encoded challenge to client:
<challenge xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
The decoded challenge is:
rspauth=ea40f60335c427b5527b84dbabcdfffd
Step 7 (alt): Server returns error to client:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<temporary-auth-failure/>
</failure>
</stream:stream>
Step 8: Client responds to the challenge:
<response xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>
Step 9: Server informs client of successful authentication:
<success xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>
Step 9 (alt): Server informs client of failed authentication:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<temporary-auth-failure/>
</failure>
</stream:stream>
Step 10: Client initiates a new stream to server:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
to=’example.com’
version=’1.0’>
Step 11: Server responds by sending a stream header to client along
with any additional features (or an empty features element):
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
id=’c2s_345’
from=’example.com’
version=’1.0’>
<stream:features>