editorial review

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@284 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2006-12-20 21:35:36 +00:00
parent 36d043ec3f
commit 6becab97f0
5 changed files with 58 additions and 162 deletions

View File

@ -11,7 +11,7 @@
&LEGALNOTICE;
<number>0157</number>
<status>Proposed</status>
<type>Standards Track</type>
<type>Informational</type>
<jig>Standards JIG</jig>
<approver>Council</approver>
<dependencies>
@ -60,105 +60,21 @@
</header>
<section1 topic='Introduction' anchor='intro'>
&RFC3920BISNOTE;
<p>&rfc2142; specifies conventional electronic mailbox names for common services, roles, and functions related to SMTP, NNTP, and HTTP (such as postmaster@domain.tld, usenet@domain.tld, and webmaster@domain.tld). However, no such conventional email address or Jabber ID (JID) has been specified for XMPP services. This document remedies that oversight.</p>
<p>&rfc2142; specifies conventional electronic mailbox names for common services, roles, and functions related to SMTP, NNTP, and HTTP (such as postmaster@domain.tld, usenet@domain.tld, and webmaster@domain.tld). However, no such conventional email address or XMPP address (JID) has been specified for XMPP services. This document remedies that oversight.</p>
</section1>
<section1 topic='XMPP Address' anchor='xmpp'>
<p>Many existing Jabber/XMPP server implementations use the bare domain of the server as an alias for the server administrators, such that a &MESSAGE; stanza addressed to that domain name (e.g., "jabber.org") is delivered to the JIDs of the server administrators (this does not apply to &IQ; or &PRESENCE; stanzas). It is RECOMMENDED that all server implementations support this functionality, and the authors will work toward standardization of this functionality in the forthcoming revisions to &rfc3920;.</p>
<p>Many existing Jabber/XMPP server implementations use the bare domain of the server as an alias for the server administrator(s), such that a &MESSAGE; stanza addressed to that domain name (e.g., "jabber.org") is delivered to the JIDs of the server administrator(s). <note>This does not apply to &IQ; or &PRESENCE; stanzas.</note> An XMPP server implementation SHOULD support this functionality. A domain that provides such functionality MAY also advertise the service through an XMPP URI (see &rfc4622;) of &lt;xmpp:domain.tld&gt; or (per &xep0147;) &lt;xmpp:domain.tld?message&gt;.</p>
</section1>
<section1 topic='Email Address' anchor='email'>
<p>Consistent with <cite>RFC 2142</cite>, a domain that offers a Jabber/XMPP service SHOULD provide an Internet mailbox of "XMPP" for inquiries related to that service, which MAY be advertised through a URI of &lt;mailto:xmpp@domain.tld&gt;.</p>
<p>Consistent with <cite>RFC 2142</cite>, a domain that offers a Jabber/XMPP service SHOULD provide an Internet mailbox of "XMPP" for inquiries related to that service. A domain that provides such functionality MAY also advertise the service through a Mailto URI (see &rfc2368;) of &lt;mailto:xmpp@domain.tld&gt;.</p>
</section1>
<!--
<section1 topic='Extended Server Information' anchor='disco'>
<p>The administrators of a Jabber/XMPP service may desire to advertise more detailed contact information related to that service. This contact information may include email addresses, web URLs, and JIDs for specific roles and functions such as abuse reports, customer feedback, sales inquiries, technical support, and security concerns. For this purpose, domains MUST support the electronic mailboxes required by <cite>RFC 2142</cite>. However, additional contact mechanisms may be desirable, and it would be helpful if those who want to initiate contact could discover the contact information using standard XMPP extensions, specifically &xep0030;. To make such discovery possible, we specify a &xep0128; mechanism that a server MAY return in response to service discovery information ("disco#info") requests sent to the bare domain of the server. This information SHOULD be scoped using a FORM_TYPE of "http://jabber.org/network/serverinfo" (as already specified in <cite>XEP-0128</cite>) and data form fields registered for this purpose as defined in the <link url='#registrar'>XMPP Registrar Considerations</link> section of this document.</p>
<p>To illustrate this usage, consider the following example of a disco#info request sent to the mythical shakespeare.lit XMPP server:</p>
<example caption='Entity queries server for information'><![CDATA[
<iq from='juliet@capulet.com/chamber'
to='shakespeare.lit'
id='disco1'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<example caption='Server communicates information'><![CDATA[
<iq from='shakespeare.lit'
to='juliet@capulet.com/chamber'
id='disco1'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='server' type='im'/>
<feature var='http://jabber.org/protocol/disco'/>
<x xmlns='jabber:x:data' type='result'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/network/serverinfo</value>
</field>
<field var='abuse-addresses'>
<value>mailto:abuse@shakespeare.lit</value>
<value>xmpp:shakespeare.lit/abuse</value>
</field>
<field var='feedback-addresses'>
<value>http://shakespeare.lit/feedback.php</value>
<value>mailto:feedback@shakespeare.lit</value>
<value>xmpp:shakespeare.lit/feedback</value>
</field>
<field var='sales-addresses'>
<value>xmpp:bard@shakespeare.lit</value>
</field>
<field var='security-addresses'>
<value>xmpp:shakespeare.lit/security</value>
</field>
<field var='support-addresses'>
<value>http://shakespeare.lit/support.php</value>
<value>xmpp:shakespeare.lit/support</value>
</field>
</x>
</query>
</iq>
]]></example>
</section1>
-->
<section1 topic='Security Considerations' anchor='security'>
<p>Advertising contact addresses may open those addresses to unwanted communication. Server administrators should balance the need for openness with the desire for control over communication with customers and peers. That said, certain contact addresses (e.g., abuse addresses and security addresses) may enable server administrators to more quickly learn of abusive usage and potential security holes, and advertisement of those addresses is strongly encouraged.</p>
<p>Providing or advertising contact addresses may open those addresses to unwanted communication. Server administrators should balance the need for openness with the desire for control over communication with customers and peers.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>
</section1>
<!--
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>The &REGISTRAR; shall include the following information in its registries.</p>
<section2 topic='Field Standardization' anchor='registrar-formtype'>
<p>&xep0068; defines a process for standardizing the fields used within Data Forms qualified by a particular namespace, and <cite>XEP-0128</cite> describes how to use field standardization in the context of service discovery. This section registers fields for server information scoped by the "http://jabber.org/network/serverinfo" FORM_TYPE.</p>
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>http://jabber.org/network/serverinfo</name>
<doc>XEP-0157</doc>
<desc>
Forms enabling the communication of contact addresses
and other server information.
</desc>
<field
var='abuse-addresses'
type='list-multi'
label='One or more addresses for communication related to abusive traffic'/>
<field
var='feedback-addresses'
type='list-multi'
label='One or more addresses for customer feedback'/>
<field
var='sales-addresses'
type='list-multi'
label='One or more addresses for communication related to sales and marketing'/>
<field
var='security-addresses'
type='list-multi'
label='One or more addresses for communication related to security concerns'/>
<field
var='support-addresses'
type='list-multi'
label='One or more addresses for customer support'/>
</form_type>
]]></code>
</section2>
<p>This document requires no interaction with the &REGISTRAR;.</p>
</section1>
-->
</xep>

View File

@ -7,7 +7,7 @@
<xep>
<header>
<title>Dialback Key Generation and Validation</title>
<abstract>This document explains how to generate and validate the keys used in the XMPP server dialback protocol.</abstract>
<abstract>This document provides a recommended method for generating and validating the keys used in the XMPP server dialback protocol.</abstract>
&LEGALNOTICE;
<number>0185</number>
<status>Proposed</status>
@ -56,19 +56,19 @@
</header>
<section1 topic='Introduction' anchor='intro'>
&RFC3920BISNOTE;
<p><cite>RFC 3920</cite> does not specify how to generate the keys used in the server dialback protocol, and why each of the variables used in key generation is crucial for security. This document is provided for discussion purposes and aims at clarifying the key generation and its validation mechanism and to show common attacks on weak mechanisms. It is not meant to supersede the text in <cite>RFC 3920</cite>; however, the recommendations in this document have been incorporated into <cite>rfc3920bis</cite>.</p>
<p><cite>RFC 3920</cite> does not specify in detail how to generate the keys used in the server dialback protocol, and why each of the variables used in key generation is crucial for security. This document is provided for discussion purposes and aims at clarifying the key generation and its validation mechanism and to show common attacks on weak mechanisms. It is not meant to supersede the text in <cite>RFC 3920</cite>; however, the recommendations in this document have been incorporated into <cite>rfc3920bis</cite>.</p>
</section1>
<section1 topic='Dialback Explained'>
<p>The Originating Server, which generates the dialback key, and the Authoritative Server, which validates the dialback key, may reside on different hosts or be running in separate processes. The method used in key generation and validation should not require interactive communication between Originating Server, Authoritative Server and optionally a third party like a database.</p>
<p>The key is generated based on</p>
<p>The key is generated based on:</p>
<ul>
<li>the (hostname of) Originating Server,</li>
<li>the (hostname of) Receiving Server,</li>
<li>the Stream ID,</li>
<li>and a secret known by the Authoritative Server's network.</li>
</ul>
<p>The last item, a shared secret known to Originating Server and Authoritative Server, is used in a Keyed-Hash Message Authentication Code (HMAC) to generate and validate the dialback keys. This key must either be set up in a configuration option for each host or process or generated as a random string when starting the server.</p>
<p>&nistfips198a; recommends that the length of the key should be at least half of the size of the hash function output. To fulfill this requirement, the secret should be hashed with the hash function prior to usage as key in HMAC.</p>
<p>The last item, a shared secret known to Originating Server and Authoritative Server, is used in a Keyed-Hash Message Authentication Code (HMAC) to generate and validate the dialback keys. This key must either be set up in a configuration option for each host or process, or generated as a random string when starting the server.</p>
<p>&nistfips198a; recommends that the length of the key should be at least half the size of the hash function output. To fulfill this requirement, the secret SHOULD be hashed with the hash function prior to usage as a key in HMAC.</p>
<p>The Stream ID and the involved hostnames should be concatenated with a unicode space character (U+0020) for the delimiter.</p>
<code>
key = HEX( HMAC-SHA256( SHA256(Secret), { Receiving Server, ' ',
@ -76,8 +76,10 @@ key = HEX( HMAC-SHA256( SHA256(Secret), { Receiving Server, ' ',
</code>
<p>To avoid problems of encoding, a hexadecimal representation of the digest algorithm output SHOULD be used.</p>
</section1>
<section1 topic='Example Setup'>
<table caption='Example data used in this document'>
<section1 topic='Key Generation and Validation'>
<p>This document closely follows the description of the dialback protocol in <cite>RFC 3920</cite>, but omits steps that are not important for the generation and validation of the dialback keys. For ease of comparison the numbering of the steps is the same as in section 8.3 of <cite>RFC 3920</cite>. Any line breaks in the examples are included for the purpose of readability only.</p>
<p>The following data values are used in the examples:</p>
<table caption='Data Used in Examples'>
<tr>
<td>Originating and Authoritative Server</td>
<td>example.com</td>
@ -95,9 +97,6 @@ key = HEX( HMAC-SHA256( SHA256(Secret), { Receiving Server, ' ',
<td>D60000229F</td>
</tr>
</table>
</section1>
<section1 topic='Key Generation and Validation'>
<p>This document closely follows the description of the dialback protocol in RFC 3920, but omits steps that are not important for the generation and validation of the dialback keys. For ease of comparison the numbering of the steps is the same as in section 8.3 of RFC 3920.</p>
<p>3. Receiving Server sends a stream header back to the Originating Server, including a unique ID for this interaction:</p>
<code><![CDATA[
<stream:stream
@ -110,9 +109,18 @@ key = HEX( HMAC-SHA256( SHA256(Secret), { Receiving Server, ' ',
]]></code>
<p>The Originating Server now generates a dialback key to be sent to the Receiving Server:</p>
<code>
key = HMAC-SHA256( SHA256(secret), { Receiving server, ' ', Originating server, ' ', Stream ID})
= HMAC-SHA256( SHA256('s3cr3tf0rd14lb4ck'), { 'example.net', ' ', 'example.com', ' ', 'D60000229F' })
= HMAC-SHA256( 'a7136eb1f46c9ef18c5e78c36ca257067c69b3d518285f0b18a96c33beae9acc', 'example.net example.com D60000229F')
key = HMAC-SHA256(
SHA256(secret),
{ Receiving server, ' ', Originating server, ' ', Stream ID}
)
= HMAC-SHA256(
SHA256('s3cr3tf0rd14lb4ck'),
{ 'example.net', ' ', 'example.com', ' ', 'D60000229F' }
)
= HMAC-SHA256(
'a7136eb1f46c9ef18c5e78c36ca257067c69b3d518285f0b18a96c33beae9acc',
'example.net example.com D60000229F'
)
= '008c689ff366b50c63d69a3e2d2c0e0e1f8404b0118eb688a0102c87cb691bdc'
</code>
<p>4. The Originating Server sends the generated dialback key to the Receiving Server:</p>
@ -134,9 +142,18 @@ key = HMAC-SHA256( SHA256(secret), { Receiving server, ' ', Originating server,
]]></code>
<p>The Authoritative Server calculates the valid key for this verify request, using data supplied in the packet and the secret shared with the Originating Server.</p>
<code>
key = HMAC-SHA256( secret, { Receiving Server, ' ', Authoritative Server, ' ', Stream ID })
= HMAC-SHA256( SHA256('s3cr3tf0rd14lb4ck'), { 'example.net', ' ', 'example.com', ' ', 'D60000229F' })
= HMAC-SHA256( 'a7136eb1f46c9ef18c5e78c36ca257067c69b3d518285f0b18a96c33beae9acc', 'example.net example.com D60000229F')
key = HMAC-SHA256(
secret,
{ Receiving Server, ' ', Authoritative Server, ' ', Stream ID }
)
= HMAC-SHA256(
SHA256('s3cr3tf0rd14lb4ck'),
{ 'example.net', ' ', 'example.com', ' ', 'D60000229F' }
)
= HMAC-SHA256(
'a7136eb1f46c9ef18c5e78c36ca257067c69b3d518285f0b18a96c33beae9acc',
'example.net example.com D60000229F'
)
= '008c689ff366b50c63d69a3e2d2c0e0e1f8404b0118eb688a0102c87cb691bdc'
</code>
<p>9. The Authoritative Server compares this value to the key contained in the verification requests and informs the Originating Server of the result, in our example a success:</p>
@ -151,7 +168,7 @@ key = HMAC-SHA256( secret, { Receiving Server, ' ', Authoritative Server, ' ', S
<section1 topic='Attacks Against Key Generation Methods'>
<p>This section contains attack scenarios that illustrate why each of the factors used in key generation is important.</p>
<p>An attacker will assume the role of the Originating Server and try to send a dialback key that the Authoritative Server acknowledges as valid. If this is successful, the attacker is allowed to send packets for the hostname of the Authoritative Server.</p>
<p>In each subsection, the example hash method, which uses the SHA1 algorithm as described in &rfc3174; for simplicity, ignores one of the variables,</p>
<p>In each subsection, the example hash method, which uses the (compromised and NOT RECOMMENDED) SHA1 algorithm as described in &rfc3174; for simplicity, ignores one of the variables,</p>
<ul>
<li>Originating Server,</li>
<li>Stream ID,</li>
@ -213,7 +230,7 @@ SHA1('s3cr3tf0rd14lb4ckexample.netexample.com') =
<code>
key = SHA1({ Secret, Originating Server, Stream ID })
</code>
<p>The attacker can use a dialback key and stream ID we have sent a domain under his control.</p>
<p>The attacker can use a dialback key and stream ID we have sent to a domain under his control.</p>
<code><![CDATA[
<db:verify
to='example.com'
@ -250,7 +267,7 @@ SHA1('example.netexample.comD60000229F') =
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>This document introduces no security considerations or concerns above and beyond those discussed in <cite>RFC3920</cite>, but describes what might happen if the security considerations are ignored.</p>
<p>This document introduces no security considerations or concerns above and beyond those discussed in <cite>RFC 3920</cite>, but describes what might happen if the security considerations are ignored.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document requires no interaction with &IANA;.</p>

View File

@ -7,7 +7,7 @@
<xep>
<header>
<title>Best Practice for Closing Idle Streams</title>
<abstract>This document specifies best practice for closing an idle XMPP stream.</abstract>
<abstract>This document specifies a best practice for closing an idle XMPP stream.</abstract>
&LEGALNOTICE;
<number>0190</number>
<status>Proposed</status>
@ -47,76 +47,38 @@
<section1 topic='Introduction' anchor='intro'>
&RFC3920BISNOTE;
<p><cite>RFC 3920</cite> offers several ways on how to terminate an XMPP stream, but
doesn't always make a clear statement which one to take. This can lead
to faulty implementations. In particular, closing a stream that hasn't
been in use for a while is very often achieved using a connection-timeout
error, then closing the socket. This can lead to loss of data. Therefore
this document proposes a practice that will avoid such data loss. Note: The
recommendation described herein has been incorporated into <cite>rfc3920bis</cite>.</p>
<p><cite>RFC 3920</cite> describes several ways to terminate an XMPP stream, but does not always make a clear statement about which to use. This can lead to faulty implementations. In particular, closing a stream that has not been in use for a while is very often achieved using a connection-timeout error, then closing the socket. This can lead to loss of data. Therefore this document proposes a practice that will avoid such data loss.</p>
<p>Note: The recommendation described herein has been incorporated into <cite>rfc3920bis</cite>.</p>
</section1>
<!-- section1 topic='How Not to Close an Idle Stream' anchor='dont'>
<section2 topic='Using a connection-timeout error'>
<p>Although RFC 3920 provides for an error condition
<code><![CDATA[ <connection-timeout/> ]]></code>
such error MUST NOT be used to close an idle connection, unless
the sender is expecting a message from the other entity, and a timeout
has occured instead, like during a dialback or SASL negotiation.</p>
<p>This has been a popular strategy, but it can cause frequent data
loss each time a connection is timeouted while the other entity just
started transmitting data.</p>
</section2>
<section2 topic='Closing the TCP connection without warning'>
<p>Several implementations even close the TCP connection without an
error or a stream shutdown. This has the same effects of data loss
as the friendlier variant mentioned before. Additionally it leaves
the other side wondering if the termination was intentional or erroneous.
This method MUST NOT be put into practice.</p>
</section2>
</section1 -->
<section1 topic='How to Close an Idle Stream' anchor='do'>
<section2 topic='Handshake Stream Shutdown'>
<p>As shown in the basic "session" example in the
Simplified Stream Examples (4.8 of RFC 3920),
it is a valid transaction to close the outgoing stream by sending
<p>As shown in the basic "session" example in the Simplified Stream Examples (4.8 of RFC 3920), it is a valid transaction to close the outgoing stream by sending
<code><![CDATA[ </stream:stream> ]]></code>
then wait for the other entity to close its stream, like this:
<code><![CDATA[ </stream:stream> ]]></code>
and shut down the underlying TCP connection.</p>
<p>This will ensure that, should the other entity have transmitted
any data, it will arrive and be processed before the TCP connection
is terminated.</p>
<p>Special care MUST be taken that under no circumstance further
packets may be written to the socket after the stream was closed,
until the other side shuts down the socket.</p>
<p>On the outgoing TCP connection you MAY do a read-only shutdown
of the socket, as long as the other side will safely be able to
send its stream termination token.</p>
<p>This will ensure that, should the other entity have transmitted any data, it will arrive and be processed before the TCP connection is terminated.</p>
<p>Special care MUST be taken that under no circumstance further packets may be written to the socket after the stream was closed, until the other side shuts down the socket.</p>
<p>On the outgoing TCP connection, an implementation MAY do a read-only shutdown of the socket, as long as the other side will safely be able to send its stream termination token.</p>
</section2>
<section2 topic='Handshake Failure'>
<p>In case the other entity fails to close the stream within a
reasonable time frame, the entity that started the handshake is
entitled to terminate the TCP connection. Since the stream has
already been closed, it is correct not to produce an error condition.</p>
<p>In case the other entity fails to close the stream within a reasonable time frame, the entity that started the handshake is entitled to terminate the TCP connection. Since the stream has already been closed, it is correct not to produce an error condition.</p>
</section2>
</section1>
<section1 topic='Conclusion' anchor='conclusion'>
<p>Please update your implementations to use the 'Handshake Stream Shutdown'
strategy when shutting down streams you no longer need.</p>
<p>Even not to shut down idle streams at all is a better strategy than to
shut them down by creating an error condition, so if your application
has no necessity for shutting down idle connections, just don't do it.</p>
<section1 topic='Implementation Notes' anchor='impl'>
<p>Existing implementations should be updated to use the 'Handshake Stream Shutdown' strategy when shutting down streams that are no longer needed. This strategy is fully backwards-compatible and does not introduce any known communication problems.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>This proposal introduces no new security aspects.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This proposal requires no interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<p>This proposal requires no interaction with the &REGISTRAR;.</p>
</section1>

View File

@ -183,7 +183,7 @@ S: <iq type='result' id='bind_1'>
]]></example>
</section1>
<section1 topic='Dialback Stream Feature' anchor='dialback'>
<p>As specified in <cite>RFC 3920</cite>, suupport for the server dialback protocol is currently adverised through inclusion of a dialback namespace prefix in the stream header:</p>
<p>As specified in <cite>RFC 3920</cite>, support for the server dialback protocol is currently adverised through inclusion of a dialback namespace prefix in the stream header:</p>
<example caption='Stream header with dialback namespace advertisement'><![CDATA[
<stream:stream
xmlns:stream='http://etherx.jabber.org/streams'

View File

@ -41,7 +41,8 @@
</header>
<section1 topic='Introduction' anchor='proto'>
&RFC3920BISNOTE;
<p><cite>RFC 3920</cite> introduced the concept of binding a resource to an XML stream (this concept superseded part of the older jabber:iq:auth protocol described in &xep0078;). As defined in <cite>RFC 3920</cite>, resource binding enables a client to bind one resource to a stream but does not enable a client to unbind a resource and leaves underspecified what a server and client should do if a client binds more than one resource to a stream. Because the ability to bind multiple resources to a stream is desirable in certain environments (e.g., for devices that are unable to open more than one TCP connection or when a machine runs a client daemon that is used by multiple applications), this document proposes improvements to resource binding in order to address these shortcomings. Note: The recommendations described herein have been incorporated into <cite>rfc3920bis</cite>.</p>
<p><cite>RFC 3920</cite> introduced the concept of binding a resource to an XML stream (this concept superseded part of the older jabber:iq:auth protocol described in &xep0078;). As defined in <cite>RFC 3920</cite>, resource binding enables a client to bind one resource to a stream but does not enable a client to unbind a resource and leaves underspecified what a server and client should do if a client binds more than one resource to a stream. Because the ability to bind multiple resources to a stream is desirable in certain environments (e.g., for devices that are unable to open more than one TCP connection or when a machine runs a daemon process that is used by multiple applications), this document proposes improvements to resource binding in order to address these shortcomings.</p>
<p>Note: The recommendations described herein have been incorporated into <cite>rfc3920bis</cite>.</p>
</section1>
<section1 topic='Unbinding a Resource' anchor='unbind'>
<p>In order to properly manage the resources associated with an XML stream, a client must be able to unbind resources. This shall be completed by sending an IQ-set with a child element of &lt;unbind/&gt; qualified by the 'urn:ietf:params:xml:ns:xmpp-bind' namespace, which in turn has a child element of &lt;resource/&gt; whose XML character data specifies the resource to be unbound:</p>
@ -53,7 +54,7 @@
</iq>
]]></example>
<p>If the server does not understand the &lt;unbind/&gt; element, it MUST return an error of &badrequest;. Otherwise, if there is no such resource, the server MUST return an error of &notfound;. When the client unbinds the only resource associated with the stream, the server SHOULD close the stream and terminate the TCP connection.</p>
<p>A server SHOULD advertise its support for the 'urn:ietf:params:xml:ns:xmpp-bind' namespace by returning an appropriate stream feature as shown below:</p>
<p>A server SHOULD advertise its support for the 'urn:ietf:params:xml:ns:xmpp-bind' namespace and the unbind functionality by returning an appropriate stream feature as shown below:</p>
<example caption='Unbind Stream Feature'><![CDATA[
<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>