git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1037 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-07-11 14:54:28 +00:00
parent b7f29c155f
commit 7f18520258
1 changed files with 37 additions and 38 deletions

View File

@ -28,8 +28,8 @@
&stpeter;
&remko;
<revision>
<version>1.4pre1</version>
<date>in progress, last updated 2007-07-10</date>
<version>1.4pre2</version>
<date>in progress, last updated 2007-07-11</date>
<initials>psa/jjh</initials>
<remark><p>In response to persistent security concerns over caps poisoning, defined method for hashing concatenation of identity and supported features.</p></remark>
</revision>
@ -120,36 +120,35 @@
<presence from='romeo@montague.lit/home'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='/>
ver='8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
</presence>
]]></code>
<p>The 'node' attribute represents the client Romeo is using. 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 client string 'http://exodus.jabberstudio.org/caps' and a version string 'OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='. Your client therefore sends a service discovery query to Romeo, asking what his client can do (note that the disco#info query is sent to a node of "node#ver"):</p>
<p>At this point, your client has no idea what the capabilities are of someone with a client string 'http://exodus.jabberstudio.org/caps' and a version string '8RovUdtOmiAjzj+xI7SK5BCw3A8='. Your client therefore sends a service discovery query to Romeo, asking what his client can do (note that the disco#info query is sent to a node of "node#ver"):</p>
<code><![CDATA[
<iq type='get' from='juliet@capulet.lit/chamber' to='romeo@montague.lit/home' id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='/>
node='http://exodus.jabberstudio.org/caps#8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
</iq>
]]></code>
<p>The response is:</p>
<code><![CDATA[
<iq type='result' from='romeo@montague.lit/home' to='juliet@capulet.lit/chamber' id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='>
node='http://exodus.jabberstudio.org/caps#8RovUdtOmiAjzj+xI7SK5BCw3A8='>
<identity category='client' type='pc'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
<feature var='http://jabber.org/protocol/feature-neg'/>
<feature var='http://jabber.org/protocol/muc'/>
</query>
</iq>
]]></code>
<p>At this point, your client knows that anyone advertising a version string of 'OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw==' has a client that can do MUC. 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>
<p>At this point, your client knows that anyone advertising a version string of '8RovUdtOmiAjzj+xI7SK5BCw3A8=' has a client that can do MUC. 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'
node='http://exodus.jabberstudio.org/caps'
ver='OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='/>
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>
@ -157,8 +156,8 @@
<code><![CDATA[
<presence from='nurse@capulet.lit/chamber'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='NWExN2ZhNGI0Zjk1OWM5NDY0MTM4OGQyZjA5ZTNkMDk3YTUzZGY1OA=='/>
node='http://psi-im.org/caps'
ver='uCoVCteRe3ty2wU2gHxkMaA7xhs='/>
</presence>
]]></code>
<p>... or the following presence ...</p>
@ -166,7 +165,7 @@
<presence from='bard@shakespeare.lit/globe'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/caps'
ver='YjlhNjEwNjJkMTk3ZTdjM2YyNmQ5MjliY2ZkN2I5NDQwMDJhYTAyOA=='/>
ver='zHyEOgxTrkpSdGcQKH8EFPLsriY='/>
</presence>
]]></code>
<p>... you have no information about what this contact's client is capable of (as he is using a different client/version), and you therefore need to query for capabilities explicitly again via service discovery.</p>
@ -218,7 +217,7 @@
</tr>
<tr>
<td>node</td>
<td>A unique identifier for the software underlying the entity, typically a URL at the website of the project or company that produces the software.</td>
<td>A unique identifier for the software underlying the entity, typically a URL at the website of the project or company that produces the software; required for backward-compatibility.</td>
<td>REQUIRED</td>
</tr>
<tr>
@ -234,22 +233,20 @@
<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 by category and then by type.</li>
<li>For each identity, append the category and then the type (if it exists) to S.</li>
<li>Sort the service discovery identities by category and then by type, formatted as "category" "/" "type".</li>
<li>For each identity, append the category/type (if it exists) to S, followed by the '&lt;' character.</li>
<li>Sort the supported features.</li>
<li>For each feature, append the feature to S.</li>
<li>Compute H by hashing S using the SHA-1 algorithm as specified in &rfc3174; (where the output is hexadecimal-encoded, not binary).</li>
<li>Compute ver by encoding H using Base64 as specified in Section 4 of &rfc4648;.</li>
<li>For each feature, append the feature to S, followed by the '&lt;' character.</li>
<li>Compute ver by hashing S using the SHA-1 algorithm as specified in &rfc3174; (with binary output) and encoding the hash using Base64 as specified in Section 4 of &rfc4648;.</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", "http://jabber.org/protocol/feature-neg", and "http://jabber.org/protocol/muc". The value of the 'ver' attribute would be generated as follows:</p>
<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". The value of the 'ver' attribute would be generated as follows:</p>
<ol>
<li>E = ''</li>
<li>Only one identity: client/pc</li>
<li>E = clientpc</li>
<li>Sort the features: "http://jabber.org/protocol/disco#info", "http://jabber.org/protocol/disco#items", "http://jabber.org/protocol/feature-neg", "http://jabber.org/protocol/muc".</li>
<li>E = clientpchttp://jabber.org/protocol/disco#infohttp://jabber.org/protocol/disco#itemshttp://jabber.org/protocol/feature-neghttp://jabber.org/protocol/muc</li>
<li>H = 980d1268c58c4a888a950dc80e451ee7405b4253</li>
<li>ver = OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw==</li>
<li>E = 'client/pc&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>E = 'client/pc&lt;http://jabber.org/protocol/disco#info&lt;http://jabber.org/protocol/disco#items&lt;&lt;http://jabber.org/protocol/muc&lt;'</li>
<li>ver = 8RovUdtOmiAjzj+xI7SK5BCw3A8=</li>
</ol>
</section1>
@ -263,37 +260,35 @@
<presence>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='/>
ver='8RovUdtOmiAjzj+xI7SK5BCw3A8='/>
</presence>
]]></example>
</section2>
<section2 topic="Discovering Capabilities" anchor='discover'>
<p>A contact can learn what features a user's client supports by sending a disco#info request (as defined in <strong>XEP-0030: Service Discovery</strong>) to any client that sent a particular value of the <strong>ver</strong> attribute. If the requestor has received the same annotation from multiple JIDs, the requestor SHOULD pick a random JID from that list to which the requestor will send the <strong>disco#info</strong> request.</p>
<p>The <strong>disco#info</strong> request is sent to a JID + node combination that consists of the chosen <strong>&lt;user@host/resource&gt;</strong> JID and a service discovery <strong>node</strong> that is constructed as follows: concatenate (1) the value of the caps <strong>'node'</strong> attribute, (2) the "#" character, and (3) the version number specified in the caps <strong>'ver'</strong> attribute.</p>
<p>A contact can learn what features a user's client supports by sending a disco#info request (as defined in <strong>XEP-0030: Service Discovery</strong>) to any client that sent a particular value of the <strong>ver</strong> attribute.</p>
<example caption='Disco#info request for client#version'><![CDATA[
<iq type='get' from='bard@shakespeare.lit/globe' to='randomuser1@capulet.lit/resource' id='123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='/>
<iq type='get' from='bard@shakespeare.lit/globe' to='someuser@capulet.lit/resource' id='123'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>The random user then returns all of the capabilities supported by the base installation of the application without plugins or other add-ons:</p>
<p>The user then returns all of the capabilities supported by software.</p>
<example caption='Disco#info response for client#version'><![CDATA[
<iq type='result' from='randomuser1@capulet.lit/resource' to='bard@shakespeare.lit/globe' id='123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#OTgwZDEyNjhjNThjNGE4ODhhOTUwZGM4MGU0NTFlZTc0MDViNDI1Mw=='>
<iq type='result' from='someuser@capulet.lit/resource' to='bard@shakespeare.lit/globe' id='123'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
<identity category='client' type='pc'/>
<feature var='http://jabber.org/protocol/disco#info'/>
<feature var='http://jabber.org/protocol/disco#items'/>
<feature var='http://jabber.org/protocol/feature-neg'/>
<feature var='http://jabber.org/protocol/muc'/>
</query>
</iq>
]]></example>
<p>The client MUST check the identities and supported features against the 'ver' value by calculating the hash as described under <link url='#ver'>Generating the ver Attribute</link> and making sure that the values match. If the values do not match, the client MUST NOT accept the 'ver' value as reliable and SHOULD check the value of another user who advertises that value (if any). This helps to prevent poisoning of entity capabilities information.</p>
</section2>
<section2 topic='Stream Feature' anchor='stream'>
@ -302,7 +297,7 @@
<stream:features>
<c xmlns='http://jabber.org/protocol/caps'
node='http://jabberd.org/entity'
ver='YThjZWU2MTE0MDVkMmE5N2U0MjYzZWU1ZDI2MzNmOWUyNGRhNmQwNA=='/>
ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='>
</stream:features>
]]></example>
</section2>
@ -378,7 +373,7 @@
<xs:extension base='empty'>
<xs:attribute name='ext' type='xs:NMTOKENS' use='optional'/>
<xs:attribute name='hash' type='xs:NMTOKEN' use='optional' default='sha-1'/>
<xs:attribute name='node' type='xs:string' use='required'/>
<xs:attribute name='node' type='xs:string' use='optional'/>
<xs:attribute name='ver' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
@ -395,6 +390,10 @@
]]></code>
</section1>
<section1 topic='Legacy Format' anchor='legacy'>
<p>Before Version 1.4 of this specification, the 'node' attribute was required, the 'ver' attribute was generated differently, and the 'ext' attribute was used more extensively. 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 backward-compatibility with the legacy format, the 'node' attribute is REQUIRED and the 'ext' attribute MAY be included.</p>
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>Thanks to Rachel Blackman, Dave Cridland, Richard Dobson, Sergei Golovan, Justin Karneges, Jacek Konieczny, Ian Paterson, Kevin Smith, Tomasz Sterna, and Michal Vaner for comments and suggestions.</p>
</section1>