git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1989 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2008-06-18 16:02:20 +00:00
parent a707bad489
commit 0c448ab6d3
1 changed files with 335 additions and 95 deletions

View File

@ -7,7 +7,7 @@
<xep>
<header>
<title>Server Dialback</title>
<abstract>This specification defines the Server Dialback protocol, which is used between XMPP servers to provide identity verification. Server dialback uses the Domain Name System (DNS) as the basis for verifying identity; the basic approach is that when a receiving server receives a server-to-server connection request from an originating server, it does not accept the request until it has verified a key with an authoritative server for the domain asserted by the originating server. Although Server Dialback does not provide strong authentication or trusted federation and although it is subject to DNS poisoning attacks, since its development in the year 2000 it has effectively prevented most instances of address spoofing on the XMPP network.</abstract>
<abstract>This specification defines the Server Dialback protocol, which is used between XMPP servers to provide identity verification. Server Dialback uses the Domain Name System (DNS) as the basis for verifying identity; the basic approach is that when a receiving server receives a server-to-server connection request from an originating server, it does not accept the request until it has verified a key with an authoritative server for the domain asserted by the originating server. Although Server Dialback does not provide strong authentication or trusted federation and although it is subject to DNS poisoning attacks, since its development in the year 2000 it has effectively prevented most instances of address spoofing on the XMPP network.</abstract>
&LEGALNOTICE;
<number>0220</number>
<status>Experimental</status>
@ -20,13 +20,27 @@
<supersedes/>
<supersededby/>
<shortname>dialback</shortname>
&jer;
&stpeter;
&jer;
<revision>
<version>0.2</version>
<date>2008-06-17</date>
<date>2008-06-18</date>
<initials>psa</initials>
<remark><p>Rewrote introduction; separated sections into subsections, as has been done for xmppbis Internet-Drafts; explained and illustrated failure cases more completely; added text about different federation models; added explanatory text about scenarios in which Server Dialback is used and not used.</p></remark>
<remark>
<ul>
<li>Rewrote introduction.</li>
<li>Provided motivating text about why diablack is used.</li>
<li>Added text about different federation models.</li>
<li>More clearly described what dialback accomplishes and what it does not accomplish.</li>
<li>Added explanatory text about scenarios in which Server Dialback is used and not used.</li>
<li>Clarified basic description of how dialback works.</li>
<li>Clarified discovery of dialback support.</li>
<li>Separated sections into subsections, as has been done for rfc3920bis and rfc3921bis.</li>
<li>Described the protocol flows in much greater detail.</li>
<li>Explained and illustrated failure cases more completely.</li>
<li>Clarified reuse of negotiated connections, a.k.a. piggybacking.</li>
</ul>
</remark>
</revision>
<revision>
<version>0.1</version>
@ -71,12 +85,12 @@
<section2 topic="When Dialback Is Used" anchor="intro-when">
<p>Server Dialback is typically used in two scenarios:</p>
<ol start='1'>
<li><p>When a peer server does not support XMPP 1.0 as defined in <cite>RFC 3920</cite> or, more generally, does not offer negotiation of TLS.</p></li>
<li><p>When STARTTLS negotiation succeeds with a peer server but the peer's certificate is not strong enough to result in mutual authentication via SASL (e.g., because the certificate presented by the peer service during TLS negotiation is self-signed and thus provides even weaker identity verification than DNS).</p></li>
<li><p>When a peer service does not support XMPP 1.0 as defined in <cite>RFC 3920</cite> or, more generally, does not offer negotiation of TLS.</p></li>
<li><p>When STARTTLS negotiation succeeds with a peer service but the peer's certificate is not strong enough to result in mutual authentication via SASL (e.g., because the certificate presented by the peer service during TLS negotiation is self-signed and and local service policies stipulate that it is preferable to weakly identify the peer service via Server Dialback rather than depend on the self-signed certificate for identity verification).</p></li>
</ol>
<p>Both of these scenarios result in an untrusted connection (verified federation in the first scenario and encrypted federation in the second scenario). However, depending on local security policies, a server may accept such an untrusted connection if the use of Server Dialback results in weak identity verification.</p>
<p>Dialback is not used if SASL is used for server-to-server authentication, since SASL provides strong authentication using certificates, pre-established passwords, or other credentials.</p>
<p>Note: Use of Server Dialback cannot proceed unless a server determines that its peer supports the Server Dialback protocol. For details, see the <link url='support'>Determining Support</link> section of this document.</p>
<p>A service cannot begin negotiation of Server Dialback unless its peer advertises support for the Server Dialback protocol. As described under <link url='o2r-processinitial'>Receiving Server Processes Initial Stream Header</link>, a peer advertises support through inclusion of the Server Dialback namespace declaration in its response stream header and (for XMPP 1.0 servers) through inclusion of the Server Dialback stream feature.</p>
</section2>
<section2 topic="How Dialback Works" anchor="intro-howitworks">
@ -129,7 +143,7 @@ Originating Receiving
| <---------------------- |
| |
]]></code>
<p>Note: In Steps 1 and 3, it is not always necessary to open a new TCP connection and establish a new stream; for details, see the section on <link url='#piggybacking'>Reuse of Negotiated Connections</link>.</p>
<p>Note: In Steps 1 and 3, it is not always necessary to open a new TCP connection and establish a new stream; for details, see the section on <link url='#piggybacking'>Reuse of Negotiated Connections (Piggybacking)</link>.</p>
</section2>
</section1>
@ -152,7 +166,7 @@ Originating Receiving
<li>"R2A:" -- packets sent from the Receiving Server to the Authoritative Server.</li>
<li>"A2R:" -- packets sent from the Authoritative Server to the Receiving Server.</li>
</ul>
<p>Note: Any error that occurs during dialback negotiation MUST be considered a stream error, resulting in termination of the stream and potentially of the underlying TCP connection. The possible error conditions are specified in the protocol description below.</p>
<p>Note: Any error that occurs during dialback negotiation MUST be considered a stream error, resulting in termination of the stream and potentially of the underlying TCP connection. The possible error conditions are specified in the protocol description below.</p>
<p>The flow of events is as follows.</p>
<section2 topic='Stream Setup Between Originating Server and Receiving Server' anchor='o2r'>
@ -170,7 +184,7 @@ _xmpp-server._tcp.xmpp.example.com. 86400 IN SRV 20 0 9625 x2.example.com
<section3 topic='Originating Server Opens TCP Connection' anchor='o2r-connect'>
<p>Once the Originating Server has resolved "xmpp.example.com" to an IP address of 192.0.2.2 and port of 9625, it opens a TCP connection to that IP and port.</p>
<p>Note: Instead of opening a new TCP connection to the Receiving Server, the Originating Server MAY reuse an existing TCP connnection; for details, see the <link url='piggybacking'>Piggybacking</link> section of this document.</p>
<p>Note: Instead of opening a new TCP connection to the Receiving Server, the Originating Server MAY reuse an existing TCP connnection; for details, see the <link url='piggybacking'>Reuse of Negotiated Connections (Piggybacking)</link> section of this document.</p>
</section3>
<section3 topic='Originating Server Sends Initial Stream Header' anchor='o2r-sendinitial'>
@ -190,7 +204,7 @@ O2R: <stream:stream
<li>The Server Dialback namespace MUST be 'jabber:server:dialback'.</li>
<li>The prefix for the Server Dialback namespace SHOULD be 'db:'.</li>
</ol>
<p>Note: An implementation MAY accept only the 'db:' namespace prefix.</p>
<p>Until the initial stream has been validated, the Originating Server MUST NOT send any further XML data to the Receiving Server over that stream.</p>
</section3>
<section3 topic='Receiving Server Processes Initial Stream Header' anchor='o2r-processinitial'>
@ -221,6 +235,7 @@ R2O: <stream:features>
</dialback>
</stream:features>
]]></example>
<p>Note: If the Receiving Server receives any XML stanzas from the Originating Server before the initial stream has been validated, the Receiving Server MUST silently drop those stanzas.</p>
</section4>
<section4 topic='Error Cases' anchor='o2r-processinitial-error'>
<p>There are several reasons why processing of the initial stream header might fail:</p>
@ -228,7 +243,7 @@ R2O: <stream:features>
<li>The Server Dialback namespace name provided by the Originating Server is incorrect.</li>
<li>The Server Dialback namespace prefix provided by the Originating Server is not supported by the Receiving Server (note: an implementation MAY accept only the 'db:' namespace prefix).</li>
<li>The value of the 'to' address provided by the Originating Server does not match a hostname serviced by the Receiving Server.</li>
<li>Communication with the hostname of the 'from' address provided by the Originating Server is not accepted by the Receiving Server.</li>
<li>The Receiving Server does not accept communication with the hostname of the 'from' address provided by the Originating Server.</li>
</ol>
<p>These error cases are described more fully in the rest of this section.</p>
<p>If the Server Dialback namespace name is incorrect, then the Receiving Server SHOULD generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
@ -280,12 +295,13 @@ R2O: </stream:stream>
</section4>
<section4 topic='Error Cases' anchor='o2r-response-error'>
<p>There are several reasons why processing of the response stream header might fail:</p>
<p>There are several reasons why processing of the response stream header and stream features might fail:</p>
<ol start='1'>
<li>The Server Dialback namespace name provided by the Receiving Server is incorrect.</li>
<li>The Server Dialback namespace prefix provided by the Receiving Server is not supported by the Originating Server (note: an implementation MAY accept only the 'db:' namespace prefix).</li>
<li>The value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Originating Server.</li>
<li>Communication with the hostname of the 'from' address provided by the Receiving Server is not accepted by the Originating Server.</li>
<li>The Originating Server does not accept communication with the hostname of the 'from' address provided by the Receiving Server.</li>
<li>The Receiving Server does not advertise support for Server Dialback via a Server Dialback namespace declaration or stream feature.</li>
</ol>
<p>These error cases are described more fully in the rest of this section.</p>
<p>If the Server Dialback namespace name is incorrect, then the Originating Server SHOULD generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
@ -325,15 +341,17 @@ O2R: <stream:error>
O2R: </stream:stream>
]]></example>
<p>Note: The foregoing error flows specify that the Originating Server SHOULD return a stream error. However, depending on local security policies, the Originating Server MAY silently terminate the XML stream and underlying TCP connection instead of returning a stream error (e.g., to prevent certain denial of service attacks).</p>
<p>If the Receiving Server does not advertise support for Server Dialback via a Server Dialback namespace declaration or stream feature, then the Originating Server's attempt to negotiate Server Dialback fails and the Originating Server SHOULD return a &timeout; stanza error to the local entity that generated the stanza that triggered the Server Dialback attempt in the first place (if any).</p>
</section4>
</section3>
</section2>
<section2 topic='Generation and Exchange of the Dialback Key' anchor='key'>
<section2 topic='Generation and Exchange of Dialback Key' anchor='key'>
<section3 topic='Originating Server Generates Dialback Key' anchor='key-gen'>
<p>Once the Originating Server has established an XML stream with the Receiving Server, it MUST generate a dialback key for verification by the Authoritative Server.</p>
<p>The method for generating (and verifying) the keys used in Server Dialback MUST take into account the following pieces of information:</p>
<ul>
<li>the hostname of the Originating Server</li>
@ -350,7 +368,7 @@ HMAC-SHA256
{Receiving Server, ' ', Originating Server, ' ', Stream ID}
)
]]></example>
<p>The shared secret SHOULD either be set up in a configuration option for each host or process within the Authoritative Server's network or generated as a random string when starting each host or process. The secret's length SHOULD be at least 128 bits or 16 characters long.</p>
<p>The shared secret SHOULD either be set up in a configuration option for each host or process within the Authoritative Server's network or generated as a random string when starting each host or process. The secret's length SHOULD be at least 128 bits or 16 characters long.</p>
<p>Consider the following scenario:</p>
<ul>
<li>The Originating Server is "example.org"</li>
@ -385,7 +403,7 @@ that is,
</section3>
<section3 topic='Originating Server Sends Dialback Key' anchor='key-send'>
<p>Once the Originating Server has processed the response stream header from the Receiving Server and has generated a dialback key for verification by the Receiving Server, it MUST then send that key to the Receiving Server. This is done by creating a &lt;db:result/&gt; element whose XML character data is the dialback key; the element SHOULD possess a 'from' attribute whose value is the hostname of the Originating Server and SHOULD possess a 'to' attribute whose value is the hostname of the Receiving Server.</p>
<p>Once the Originating Server has processed the response stream header from the Receiving Server and has generated a dialback key for verification by the Receiving Server, it MUST then send that key to the Receiving Server. This is done by creating a &lt;db:result/&gt; element whose XML character data is the dialback key; the element MUST possess a 'from' attribute whose value is the hostname of the Originating Server and MUST possess a 'to' attribute whose value is the hostname of the Receiving Server.</p>
<p>Note: All XML elements qualified by the Server Dialback namespace MUST be prefixed with the namespace prefix advertised on the stream header originally sent by the entity sending the element.</p>
<example caption="Originating Server Sends Dialback Key"><![CDATA[
O2R: <db:result
@ -432,55 +450,244 @@ O2R: </stream:stream>
</section2>
<section2 topic='Stream Setup Between Receiving Server and Authoritative Server' anchor='r2a'>
<p>The Receiving Server performs a DNS lookup for the Authoritative Server (in accordance with the procedure described in RFC 3920) and establishes a TCP connection to the Authoritative Server at the IP address and port discovered during the DNS lookup (here assumed to be "192.0.2.23" and "5269"). If the Receiving Server cannot connect to the Authoritive Server, it MUST return a &lt;remote-connection-failed/&gt; stream error to the Originating Server and terminate both the XML stream and the underlying TCP connection.</p>
<p>The Receiving Server sends a stream header to the Authoritative Server:</p>
<example caption="Stream Header"><![CDATA[
<section3 topic='Receiving Server Resolves Authoritative Server' anchor='r2a-resolve'>
<p>Before opening a TCP connection to the Authoritative Server, the Receiving Server must first determine the appropriate IP address and port at which to connect. This is done by resolving the Authoritative Server's hostname ("example.org") using the Domain Name System. As described in <cite>XMPP Core</cite>, the Receiving Server shall first attempt to resolve a TCP service of _xmpp-server for that hostname using DNS SRV records. Here we assume that example.org has the following records in its DNS configuration:</p>
<example caption="DNS SRV Record for Authoritative Server"><![CDATA[
_xmpp-server._tcp.example.org. 86400 IN SRV 10 0 5269 foo.example.org
]]></example>
<p>These records show that server-to-server connections for the XMPP service "example.org" are serviced by the physical machine foo.example.org at port 5269.</p>
<p>The Receiving Server would then resolve that machine to an IP address, in this case "192.0.2.23".</p>
<p>Note: As described in <cite>XMPP Core</cite>, if the Authoritative Server does not provide appropriate DNS SRV records then in order to resolve the hostname of the Authoritative Server the Receiving Server may fall back to normal IPv4/IPv6 address record resolution to determine the IP address and assume a port of 5269 as registered with the IANA.</p>
</section3>
<section3 topic='Receiving Server Opens TCP Connection' anchor='r2a-connect'>
<p>Once the Receiving Server has resolved "example.org" to an IP address of 192.0.2.23 and port of 5269, it opens a TCP connection to that IP and port.</p>
<p>Note: Instead of opening a new TCP connection to the Authoritative Server, the Receiving Server MAY reuse an existing TCP connnection; for details, see the <link url='piggybacking'>Reuse of Negotiated Connections (Piggybacking)</link> section of this document.</p>
</section3>
<section3 topic='Receiving Server Sends Initial Stream Header' anchor='r2a-sendinitial'>
<p>Once the Receiving Server has opened a TCP connection to the resolved IP address and port of the Authoritative Server, it sends an initial stream header to the Authoritative Server as described in <cite>XMPP Core</cite>.</p>
<example caption="Initial Stream Header"><![CDATA[
R2A: <stream:stream
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
xmlns:stream='http://etherx.jabber.org/streams'
from='xmpp.example.com'
to='example.org'
version='1.0'>
]]></example>
<p>Note: If the namespace name is incorrect, then the Authoritative Server MUST generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection. If the value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Authoritative Server, then the Authoritative Server MUST generate a &lt;host-unknown/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<p>The Authoritative Server sends the Receiving Server a stream header:</p>
<example caption="Stream Header"><![CDATA[
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
xmlns:stream='http://etherx.jabber.org/streams'
from='xmpp.example.com'
to='example.org'
version='1.0'>
]]></example>
<p>In addition to the core XMPP rules regarding initial stream headers, the following dialback-related rules apply to the initial stream header:</p>
<ol start='1'>
<li>It MUST include a declaration for the Server Dialback namespace.</li>
<li>The Server Dialback namespace MUST be 'jabber:server:dialback'.</li>
<li>The prefix for the Server Dialback namespace SHOULD be 'db:'.</li>
</ol>
<p>Note: An implementation MAY accept only the 'db:' namespace prefix.</p>
</section3>
<section3 topic='Authoritative Server Processes Initial Stream Header' anchor='r2a-processinitial'>
<p>When the Authoritative Server receives the initial stream header from the Receiving Server, it MUST proceed as follows.</p>
<section4 topic='Success Case' anchor='r2a-processinitial-success'>
<p>If the Authoritative Server can successfully process the initial stream header, it MUST return a response stream header to the Receiving Server over the same TCP connection.</p>
<example caption="Response Stream Header"><![CDATA[
A2R: <stream:stream
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
xmlns:stream='http://etherx.jabber.org/streams'
from='example.org'
id='F92200006D'
id='D60000229F'
to='xmpp.example.com'
version='1.0'>
]]></example>
<p>Note: If any of the namespace names provided by the Authoritative Server is incorrect, then the Receiving Server MUST generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection between it and the Authoritative Server. If the value of the 'to' address provided by the Authoritative Server does not match a hostname serviced by the Receiving Server, then the Receiving Server MUST generate a &lt;host-unknown/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection. If a stream error occurs between the Receiving Server and the Authoritative Server, then the Receiving Server MUST not only terminate the XML stream and the underlying TCP connection between it and the Authoritative Server but also terminate the XML stream and the underlying TCP connection between it and the Originating Server, generating a &lt;remote-connection-failed/&gt; stream error for the latter stream.</p>
<p>The Authoritative Server SHOULD also send stream features to the Receiving Server, including the dialback feature:</p>
<example caption="Stream Header"><![CDATA[
]]></example>
<p>In addition to the core XMPP rules regarding response stream headers, the following dialback-related rules apply to the response stream header:</p>
<ol start='1'>
<li>If the initial stream header included a Server Dialback namespace declaration and the Authoritative Server supports the Server Dialback protocol, the response stream header also MUST include a declaration for the Server Dialback namespace.</li>
<li>If the initial stream header did not include a Server Dialback namespace declaration and the Authoritative Server supports the Server Dialback protocol, the response stream header MAY include a Server Dialback namespace declaration.</li>
<li>If the response stream header includes a Server Dialback namespace declaration, the Server Dialback namespace MUST be 'jabber:server:dialback' and the prefix for the Server Dialback namespace SHOULD be 'db:'.</li>
</ol>
<p>After sending the response stream header, the Authoritative Server shall also send stream features to the Receiving Server. The Authoritative Server SHOULD include the dialback feature in its initial stream features advertisement, including an indication of whether Server Dialback negotiation is optional or required.</p>
<example caption="Stream Features"><![CDATA[
A2R: <stream:features>
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
<dialback xmlns='urn:xmpp:features:dialback'/>
<dialback xmlns='urn:xmpp:features:dialback'>
<optional/>
</dialback>
</stream:features>
]]></example>
]]></example>
</section4>
<section4 topic='Error Cases' anchor='r2a-processinitial-error'>
<p>There are several reasons why processing of the initial stream header might fail:</p>
<ol start='1'>
<li>The Server Dialback namespace name provided by the Receiving Server is incorrect.</li>
<li>The Server Dialback namespace prefix provided by the Receiving Server is not supported by the Authoritative Server (note: an implementation MAY accept only the 'db:' namespace prefix).</li>
<li>The value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Authoritative Server.</li>
<li>The Authoritative Server does not accept communication with the hostname of the 'from' address provided by the Receiving Server.</li>
</ol>
<p>These error cases are described more fully in the remainder of this section.</p>
<p>If the Server Dialback namespace name is incorrect, then the Authoritative Server SHOULD generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Invalid Namespace"><![CDATA[
A2R: <stream:error>
<invalid-namespace
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
A2R: </stream:stream>
]]></example>
<p>If the Server Dialback namespace prefix is not supported by the Authoritative Server, then the Authoritative Server SHOULD generate a &lt;bad-namespace-prefix/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Bad Namespace Prefix"><![CDATA[
A2R: <stream:error>
<bad-namespace-prefix
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
A2R: </stream:stream>
]]></example>
<p>If the value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Authoritative Server, then the Authoritative Server SHOULD generate a &lt;host-unknown/&gt; or &lt;host-gone/&gt; stream error condition (as appropriate) and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Host Unknown"><![CDATA[
A2R: <stream:error>
<host-unknown
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
A2R: </stream:stream>
]]></example>
<p>If the Authoritative Server does not allow communication with the hostname of the 'from' address provided by the Receiving Server, then the Authoritative Server SHOULD generate a &lt;not-authorized/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Not Authorized"><![CDATA[
A2R: <stream:error>
<not-authorized
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
A2R: </stream:stream>
]]></example>
<p>Note: The foregoing error flows specify that the Authoritative Server SHOULD return a stream error. However, depending on local security policies, the Authoritative Server MAY silently terminate the XML stream and underlying TCP connection instead of returning a stream error (e.g., to prevent certain denial of service attacks).</p>
</section4>
</section3>
<section3 topic='Receiving Server Processes Response Stream Header' anchor='r2a-processresponse'>
<p>When the Receiving Server receives the response stream header from the Authoritative Server, it MUST proceed as follows.</p>
<section4 topic='Success Case' anchor='r2a-processresponse-success'>
<p>If the response stream header can be successfully processed, the Receiving Server MUST send the dialback key it received from the Originating Server as described under <link url='verify'>Exchange of Verification Request between Receiving Server and Authoritative Server</link>.</p>
</section4>
<section4 topic='Error Cases' anchor='r2a-response-error'>
<p>There are several reasons why processing of the response stream header and stream features might fail:</p>
<ol start='1'>
<li>The Server Dialback namespace name provided by the Authoritative Server is incorrect.</li>
<li>The Server Dialback namespace prefix provided by the Authoritative Server is not supported by the Receiving Server (note: an implementation MAY accept only the 'db:' namespace prefix).</li>
<li>The value of the 'to' address provided by the Authoritative Server does not match a hostname serviced by the Receiving Server.</li>
<li>The Receiving Server does not accept communication with the hostname of the 'from' address provided by the Authoritative Server.</li>
<li>The Authoritative Server does not advertise support for Server Dialback via a Server Dialback namespace declaration or stream feature.</li>
</ol>
<p>These error cases are described more fully in the remainder of this section.</p>
<p>If the Server Dialback namespace name is incorrect, then the Receiving Server SHOULD generate an &lt;invalid-namespace/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Invalid Namespace"><![CDATA[
R2A: <stream:error>
<invalid-namespace
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>If the Server Dialback namespace prefix is not supported by the Receiving Server, then the Receiving Server SHOULD generate a &lt;bad-namespace-prefix/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Bad Namespace Prefix"><![CDATA[
R2A: <stream:error>
<bad-namespace-prefix
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>If the value of the 'to' address provided by the Authoritative Server does not match a hostname serviced by the Receiving Server, then the Receiving Server SHOULD generate a &lt;host-unknown/&gt; or &lt;host-gone/&gt; stream error condition (as appropriate) and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Host Unknown"><![CDATA[
R2A: <stream:error>
<host-unknown
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>If the Receiving Server does not allow communication with the hostname of the 'from' address provided by the Authoritative Server, then the Receiving Server SHOULD generate a &lt;not-authorized/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Not Authorized"><![CDATA[
R2A: <stream:error>
<not-authorized
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>Note: The foregoing error flows specify that the Receiving Server SHOULD return a stream error. However, depending on local security policies, the Receiving Server MAY silently terminate the XML stream and underlying TCP connection instead of returning a stream error (e.g., to prevent certain denial of service attacks).</p>
<p>If the Authoritative Server does not advertise support for Server Dialback via a Server Dialback namespace declaration or stream feature, then the Receiving Server's attempt to request verification of the Originating Server's dialback key fails and the Receiving Server MUST return a &remoteconnection; stream error to the Originating Server.</p>
</section4>
</section3>
</section2>
<section2 topic='Exchange of Verification Request between Receiving Server and Authoritative Server' anchor='verify'>
<p>The Receiving Server sends the Authoritative Server a request for verification of a key:</p>
<example caption="Verification Request"><![CDATA[
<section2 topic='Exchange of Verification Request' anchor='verify'>
<section3 topic='Receiving Server Sends Verification Request' anchor='verify-send'>
<p>Once the Receiving Server has established an XML stream with the Authoritative Server, it MUST send to the Authoritative Server the dialback key it received from the Originating Server. This is done by creating a &lt;db:verify/&gt; element whose XML character data is the dialback key; the element MUST possess a 'from' attribute whose value is the hostname of the Receiving Server, MUST possess a 'to' attribute whose value is the hostname of the Originating Server, and MUST possess an 'id' attribute whose value is the stream identifier from the Receiving Server's response stream header to the Originating Server.</p>
<p>Note: All XML elements qualified by the Server Dialback namespace MUST be prefixed with the namespace prefix advertised on the stream header originally sent by the entity sending the element.</p>
<example caption="Receiving Server Sends Verification Request"><![CDATA[
R2A: <db:verify
from='xmpp.example.com'
id='D60000229F'
to='example.org'>
37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:verify>
]]></example>
<p>Note: Passed here are the hostnames of the Receiving Server ('from') and the Originating Server ('to'), 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 5. Based on this information, as well as shared secret information within the Authoritative Server's network, the Authoritative Server determines whether the key is valid or invalid. If the value of the 'to' address does not match a hostname serviced by the Authoritative Server, then the Authoritative Server MUST generate a &lt;host-unknown/&gt; 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 sent by the Receiving Server in the 'from' address of the stream header it sent to the Authoritative Server in Step 7, then the Authoritative Server MUST generate an &lt;invalid-from/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
]]></example>
</section3>
<section3 topic='Authoritative Server Processes Verification Request' anchor='verify-process'>
<section4 topic='Success Case' anchor='verify-process-success'>
<p>If the verification request can be successfully processed, the Authoritative Server MUST validate the dialback key it received from the Receiving Server as described under <link url='validate'>Validation of Dialback Key by Authoritative Server</link>.</p>
</section4>
<section4 topic='Error Cases' anchor='verify-process-error'>
<p>There are several reasons why processing of the verification request might fail:</p>
<ol start='1'>
<li>The value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Authoritative Server's network.</li>
<li>The value of the 'from' address provided by the Receiving Server does not match the hostname sent by the Receiving Server in the 'from' address of the initial stream header it sent to the Authoritative Server.</li>
</ol>
<p>These error cases are described more fully in the remainder of this section.</p>
<p>If the value of the 'to' address provided by the Receiving Server does not match a hostname serviced by the Authoritative Server's network, then the Authoritative Server MUST generate a &lt;host-unknown/&gt; or &lt;host-gone/&gt; stream error condition (as appropriate) and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Host Unknown"><![CDATA[
R2A: <stream:error>
<host-unknown
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>If the value of the 'from' address provided by the Receiving Server does not match the hostname sent by the Receiving Server in the 'from' address of the initial stream header it sent to the Authoritative Server, then the Authoritative Server MUST generate an &lt;invalid-from/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Invalid From"><![CDATA[
R2A: <stream:error>
<invalid-from
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Validation of Verification Request by Authoritative Server' anchor='validate'>
<p>The Authoritative Server determines whether the key was valid or invalid and informs the Receiving Server of its determination, where the &lt;db:verify/&gt; element SHOULD include the key sent by the Receiving Server:</p>
<example caption="Key is Valid"><![CDATA[
<section2 topic='Validation of Dialback Key and Exchange of Validation Result' anchor='validate'>
<section3 topic='Authoritative Server Determines Validity of Dialback Key' anchor='validate-determine'>
<p>If the Authoritative Server can successfully process the verification request, it MUST determine whether the key is valid or invalid.</p>
<p>The key shall be considered <em>valid</em> if the Authoritative Server determines that the key matches the output it would have produced using its key generation algorithm with the inputs specified in the XML attributes of the verification request along with its shared secret.</p>
<p>The key shall be considered <em>invalid</em> if the Authoritative Server determines that the key does not match the output it would have produced using its key generation algorithm with the inputs specified in the XML attributes of the verification request along with its shared secret.</p>
</section3>
<section3 topic='Authoritative Server Sends Validation Result' anchor='validate-send'>
<p>Once the Authoritative Server determines whether the key is valid or invalid, it MUST inform the Receiving Server of its determination. This is done by creating a &lt;db:verify/&gt; element whose XML character data is the dialback key; the element MUST possess a 'from' attribute whose value is the hostname of the Originating Server, MUST possess a 'to' attribute whose value is the hostname of the Receiving Server, MUST possess an 'id' attribute whose value is the stream identifier from the Receiving Server's response stream header to the Originating Server as communicated in the verification request, and MUST possess a 'type' attribute whose value is either "valid" or "invalid".</p>
<example caption="Key is Valid"><![CDATA[
A2R: <db:verify
from='example.org'
id='D60000229F'
@ -488,9 +695,9 @@ A2R: <db:verify
type='valid'>
37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:verify>
]]></example>
<p>Or:</p>
<example caption="Key is Invalid"><![CDATA[
]]></example>
<p>Or:</p>
<example caption="Key is Invalid"><![CDATA[
A2R: <db:verify
from='example.org'
id='D60000229F'
@ -498,30 +705,91 @@ A2R: <db:verify
type='invalid'>
37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:verify>
]]></example>
<p>Note: If the ID does not match that provided by the Receiving Server in Step 3, then the Receiving Server MUST generate an &lt;invalid-id/&gt; 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 serviced by the Receiving Server, then the Receiving Server MUST generate a &lt;host-unknown/&gt; 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 in the 'from' address of the stream header it sent to the Receiving Server in Step 2, then the Receiving Server MUST generate an &lt;invalid-from/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection. After receiving the verification from the Authoritative Server, the Receiving Server SHOULD terminate the stream between them and the underlying TCP connection.</p>
]]></example>
</section3>
<section3 topic='Receiving Server Processes Validation Result' anchor='validate-process'>
<section4 topic='Success Case' anchor='validate-process-success'>
<p>If the validation result can be successfully processed, the Receiving Server MUST inform the Originating Server of the Server Dialback results described under <link url='result'>Communication of Result from Receiving Server to Originating Server</link>. The Receiving Server then SHOULD also terminate the XML stream and the underlying TCP connection between the Receiving Server and the Authoritative Server.</p>
</section4>
<section4 topic='Error Cases' anchor='validate-process-error'>
<p>There are several reasons why processing of the validation result might fail:</p>
<ol start='1'>
<li>The value of the 'id' attribute does not match that provided by the Receiving Server in the verification request.</li>
<li>The value of the 'from' address does not match the hostname represented by the Originating Server in the 'from' address of the initial stream header it sent to the Receiving Server.</li>
<li>The value of the 'to' address does not match a hostname serviced by the Receiving Server.</li>
</ol>
<p>These error cases are described more fully in the remainder of this section.</p>
<p>If the value of the 'id' attribute does not match that provided by the Receiving Server in the verification request, then the Receiving Server MUST generate an &lt;invalid-id/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection between it and the Authoritative Server.</p>
<example caption="Invalid ID"><![CDATA[
R2A: <stream:error>
<invalid-id
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>The value of the 'from' address does not match the hostname represented by the Originating Server in the 'from' address of the initial stream header it sent to the Receiving Server, then the Receiving Server MUST generate an &lt;invalid-from/&gt; stream error condition and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Invalid From"><![CDATA[
R2A: <stream:error>
<invalid-from
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
<p>If the value of the 'to' address does not match a hostname serviced by the Receiving Server, then the Receiving Server MUST generate a &lt;host-unknown/&gt; or &lt;host-gone/&gt; stream error condition (as appropriate) and terminate both the XML stream and the underlying TCP connection.</p>
<example caption="Host Unknown"><![CDATA[
R2A: <stream:error>
<host-unknown
xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
</stream:error>
R2A: </stream:stream>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Communication of Result From Receiving Server to Originating Server' anchor='result'>
<p>The Receiving Server informs the Originating Server of the result, where the &lt;db:result/&gt; element SHOULD include the key sent by the Originating Server:</p>
<example caption="Result"><![CDATA[
<section2 topic='Communication and Handling of Verification Result' anchor='result'>
<section3 topic='Receiving Server Communicates Verification Result' anchor='result-communicate'>
<p>Once the Receiving Server successfully processes the validation result it received from the Authoritative Server, it informs the Originating Server of the result. This is done by creating a &lt;db:result/&gt; element whose XML character data is the dialback key; the element MUST possess a 'from' attribute whose value is the hostname of the Receiving Server, MUST possess a 'to' attribute whose value is the hostname of the Originating Server, MUST possess an 'id' attribute whose value is the stream identifier from the Receiving Server's response stream header to the Originating Server, and MUST possess a 'type' attribute whose value is either "valid" or "invalid".</p>
<example caption="Receiving Server Sends Verification Result"><![CDATA[
R2O: <db:result
from='xmpp.example.com'
to='example.org'
type='valid'>
37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643
</db:result>
]]></example>
<p>Note: At this point, the connection from the Originating Server to the Receiving Server has either been validated or reported as invalid. If the connection is invalid, then the Receiving Server MUST terminate both the XML stream and the underlying TCP connection between itself and the Originating Server. If the connection is valid, the Receiving Server has verified the identity of the Originating Server; as a result, the Originating Server may now send XML stanzas to the Receiving Server over the validated connection (i.e., over the "initial stream" from the Originating Server to the Receiving Server).</p>
<p>Until the initial stream has been validated, the Originating Server MUST NOT send any further XML data to the Receiving Server. If it receives any XML stanzas from the Originating Server before the initial stream has been validated, the Receiving Server MUST silently drop them.</p>
<p>After successful dialback negotiation, the Receiving Server MUST follow the rules specified in RFC 3920 regarding inclusion and checking of 'from' and 'to' attributes on all XML stanzas it receives from the Originating Server. These checks help to prevent address spoofing.</p>
<p>As mentioned, Server Dialback results in weak identity verification in one direction only (in the foregoing text, verification of the Originating Server by the Receiving Server). In order to proceed with bi-directional communication so that the Receiving Server may sent XML stanzas to the Originating Server, the Receiving Server MUST now also initiate a dialback negotiation with the Originating Server (this happens on a different TCP connection).</p>
]]></example>
</section3>
<section3 topic='Receiving Server Handles Verification Result' anchor='result-handle'>
<section4 topic='Invalid Connection' anchor='result-handle-invalid'>
<p>If the Authoritative Server reported the dialback key as invalid, then the Receiving Server MUST terminate both the XML stream and the underlying TCP connection between itself and the Originating Server.</p>
</section4>
<section4 topic='Valid Connection' anchor='result-handle-valid'>
<p>If the Authoritative Server reported the dialback key as valid, the Receiving Server has verified the identity of the Originating Server. As a result, the Receiving Server may now accept XML stanzas from the Originating Server over the validated connection (i.e., over the "initial stream" from the Originating Server to the Receiving Server). However, in accordance with <cite>XMPP Core</cite>, the Receiving Server MUST follow the rules specified therein regarding inclusion and checking of 'from' and 'to' attributes on all XML stanzas it receives from the Originating Server. These checks help to prevent address spoofing.</p>
<p>Note: If the Receiving Server receives any XML stanzas from the Originating Server before the initial stream has been validated, the Receiving Server MUST silently drop those stanzas.</p>
<p>As mentioned, Server Dialback results in weak identity verification in one direction only (in the foregoing text, verification of the Originating Server by the Receiving Server). In order to proceed with bi-directional communication so that the Receiving Server may send XML stanzas to the Originating Server, the Receiving Server MUST now also initiate a dialback negotiation with the Originating Server (i.e., assume the role of an originating server in a new dialback negotiation).</p>
</section4>
</section3>
</section2>
</section1>
<section1 topic="Reuse of Negotiated Connections" anchor="piggybacking">
<p>After the Receiving Server has validated the connection from the Originating Server, the Originating Server may wish to reuse that connection for validation of additional domains. This feature is called PIGGYBACKING. Support for piggybacking is OPTIONAL.</p>
<p>One common motivation for such reuse is the existence of additional services associated with the Originating Server but hosted at subdomains of the Originating Server (the use of subdomains helps to ensure proper routing of XML stanzas to the hosted services). For example, the "example.org" XMPP server may host a groupchat service at "chat.example.org". In order to accept XML stanzas from rooms at "chat.example.org" intended for addresses at "xmpp.example.com", the "xmpp.example.com" domain will need to validate the "chat.example.org" domain (just as it already did for the "example.org" domain). Thus the "example.org" server would now initiate a dialback negotiation with "xmpp.example.com" but specify the Originating Server as "chat.example.org".</p>
<section1 topic="Reuse of Negotiated Connections (Piggybacking)" anchor="piggybacking">
<p>After the Receiving Server has validated a connection from the Originating Server, the Originating Server may wish to reuse that connection for validation of additional domains. This feature is called PIGGYBACKING. Support for piggybacking is OPTIONAL.</p>
<p>One common motivation for such reuse is the existence of additional services associated with the Originating Server but hosted at subdomains of the Originating Server (the use of subdomains helps to ensure proper routing of XML stanzas to the hosted services). For example, the "example.org" XMPP server may host a groupchat service at "chat.example.org". In order to accept XML stanzas from rooms at "chat.example.org" intended for addresses at "xmpp.example.com", the "xmpp.example.com" domain will need to validate the "chat.example.org" domain (just as it already did for the "example.org" domain). Thus the "example.org" server would now initiate a dialback negotiation with "xmpp.example.com" but specify the Originating Server as "chat.example.org".</p>
<p>However, because the "example.org" server already has a validated connection open to the Receiving Server ("xmpp.example.com"), it MAY send a &lt;db:result/&gt; element with the key to be validated for the new Originating Server ("chat.example.org") over the XML stream that has already been negotiated, rather than opening a new TCP connection and XML stream.</p>
<example caption="Piggybacked Key"><![CDATA[
O2R: <db:result
@ -530,7 +798,7 @@ O2R: <db:result
88a96894060d5f4258c37cd51b772e5a483430d8203f71d3782cac72a0866458
</db:result>
]]></example>
<p>The Receiving Server SHOULD accept this &lt;db:result/&gt; element (as it did for the first &lt;db:result/&gt; element) and process it according to the rules already specified. If that process is successful, it would eventually result in sending of a &lt;db:result/&gt; element from the Receiving Server to the Originating Server.</p>
<p>The Receiving Server SHOULD accept this &lt;db:result/&gt; element (as it did for the first &lt;db:result/&gt; element) and process it according to the rules already specified. If that process is successful, it would eventually result in sending of a &lt;db:result/&gt; element from the Receiving Server to the Originating Server.</p>
<example caption="Piggybacked Result"><![CDATA[
R2O: <db:result
from='xmpp.example.com'
@ -548,37 +816,11 @@ R2O: <db:result
88a96894060d5f4258c37cd51b772e5a483430d8203f71d3782cac72a0866458
</db:result>
]]></example>
</section1>
<section1 topic="Determining Support" anchor="support">
<p>Support for the Server Dialback protocol can be indicated in two ways:</p>
<ol start='1'>
<li>By inclusion of the Server Dialback feature in a given set of stream features; this is REQUIRED for XMPP 1.0 servers, but not supported by older implementations and deployments.</li>
<li>By inclusion of the dialback namespace declaration in the stream header; this is REQUIRED for all servers.</li>
</ol>
<p>The former method is preferred, but the latter method is also specified herein for the purpose of backwards-compatibility with older "XMPP 0.9" deployments.</p>
<p>The Server Dialback stream feature is advertised by including in any given set of stream features a &lt;dialback/&gt; element qualified by the 'urn:xmpp:features:dialback' namespace; the &lt;dialback/&gt; element MAY also include an empty &lt;required/&gt; element, indicating that the entity sending the stream features requires dialback to be negotiated for the stream.</p>
<example caption="Stream Features"><![CDATA[
<stream:features>
<dialback xmlns='urn:xmpp:features:dialback'>
<required/>
</dialback>
</stream:features>
]]></example>
<p>As mentioned, support for the Server Dialback protocol can also be advertised by including the dialback namespace declaration in a stream header.</p>
<example caption="Stream Header"><![CDATA[
<stream:stream
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
xmlns:stream='http://etherx.jabber.org/streams'
from='example.com'
to='example.net'>
]]></example>
<p>No matter which method is used, a service SHOULD advertise support for Server Dialback only at a point in the stream negotiation when it will accept negotiation of Server Dialback for that stream. For example, if a service wishes to be backwards-compatible with older "XMPP 0.9" deployments, it SHOULD include the Server Dialback namespace declaration in the initial stream header it sends to other servers (so that "XMPP 0.9" servers can proceed with dialback in the absence of TLS and SASL authentication). However, in the midst of stream negotiation with an XMPP 1.0 or higher server, a service SHOULD advertise the dialback stream feature only at a point when negotiation of Server Dialback is allowed in accordance with local service policies (e.g., after TLS negotiation in the case when a self-signed certificate was presented by the Originating Server and local service policies stipulate that it is preferable to weakly identify the Originating Server via Server Dialback rather than depend on the self-signed certificate for identity verification).</p>
<p>Note: a &lt;db:result/&gt; element of type "error" MUST NOT be considered a stream error and therefore MUST NOT result in termination of the stream and the underlying TCP connection, which presumably is being used for sending XML stanzas from the Originating Server to the Receiving Server.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>Server dialback helps protect against domain spoofing, thus making it more difficult to spoof XML stanzas. It is not a mechanism for authenticating, securing, or encrypting streams between servers as is done via SASL and TLS, and results in weak verification of server identities only. Furthermore, it is susceptible to DNS poisoning attacks unless DNSSEC (see &rfc4033;) is used, and even if the DNS information is accurate, dialback cannot protect from attacks where the attacker is capable of hijacking the IP address of the remote domain. Domains requiring robust security SHOULD use TLS and SASL. If SASL is used for server-to-server authentication, dialback SHOULD NOT be used since it is unnecessary.</p>
<p>Server Dialback helps protect against domain spoofing, thus making it more difficult to spoof XML stanzas. It is not a mechanism for authenticating, securing, or encrypting streams between servers as is done via SASL and TLS, and results in weak verification of server identities only. Furthermore, it is susceptible to DNS poisoning attacks unless DNSSEC (see &rfc4033;) is used. Even if the DNS information is accurate, Server Dialback cannot protect against attacks where the attacker is capable of hijacking the IP address of the remote domain. Domains requiring robust security SHOULD use TLS and SASL. If SASL is used for server-to-server authentication, Server Dialback SHOULD NOT be used since it is unnecessary.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
@ -662,10 +904,8 @@ R2O: <db:result
<xs:element name='dialback'>
<xs:complexType>
<xs:choice minOccurs='1' maxOccurs='1'>
<xs:element name='required'
type='empty'/>
<xs:element name='required'
type='empty'/>
<xs:element name='optional' type='empty'/>
<xs:element name='required' type='empty'/>
</xs:choice>
</xs:complexType>