git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1592 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2008-01-22 00:48:13 +00:00
parent 88e50846aa
commit 6057a1fb42
1 changed files with 89 additions and 78 deletions

View File

@ -34,8 +34,8 @@
<jid>jajcus@jabber.bnet.pl</jid>
</author>
<revision>
<version>1.5pre15</version>
<date>in progress, last updated 2008-01-17</date>
<version>1.5pre16</version>
<date>in progress, last updated 2008-01-21</date>
<initials>psa/jjh</initials>
<remark>
<ul>
@ -47,7 +47,6 @@
<li>Clarified meaning and construction of caps node attribute and disco node attribute</li>
<li>Specified that node attribute shall be included in disco#info request for backwards-compatibility</li>
<li>Clarified handling of the legacy format to assist developers</li>
<li>Defined recommended n, os, and v attributes to include the information from XEP-0092</li>
<li>Added service discovery feature for caps optimization to prevent confusion regarding server support of caps vs. caps optimization</li>
</ul>
</remark>
@ -144,21 +143,19 @@
<presence from='romeo@montague.lit/orchard'>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Exodus'
node='http://code.google.com/p/exodus'
v='0.9.1'
ver='8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
ver='SrFo9ar2CCk2EnOH4q4QANeuxLQ='/>
</presence>
]]></code>
<p>The 'node' attribute represents the client software Romeo is using. The optional 'v' attribute represents the specific version of that client software (it is only an "FYI" and is not used further in entity capabilities). The 'ver' attribute is a specially-constructed string that represents the identity (see &DISCOCATEGORIES;) and supported features (see &DISCOFEATURES;) of the entity.</p>
<p>At this point, your client has no idea what the capabilities are of someone with a version string '8RovUdtOmiAjzj+xI7SK5BCw3A8='. Your client therefore sends a service discovery query to Romeo, asking what his client can do.</p>
<p>The 'node' attribute represents the client software Romeo is using. The 'ver' attribute is a specially-constructed string that represents the entity's service discovery identity (category and type as registered at &DISCOCATEGORIES; as well as, optionally, the service discovery name) and supported features (as registered at &DISCOFEATURES; as well as, optionally, &xep0128; data registered at &FORMTYPES;).</p>
<p>At this point, your client has no idea what the capabilities are of someone with a version string 'SrFo9ar2CCk2EnOH4q4QANeuxLQ='. Your client therefore sends a service discovery query to Romeo, asking what his client can do.</p>
<code><![CDATA[
<iq from='juliet@capulet.lit/chamber'
id='disco1'
to='romeo@montague.lit/orchard'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://code.google.com/p/exodus#8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
node='http://code.google.com/p/exodus#SrFo9ar2CCk2EnOH4q4QANeuxLQ='/>
</iq>
]]></code>
<p>The response is:</p>
@ -168,7 +165,7 @@
to='juliet@capulet.lit/chamber'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://code.google.com/p/exodus#8RovUdtOmiAjzj+xI7SK5BCw3A8='>
node='http://code.google.com/p/exodus#SrFo9ar2CCk2EnOH4q4QANeuxLQ='>
<identity category='client' name='Exodus 0.9.1' type='pc'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
@ -176,29 +173,23 @@
</query>
</iq>
]]></code>
<p>At this point, your client knows that anyone advertising a version string of '8RovUdtOmiAjzj+xI7SK5BCw3A8=' has a client that can do &xep0045; and the other features returned by Romeo's client (the string can be relied upon because of how it is generated and checked, as explained later in this document). Your client remembers this information, so that it does not need to explicitly query the capabilities of a contact with the same version string. For example, Benvolio may send you the following presence:</p>
<code><![CDATA[
<presence from='benvolio@capulet.lit/230193'>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Psi'
node='http://psi-im.org/'
os='PPC Mac OS X Mach-O'
v='0.11'
ver='8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
</presence>
]]></code>
<p>Now your client automatically knows that Benvolio can do MUC, without needing to ask him explicitly via service discovery.</p>
<p>On the other hand, for a person with the following presence ...</p>
<p>At this point, your client knows that anyone advertising a version string of 'SrFo9ar2CCk2EnOH4q4QANeuxLQ=' has a client that can do &xep0045; and the other features returned by Romeo's client (the string can be relied upon because of how it is generated and checked, as explained later in this document). Your client remembers this information, so that it does not need to explicitly query the capabilities of a contact with the same version string. For example, your Nurse may use the same client that Romeo does:</p>
<code><![CDATA[
<presence from='nurse@capulet.lit/chamber'>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Psi'
node='http://psi-im.org/'
os='Windows-XP 5.01.2600'
v='0.10'
ver='uCoVCteRe3ty2wU2gHxkMaA7xhs='/>
node='http://code.google.com/p/exodus'
ver='SrFo9ar2CCk2EnOH4q4QANeuxLQ='/>
</presence>
]]></code>
<p>Therefore you know that she also supports the same features that Romeo does.</p>
<p>On the other hand, for a person with the following presence ...</p>
<code><![CDATA[
<presence from='benvolio@capulet.lit/230193'>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
node='http://psi-im.org'
ver='P0wEGAHIj5lRBc5Oa872bmRB8Bg='/>
</presence>
]]></code>
<p>... or the following presence ...</p>
@ -206,9 +197,7 @@
<presence from='bard@shakespeare.lit/globe'>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Chatopus'
node='http://www.chatopus.com'
v='2.1'
ver='zHyEOgxTrkpSdGcQKH8EFPLsriY='/>
</presence>
]]></code>
@ -218,9 +207,8 @@
<section1 topic='Assumptions' anchor='assumptions'>
<p>This document makes several assumptions:</p>
<ul>
<li>The type of client I am using is of interest to the people in my roster.</li>
<li>The identity of the client I am using is of interest to the people in my roster.</li>
<li>Clients for the people on my roster might want to make user interface decisions based on my capabilities.</li>
<li>Different clients may support the same capabilities.</li>
<li>Members of a community tend to cluster around a small set of clients with a small set of capabilities. More specifically, multiple people in my roster use the same client, and they upgrade versions relatively slowly (commonly a few times a year, perhaps once a week at most, certainly not once a minute).</li>
<li>Some clients are running on networks without server-to-server connectivity enabled and without access to the Internet via HTTP.</li>
<li>Conversations are possible between users who are not on each other's rosters.</li>
@ -260,35 +248,19 @@
<td>The hashing algorithm used to generate the 'ver' attribute; see <link url='#security-mti'>Mandatory-to-Implement Technologies</link> regarding supported hashing algorithms.</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>n</td>
<td>The natural-language name of the software, equivalent to the &lt;name/&gt; element from <cite>XEP-0092</cite>. **</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>node</td>
<td>A URI that uniquely identifies a software application, typically a URL at the website of the project or company that produces the software. *</td>
<td>REQUIRED</td>
</tr>
<tr>
<td>os</td>
<td>The operating system on which the software is running, equivalent to the &lt;os/&gt; element from <cite>XEP-0092</cite>. **</td>
<td>OPTIONAL</td>
</tr>
<tr>
<td>v</td>
<td>A specific version of the software, equivalent to the &lt;version/&gt; element from <cite>XEP-0092</cite>. **</td>
<td>RECOMMENDED</td>
</tr>
<tr>
<td>ver</td>
<td>A string that specifies the identity and supported features of the entity. ***</td>
<td>A string that specifies the identity and supported features of the entity. **</td>
<td>REQUIRED</td>
</tr>
</table>
<p>* Note: It is RECOMMENDED for the value of the 'node' attribute to be an HTTP URL at which a user could find further information about the software product, such as "http://psi-im.org/" for the Psi client; this enables a processing application to also determine a unique string for the generating application, which it could maintain in a list of known software implementations (e.g., associating the name received via the disco#info reply with the URL found in the caps data).</p>
<p>** Note: Before version 1.4 of this specification, the version information was contained in the 'ver' attribute as described below.</p>
<p>*** Note: Before version 1.4 of this specification, the 'ver' attribute was used to specify the released version of the software; while the values of the 'ver' attribute that result from use of the algorithm specified herein are backwards-compatible, applications SHOULD appropriately handle the <link url='#legacy'>Legacy Format</link>.</p>
<p>* Note: It is RECOMMENDED for the value of the 'node' attribute to be an HTTP URL at which a user could find further information about the software product, such as "http://psi-im.org" for the Psi client; this enables a processing application to also determine a unique string for the generating application, which it could maintain in a list of known software implementations (e.g., associating the name received via the disco#info reply with the URL found in the caps data).</p>
<p>** Note: Before version 1.4 of this specification, the 'ver' attribute was used to specify the released version of the software; while the values of the 'ver' attribute that result from use of the algorithm specified herein are backwards-compatible, applications SHOULD appropriately handle the <link url='#legacy'>Legacy Format</link>.</p>
</section1>
<section1 topic='Generation of the ver Attribute' anchor='ver'>
@ -296,20 +268,73 @@
<p>Note: All sorting operations MUST be performed using "i;octet" collation as specified in Section 9.3 of &rfc4790;.</p>
<ol>
<li>Initialize an empty string S.</li>
<li>Sort the service discovery identities <note>A registry of service discovery identities is located at &DISCOCATEGORIES;.</note> by category and then by type (if it exists), formatted as 'category' '/' 'type'.</li>
<li>For each identity, append the 'category/type' to S, followed by the '&lt;' character.</li>
<li>Sort the service discovery identities <note>A registry of service discovery identities is located at &DISCOCATEGORIES;.</note> by category and then by type (if it exists) and then by xml:lang (if it exists), formatted as CATEGORY '/' [TYPE] '/' [LANG] '/' [NAME]. Note that each slash is included even if the TYPE, LANG, or NAME is not included.</li>
<li>For each identity, append the 'category/type/lang/name' to S, followed by the '&lt;' character.</li>
<li>Sort the supported service discovery features. <note>A registry of service discovery features is located at &DISCOFEATURES;.</note></li>
<li>For each feature, append the feature to S, followed by the '&lt;' character.</li>
<li>Compute ver by hashing S using the algorithm specified in in the 'hash' attribute (e.g., SHA-1 as defined in &rfc3174;). The hashed data MUST be generated with binary output and encoded using Base64 as specified in Section 4 of &rfc4648; (note: the Base64 output MUST NOT include whitespace and MUST set padding bits to zero). <note>The OpenSSL command for producing such output with SHA-1 is is "echo -n 'S' | openssl dgst -binary -sha1 | openssl enc -nopad -base64".</note></li>
<li>If the service discovery information response includes <cite>XEP-0128</cite> data, sort the fields by the value of the "var" attribute.</li>
<li>For each "var":
<ol>
<li>Append the var name and the '&lt;' character.</li>
<li>Sort values by the XML character data of the &lt;value/&gt; element.</li>
<li>For each value, append the value and the '&lt;' character.</li>
</ol>
</li>
<li>Compute ver by hashing S using the algorithm specified in the 'hash' attribute (e.g., SHA-1 as defined in &rfc3174;). The hashed data MUST be generated with binary output and encoded using Base64 as specified in Section 4 of &rfc4648; (note: the Base64 output MUST NOT include whitespace and MUST set padding bits to zero). <note>The OpenSSL command for producing such output with SHA-1 is is "echo -n 'S' | openssl dgst -binary -sha1 | openssl enc -nopad -base64".</note></li>
</ol>
<p>For example, consider an entity whose service discovery category is "client", whose service discovery type is "pc", and whose supported features are "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", and "http://jabber.org/protocol/muc". Using the SHA-1 algorightm, the value of the 'ver' attribute would be generated as follows:</p>
<p>Consider an entity whose category is "client", whose service discovery type is "pc", whose service discovery name is "Exodus 0.9.1", and whose supported features are "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", and "http://jabber.org/protocol/muc". Using the SHA-1 algorithm, the value of the 'ver' attribute would be generated as follows:</p>
<ol>
<li>S = ''</li>
<li>Only one identity: "client/pc"</li>
<li>S = 'client/pc&lt;'</li>
<li>S = 'client/pc//Exodus 0.9.1&lt;'</li>
<li>Sort the features: "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/muc".</li>
<li>S = 'client/pc&lt;http://jabber.org/protocol/disco#info&lt;http://jabber.org/protocol/disco#items&lt;http://jabber.org/protocol/muc&lt;'</li>
<li>ver = 8RovUdtOmiAjzj+xI7SK5BCw3A8=</li>
<li>S = 'client/pc//Exodus 0.9.1&lt;http://jabber.org/protocol/disco#info&lt;http://jabber.org/protocol/disco#items&lt;http://jabber.org/protocol/muc&lt;'</li>
<li>ver = SrFo9ar2CCk2EnOH4q4QANeuxLQ=</li>
</ol>
<p>Consider a more complex example, where the entity includes several identities (with the service discovery name in different languages) as well as extended information formatted according to <cite>XEP-0128</cite>.</p>
<code>
&lt;iq from='benvolio@capulet.lit/230193'&gt;
id='disco1'
to='juliet@capulet.lit/chamber'
type='result'&gt;
&lt;query xmlns='http://jabber.org/protocol/disco#info'
node='http://psi-im.org#P0wEGAHIj5lRBc5Oa872bmRB8Bg='&gt;
&lt;identity xml:lang='en' category='client' name='Psi' type='pc'/&gt;
&lt;identity xml:lang='el' category='client' name='&#936;' type='pc'/&gt;
&lt;feature var='http://jabber.org/protocol/disco#info'/&gt;
&lt;feature var='http://jabber.org/protocol/disco#items'/&gt;
&lt;feature var='http://jabber.org/protocol/muc'/&gt;
&lt;x xmlns='jabber:x:data' type='result'&gt;
&lt;field var='FORM_TYPE' type='hidden'&gt;
&lt;value&gt;urn:xmpp:dataforms:clientinfo&lt;/value&gt;
&lt;/field&gt;
&lt;field var='ip_version'&gt;
&lt;value&gt;ipv4&lt;/value&gt;
&lt;value&gt;ipv6&lt;/value&gt;
&lt;/field&gt;
&lt;field var='os'&gt;
&lt;value&gt;Mac&lt;/value&gt;
&lt;/field&gt;
&lt;field var='os_version'&gt;
&lt;value&gt;OS X Mach-O&lt;/value&gt;
&lt;/field&gt;
&lt;field var='software_version'&gt;
&lt;value&gt;0.11&lt;/value&gt;
&lt;/field&gt;
&lt;/x&gt;
&lt;/query&gt;
&lt;/iq&gt;
</code>
<p>Using the SHA-1 algorithm, the value of the 'ver' attribute would be generated as follows:</p>
<ol>
<li>S = ''</li>
<li>Two identities: "client/pc/Psi" and "client/pc/&#936;"</li>
<li>S = 'client/pc/el/&#936;&lt;client/pc/en/Psi&lt;'</li>
<li>Sort the features: "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/muc".</li>
<li>Sort and append the extended information: "ip_version&lt;ipv4&lt;ipv6", "os&lt;Mac", "os_version&lt;OS X 10.5.1", "software_version&lt;0.11".</li>
<li>S = 'client/pc/el/&#936;&lt;client/pc/en/Psi&lt;http://jabber.org/protocol/disco#info&lt;http://jabber.org/protocol/disco#items&lt;http://jabber.org/protocol/muc&lt;<br />
ip_version&lt;ipv4&lt;ipv6&lt;os&lt;Mac&lt;os_version&lt;OS X 10.5.1&lt;software_version&lt;0.11&lt;'</li>
<li>ver = P0wEGAHIj5lRBc5Oa872bmRB8Bg=</li>
</ol>
</section1>
@ -320,10 +345,8 @@
<presence>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Exodus'
node='http://code.google.com/p/exodus'
v='0.9.1'
ver='8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
ver='SrFo9ar2CCk2EnOH4q4QANeuxLQ='/>
</presence>
]]></example>
<p>If the supported features change during a generating entity's presence session (e.g., a user installs an updated version of a client plugin), the application MUST recompute the 'ver' attribute and SHOULD send a new presence broadcast.</p>
@ -331,9 +354,7 @@
<presence>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='Exodus'
node='http://code.google.com/p/exodus'
v='0.9.1'
ver='66/0NaeaBKkwk85efJTGmU47vXI='/>
</presence>
]]></example>
@ -348,13 +369,13 @@
to='romeo@montague.lit/orchard'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://code.google.com/p/exodus#8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
node='http://code.google.com/p/exodus#SrFo9ar2CCk2EnOH4q4QANeuxLQ='/>
</iq>
]]></example>
<p>The disco#info request is sent by the requesting entity to the generating entity. The value of the 'to' attribute MUST be the exact JID of the generating entity, which in the case of a client will be the full JID (&FULLJID;).</p>
<p>The disco 'node' attribute MUST be included for backwards-compatibility. The value of the 'node' attribute SHOULD be generated by concatenating the value of the caps 'node' attribute (e.g., "http://code.google.com/p/exodus") as provided by the generating entity, the "#" character, and the value of the caps 'ver' attribute (e.g., "8RovUdtOmiAjzj+xI7SK5BCw3A8=") as provided by the generating entity.</p>
<p>The disco 'node' attribute MUST be included for backwards-compatibility. The value of the 'node' attribute SHOULD be generated by concatenating the value of the caps 'node' attribute (e.g., "http://code.google.com/p/exodus") as provided by the generating entity, the "#" character, and the value of the caps 'ver' attribute (e.g., "SrFo9ar2CCk2EnOH4q4QANeuxLQ=") as provided by the generating entity.</p>
<p>The generating entity then returns all of the capabilities it supports.</p>
@ -364,7 +385,7 @@
to='juliet@capulet.lit/balcony'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
node='http://code.google.com/p/exodus#8RovUdtOmiAjzj+xI7SK5BCw3A8='>
node='http://code.google.com/p/exodus#SrFo9ar2CCk2EnOH4q4QANeuxLQ='>
<identity category='client' type='pc'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
@ -383,10 +404,7 @@
<stream:features>
<c xmlns='http://jabber.org/protocol/caps'
hash='sha-1'
n='jabberd14'
node='http://jabberd.org'
os='Debian GNU/Linux 2.6.9'
v='1.6.1'
ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='>
</stream:features>
]]></example>
@ -454,9 +472,6 @@
<p>A server that is managing an connected client's presence session MAY optimize presence notification traffic sent through the server by stripping off redundant capabilities annotations. Because of this, receivers of presence notifications MUST NOT expect an annotation on every presence notification they receive. If the server performs caps optimization, it MUST ensure that the first presence notification each subscriber receives contains the annotation. The server MUST also ensure that any changes in the caps information (e.g., an updated 'ver' attribute) are sent to all subscribers.</p>
<p>If a connected client determines that its server supports caps optimization, MAY choose to send the capabilities annotation only on the first presence packet, as well as whenever its capabilities change.</p>
</section2>
<section2 topic='Friendly Name' anchor='impl-name'>
<p>The 'name' attribute of the service discovery &lt;identity/&gt; element enables a responding application to specify the "friendly name" for its node. However, this attribute is excluded from the hash generation method, primarily because it is human-readable text and therefore may be provided in different localized versions. As a result, its inclusion would needlessly multiply the number of possible hash values and thus the time and resources required to validate values of the 'ver' attribute. However, a receiving application MAY send a service discovery information request to a particular JID+node combination in order to determine the friendly name, then cache the result for that JID+node only.</p>
</section2>
</section1>
@ -489,7 +504,6 @@
</section2>
<section2 topic='Information Exposure' anchor='security-exposure'>
<p>Use of entity capabilities might make it easier for an attacker to launch certain application-specific attacks, since the attacker could more easily determine the type of client being used as well as its capabilities. However, since most clients respond to Service Discovery and Software Version requests without performing access control checks, there is no new vulnerability. Entities that wish to restrict access to capabilities information SHOULD use &xep0016; to define appropriate communications blocking (e.g., an entity MAY choose to allow IQ requests only from "trusted" entities, such as those with whom it has a presence subscription of "both"); note, however, that such restrictions may be incompatible with the recommendation regarding <link url='#directed'>Directed Presence</link>.</p>
<p>A client MAY enable a human user to disable inclusion of the 'v' attribute, which specifies a version of the software. If the 'v' attribute is not included, the receiver SHOULD assume that the version is intended to be private and SHOULD NOT automatically send Software Version requests to the sender.</p>
</section2>
</section1>
@ -529,10 +543,7 @@
<xs:extension base='empty'>
<xs:attribute name='ext' type='xs:NMTOKENS' use='optional'/>
<xs:attribute name='hash' type='xs:NMTOKEN' use='required'/>
<xs:attribute name='n' type='xs:string' use='optional'/>
<xs:attribute name='node' type='xs:string' use='required'/>
<xs:attribute name='os' type='xs:string' use='optional'/>
<xs:attribute name='v' type='xs:string' use='optional'/>
<xs:attribute name='ver' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
@ -550,7 +561,7 @@
</section1>
<section1 topic='Legacy Format' anchor='legacy'>
<p>Before Version 1.4 of this specification, the 'ver' attribute was generated differently, the 'ext' attribute was used more extensively, and the 'hash' and 'v' attributes were absent. For historical purposes, Version 1.3 of this specification is archived at &lt;<link url='http://www.xmpp.org/extensions/attic/xep-0115-1.3.html'>http://www.xmpp.org/extensions/attic/xep-0115-1.3.html</link>&gt;. For backwards-compatibility with the legacy format, the 'node' attribute is REQUIRED and the 'ext' attribute MAY be included.</p>
<p>Before Version 1.4 of this specification, the 'ver' attribute was generated differently, the 'ext' attribute was used more extensively, and the 'hash' attribute was absent. For historical purposes, Version 1.3 of this specification is archived at &lt;<link url='http://www.xmpp.org/extensions/attic/xep-0115-1.3.html'>http://www.xmpp.org/extensions/attic/xep-0115-1.3.html</link>&gt;. For backwards-compatibility with the legacy format, the 'node' attribute is REQUIRED and the 'ext' attribute MAY be included.</p>
<p>An application can determine if the legacy format is in use by checking for the presence of the 'hash' attribute, which is REQUIRED in the current format.</p>
<p>If a caps-processing application supports the legacy format, it SHOULD check the 'node', 'ver', and 'ext' combinations as specified in the archived version 1.3 of this specification, and MAY cache the results.</p>
<p>If a caps-processing application does not support the legacy format, it SHOULD ignore the 'ver' value entirely (since the value cannot be verified) and SHOULD NOT cache it, since the application cannot validate the identity and features by checking the hash.</p>