<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’/>
<session xmlns=’urn:ietf:params:xml:ns:xmpp-session’/>
</stream:features>
6.6. Server-to-Server Example
The following example shows the data flow for a server authenticating
with another 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: 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 with a stream tag sent to Server1:
<stream:stream
xmlns=’jabber:server’
xmlns:stream=’http://etherx.jabber.org/streams’
from=’example.com’
id=’s2s_234’
version=’1.0’>
Step 3: Server2 informs Server1 of available authentication
mechanisms:
<stream:features>
<mechanisms xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
</mechanisms>
</stream:features>
Step 4: Server1 selects an authentication mechanism:
<auth xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’
mechanism=’DIGEST-MD5’/>
Step 5: Server2 sends a [BASE64] encoded challenge to Server1:
<challenge xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9
ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz
</challenge>
The decoded challenge is:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
Step 5 (alt): Server2 returns error to Server1:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<incorrect-encoding/>
</failure>
</stream:stream>
Step 6: Server1 sends a [BASE64] encoded response to the challenge:
<response xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v
cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3
LGNoYXJzZXQ9dXRmLTgK
</response>
The decoded response is:
username="example.org",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.org",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
Step 7: Server2 sends another [BASE64] encoded challenge to Server1:
<challenge xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
The decoded challenge is:
rspauth=ea40f60335c427b5527b84dbabcdfffd
Step 7 (alt): Server2 returns error to Server1:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<invalid-authzid/>
</failure>
</stream:stream>
Step 8: Server1 responds to the challenge:
<response xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>
Step 8 (alt): Server1 aborts negotiation:
<abort xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>
Step 9: Server2 informs Server1 of successful authentication:
<success xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>
Step 9 (alt): Server2 informs Server1 of failed authentication:
<failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’>
<aborted/>
</failure>
</stream:stream>
Step 10: 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 11: Server2 responds by sending a stream header to Server1 along
with any additional features (or an empty features element):
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
from=’example.com’
id=’s2s_345’
version=’1.0’>
<stream:features/>
7. Resource Binding
After SASL negotiation (Section 6) with the receiving entity, the
initiating entity MAY want or need to bind a specific resource to
that stream. In general this applies only to clients: in order to
conform to the addressing format (Section 3) and stanza delivery
rules (Section 10) specified herein, there MUST be a resource
identifier associated with the <node@domain> of the client (which is
either generated by the server or provided by the client
application); this ensures that the address for use over that stream
is a "full JID" of the form <node@domain/resource>.
Upon receiving a success indication within the SASL negotiation, the
client MUST send a new stream header to the server, to which the
server MUST respond with a stream header as well as a list of
available stream features. Specifically, if the server requires the
client to bind a resource to the stream after successful SASL
negotiation, it MUST include an empty <bind/> element qualified by
the ’urn:ietf:params:xml:ns:xmpp-bind’ namespace in the stream
features list it presents to the client upon sending the header for
the response stream sent after successful SASL negotiation (but not
before):
Server advertises resource binding feature to client:
<stream:stream
xmlns=’jabber:client’
xmlns:stream=’http://etherx.jabber.org/streams’
id=’c2s_345’
from=’example.com’
version=’1.0’>
<stream:features>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’/>
</stream:features>
Upon being so informed that resource binding is required, the client
MUST bind a resource to the stream by sending to the server an IQ
stanza of type "set" (see IQ Semantics (Section 9.2.3)) containing
data qualified by the ’urn:ietf:params:xml:ns:xmpp-bind’ namespace.
If the client wishes to allow the server to generate the resource
identifier on its behalf, it sends an IQ stanza of type "set" that
contains an empty <bind/> element:
Client asks server to bind a resource:
<iq type=’set’ id=’bind_1’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’/>
</iq>
A server that supports resource binding MUST be able to generate a
resource identifier on behalf of a client. A resource identifier
generated by the server MUST be unique for that <node@domain>.
If the client wishes to specify the resource identifier, it sends an
IQ stanza of type "set" that contains the desired resource identifier
as the XML character data of a <resource/> element that is a child of
the <bind/> element:
Client binds a resource:
<iq type=’set’ id=’bind_2’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>
<resource>someresource</resource>
</bind>
</iq>
Once the server has generated a resource identifier for the client or
accepted the resource identifier provided by the client, it MUST
return an IQ stanza of type "result" to the client, which MUST
include a <jid/> child element that specifies the full JID for the
connected resource as determined by the server:
Server informs client of successful resource binding:
<iq type=’result’ id=’bind_2’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>
<jid>somenode@example.com/someresource</jid>
</bind>
</iq>
A server SHOULD accept the resource identifier provided by the
client, but MAY override it with a resource identifier that the
server generates; in this case, the server SHOULD NOT return a stanza
error (e.g., <forbidden/>) to the client but instead SHOULD
communicate the generated resource identifier to the client in the IQ
result as shown above.
When a client supplies a resource identifier, the following stanza
error conditions are possible (see Stanza Errors (Section 9.3)):
o The provided resource identifier cannot be processed by the server
in accordance with Resourceprep (Appendix B).
o The client is not allowed to bind a resource to the stream (e.g.,
because the node or user has reached a limit on the number of
connected resources allowed).
o The provided resource identifier is already in use but the server
does not allow binding of multiple connected resources with the
same identifier.
The protocol for these error conditions is shown below.
Resource identifier cannot be processed:
<iq type=’error’ id=’bind_2’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>
<resource>someresource</resource>
</bind>
<error type=’modify’>
<bad-request xmlns=’urn:ietf:params:xml:ns:xmpp-stanzas’/>
</error>
</iq>
Client is not allowed to bind a resource:
<iq type=’error’ id=’bind_2’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>
<resource>someresource</resource>
</bind>
<error type=’cancel’>
<not-allowed xmlns=’urn:ietf:params:xml:ns:xmpp-stanzas’/>
</error>
</iq>
Resource identifier is in use:
<iq type=’error’ id=’bind_2’>
<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>
<resource>someresource</resource>
</bind>
<error type=’cancel’>
<conflict xmlns=’urn:ietf:params:xml:ns:xmpp-stanzas’/>
</error>
</iq>
If, before completing the resource binding step, the client attempts
to send an XML stanza other than an IQ stanza with a <bind/> child
qualified by the ’urn:ietf:params:xml:ns:xmpp-bind’ namespace, the
server MUST NOT process the stanza and SHOULD return a
<not-authorized/> stanza error to the client.
8. Server Dialback
8.1. Overview
The Jabber protocols from which XMPP was adapted include a "server
dialback" method for protecting against domain spoofing, thus making
it more difficult to spoof XML stanzas. Server dialback is not a
security mechanism, and results in weak verification of server
identities only (see Server-to-Server Communications (Section 14.4)
regarding this method’s security characteristics). Domains requiring
robust security SHOULD use TLS and SASL; see Server-to-Server
Communications (Section 14.4) for details. If SASL is used for
server-to-server authentication, dialback SHOULD NOT be used since it
is unnecessary. Documentation of dialback is included mainly for the
sake of backward-compatibility with existing implementations and
deployments.
The server dialback method is made possible by the existence of the
Domain Name System (DNS), since one server can (normally) discover
the authoritative server for a given domain. Because dialback
depends on DNS, inter-domain 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)).
Server dialback is uni-directional, and results in (weak)
verification of identities for one stream in one direction. Because
server dialback is not an authentication mechanism, mutual
authentication is not possible via dialback. Therefore, server
dialback MUST be completed in each direction in order to enable
bi-directional communications between two domains.
The method for generating and verifying the keys used in server
dialback MUST take into account the hostnames being used, the stream
ID generated by the receiving server, and a secret known by the
authoritative server’s network. The stream ID is security-critical
in server dialback and therefore MUST be both unpredictable and
non-repeating (see [RANDOM] for recommendations regarding randomness
for security purposes).
Any error that occurs during dialback negotiation MUST be considered
a stream error, resulting in termination of the stream and of the
underlying TCP connection. The possible error conditions are
specified in the protocol description below.
The following terminology applies:
o Originating Server -- the server that is attempting to establish a
connection between two domains.
o Receiving Server -- the server that is trying to authenticate that
the Originating Server represents the domain which it claims to
be.
o Authoritative Server -- the server that answers to the DNS
hostname asserted by the Originating Server; for basic
environments this will be the Originating Server, but it could be
a separate machine in the Originating Server’s network.
8.2. Order of Events
The following is a brief summary of the order of events in dialback:
1. The Originating Server establishes a connection to the Receiving
Server.
2. The Originating Server sends a ’key’ value over the connection to
the Receiving Server.
3. The Receiving Server establishes a connection to the
Authoritative Server.
4. The Receiving Server sends the same ’key’ value to the
Authoritative Server.
5. The Authoritative Server replies that key is valid or invalid.
6. The Receiving Server informs the Originating Server whether it is
authenticated or not.
We can represent this flow of events graphically as follows:
Originating Receiving
Server Server
----------- ---------
| |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| | Authoritative
| send dialback key | Server
| ----------------------> | -------------
| | |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| |
| send verify request |
| ----------------------> |
| |
| send verify response |
| <---------------------- |
|
| report dialback result |
| <---------------------- |
| |
8.3. Protocol
The detailed protocol interaction between the servers is as follows:
1. The Originating Server establishes TCP connection to the
Receiving Server.
2. The Originating Server sends a stream header to the Receiving
Server:
<stream:stream
xmlns:stream=’http://etherx.jabber.org/streams’
xmlns=’jabber:server’
xmlns:db=’jabber:server:dialback’>
Note: The ’to’ and ’from’ attributes are OPTIONAL on the root stream
element. The inclusion of the xmlns:db namespace declaration with
the name shown indicates to the Receiving Server that the Originating
Server supports dialback. If the namespace name is incorrect, then
the Receiving Server MUST generate an <invalid-namespace/> stream
error condition and terminate both the XML stream and the underlying
TCP connection.
3. The Receiving Server SHOULD send a stream header back to the
Originating Server, including a unique ID for this interaction:
<stream:stream
xmlns:stream=’http://etherx.jabber.org/streams’
xmlns=’jabber:server’
xmlns:db=’jabber:server:dialback’
id=’457F9224A0...’>
Note: The ’to’ and ’from’ attributes are OPTIONAL on the root stream
element. If the namespace name is incorrect, then the Originating
Server MUST generate an <invalid-namespace/> stream error condition
and terminate both the XML stream and the underlying TCP connection.
Note well that the Receiving Server SHOULD reply but MAY silently
terminate the XML stream and underlying TCP connection depending on
security policies in place; however, if the Receiving Server desires
to proceed, it MUST send a stream header back to the Originating
Server.
4. The Originating Server sends a dialback key to the Receiving
Server:
<db:result
to=’Receiving Server’
from=’Originating Server’>
98AF014EDC0...
</db:result>
Note: This key is not examined by the Receiving Server, since the
Receiving Server does not keep information about the Originating
Server between sessions. The key generated by the Originating Server
MUST be based in part on the value of the ID provided by the
Receiving Server in the previous step, and in part on a secret shared
by the Originating Server and Authoritative Server. If the value of
the ’to’ address does not match a hostname recognized by the
Receiving Server, then the Receiving Server MUST generate a
<host-unknown/> stream error condition and terminate both the XML
stream and the underlying TCP connection. If the value of the ’from’
address matches a domain with which the Receiving Server already has
an established connection, then the Receiving Server MUST maintain
the existing connection until it validates whether the new connection
is legitimate; additionally, the Receiving Server MAY choose to
generate a <not-authorized/> stream error condition for the new
connection and then terminate both the XML stream and the underlying
TCP connection related to the new request.
5. The Receiving Server establishes a TCP connection back to the
domain name asserted by the Originating Server, as a result of
which it connects to the Authoritative Server. (Note: As an
optimization, an implementation MAY reuse an existing connection
here.)
6. The Receiving Server sends the Authoritative Server a stream
header:
<stream:stream
xmlns:stream=’http://etherx.jabber.org/streams’
xmlns=’jabber:server’
xmlns:db=’jabber:server:dialback’>
Note: The ’to’ and ’from’ attributes are OPTIONAL on the root stream
element. If the namespace name is incorrect, then the Authoritative
Server MUST generate an <invalid-namespace/> stream error condition
and terminate both the XML stream and the underlying TCP connection.
7. The Authoritative Server sends the Receiving Server a stream
header:
<stream:stream
xmlns:stream=’http://etherx.jabber.org/streams’
xmlns=’jabber:server’
xmlns:db=’jabber:server:dialback’
id=’1251A342B...’>
Note: If the namespace name is incorrect, then the Receiving Server
MUST generate an <invalid-namespace/> stream error condition and
terminate both the XML stream and the underlying TCP connection
between it and the Authoritative Server. If a stream error occurs
between the Receiving Server and the Authoritative Server, then the
Receiving Server MUST generate a <remote-connection-failed/> stream
error condition and terminate both the XML stream and the underlying
TCP connection between it and the Originating Server.
8. The Receiving Server sends the Authoritative Server a request for
verification of a key:
<db:verify
from=’Receiving Server’
to=’Originating Server’
id=’457F9224A0...’>
98AF014EDC0...
</db:verify>
Note: Passed here are the hostnames, the original identifier from the
Receiving Server’s stream header to the Originating Server in Step 3,
and the key that the Originating Server sent to the Receiving Server
in Step 4. Based on this information, as well as shared secret
information within the Authoritative Server’s network, the key is
verified. Any verifiable method MAY be used to generate the key. If
the value of the ’to’ address does not match a hostname recognized by
the Authoritative Server, then the Authoritative Server MUST generate
a <host-unknown/> stream error condition and terminate both the XML
stream and the underlying TCP connection. If the value of the ’from’
address does not match the hostname represented by the Receiving
Server when opening the TCP connection (or any validated domain
thereof, such as a validated subdomain of the Receiving Server’s
hostname or another validated domain hosted by the Receiving Server),
then the Authoritative Server MUST generate an <invalid-from/> stream
error condition and terminate both the XML stream and the underlying
TCP connection.
9. The Authoritative Server verifies whether the key was valid or
invalid:
<db:verify
from=’Originating Server’
to=’Receiving Server’
type=’valid’
id=’457F9224A0...’/>
or
<db:verify
from=’Originating Server’
to=’Receiving Server’
type=’invalid’
id=’457F9224A0...’/>
Note: If the ID does not match that provided by the Receiving Server
in Step 3, then the Receiving Server MUST generate an <invalid-id/>
stream error condition and terminate both the XML stream and the
underlying TCP connection. If the value of the ’to’ address does not
match a hostname recognized by the Receiving Server, then the
Receiving Server MUST generate a <host-unknown/> stream error
condition and terminate both the XML stream and the underlying TCP
connection. If the value of the ’from’ address does not match the
hostname represented by the Originating Server when opening the TCP
connection (or any validated domain thereof, such as a validated
subdomain of the Originating Server’s hostname or another validated
domain hosted by the Originating Server), then the Receiving Server
MUST generate an <invalid-from/> stream error condition and terminate
both the XML stream and the underlying TCP connection. After
returning the verification to the Receiving Server, the Authoritative
Server SHOULD terminate the stream between them.
10. The Receiving Server informs the Originating Server of the
result:
<db:result
from=’Receiving Server’
to=’Originating Server’
type=’valid’/>
Note: At this point, the connection has either been validated via a
type=’valid’, or reported as invalid. If the connection is invalid,
then the Receiving Server MUST terminate both the XML stream and the
underlying TCP connection. If the connection is validated, data can
be sent by the Originating Server and read by the Receiving Server;
before that, all XML stanzas sent to the Receiving Server SHOULD be
silently dropped.
The result of the foregoing is that the Receiving Server has verified