1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-24 18:22:24 -05:00
This commit is contained in:
Peter Saint-Andre 2012-07-11 11:46:26 -06:00
parent a0f85c6073
commit 23f528de57

View File

@ -7,7 +7,7 @@
<xep> <xep>
<header> <header>
<title>Server Dialback</title> <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 accepts a server-to-server connection from an originating server, it does not process traffic over the connection 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, it has effectively prevented most instances of address spoofing on the XMPP network since its development in the year 2000.</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 accepts a server-to-server connection from an initiating server, it does not process traffic over the connection 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, it has effectively prevented most instances of address spoofing on the XMPP network since its development in the year 2000.</abstract>
&LEGALNOTICE; &LEGALNOTICE;
<number>0220</number> <number>0220</number>
<status>Experimental</status> <status>Experimental</status>
@ -29,9 +29,9 @@
<jid>fippo@psyced.org</jid> <jid>fippo@psyced.org</jid>
</author> </author>
<revision> <revision>
<version>0.13rc2</version> <version>0.13rc3</version>
<initials>ph/psa</initials> <initials>ph/psa</initials>
<date>work in progress, last updated 2012-06-27</date> <date>2012-07-10</date>
<remark> <remark>
<ul> <ul>
<li>Allowed same SRV target in multiplexing business</li> <li>Allowed same SRV target in multiplexing business</li>
@ -42,6 +42,12 @@
<li>Added another figure for the examples, reordered examples accordingly.</li> <li>Added another figure for the examples, reordered examples accordingly.</li>
<li>Notes about verify-only connections.</li> <li>Notes about verify-only connections.</li>
<li>Added note about bouncing stanzas with an &lt;internal-server-error/&gt; stanza error in section 2.1.1</li> <li>Added note about bouncing stanzas with an &lt;internal-server-error/&gt; stanza error in section 2.1.1</li>
<li>Clarified explanations thoughout the document.</li>
<li>Added terminology section.</li>
<li>Removed hokey telephone analogy.</li>
<li>Removed section about when dialback is used, since it was misleading.</li>
<li>Removed text about dialback offering only weak identify verification, since verification can be strong if DNSSEC is used.</li>
<li>Corrected XML schema to support mixed content model with &lt;error/&gt; child.</li>
</ul> </ul>
</remark> </remark>
</revision> </revision>
@ -67,7 +73,7 @@
<version>0.9</version> <version>0.9</version>
<date>2011-04-25</date> <date>2011-04-25</date>
<initials>psa</initials> <initials>psa</initials>
<remark><p>To reduce the possibility of confusion, harmonized the protocol sections so that they show only the first dialback negotiation from Originating Server to Receiving Server.</p></remark> <remark><p>To reduce the possibility of confusion, harmonized the protocol sections so that they show only the first dialback negotiation from Initiating Server to Receiving Server.</p></remark>
</revision> </revision>
<revision> <revision>
<version>0.8</version> <version>0.8</version>
@ -153,50 +159,44 @@
<section1 topic="Introduction" anchor="intro"> <section1 topic="Introduction" anchor="intro">
<section2 topic="Why Dialback?" anchor="intro-why"> <section2 topic="Why Dialback?" anchor="intro-why">
<p>When Jabber technologies were first developed in 1998, they were conceived of as a client-server system similar to email, wherein a client would connect to a server in order to communicate with other clients. Similarly, servers would connect with peer servers to provide inter-domain communication (often called "federation"). In a system that allows federation, it is important for a server to be able to determine the identity of a peer server; accepting a connection from any peer without determining its identity would result in the use of merely asserted identities and a completely uncontrolled approach to federation, which on the open Internet would rapidly devolve into chaos. Clearly such a state of affairs would be unsustainable for a network protocol aiming for widespread deployment.</p> <p>When Jabber technologies were first developed in 1998, they were conceived of as a client-server system similar to email, wherein a client would connect to a server in order to communicate with other clients. Similarly, servers would connect with peer servers to provide inter-domain communication (often called "federation"). In a system that allows federation, it is important for a server to be able to determine the identity of a peer server; accepting a connection from any peer without determining its identity would result in the use of merely asserted identities and a completely uncontrolled approach to federation, which on the open Internet would rapidly devolve into chaos. Clearly such a state of affairs would be unsustainable for a network protocol aiming for widespread deployment.</p>
<p>Such potential chaos was the state of affairs on the Jabber network during the earliest releases of the original &jabberd; server codebase (up through the 1.0 release in May 2000). Therefore the Jabber developer community designed a protocol ("Server Dialback") for weak identity verification based on the Domain Name System (DNS), built support for that protocol into the jabberd 1.2 server (released in October 2000), and mandated support for that protocol on the emerging Jabber server network.</p> <p>Such potential chaos was the state of affairs on the Jabber network during the earliest releases of the original &jabberd; server codebase (up through the 1.0 release in May 2000). Therefore the Jabber developer community designed a protocol called "Server Dialback" for identity verification based on the Domain Name System (DNS), built support for that protocol into the jabberd 1.2 server (released in October 2000), and mandated support for that protocol on the emerging Jabber server network.</p>
<p>When the early Jabber protocols were formalized by the XMPP Working Group of the &IETF; in 2002-2004, support for strong identity verification was added. That support takes the form of Transport Layer Security (TLS) for encryption of server-to-server XML streams and the Simple Authentication and Security Layer (SASL) for authentication of such streams, typically using digital certificates issued by trusted root certificate authorities (CAs). However, the Server Dialback protocol is still in wide use, and probably will be for the foreseeable future given the perceived difficulty of obtaining digital certificates issued by common CAs. Therefore it is important to maintain accurate documentation of the Server Dialback protocol. Such documentation was originally provided in &rfc3920;. Although that documentation was removed from &rfc6120;, it is still provided in this specification for the sake of interoperability.</p> <p>The basic idea behind Server Dialback is that a receiving server does not accept XMPP traffic from a sending server until it has (a) "called back" the authoritative server for the domain asserted by the sending server and (b) verified that the sending server is truly authorized to generate XMPP traffic for that domain.</p>
<p>When the early Jabber protocols were formalized by the XMPP Working Group of the &IETF; in 2002-2004, support for strong identity verification was added (see &rfc3920;). That support takes the form of Transport Layer Security (TLS) for encryption of server-to-server XML streams and the Simple Authentication and Security Layer (SASL) for authentication of such streams, typically using digital certificates issued by trusted root certification authorities (CAs). However, the Server Dialback protocol is still in wide use, and probably will be for the foreseeable future given the perceived difficulty of obtaining digital certificates issued by common CAs. In addition, the slow but steady deployment of the DNS security extensions (DNSSEC) &rfc4033; can provide a stronger basis for using Server Dialback, as explored in &dna-dns;. Therefore it is important to maintain accurate documentation of the Server Dialback protocol.</p>
</section2> </section2>
<section2 topic="What Dialback Accomplishes" anchor="intro-what"> <section2 topic="What Dialback Accomplishes" anchor="intro-what">
<p>Server Dialback is a method for weak identity verification. Such verification depends on the Domain Name System (DNS) and the use of keys based on a shared secret known to all XMPP servers within a given administrative domain. It is a proof-of-possession protocol in the sense of &rfc4949; which asserts that the Originating Server and the Authoritative Server are associated with each other.</p> <p>Server Dialback is a method for identity verification: if the dialback negotiation succeeds, the receiving server for an XML stream can associate a pair of domain names with the stream (on the concept of a domain name association, see &dna-framework;); those two domain names are the sender domain asserted by the initiating server and the domain name at the receiving server that the initiating server has indicated it wishes to communicate with.</p>
<p>Since October 2000, the use of Server Dialback has made it more difficult to spoof the hostnames of servers (and therefore the addresses of sent messages) on the XMPP network. However, Server Dialback does not provide authentication between servers and is not a security mechanism. Domains requiring high security are advised to use TLS and SASL with certificates issued by trusted roots.</p> <p>The verification accomplished in Server Dialback depends on the Domain Name System (DNS) and the use of keys based on a shared secret known to all XMPP servers within a given administrative domain. It is a proof-of-possession protocol in the sense of &rfc4949; which asserts that the initiating server and the authoritative server are associated with each other. The relative strength or weakness of the verificaiton depends in part on the strength or weakness of the process for resolving the domain names of the authoritative server; in particular, if DNSSEC is not used then Server Dialback results in weak identity verification, whereas if DNSSEC is used then Server Dialback can result in fairly strong identity verification.</p>
<p>Server Dialback is unidirectional, and results in weak identity verification for one XML stream in one direction. Because Server Dialback is not an authentication mechanism, mutual authentication is not possible via dialback. Therefore, Server Dialback needs to be completed in each direction in order to enable bidirectional communication between two domains.</p> <p>Since October 2000, the use of Server Dialback (even absent DNSSEC) has made it more difficult to spoof the hostnames of servers (and therefore the addresses of sent messages) on the XMPP network.</p>
<p>Server Dialback is unidirectional, and results in weak verification for one XML stream in one direction. Because mutual authentication is not achieved directly by this protocol, Server Dialback needs to be completed in each direction in order to enable bidirectional communication between two domains.</p>
<p>Dialback does not verify that the IP address returned by a DNS lookup of the originating domain is the same as the source IP address of the inbound TCP connection. While this might often be true, not performing this check enables large deployments to separate inbound and outbound message routing.</p> <p>Dialback does not verify that the IP address returned by a DNS lookup of the originating domain is the same as the source IP address of the inbound TCP connection. While this might often be true, not performing this check enables large deployments to separate inbound and outbound message routing.</p>
</section2> </section2>
<section2 topic="When Dialback Is Used" anchor="intro-when"> <section2 topic="Terminology" anchor="intro-terms">
<p>Server Dialback is typically used in two scenarios:</p> <p>This document uses the following terms.</p>
<ol start='1'> <dl>
<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> <di><dt>Authoritative Server</dt><dd>The machine that is discovered by means of a DNS lookup for the Sender Domain; for simple deployments this will be the Initiating Server, but it could be a separate machine in the Initiating Server's network (where "network" is defined by knowledge of a shared secret for verification of dialback keys).</dd></di>
<li><p>When STARTTLS negotiation succeeds with a peer service but the peer's certificate cannot be used to establish the peer's identity.</p></li> <di><dt>Domain Pair</dt><dd>The combination of the Sender Domain and Target Domain.</dd></di>
</ol> <di><dt>Initiating Server</dt><dd>The machine that wants to send a message from an entity at the Sender Domain to an entity at the Target Domain (and thus the machine that is attempting to establish a domain name association between the Target Domain and the XML stream from the Initiating Server to the Receiving Server). Note well that in older documentation of the Server Dialback protocol, this was called the Originating Server.</dd></di>
<p>Both of these scenarios result in an untrusted connection. However, depending on local security policies, a server might accept such an untrusted connection if the use of Server Dialback results in weak identity verification.</p> <di><dt>Receiving Server</dt><dd>The machine to which the Initiating Server has opened a connection for the purpose of sending a message from the Sender Domain to the Target Domain (and thus the machine that is trying to verify that the Initiating Server represents the Sender Domain).</dd></di>
<di><dt>Sender Domain</dt><dd>The domain name asserted by the Initiating Server as the domainpart of the XMPP 'from' address of stanzas that will flow over the XML stream from the Initiating Server to the Receiving Server.</dd></di>
<di><dt>Target Domain</dt><dd>The domain name specified by the Initiating Server as the domainpart of the XMPP 'to' address of stanzas that will flow over the XML stream from the Initiating Server to the Receiving Server.</dd></di>
</dl>
</section2> </section2>
<section2 topic="How Dialback Works" anchor="intro-howitworks"> <section2 topic="How Dialback Works" anchor="intro-howitworks">
<p>The basic idea behind Server Dialback is that a receiving server does not accept XMPP traffic from a sending server until it has (a) "called back" the authoritative server for the domain asserted by the sending server and (b) verified that the sending server is truly authorized to generate XMPP traffic for that domain.</p>
<p>A helpful analogy might be the following telephone scenario:</p>
<ol start='1'>
<li>A worker from your electric utility company knocks on your front door and says he needs to enter your house to check your usage meter.</li>
<li>Rather than letting him in, you ask for his employee ID number and politely close the door for a few moments.</li>
<li>You open the phone book, find the authoritative phone number for the utility company's headquarters, and call them on the phone.</li>
<li>After being transferred to the customer service department, you ask if a worker with that particular ID number is authorized to be visiting your house.</li>
<li>The company tells you that the worker is authorized, so you thank them and hang up.</li>
<li>You then reopen the front door and allow the worker to enter your house.</li>
</ol>
<p>In Server Dialback, the equivalent of the utility company worker is the ORIGINATING SERVER, i.e., the machine that wants to send a message from an entity at the SENDER DOMAIN to an entity at the TARGET DOMAIN and thus is attempting to establish a connection for the DOMAIN PAIR (combination of Sender Domain and Target Domain). The equivalent of the person at the house is the RECEIVING SERVER, i.e., the machine to which the Originating Server has opened a connection for the purpose of sending a message from the Sender Domain to the Target Domain (and thus the machine that is trying to verify that the Originating Server represents the Sender Domain). And the equivalent of the company headquarters is the AUTHORITATIVE SERVER, i.e., the machine that is discovered from a DNS lookup for the Sender Domain; for simple deployments this will be the Originating Server, but it could be a separate machine in the Originating Server's network (where "network" is defined by knowledge of a shared secret for verification of dialback keys).</p>
<p>The basic flow of events in Server Dialback consists of the following four steps:</p> <p>The basic flow of events in Server Dialback consists of the following four steps:</p>
<ol start='1'> <ol start='1'>
<li>The Originating Server generates a dialback key and sends that value over its XML stream with the Receiving Server. (If the Originating Server does not yet have an XML stream to the Receiving Server, it will first need to perform a DNS lookup on the Target Domain and thus discover the Receiving Server, open a TCP connection to the discovered IP address and port, and establish an XML stream with the Receiving Server.)</li> <li><p>The Initiating Server generates a dialback key and sends that value over its XML stream with the Receiving Server. (If the Initiating Server does not yet have an XML stream to the Receiving Server, it will first need to perform a DNS lookup on the Target Domain and thus discover the Receiving Server, open a TCP connection to the discovered IP address and port, and establish an XML stream with the Receiving Server.)</p></li>
<li>Instead of immediately accepting XML stanzas on the connection from the Originating Server, the Receiving Server sends the same dialback key over its XML stream with the Authoritative Server for verification. (If the Receiving Server does not yet have an XML stream to the Authoritative Server, it will first need to perform a DNS lookup on the Sender Domain and thus discover the Authoritative Server, open a TCP connection to the discovered IP address and port, and establish an XML stream with the Authoritative Server).</li> <li><p>Instead of immediately accepting XML stanzas on the connection from the Initiating Server, the Receiving Server sends the same dialback key over its XML stream with the Authoritative Server for verification. (If the Receiving Server does not yet have an XML stream to the Authoritative Server, it will first need to perform a DNS lookup on the Sender Domain and thus discover the Authoritative Server, open a TCP connection to the discovered IP address and port, and establish an XML stream with the Authoritative Server).</p></li>
<li>The Authoritative Server informs the Receiving Server whether the key is valid or invalid.</li> <li><p>The Authoritative Server informs the Receiving Server whether the key is valid or invalid.</p></li>
<li>The Receiving Server informs the Originating Server whether its identity has been verified or not.</li> <li><p>The Receiving Server informs the Initiating Server whether its identity has been verified or not.</p></li>
</ol> </ol>
<p>After Step 4, the Originating Server is authorized to send stanzas from the Sender Domain to the Target Domain as communicated in the 'to' and 'from' attributes of the dialback negotiation. In addition to a weak identity verification of the Sender Domain, this also ensures that the Receiving Server is accepting stanzas for the Target Domain.</p> <p>After Step 4, the Initiating Server is authorized to send stanzas from the Sender Domain to the Target Domain as communicated in the 'to' and 'from' attributes of the dialback negotiation. In addition to identity verification of the Sender Domain, this also ensures that the Receiving Server is accepting stanzas only for the Target Domain.</p>
<p>We can represent the flow of events graphically as follows.</p> <p>We can represent the flow of events graphically as follows.</p>
<code><![CDATA[ <code><![CDATA[
Originating Receiving Initiating Receiving
Server Server Server Server
----------- --------- ----------- ---------
| | | |
@ -234,86 +234,131 @@ Originating Receiving
<p>This section describes the protocol in detail.</p> <p>This section describes the protocol in detail.</p>
<p>Assumptions used in the examples:</p> <p>Assumptions used in the examples:</p>
<ul> <ul>
<li>"capulet.lit" is acting as Originating Server in sections 2.1.1 and 2.2.1 and as Receiving Server in sections 2.1.2 and 2.2.2. A DNS SRV lookup on this domain resolves to the machine "orchard.capulet.lit".</li> <li>The server hosting "capulet.lit" is acting as the Initiating Server in sections 2.1.1 and 2.2.1 and as the Receiving Server in sections 2.1.2 and 2.2.2. A DNS SRV lookup on "capulet.lit" resolves to "orchard.capulet.lit".</li>
<li>"montague.lit" is acting as Receiving Server in sections 2.1.1 and 2.2.2 and as Authoritative Server in sections 2.1.2 and 2.2.2. A DNS SRV lookup on this domain resolves to the machine "receiver.montague.lit"</li> <li>The server hosting "montague.lit" is acting as Receiving Server in sections 2.1.1 and 2.2.2 and as Authoritative Server in sections 2.1.2 and 2.2.2. A DNS SRV lookup on "montague.lit" resolves to the machine "home.montague.lit"</li>
<li>The stream ID of the stream from "capulet.lit" to "montague.lit" is "D60000229F".</li> <li>The stream ID of the response stream header sent from "capulet.lit" to "montague.lit" is "D60000229F".</li>
<li>The stream ID of the stream from "montague.lit" to "capulet.lit" is "417GAF25".</li> <li>The stream ID of the response stream header sent from "montague.lit" to "capulet.lit" is "417GAF25".</li>
<li>The shared secret of the "capulet.lit" domain is "s3cr3tf0rd14lb4ck".</li> <li>The shared secret within the "capulet.lit" domain is "s3cr3tf0rd14lb4ck".</li>
<li>The shared secret of the "montague.lit" domain is "d14lb4ck43v3r".</li> <li>The shared secret within the "montague.lit" domain is "d14lb4ck43v3r".</li>
</ul> </ul>
<p>Note: All XML elements qualified by the Server Dialback namespace MUST be prefixed with the namespace prefix for the 'jabber:server:dialback' namespace as advertised on the stream header originally sent by the entity sending the element. <note>RFC 3920 stipulated that "an implementation SHOULD generate only the 'db:' prefix for such elements and MAY accept only the 'db:' prefix." This restriction was included for the sake of backward compatibility with the jabberd 1.x codebase and is no longer necessary.</note></p> <p>This section can be read in two ways:</p>
<p>Section 2.1 describes the protocol from the perspective of an active, outbound connection. Section 2.2 describes the protocol from the perspective of an inbound connection. Note that both parts can be implemented, tested, and used separately. To illustrate this, the examples show two dialback negotiations, one happening in each direction. The following figure gives an overview of where each example is embedded in the process and illustrates the changing roles of each server.</p> <ol>
<li><p>To understand the protocol flow of each dialback negotiation, read Section 2.1.1 and Section 2.2.1 (aspects of the dialback negotiation from capulet.lit as Initiating Server to montague.lit as Receiving Server), then Section 2.1.2 and 2.2.2 (aspects of the dialback negotiation from montague.lit as Initiating Server to capulet.lit as Receiving Server).</p></li>
<li><p>To implement the code for either an outbound connection or an inbound connection, read Section 2.1 (outbound) or Section 2.2 (outbound). Note that both parts can be implemented, tested, and used separately.</p></li>
</ol>
<p>The following figure gives an overview of where each example is embedded in the process and illustrates the changing roles of each server.</p>
<code><![CDATA[ <code><![CDATA[
#############################################################################
STREAM FROM CAPULET.LIT TO MONTAGUE.LIT
#############################################################################
capulet.lit montague.lit capulet.lit montague.lit
(Originating Server) (Receiving Server) (as Initiating) (as Receiving
Server) Server)
----------- --------- ----------- ---------
| | | |
| [if necessary, | | [if necessary, |
| perform DNS lookup | | perform DNS |
| on Target Domain, | | lookup on |
| open TCP connection, | | Target Domain, |
| and establish stream] | | open TCP |
| -----------------------> | | connection, |
| and establish |
| stream] |
| -----------------> |
| (ID D60000229F) |
| | | |
| (stream id D60000229F) | capulet.lit | |
| send dialback key | (Authoritative Server) | send | capulet.lit
| -------(STEP 1)--------> | ----------- | dialback key | (as Authoritative
| Example 1 / 9 | | | -----(STEP 1)----> | Server)
| Ex 1 / 9 | ------------
| | [if necessary, | | | [if necessary, |
| | perform DNS lookup, | | | perform DNS |
| | on Sender Domain, | | | lookup on |
| | open TCP connection, | | | Sender Domain, |
| | and establish stream] | | | open TCP |
| | -----------------------> | | | connection, |
| | and establish |
| | stream] |
| | -----------------> |
| | | | | |
| | send verify request | | | send |
| | -------(STEP 2)--------> | | | verify request |
| | ----(STEP 2)-----> |
| | | | | |
| | send verify response | | | send |
| | <------(STEP 3)--------- | | | verify response |
| | <----(STEP 3)----- |
| | | | | |
| report dialback result | | | report | |
| <-------(STEP 4)-------- | | | dialback result | |
| Example 2,3,4/10,11,12 | | | <-----(STEP 4)---- | |
| Ex 2,3,4/10,11,12 | |
| | | | | |
| ---- stanzas from -----> | | | - stanzas flow -> | |
| capulet.lit | | | from capulet.lit | |
| to montague.lit | | | to montague.lit | |
| (Originating Server) (Receiving Server) | | |
#############################################################################
STREAM FROM MONTAGUE.LIT TO CAPULET.LIT
#############################################################################
| | |
| montague.lit capulet.lit
| (as Initiating (as Receiving
| Server) Server)
| --------- ---------- | --------- ----------
| | | | | |
| | [may reuse connection] | | | [may reuse |
| | (stream id 417GAF25) | | | connection or |
| | open new stream] |
| | -----------------> |
| | (ID 417GAF25) |
| | | | | |
| | | montague.lit | | | montague.lit
| | send dialback key | (Authoritative Server) | | send | (as Authoritative
| | -------(STEP 1)--------> | ----------- | | dialback key | Server)
| | -----(STEP 1)----> | -----------
| | | | | | | |
| | | [may open TCP connection | | | | [may reuse |
| [may reuse connection] | | and establish stream] | | | | connection or |
| [------(STEP 2)------->] | | -------(STEP 2)---------> | | | | open new stream] |
| | | Example 5 / 13 | | | | -----------------> |
| | | (ID 417GAF25) |
| | | | | | | |
| | | send verify response | | | | send |
| | | <------(STEP 3)---------- | | | | verify request |
| | | Example 6,7,8/14,15,16 | | | | -----(STEP 2)----> |
| | | Ex 5 / 13 |
| | | | | | | |
| | report dialback result | | | | | send |
| | <------(STEP 4)--------- | | | | | verify response |
| | | <----(STEP 3)----- |
| | | Ex 6,7,8/14,15,16 |
| | | | | | | |
| | ---- stanzas from -----> | | | | report | |
| | montague.lit to | | | | dialback result | |
| | capulet.lit | | | | <----(STEP 4)----- | |
| | | |
| | - stanzas flow -> | |
| | from montague.lit | |
| | to capulet.lit | |
]]></code> ]]></code>
<p>Note: All XML elements qualified by the Server Dialback namespace MUST be prefixed with the namespace prefix for the 'jabber:server:dialback' namespace as advertised on the stream header originally sent by the entity sending the element. <note>RFC 3920 stipulated that "an implementation SHOULD generate only the 'db:' prefix for such elements and MAY accept only the 'db:' prefix." This restriction was included for the sake of backward compatibility with the jabberd 1.x codebase and is no longer necessary.</note></p>
<section2 topic="Outbound Connection"> <section2 topic="Outbound Connection">
<p>On an outbound connection there are two different tasks that the sending server can perform. The first task is to request authorization to send stanzas from the Sender Domain to the Target Domain, which is described under Section 2.1.1. The second task is to respond to requests on the validity of a given dialback key as described under Section 2.1.2.</p>
<section3 topic="Originating Server Generates Outbound Request for Authorization by Receiving Server"> <p>On an outbound connection there are two different tasks:</p>
<p>This subsection describes the interaction between the Originating Server and the Receiving Server, from the perspective of the Originating Server.</p> <ol>
<p>When the Originating Server has stanzas to send from the Sender Domain to the Target Domain, does not have a verified connection, or is currently attempting to get a verified connection for this domain pair, it sends a new dialback key to the Receiving Server.</p> <li>Request authorization to send stanzas from a Sender Domain to a Target Domain, i.e., act as an Initiating Server in relation to a Receiving Server; this is is described under Section 2.1.1.</li>
<p>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 Sender Domain and MUST possess a 'to' attribute whose value is the Target Domain.</p> <li>Generate verification requests about the validity of dialback keys, i.e., act as a Receiving Server in relation to an Authoritative Server; this is described under Section 2.1.2.</li>
<example caption="Originating Server Sends Dialback Key (Step 1)"><![CDATA[ </ol>
<section3 topic="Initiating Server Generates Outbound Request for Authorization by Receiving Server">
<p>This subsection describes the interaction between the server hosting capulet.lit (acting as an Initiating Server) and the server hosting montague.lit (acting as a Receiving Server), from the outbound perspective of the Initiating Server.</p>
<p>When the Initiating Server has stanzas to send from the Sender Domain to the Target Domain, does not have a verified connection, or is currently attempting to get a verified connection for this domain pair, it sends a new dialback key to the Receiving Server.</p>
<p>To do so, either it can reuse an existing XML stream or it needs to establish a new connection. To establish a new connection, the Initiating Server performs a DNS lookup on the Target Domain, thus finding the IP address and port for server-to-server communication at an authoritative machine for the Target Domain (here the "home.montague.lit").</p>
<p>After the XML stream is established from the Initiating Server to the Receiving Server, the Initiating Server sends a dialback 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 Sender Domain and MUST possess a 'to' attribute whose value is the Target Domain.</p>
<example caption="Initiating Server Sends Dialback Key (Step 1)"><![CDATA[
send: <db:result send: <db:result
from='capulet.lit' from='capulet.lit'
to='montague.lit'> to='montague.lit'>
@ -328,30 +373,30 @@ key = HMAC-SHA256(
) )
= 404fe54e60d0259b2b6d9a620e72990ab3e8fe2faca420653da71eb80597e5a4 = 404fe54e60d0259b2b6d9a620e72990ab3e8fe2faca420653da71eb80597e5a4
</code> </code>
<p>Note: The Receiving Server MAY use any method to determine the validity of the dialback key and the identity of the Originating Sever. The Originating Server MUST NOT make any assumptions about how the Receiving Server verifies the key. This includes the assumption that the key is ever verified by the Receiving Server.</p> <p>Note: The Receiving Server MAY use any method to determine the validity of the dialback key and the identity of the Initiating Server. The Initiating Server MUST NOT make any assumptions about how the Receiving Server verifies the key. This includes the assumption that the key is even verified by the Receiving Server through communication with the Authoritative Server.</p>
<p>After that, the Originating Server waits for the verification result. If the Originating Server wishes to send any stanzas for this domain pair, it MUST queue them for sending after it has received authorization to send stanzas from the Receiving Server, and MUST NOT attempt to send stanzas until it has received such authorization. The Originating Server MUST NOT attempt to re-verify the domain pair on this TCP connection.</p> <p>After sending the dialback key, the Initiating Server waits for the verification result from the Receiving Server. If the Initiating Server wishes to send any stanzas for this domain pair, it MUST queue them for sending after it has received authorization to send stanzas from the Receiving Server, and MUST NOT attempt to send stanzas until it has received such authorization. The Initiating Server MUST NOT attempt to re-verify the domain pair on this TCP connection.</p>
<p>Note: While waiting for the verification result, the Originating Server SHOULD continue to send stanzas for any domain pair that has already been verified on that connection. It MAY send out additional dialback keys for different domain pairs and issue dialback verification requests as described under Section 2.1.2. To avoid Denial-of-Service attacks (&rfc4732;), the Originating Server MAY impose a timeout on key verification.</p> <p>Note: While waiting for the verification result, the Initiating Server SHOULD continue to send stanzas for any domain pair that has already been verified on that connection. It MAY send out additional dialback keys for different domain pairs and issue dialback verification requests as described under Section 2.1.2. To avoid denial of service attacks (&rfc4732;), the Initiating Server MAY impose a timeout on key verification.</p>
<p>If the stream or the underlying TCP connection is closed by the remote side while waiting for the verification result, this is to be handled similar to receiving an error as described below.</p> <p>If the stream or the underlying TCP connection is closed by the Receiving Server while the Initiating Server is waiting for the verification result, the Initiating Server shall behave as it does when receiving a dialback error as described below.</p>
<p>After the Receiving Server has verified the request, the Originating Server receives the verification result.</p> <p>After the Receiving Server has verified the request, the Initiating Server receives the verification result in the form of a &lt;db:result/&gt; element, where the 'from' attribute MUST be the Target Domain, the 'to' attribute MUST be the Sender Domain, and the 'type' attribute MUST have a value of "valid" or "invalid" (for the value of "error", see below).</p>
<p>The result is either valid...</p> <p>Thus the result is either valid...</p>
<example caption="Originating Server Receives Valid Verification Result from Receiving Server (Step 4)"><![CDATA[ <example caption="Initiating Server Receives Valid Verification Result from Receiving Server (Step 4)"><![CDATA[
recv: <db:result recv: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
type='valid'/> type='valid'/>
]]></example> ]]></example>
<p>... or invalid ...</p> <p>... or invalid ...</p>
<example caption="Originating Server Receives Invalid Verification Result from Receiving Server (Step 4)"><![CDATA[ <example caption="Initiating Server Receives Invalid Verification Result from Receiving Server (Step 4)"><![CDATA[
recv: <db:result recv: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
type='invalid'/> type='invalid'/>
]]></example> ]]></example>
<p>If the value of the 'type' attribute is "valid", then the connection between the domain pair is considered verified and the Originating Server can send any outbound stanzas it has queued up for routing to the Receiving Server for the domain pair. FIXME: note about enabling session managment or doing compression!</p> <p>Note: There are no examples for Step 2 and Step 3 in this section of the document; see the examples under Sections 2.1.2 and 2.2.2.</p>
<p>If the value of the 'type' attribute is "invalid", then the Receiving Server is reporting that Originating Server's identity (as valid for the Sender Domain) could not be verified by the Authoritative Server. In this case, the Originating Server MUST NOT attempt to send any outbound stanzas it has queued up for routing to the Receiving Server for the domain pair but instead return them to the respective senders at the Sender Domain with a &internalserver; stanza error.</p> <p>If the value of the 'type' attribute is "valid", then the connection between the domain pair is considered verified and the Initiating Server can send any outbound stanzas it has queued up for routing to the Receiving Server for the domain pair (i.e., from the Sender Domain to the Target Domain). Naturally, the Initiating Server can also enable or negotiate other stream features at this point, such as &xep0138; and &xep0198;.</p>
<p>Note that, since the Receiving Server will most likely close the stream and the underlying TCP connection the Originating Server should not attempt to send further stanzas for other domain pairs who have already been authorized.</p> <p>If the value of the 'type' attribute is "invalid", then the Receiving Server is reporting that Initiating Server's identity (as valid for the Sender Domain) could not be verified (e.g., by checking it with the Authoritative Server). In this case, the Initiating Server MUST NOT attempt to send any outbound stanzas it has queued up for routing to the Receiving Server for the domain pair but instead MUST return such stanzas to the respective senders at the Sender Domain with an &internalserver; stanza error. Since the Receiving Server will most likely close the stream and the underlying TCP connection if that occurs (see Section 2.2.1), the Initiating Server SHOULD NOT attempt to send further stanzas for other domain pairs that have already been authorized.</p>
<p>If the value of the 'type' attribute is "error", this indicates a problem which is not related to the validity of the dialback key provided. The error conditions are explained in detail under <link url='#advertisement-errors'>Dialback with Error Handling</link>. Such an error is to be considered non-fatal for the XML stream, but the Originating Server MUST return any queued stanzas to the respective senders at the Sender Domain with a &timeout; stanza error.</p> <p>If the value of the 'type' attribute is "error", this indicates a problem which is not related to the validity of the dialback key provided. The error conditions are explained in detail under <link url='#advertisement-errors'>Dialback with Error Handling</link>. Such an error is to be considered non-fatal for the XML stream, but the Initiating Server MUST return any queued stanzas to the respective senders at the Sender Domain with a &timeout; stanza error.</p>
<example caption="Originating Server Receives Dialback Error from Receiving Server (Step 4)"><![CDATA[ <example caption="Initiating Server Receives Dialback Error from Receiving Server (Step 4)"><![CDATA[
recv: <db:result recv: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
@ -363,11 +408,11 @@ recv: <db:result
]]></example> ]]></example>
</section3> </section3>
<section3 topic="Receiving Server Generates Outbound Request for Verification of Originating Server by Authoritative Server"> <section3 topic="Receiving Server Generates Outbound Request for Verification of Initiating Server by Authoritative Server">
<p>This subsection describes the interaction between the Receiving Server and the Authoritative Server, from the perspective of the Receiving Server.</p> <p>This subsection describes the interaction between the server hosting capulet.lit (acting as a Receiving Server) and the server hosting montague.lit (acting as an Authoritative Server), from the outbound perspective of the Receiving Server.</p>
<p>To determine the validity of a dialback key received from the Originating Server, the Receiving Server needs to establish communications with the Authoritative Server. To do so, either it can reuse an existing XML stream or it needs to establish a new connection. To establish a new connection, the Receiving Server performs a DNS lookup on the Sender Domain, thus finding the IP address and port for server-to-server communication at an authoritative machine for the Sender Domain asserted by the Originating Server (here the machine is "orchard.capulet.lit").</p> <p>To determine the validity of a dialback key received from the Initiating Server, the Receiving Server needs to establish communications with the Authoritative Server. To do so, either it can reuse an existing XML stream or establish a new connection. To establish a new connection, the Receiving Server performs a DNS lookup on the Sender Domain, thus finding the IP address and port for server-to-server communication at an authoritative machine for the Sender Domain asserted by the Initiating Server (here the machine is "orchard.capulet.lit").</p>
<p>After the XML stream is established from the Receiving Server to the Authoritative Server, the Receiving Server sends a verification request. This is done by creating a &lt;db:verify/&gt; element whose XML character data is the dialback key received from the Originating Server; the element MUST possess a 'from' attribute whose value is the Target Domain, MUST possess a 'to' attribute whose value is the Sender Domain as provided in the 'from' attribute of Step 1, and MUST possess an 'id' attribute whose value is the stream identifier of the Receiving Server's response stream header to the Originating Server. The combination of 'from', 'to', and 'id' attributes makes it possible for the Receiving Server to uniquely identify the TCP connection on which it received the original request in Step 1.</p> <p>After the XML stream is established from the Receiving Server to the Authoritative Server, the Receiving Server sends a verification request. This is done by creating a &lt;db:verify/&gt; element whose XML character data is the dialback key received from the Initiating Server; the element MUST possess a 'from' attribute whose value is the Target Domain, MUST possess a 'to' attribute whose value is the Sender Domain as provided in the 'from' attribute of Step 1, and MUST possess an 'id' attribute whose value is the stream ID of the response stream header sent from the Receiving Server to the Initiating Server (here "417GAF25"). The combination of 'from', 'to', and 'id' attributes makes it possible for the Receiving Server to uniquely identify the TCP connection on which it received the original request in Step 1.</p>
<p>Note: An implementation MAY open a separate connection to the Authoritative Server for the sole purpose of doing key verification. Such an implementation SHOULD close the connection immediately after receiving the verification result. Not using TLS or any other stream features may reduce the number of round trips in that case.</p> <p>Note: An implementation MAY open a separate connection to the Authoritative Server for the sole purpose of doing key verification. Such an implementation SHOULD close the connection immediately after receiving the verification result. Not using TLS or any other stream features can reduce the number of round trips in that case.</p>
<example caption="Receiving Server Sends Verification Request to Authoritative Server (Step 2)"><![CDATA[ <example caption="Receiving Server Sends Verification Request to Authoritative Server (Step 2)"><![CDATA[
send: <db:verify send: <db:verify
from='capulet.lit' from='capulet.lit'
@ -376,7 +421,7 @@ send: <db:verify
d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496 d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496
</db:verify> </db:verify>
]]></example> ]]></example>
<p>After that, the Receiving Server waits for the verification result. While doing so, it can still use the connection to send any dialback packets or stanzas for domain pairs that have already been validated.</p> <p>After that, the Receiving Server waits for the verification result. While doing so, it can still use the connection to send dialback packets or to send stanzas for domain pairs that have already been validated.</p>
<p>Here again, the result is either valid...</p> <p>Here again, the result is either valid...</p>
<example caption="Receiving Server is Informed by Authoritative Server that Key is Valid (Step 3)"><![CDATA[ <example caption="Receiving Server is Informed by Authoritative Server that Key is Valid (Step 3)"><![CDATA[
recv: <db:verify recv: <db:verify
@ -408,29 +453,34 @@ recv: <db:verify
</db:verify> </db:verify>
]]></example> ]]></example>
<p>Note: If the underlying TCP connection is closed by the remote side while there are pending verification requests, those requests SHOULD be considered failed and therefore be treated like an error response.</p> <p>Note: If the underlying TCP connection is closed by the remote side while there are pending verification requests, those requests SHOULD be considered failed and therefore be treated like an error response.</p>
<p>After receiving the validation result from the Authoritative Server, the Receiving Server determines the inbound connection that the dialback key was originally received on. This connection is uniquely identified by the combination of the 'from', 'to', and 'id' attributes. If no inbound connection is found that matches this combination, the verification result MAY be dropped silently. If an inbound connection is found, the Receiving Server uses it to communicate the verification result to the Originating Server. A positive result indicates the readiness of the Receiving Server to accept stanzas from the Originating Server for this domain pair.</p> <p>After receiving the validation result from the Authoritative Server, the Receiving Server determines the inbound connection that the dialback key was originally received on. This connection is uniquely identified by the combination of the 'from', 'to', and 'id' attributes. If no inbound connection is found that matches this combination, the verification result SHOULD be dropped silently. If an inbound connection is found, the Receiving Server uses it to communicate the verification result to the Initiating Server. A positive result indicates the readiness of the Receiving Server to accept stanzas from the Initiating Server for this domain pair.</p>
<p>Note that when receiving an verification result of type 'invalid', the Receiving Server MAY choose not to relay this result to the Originating Server. Instead, it might send a dialback error such as &lt;forbidden/&gt; to the Originating Server. Compared to sending an result of type invalid, this behaviour will not result in the loss of the whole stream and any previously domain pairs previously negotiated, while at the same time not accepting stanzas from the spoofed domain.</p> <p>When receiving a verification result of type "invalid", the Receiving Server MAY choose not to relay this result to the Initiating Server. Instead, it might send a dialback error such as &lt;forbidden/&gt; to the Initiating Server. Compared to sending a result of type "invalid", this behavior will not result in the loss of the whole stream and any previously domain pairs previously negotiated, while at the same time not accepting stanzas from the spoofed domain.</p>
</section3> </section3>
</section2> </section2>
<section2 topic="Inbound Connection"> <section2 topic="Inbound Connection">
<p>There are two different tasks on an inbound connection. The first task is to authorize inbound connections, which is described under Section 2.2.1. The second task is to answer requests for the validity of a dialback key, which is described under Section 2.2.2.</p> <p>There are two different tasks on an inbound connection:</p>
<ol>
<li>Authorize inbound connections, i.e., act as a Receiving Server in relation to an Initiating Server; this is described under Section 2.2.1.</li>
<li>Answer verification requests about the validity of dialback keys, i.e., act as an Authoritative Server in relation to a Receiving Server; this is described under Section 2.2.2.</li>
</ol>
<section3 topic="Receiving Server Handles Inbound Authorization Request from Originating Server"> <section3 topic="Receiving Server Handles Inbound Authorization Request from Initiating Server">
<p>This subsection describes the interaction between the Originating Server and the Receiving Server, from the perspective of the Receiving Server (i.e., this section is the mirror image of Section 2.1.1).</p> <p>This subsection describes the interaction between the server hosting capulet.lit (acting as an Initiating Server) and the server hosting montague.net (acting as a Receiving Server), from the inbound perspective of the Receiving Server (i.e., this section is the mirror image of Section 2.1.1).</p>
<example caption="Receiving Server Receives Dialback Key from Originating Server (Step 1)"><![CDATA[ <example caption="Receiving Server Receives Dialback Key from Initiating Server (Step 1)"><![CDATA[
recv: <db:result recv: <db:result
from='capulet.lit' from='capulet.lit'
to='montague.lit'> to='montague.lit'>
404fe54e60d0259b2b6d9a620e72990ab3e8fe2faca420653da71eb80597e5a4 404fe54e60d0259b2b6d9a620e72990ab3e8fe2faca420653da71eb80597e5a4
</db:result> </db:result>
]]></example> ]]></example>
<p>This key MUST be verified before the Originating Server is authorized to send stanzas from the Sender Domain ('capulet.lit'). The verification process might fail prematurely, for example, if the Receiving Server's policy states that connections from the Originating Server or the Sender Domain are not allowed.</p> <p>This key MUST be verified before the Initiating Server is authorized to send stanzas from the Sender Domain ("capulet.lit") to the Target Domain ("montague.lit"). Note that the verification process might fail prematurely, for example, if the Receiving Server's policy states that connections from the Initiating Server or the Sender Domain are not allowed.</p>
<p>The usual method for verifying that the Originating Server is authorized to send stanzas for the Sender Domain is to "dial back" the Authoritative Server for the Sender Domain and ask it to validate the dialback key which is contained in the XML character data of the request. Other methods can be used for verifying the identity of the Originating Server. For example, if TLS is used the Receiving Server can attempt to validate the certificate according to the rules specified in &xep0178; and &rfc6125; and send a dialback result without performing the actual dial-back (this technique is called "dialback without dial-back" or D-W-D).</p> <p>The traditional method for verifying that the Initiating Server is authorized to send stanzas from the Sender Domain is for the Receiving Server to "dial back" the Authoritative Server for the Sender Domain and ask it to validate the dialback key which is contained in the XML character data of the request. However, other methods can be used for verifying the identity of the Initiating Server. For example, if TLS is used the the Receiving Server can attempt to verify the certificate (according to the rules specified in &xep0178; and &rfc6125;, or according to some other method such as the one discussed in &dna-dns;) and then send a dialback result without performing the actual dial-back to the Authoritative Server (this technique is sometimes called "dialback without dial-back")
.</p>
<p>Note: The Receiving Server MUST continue to accept and process stanzas for already verified domain pairs, and MUST continue to process both &lt;db:result/&gt; and &lt;db:verify/&gt; elements.</p> <p>Note: The Receiving Server MUST continue to accept and process stanzas for already verified domain pairs, and MUST continue to process both &lt;db:result/&gt; and &lt;db:verify/&gt; elements.</p>
<p>If the Target Domain as given in the 'to' attribute of the element is not a configured domain of the Receiving Server, this results in a dialback error. This error, which is explained further under <link url='#advertisement-errors'>Section 2.4.2</link>, is not a stream error and therefore MUST NOT result in closing of the stream as described in Section 4.4 of <cite>RFC 6120</cite>, since the stream might already be used for sending XML stanzas for other domain pairs.</p> <p>If the Target Domain as given in the 'to' attribute of the element is not a configured domain of the Receiving Server, this results in a dialback error. This error, which is explained further under <link url='#advertisement-errors'>Section 2.4.2</link>, is not a stream error and therefore MUST NOT result in closing of the stream as described in Section 4.4 of <cite>RFC 6120</cite>, since the stream might already be used for exchanging XML stanzas for other domain pairs.</p>
<example caption="Receiving Server Sends Dialback Error to Originating Server (Step 4)"><![CDATA[ <example caption="Receiving Server Sends Dialback Error to Initiating Server (Step 4)"><![CDATA[
send: <db:result send: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
@ -440,28 +490,27 @@ send: <db:result
</error> </error>
</db:result> </db:result>
]]></example> ]]></example>
<p>After the validity of the key has been established (for example, by the Authoritative Server), the domain pair is to be considered as verified and the Receiving Server MUST accept stanzas from the Originating Server for the verified domain pair.</p> <p>After the validity of the key has been established (for example, by the Authoritative Server), the domain pair is to be considered as verified and the Receiving Server MUST accept stanzas from the Initiating Server for the verified domain pair.</p>
<p>In addition, the Originating Server is notified of the result. This is done by creating a &lt;db:result/&gt; element which MUST possess a 'from' attribute whose value is the Target Domain, MUST possess a 'to' attribute whose value is the Sender Domain, and MUST possess a 'type' attribute whose value is either "valid" or "invalid".</p> <p>In addition, the Receiving Server SHALL notify the Initiating Server of the result. This is done by creating a &lt;db:result/&gt; element which MUST possess a 'from' attribute whose value is the Target Domain, MUST possess a 'to' attribute whose value is the Sender Domain, and MUST possess a 'type' attribute whose value is either "valid" or "invalid" (or "error", as shown above).</p>
<p>Therefore, here again the result is either valid...</p> <p>Therefore, here again the result is either valid (this is the same as Example 2)...</p>
<example caption="Receiving Server Sends Valid Verification Result to Originating Server (Step 4)"><![CDATA[ <example caption="Receiving Server Sends Valid Verification Result to Initiating Server (Step 4)"><![CDATA[
send: <db:result send: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
type='valid'/> type='valid'/>
]]></example> ]]></example>
<p>... or invalid ...</p> <p>... or invalid (this is the same as Example 3)...</p>
<example caption="Receiving Server Sends Invalid Verification Result to Originating Server (Step 4)"><![CDATA[ <example caption="Receiving Server Sends Invalid Verification Result to Initiating Server (Step 4)"><![CDATA[
send: <db:result send: <db:result
from='montague.lit' from='montague.lit'
to='capulet.lit' to='capulet.lit'
type='invalid'/> type='invalid'/>
]]></example> ]]></example>
<p>If the type is 'invalid', the Originating Server is attempting to spoof the Sender Domain. The Receiving Server MUST NOT accept stanzas from the Originating Server for the Sender Domain, SHOULD log the attempt, and MUST close the XML stream (as described in Section 4.4 of <cite>RFC 6120</cite>).</p> <p>If the type is "invalid", the Initiating Server is attempting to spoof the Sender Domain. The Receiving Server MUST NOT accept stanzas from the Initiating Server for the Sender Domain, SHOULD log the attempt, and MUST close the XML stream (as described in Section 4.4 of <cite>RFC 6120</cite>).</p>
<p>As mentioned, Server Dialback results in weak identity verification of the Sender Domain by the Target Domain. In order to proceed with bidirectional communication so that the Target Domain can send XML stanzas to the Sender Domain, the Receiving Server needs to initiate a dialback negotiation with the Originating Server (i.e., assume the role of an originating server in a new dialback negotiation on a new TCP connection).</p>
</section3> </section3>
<section3 topic="Authoritative Server Handles Inbound Verification Request from Receiving Server"> <section3 topic="Authoritative Server Handles Inbound Verification Request from Receiving Server">
<p>This subsection describes the interaction between the Receiving Server and the Authoritative Server, from the perspective of the Authoritative Server (i.e., this section is the mirror image of Section 2.1.2).</p> <p>This subsection describes the interaction between the server hosting capulet.lit (acting as a Receiving Server) and the server hosting montague.lit (acting as an Authoritative Server), from the inbound perspective of the Authoritative Server (i.e., this section is the mirror image of Section 2.1.2).</p>
<example caption="Authoritative Server Receives Verification Request from Receiving Server (Step 2)"><![CDATA[ <example caption="Authoritative Server Receives Verification Request from Receiving Server (Step 2)"><![CDATA[
recv: <db:verify recv: <db:verify
from='capulet.lit' from='capulet.lit'
@ -470,7 +519,7 @@ recv: <db:verify
d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496 d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496
</db:verify> </db:verify>
]]></example> ]]></example>
<p>If the Target Domain as given in the 'to' attribute of the element does not match a configured local domain, this results in a dialback error. This error, which is explained further under Section 2.4, is not a stream error and therefore MUST NOT result in closing of the stream (as described in Section 4.4 of <cite>RFC 6120</cite>), since the stream might already be used for sending XML stanzas for other domain pairs.</p> <p>If the Target Domain as given in the 'to' attribute of the element does not match a configured local domain according to the Authoritative Server, this results in a dialback error. This error, which is explained further under Section 2.4, is not a stream error and therefore MUST NOT result in closing of the stream (as described in Section 4.4 of <cite>RFC 6120</cite>), since the stream might already be used for sending XML stanzas for other domain pairs.</p>
<example caption="Authoritative Server Sends Dialback Error to Receiving Server (Step 3)"><![CDATA[ <example caption="Authoritative Server Sends Dialback Error to Receiving Server (Step 3)"><![CDATA[
send: <db:verify send: <db:verify
from='montague.lit' from='montague.lit'
@ -491,7 +540,7 @@ key = HMAC-SHA256(
= d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496 = d4afb251ac62eb6fc778dac7ad65c43fdee29c4930ba204d479191566ea99496
</code> </code>
<p>The Authoritative Server then notifies the Receiving Server whether the key is valid. This is done by creating a &lt;db:verify/&gt; element which MUST possess 'from' and 'to' attributes whose values are swapped from the request, MUST possess an 'id' attribute whose value is copied from the 'id' value of the request, and MUST possess a 'type' attribute whose value is either "valid" or "invalid".</p> <p>The Authoritative Server then notifies the Receiving Server whether the key is valid. This is done by creating a &lt;db:verify/&gt; element which MUST possess 'from' and 'to' attributes whose values are swapped from the request, MUST possess an 'id' attribute whose value is copied from the 'id' value of the request, and MUST possess a 'type' attribute whose value is either "valid" or "invalid".</p>
<p>Therefore, here again the result is either valid...</p> <p>Therefore, here again the result is either valid (this is the same as Example 7)...</p>
<example caption="Authoritative Server Informs Receiving Server that Key is Valid (Step 3)"><![CDATA[ <example caption="Authoritative Server Informs Receiving Server that Key is Valid (Step 3)"><![CDATA[
send: <db:verify send: <db:verify
from='montague.lit' from='montague.lit'
@ -499,7 +548,7 @@ send: <db:verify
to='capulet.lit' to='capulet.lit'
type='valid'/> type='valid'/>
]]></example> ]]></example>
<p>... or invalid ...</p> <p>... or invalid (this is the same as Example 8)...</p>
<example caption="Authoritative Server Informs Receiving Server that Key is Invalid (Step 3)"><![CDATA[ <example caption="Authoritative Server Informs Receiving Server that Key is Invalid (Step 3)"><![CDATA[
send: <db:verify send: <db:verify
from='montague.lit' from='montague.lit'
@ -512,14 +561,14 @@ send: <db:verify
</section2> </section2>
<section2 topic="Directionality" anchor='directionality'> <section2 topic="Directionality" anchor='directionality'>
<p>The result of the protocol exchanges shown in the foregoing two sections is that the Receiving Server has verified the identity of the Originating Server, so that the Originating Server can send, and the Receiving Server can accept, XML stanzas over the "initial stream" (i.e., the stream from the Originating Server to the Receiving Server). In order to verify the identities of the entities using the "response stream" (i.e., the stream from the Receiving Server to the Originating Server), dialback MUST be completed in the opposite direction as well (i.e., with a reversal of roles so that the Receiving Server is now acting as an originating server and the Originating Server is now acting as a receiving server).</p> <p>The result of the protocol exchanges shown in the foregoing two sections is that the server hosting montague.lit (acting as a Receiving Server) has verified the identity of the server hosting capulet.lit (acting as an Initiating Server); as a result, the Initiating Server can send, and the Receiving Server can accept, XML stanzas over the stream from capulet.lit to montague.lit. In order for montague.lit to send stanzas to capulet.lit, dialback MUST be completed in the opposite direction as well (i.e., with a reversal of roles so that the server hosting montague.lit would act as an Initiating Server and capulet.lit would act as a Receiving Server).</p>
</section2> </section2>
<section2 topic="Advertisement" anchor='advertisement'> <section2 topic="Advertisement" anchor='advertisement'>
<section3 topic="Traditional Dialback" anchor='advertisement-traditional'> <section3 topic="Traditional Dialback" anchor='advertisement-traditional'>
<p>Support for the traditional server dialback protocol (originally specified in <cite>RFC 3920</cite>) is indicated by inclusion of the dialback namespace declaration in the stream header.</p> <p>Support for the traditional server dialback protocol (originally specified in <cite>RFC 3920</cite>) is indicated by inclusion of the dialback namespace declaration in the stream header.</p>
<example caption="Stream Header"><![CDATA[ <example caption="Stream Header With Dialback Namespace Declaration"><![CDATA[
<stream:stream <stream:stream
xmlns='jabber:server' xmlns='jabber:server'
xmlns:db='jabber:server:dialback' xmlns:db='jabber:server:dialback'
@ -527,7 +576,8 @@ send: <db:verify
from='montague.lit' from='montague.lit'
to='capulet.lit'> to='capulet.lit'>
]]></example> ]]></example>
<p>Although this method of advertising protocol support has been superseded by the use of stream features as originally defined in <cite>RFC 3920</cite>, the server dialback protocol predates the existence of stream features and therefore the namespace declaration method is still used in this instance.</p> <p>Note: Although in general advertising protocol support by means of an XML namespace declaration has been superseded by the use of stream features as originally defined in <cite>RFC 3920</cite>, the server dialback protocol predates the existence of stream features and therefore the namespace declaration method is still used in this instance.</p>
<p>Note: It is conventional to use a namespace prefix of "db" for Server Dialback elements. Although the prefix is allowed to be other than "db" according to the XML namespaces specification (&w3xmlnamespaces;), some existing implementations and deployments might accept only the "db" prefix.</p>
</section3> </section3>
<section3 topic="Dialback with Error Handling" anchor='advertisement-errors'> <section3 topic="Dialback with Error Handling" anchor='advertisement-errors'>
@ -545,9 +595,9 @@ send: <db:verify
<section2 topic="Dialback Error Conditions" anchor='errors'> <section2 topic="Dialback Error Conditions" anchor='errors'>
<!-- credits: Matthias in http://mail.jabber.org/pipermail/standards/2007-June/015662.html --> <!-- credits: Matthias in http://mail.jabber.org/pipermail/standards/2007-June/015662.html -->
<p><cite>RFC 3920</cite> introduced stream errors for any errors related to dialback. However, this turned out to be overly aggressive, particularly if the XML stream was used to multiplex stanzas from more than one domain pair (since closing the stream would result in throwing away accumulated dialback state for a potentially large number of domain pairs). Therefore this specification introduces a third value for the 'type' attribute, with the value "error".</p> <p><cite>RFC 3920</cite> introduced stream errors for any errors related to dialback. However, this turned out to be overly aggressive, particularly if the XML stream was used to multiplex stanzas for more than one domain pair (since closing the stream would result in throwing away accumulated dialback state for a potentially large number of domain pairs). Therefore this specification introduces a third value for the 'type' attribute: "error".</p>
<p>This usage of the 'error' value for the 'type' attribute is not fully backward compatible with <cite>RFC 3920</cite>. However, the server that generates the error SHOULD still attempt to send the dialback error instead of terminating the stream, as the worst thing that can happen is that the remote server terminates the stream if it does not understand the error or if it eventually times out the connection. Furthermore, a server SHOULD send these errors only to XMPP 1.0 peers that advertise support for dialback errors as described under Section 2.3.2. Dialback errors are to be considered non-fatal for the XML stream, but the Originating Server MUST return queued stanzas to the respective senders with a &timeout; stanza error. If an error is encountered in Step 3, the Receiving Server MUST send a &lt;remote-server-not-found/&gt; error to the Originating Server.</p> <p>This usage of the 'error' value for the 'type' attribute is not fully backward compatible with <cite>RFC 3920</cite>. However, the server that generates the error SHOULD still attempt to send the dialback error instead of terminating the stream, as the worst thing that can happen is that the remote server terminates the stream if it does not understand the error or if it eventually times out the connection. Furthermore, a server SHOULD send these errors only to XMPP 1.0 peers that advertise support for dialback errors as described under Section 2.4.2. Dialback errors are to be considered non-fatal for the XML stream, but the Initiating Server MUST return queued stanzas to the respective senders with a &timeout; stanza error. If an error is encountered in Step 3 of the dialback negotiation, the Receiving Server MUST send a &lt;remote-server-not-found/&gt; error to the Initiating Server.</p>
<p>When the &lt;db:verify/&gt; or &lt;db:result/&gt; element is of type "error", the element MUST contain an &lt;error/&gt; element, which is similar to a "stanza error" as specified in &xmppcore;. This specification re-uses the following stanza error conditions:</p> <p>When the &lt;db:verify/&gt; or &lt;db:result/&gt; element is of type "error", the element MUST contain an &lt;error/&gt; element qualified by the Server Dialback namespace, which MUST in turn contain an XML element qualified by the 'urn:ietf:params:xml:ns:xmpp-stanzas' namespace (i.e., a stanza error condition), in accordance with the following table.</p>
<table caption='Dialback error conditions'> <table caption='Dialback error conditions'>
<tr> <tr>
<th>Condition</th> <th>Condition</th>
@ -561,7 +611,7 @@ send: <db:verify
</tr> </tr>
<tr> <tr>
<td>&remoteconnection;</td> <td>&remoteconnection;</td>
<td>The Receiving Server was unable to establish a connection to the Authoritative Server and therefore could not validate the identity of the Originating Server.</td> <td>The Receiving Server was unable to establish a connection to the Authoritative Server and therefore could not validate the identity of the Initiating Server.</td>
<td>Step 4</td> <td>Step 4</td>
</tr> </tr>
<tr> <tr>
@ -576,52 +626,51 @@ send: <db:verify
</tr> </tr>
<tr> <tr>
<td>&policy;</td> <td>&policy;</td>
<td>The Receiving Server enforces a policy which mandates usage of TLS before dialback and the Originating Server did send the dialback request without using TLS.</td> <td>The Receiving Server enforces a policy which mandates usage of TLS before dialback and the Initiating Server sent the dialback request without using TLS.</td>
<td>Step 3 or 4</td> <td>Step 3 or 4</td>
</tr> </tr>
<tr> <tr>
<td>&notauthorized;</td> <td>&notauthorized;</td>
<td>The Receiving Server enforces a policy which requires a valid x509 certificate containing the identity of the Sender Domain for dialback requests and the Originating Server did not provide a certificate with an identity that matches the Sender Domain.</td> <td>The Receiving Server enforces a policy which requires a valid x509 certificate containing the identity of the Sender Domain for dialback requests and the Initiating Server did not provide a certificate with an identity that matches the Sender Domain.</td>
<td>Step 3</td> <td>Step 3</td>
</tr> </tr>
<tr> <tr>
<td>&forbidden;</td> <td>&forbidden;</td>
<td>The Receiving Server received an 'invalid' response when attempting to verify the dialback key with the Authoritative Server.</td> <td>The Receiving Server received an "invalid" response when attempting to verify the dialback key with the Authoritative Server.</td>
<td>Step 4</td> <td>Step 4</td>
</tr> </tr>
<tr> <tr>
<td>&notacceptable;</td> <td>&notacceptable;</td>
<td>The Receiving Server was unable to establish the asserted identity of the Originating Server.</td> <td>The Receiving Server was unable to establish the asserted identity of the Initiating Server.</td>
<td>Step 4</td> <td>Step 4</td>
</tr> </tr>
</table> </table>
</section2> </section2>
<section2 topic="Multiplexing" anchor='multiplex'> <section2 topic="Multiplexing" anchor='multiplex'>
<p>A single XML stream between Originating Server and Receiving Server can be used to multiplex stanzas for more than one domain pair. We call this usage "MULTIPLEXING" (historically it has also been known as piggybacking). One common motivation for multiplexing is virtual hosting, under which many domains are hosted on the same server. Another common motivation for such reuse is the existence of additional services associated with the Sender Domain but hosted at "subdomains" thereof. For example, both the "montague.lit" and the "capulet.lit" XMPP servers might host &xep0045; services at "chat.montague.lit" and "rooms.capulet.lit" respectively. Without multiplexing, many server-to-server connections would be necessary to exchange stanzas between those domains. With more domains, the number of connections might exceed the maximum number of connections allowed from a single IP address as explained in &xep0205;. Multiplexing reduces the number of connections to two.</p> <p>A single XML stream between Initiating Server and Receiving Server can be used to multiplex stanzas for more than one domain pair. We call this usage "multiplexing" (historically it has also been known as "piggybacking"). One common motivation for multiplexing is virtual hosting, under which many domains are hosted on the same server. Another common motivation for such reuse is the existence of additional services associated with the Sender Domain but hosted at "subdomains" thereof. For example, both the "montague.lit" and the "capulet.lit" XMPP servers might host &xep0045; services at "chat.montague.lit" and "rooms.capulet.lit" respectively. Without multiplexing, many server-to-server connections would be necessary to exchange stanzas between those domains. With more domains, the number of connections might exceed the maximum number of connections allowed from a single IP address as explained in &xep0205;. Multiplexing reduces the number of connections to two.</p>
<p>Note: Because dialback operates on domain pairs, a total of eight dialback negotiations is necessary for a bidirectional exchange of stanzas between two sending domains and two target domains.</p> <p>Note: Because dialback operates on domain pairs, a total of eight dialback negotiations is necessary for a bidirectional exchange of stanzas between two sending domains and two target domains.</p>
<section3 topic="Multiplexing Sender Domains" anchor="sendermultiplex"> <section3 topic="Multiplexing Sender Domains" anchor="sendermultiplex">
<p>In order to accept XML stanzas from rooms at "rooms.capulet.lit" intended for addresses at "montague.lit", the "montague.lit" domain will need to validate the "rooms.capulet.lit" domain (just as it already did for the "capulet.lit" domain). Thus the Originating Server would now initiate a dialback negotiation with "montague.lit" but specify the Sender Domain as "rooms.capulet.lit". Specifying different Sender Domains is called "SENDER MULTIPLEXING" and MAY be used without further negotation.</p> <p>In order to accept XML stanzas from rooms at "rooms.capulet.lit" intended for addresses at "montague.lit", the "montague.lit" domain will need to validate the "rooms.capulet.lit" domain (just as it already did for the "capulet.lit" domain). Thus the server hosting both capulet.lit and rooms.capulet.lit would now initiate a dialback negotiation with the server hosting montague.lit but specify the Sender Domain as "rooms.capulet.lit". Specifying different Sender Domains is called "sender multiplexing" and MAY be used without further negotation.</p>
</section3> </section3>
<section3 topic="Multiplexing Target Domains" anchor="targetmultiplex"> <section3 topic="Multiplexing Target Domains" anchor="targetmultiplex">
<p>Likewise, to send stanzas to rooms at "chat.montague.lit" from addresses at "capulet.lit", the Originating Server would initiate dialback negotiation with "chat.montague.lit" on the same connection that might already be used to send stanzas from "capulet.lit" to "montague.lit", specifying the Target Domain as "chat.montague.lit". Specifying different target domains is called "TARGET MULTIPLEXING".</p> <p>Likewise, to send stanzas to rooms at "chat.montague.lit" from addresses at "capulet.lit", the server hosting both capulet.lit and rooms.capulet.lit would initiate dialback negotiation with the server hosting chat.montague.lit (probably on the same connection that is already used to send stanzas from "capulet.lit" to "montague.lit"), specifying the Target Domain as "chat.montague.lit". Specifying different target domains is called "target multiplexing".</p>
<p>The Originating Server SHOULD NOT use Target Multiplexing unless the Receiving Server has signalled support for dialback error handling via &lt;stream:features/&gt; as described under <link url='#advertisement-errors'>Dialback with Error Handling</link>. The Originating Server MAY then attempt to multiplex a Sender Domain 'B' on the stream to the Receiving Server that is already used for Sender Domain 'A' if the hostname and port resolution results in the same IP address and port combination. For example:</p> <p>The Initiating Server SHOULD NOT use target multiplexing unless the Receiving Server has signalled support for dialback error handling via &lt;stream:features/&gt; as described under <link url='#advertisement-errors'>Dialback with Error Handling</link>. The Initiating Server MAY then attempt to multiplex a new Sender Domain on the stream to the Receiving Server that is already used for another Sender Domain if the hostname and port resolution results in the same IP address and port combination. For example:</p>
<example caption="DNS SRV Record for the montague.lit Zone"><![CDATA[ <example caption="DNS SRV Record for the montague.lit Zone"><![CDATA[
_xmpp-server._tcp.montague.lit. 86400 IN SRV 10 0 5269 receiver.montague.lit _xmpp-server._tcp.montague.lit. 86400 IN SRV 10 0 5269 home.montague.lit
_xmpp-server._tcp.chat.montague.lit. 86400 IN SRV 10 0 5269 receiver.montague.lit _xmpp-server._tcp.chat.montague.lit. 86400 IN SRV 10 0 5269 home.montague.lit
receiver.montague.lit. 86400 IN A 10.44.0.4 home.montague.lit. 86400 IN A 10.44.0.4
]]></example> ]]></example>
<p>Because DNS SRV lookups for both "montague.lit" and "chat.montague.lit" point to the same target ("receiver.montague.lit") and port (5269) or in absence of SRV records resolve to the same IP address (10.44.0.4) and port (5269), "capulet.lit" MAY initiate a dialback negotation from "capulet.lit" to "chat.montague.lit" over the same XML stream that is already used to send stanzas from "capulet.lit" to "montague.lit".</p> <p>Because DNS SRV lookups for both "montague.lit" and "chat.montague.lit" point to the same target ("home.montague.lit") and port (5269), or in absence of SRV records they resolve to the same IP address (10.44.0.4) and port (5269), "capulet.lit" MAY initiate a dialback negotation from "capulet.lit" to "chat.montague.lit" over the same XML stream that is already used to send stanzas from "capulet.lit" to "montague.lit".</p>
<p>&xep0288; extends those rules since any domain that has been used as a source domain can be used as a target domain without further negotiation.</p> <p>&xep0288; extends those rules since any domain that has been used as a source domain can be used as a target domain without further negotiation.</p>
</section3> </section3>
</section2> </section2>
</section1> </section1>
<section1 topic='Security Considerations' anchor='security'> <section1 topic='Security Considerations' anchor='security'>
<p>Server Dialback helps protect against domain spoofing, thus making it more difficult to spoof XML stanzas. Absent the use of DNS security (DNSSEC, &rfc4033;), Server Dialback does not provide a mechanism for authenticating a stream, as is done via TLS and SASL, and results in weak verification of server identities only. Furthermore, if DNSSEC is not used then it is susceptible to DNS poisoning attacks. 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.</p> <p>Server Dialback helps protect against domain spoofing, thus making it more difficult to spoof XML stanzas. Absent the use of DNS security (DNSSEC, &rfc4033;), Server Dialback does not provide a mechanism for authenticating a stream, as is done via TLS and SASL, and results in weak verification of server identities only. Furthermore, if DNSSEC is not used then it is susceptible to DNS poisoning attacks.</p>
<p>If DNSSEC is used, Server Dialback provides stream authentication only (i.e., a strong association between a domain name and an XML stream). However, Server Dialback by itself does not provide confidentiality, data integrity, or stream encryption, as is done via TLS and SASL.</p> <p>If DNSSEC is used, Server Dialback provides stream authentication only (i.e., a strong association between a domain name and an XML stream). However, Server Dialback by itself does not provide confidentiality, data integrity, or stream encryption. Some existing implementations are known to support dialback over TLS, however this specification doe snot define that usage.</p>
<p>Domains requiring more robust security SHOULD use TLS and SASL with strong identity verification.</p>
</section1> </section1>
<section1 topic='IANA Considerations' anchor='iana'> <section1 topic='IANA Considerations' anchor='iana'>
@ -638,7 +687,7 @@ receiver.montague.lit. 86400 IN A 10.44.0.
<code><![CDATA[ <code><![CDATA[
<feature> <feature>
<ns>urn:xmpp:features:dialback</ns> <ns>urn:xmpp:features:dialback</ns>
<name>dialback</name> <name>Server Dialback</name>
<element>dialback</element> <element>dialback</element>
<desc>Support for Server Dialback with dialback errors</desc> <desc>Support for Server Dialback with dialback errors</desc>
<doc>XEP-0220</doc> <doc>XEP-0220</doc>
@ -653,7 +702,7 @@ receiver.montague.lit. 86400 IN A 10.44.0.
<section1 topic='XML Schema' anchor='schema'> <section1 topic='XML Schema' anchor='schema'>
<section2 topic="Dialback" anchor="schema-dialback"> <section2 topic="Dialback" anchor="schema-dialback">
<p>Note Well: the 'error' value for the 'type' attribute was added since RFC 3920.</p> <p>Note Well: the 'error' value for the 'type' attribute and the &lt;error/&gt; child element were added since RFC 3920.</p>
<code><![CDATA[ <code><![CDATA[
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
@ -663,10 +712,14 @@ receiver.montague.lit. 86400 IN A 10.44.0.
xmlns='jabber:server:dialback' xmlns='jabber:server:dialback'
elementFormDefault='qualified'> elementFormDefault='qualified'>
<xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'
schemaLocation='http://xmpp.org/schemas/stanzaerror.xsd'/>
<xs:element name='result'> <xs:element name='result'>
<xs:complexType> <xs:complexType mixed='true'>
<xs:simpleContent> <xs:all>
<xs:extension base='xs:NMTOKEN'> <xs:element name='error' type='errorType'/>
</xs:all>
<xs:attribute name='from' type='xs:string' use='required'/> <xs:attribute name='from' type='xs:string' use='required'/>
<xs:attribute name='to' type='xs:string' use='required'/> <xs:attribute name='to' type='xs:string' use='required'/>
<xs:attribute name='type' use='optional'> <xs:attribute name='type' use='optional'>
@ -678,17 +731,15 @@ receiver.montague.lit. 86400 IN A 10.44.0.
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:element name='verify'> <xs:element name='verify'>
<xs:complexType> <xs:complexType mixed='true'>
<xs:simpleContent> <xs:all>
<xs:extension base='xs:NMTOKEN'> <xs:element name='error' type='errorType'/>
</xs:all>
<xs:attribute name='from' type='xs:string' use='required'/> <xs:attribute name='from' type='xs:string' use='required'/>
<xs:attribute name='id' type='xs:NMTOKEN' use='required'/>
<xs:attribute name='to' type='xs:string' use='required'/> <xs:attribute name='to' type='xs:string' use='required'/>
<xs:attribute name='type' use='optional'> <xs:attribute name='type' use='optional'>
<xs:simpleType> <xs:simpleType>
@ -699,11 +750,15 @@ receiver.montague.lit. 86400 IN A 10.44.0.
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
<xs:complexType name='errorType'>
<xs:sequence xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
<xs:group ref='err:stanzaErrorGroup'/>
</xs:sequence>
</xs:complexType>
</xs:schema> </xs:schema>
]]></code> ]]></code>
</section2> </section2>