git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@272 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2006-12-13 23:16:18 +00:00
parent d8995ddf5c
commit 35ab60cdc0
1 changed files with 153 additions and 120 deletions

View File

@ -37,6 +37,12 @@
</author>
&stpeter;
&infiniti;
<revision>
<version>0.13</version>
<date>2006-12-13</date>
<initials>psa/ip</initials>
<remark><p>Clarified chat session negotiation of OTR settings; defined stream feature.</p></remark>
</revision>
<revision>
<version>0.12</version>
<date>2006-11-23</date>
@ -111,7 +117,7 @@
</revision>
</header>
<section1 topic='Introduction' anchor='intro'>
<p>Many XMPP clients implement some form of client-side message archiving. However, it is not always convenient or even possible to archive messages locally, e.g., because it is easier to keep all archives in one universally accessable place (not scattered around on multiple computers or devices) or because the client operates in a web browser or resides on a mobile device that does not have sufficient local storage for message archiving. In addition, server-side archiving makes it possible to offer new services such as integration of IM and email. Therefore it is beneficial to define methods for server-side archiving of XMPP messages.</p>
<p>Many XMPP clients implement some form of client-side message archiving. However, it is not always convenient or even possible to archive messages locally, e.g., because it is easier to keep all archives in one universally accessible place (not scattered around on multiple computers or devices) or because the client operates in a web browser or resides on a mobile device that does not have sufficient local storage for message archiving. In addition, server-side archiving makes it possible to offer new services such as integration of IM and email. Therefore it is beneficial to define methods for server-side archiving of XMPP messages.</p>
<p>There are two main approaches to this problem:</p>
<ol start='1'>
<li>Enable the client to send individual messages or entire conversations to the server for archiving (optionally after encryption); we call this manual archiving.</li>
@ -128,17 +134,17 @@
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
]]></example>
<p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'urn:xmpp:archive#name', where 'name' is 'auto' for the <link url='#auto'>Automated Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automated Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, or 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p>
<p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'http://www.xmpp.org/extensions/xep-0136.html#ns-name', where 'name' is 'auto' for the <link url='#auto'>Automated Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automated Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, and 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p>
<example caption='Server Service Discovery response'>
<![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
...
<feature var='urn:xmpp:archive#auto'/>
<feature var='urn:xmpp:archive#encrypt'/>
<feature var='urn:xmpp:archive#manage'/>
<feature var='urn:xmpp:archive#manual'/>
<feature var='urn:xmpp:archive#pref'/>
<feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-auto'/>
<feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-encrypt'/>
<feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-manage'/>
<feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-manual'/>
<feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-pref'/>
...
</query>
</iq>
@ -160,7 +166,7 @@
<p>In order to determine its user's current Save Mode(s) and OTR Mode(s), a client sends an empty &lt;pref/&gt; element to its server:</p>
<example caption='Client Requests Archiving Preferences'><![CDATA[
<iq type='get' id='pref1'>
<pref xmlns='urn:xmpp:archive'/>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
]]></example>
<p>The server responds with the default Save Mode and OTR Mode (a single &lt;default/&gt; element) and any specific Save Modes and OTR Modes for individual contacts (zero or more &lt;item/&gt; elements).</p>
@ -173,7 +179,7 @@
<p>The server MUST also include an &lt;auto/&gt; element reflecting the current <link url='#auto'>Automated Archiving</link> settings for <em>this stream</em>.</p>
<example caption='Server Returns Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default save='body' otr='concede' expire='31536000'/>
<item jid='romeo@montague.net' save='false' otr='require'/>
<item jid='benvolio@montague.net' save='message' expire='630720000' otr='forbid'/>
@ -187,7 +193,7 @@
<p>If the user has never set the default Modes, the 'save' and 'otr' attributes SHOULD specify the server's default settings, and the 'unset' attribute SHOULD be set to 'true'. Note: The 'unset' attribute defaults to 'false'.</p>
<example caption='Server Returns Service Default Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default save='false' otr='concede' unset='true'/>
<method type='auto' use='concede'/>
<method type='local' use='concede'/>
@ -202,7 +208,7 @@
<p>A client may set the default Modes:</p>
<example caption='Client Sets Default Modes'><![CDATA[
<iq type='set' id='pref2'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default save='false' otr='prefer'/>
</pref>
</iq>
@ -214,13 +220,13 @@
<p>The server then MUST inform all of the user's connected resources that have previously requested the user's archiving preferences:</p>
<example caption='Server Pushes New Modes'><![CDATA[
<iq type='set' id='push1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default save='false' otr='prefer'/>
</pref>
</iq>
<iq type='set' id='push2' to='juliet@capulet.com/pda'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default save='false' otr='prefer'/>
</pref>
</iq>
@ -235,7 +241,7 @@
<p>A client may use a similar protocol to set the Modes for a particular contact or domain of contacts (bare JID, full JID or domain). Note: It is STRONGLY RECOMMENDED for the value of the 'jid' attribute to be a bare JID (&BAREJID;).</p>
<example caption='Client Sets Modes for a Contact'><![CDATA[
<iq type='set' id='pref3'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
@ -245,13 +251,13 @@
]]></example>
<example caption='Server Pushes New Modes'><![CDATA[
<iq type='set' id='push3' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
<iq type='set' id='push4' to='juliet@capulet.com/pda'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
</pref>
</iq>
@ -261,7 +267,7 @@
<section2 topic='Setting Archiving Method Preferences' anchor='pref-jid'>
<example caption='Client Sets Method Preferences'><![CDATA[
<iq type='set' id='pref4'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -273,7 +279,7 @@
]]></example>
<example caption='Server Pushes New Method Preferences'><![CDATA[
<iq type='set' id='push5' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -281,7 +287,7 @@
</iq>
<iq type='set' id='push6' to='juliet@capulet.com/pda'>
<pref xmlns='urn:xmpp:archive'>
<pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<method type='auto' use='concede'/>
<method type='local' use='forbid'/>
<method type='manual' use='prefer'/>
@ -294,94 +300,101 @@
<p>A user will sometimes exchange messages with contacts who prefer that their conversations are not archived by either party.</p>
<section2 topic='OTR Negotiation' anchor='otr-nego'>
<p>Any client that archives messages SHOULD support <cite>Chat Session Negotiation</cite> and its 'otr' field both to give other contacts the opportunity to indicate this preference, and to negotiate an "Off The Record" (OTR) policy that complies with its user's own <link url='#pref'>Archiving Preferences</link>.</p>
<p>Note: A client MUST NOT propose or agree to enable OTR unless it has confirmed that its server will allow it to switch off <link url='#auto'>Automated Archiving</link>.</p>
<table caption='OTR options offered when client initiates a chat negotiation'>
<p>Note: A client MUST NOT propose or agree to enable OTR (i.e., disallow message logging) unless it has confirmed that its server will allow it to switch off <link url='#auto'>Automated Archiving</link>.</p>
<p>Both parties to a chat session negotiation may have OTR preferences (i.e, the initiating party or "user" and the responding party or "contact"). These preferences will interact in the ways specified below, resulting either in a successful negotiation or an unsuccessful negotiation (naturally, an unsuccessful negotiation can lead to a subsequent negotiation attempt by the user or the contact).</p>
<p>The following table shows what chat session negotiation values the initating party (i.e., the "user") should send for the 'otr' field in the initial data form for a chat session negotiation (note: 'may' means that the receiving party MAY enable message logging and 'mustnot' means that the receiving party MUST NOT enable logging).</p>
<table caption='OTR options offered by initiating party (user)'>
<tr>
<th>OTR Archive Preference</th>
<th>Offered options*</th>
<th>User's OTR Preference</th>
<th>Offering 'otr' Negotiation Option(s)*</th>
</tr>
<tr>
<td>require</td>
<td>true***</td>
<td>may**</td>
</tr>
<tr>
<td>prefer</td>
<td>true,false</td>
<td>may,mustnot</td>
</tr>
<tr>
<td>approve</td>
<td>true,false</td>
<td>may,mustnot</td>
</tr>
<tr>
<td>concede</td>
<td>false,true**</td>
<td>mustnot,may***</td>
</tr>
<tr>
<td>oppose</td>
<td>false,true**</td>
<td>mustnot,may***</td>
</tr>
<tr>
<td>forbid</td>
<td>false**</td>
<td>mustnot***</td>
</tr>
</table>
<p>* In order of preference, the first value is the default</p>
<p>** Alternatively, the client MAY decide not to <em>initiate</em> an OTR negotiation and to save messages (until the contact initiates a negotiation).</p>
<p>*** If the client receives no response it MUST NOT send any messages to the contact.</p>
<p>Note: When negotiating a chat session the client MUST include the &lt;required/&gt; element inside the 'otr' &lt;field/&gt; element. If the client receives no successful response to its chat negotiation request (and if the OTR Mode is not 'require') then it SHOULD proceed as if the contact had responded with the value of the 'otr' &lt;field/&gt; element set to 'false'.</p>
<table caption='OTR state selected when client responds to each of the four possible offers'>
<p>** If the user receives no response it MUST NOT send any messages to the contact.</p>
<p>*** Alternatively, the user MAY decide not to <em>initiate</em> an OTR negotiation and to save messages (until the contact initiates a negotiation).</p>
<p>Note: When negotiating a chat session, the user MUST include the &lt;required/&gt; element inside the 'otr' &lt;field/&gt; element. If the user does not receive a successful response to its chat negotiation request (and if the OTR Mode is not 'require'), then it SHOULD proceed as if the contact had responded with the value of the 'otr' &lt;field/&gt; element set to 'false'.</p>
<p>The following table shows what chat session negotiation values the responding party (i.e., "contact") should send for the 'otr' field in its response to a chat session negotiation request from the user.</p>
<table caption='OTR value selected by responding party (contact)'>
<tr>
<th>OTR Archive Preference</th>
<th>true</th>
<th>true,false*</th>
<th>false,true*</th>
<th>false</th>
<th>Contact's OTR Preference</th>
<th colspan='4'>Responding 'otr' Negotiation Values*</th>
</tr>
<tr>
<th>Initiator Options --&gt;</th>
<th>may</th>
<th>may,mustnot*</th>
<th>mustnot,may*</th>
<th>mustnot</th>
</tr>
<tr>
<td>require</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>may</td>
<td>may</td>
<td>may</td>
<td>fail**</td>
</tr>
<tr>
<td>prefer</td>
<td>true</td>
<td>true</td>
<td>true</td>
<td>false</td>
<td>may</td>
<td>may</td>
<td>may</td>
<td>mustnot</td>
</tr>
<tr>
<td>approve</td>
<td>true</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>may</td>
<td>may</td>
<td>mustnot</td>
<td>mustnot</td>
</tr>
<tr>
<td>concede</td>
<td>true</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>may</td>
<td>may</td>
<td>mustnot</td>
<td>mustnot</td>
</tr>
<tr>
<td>oppose</td>
<td>true</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>may</td>
<td>mustnot</td>
<td>mustnot</td>
<td>mustnot</td>
</tr>
<tr>
<td>forbid</td>
<td>fail**</td>
<td>false</td>
<td>false</td>
<td>false</td>
<td>mustnot</td>
<td>mustnot</td>
<td>mustnot</td>
</tr>
</table>
<p>* The first value is the default.</p>
<p>** The client MUST NOT send any messages to the contact.</p>
<p>** The negotiation fails and the parties MUST NOT exchange any messages; however, the recipient MAY attempt to initiate a chat session negotiation with the other party.</p>
<p>Note: If a contact does not include an 'otr' field in its initial Chat Session Negotiation request, and a user's Archiving Preferences indicate that OTR is <em>required</em>, then the client MUST refuse the request. It MAY then send its own Chat Session Negotiation request with an 'otr' field.</p>
<p>If a user's OTR preference for a contact changes during a Chat Session that has been negotiated with the contact, and if the new preference would affect the value of the 'otr' field that was previously negotiated, then the client MUST immediately renegotiate the 'otr' field according to the user's new OTR preference (or terminate the Chat Session).</p>
</section2>
@ -394,7 +407,7 @@
<section2 topic='Introduction' anchor='manual-intro'>
<p>While automated archiving is easy for the client and server to implement, there are many contexts in which manual archiving is required. For examples, when:</p>
<ul>
<li>Messages are encrypted using evanscent keys, as in &xep0116;</li>
<li>Messages are encrypted using evanescent keys, as in &xep0116;</li>
<li>A client's own server does not support automated archiving but it (or another server) does support manual archiving</li>
<li>A server does not support encryption of auto-archived collections</li>
<li>A client wants to maintain a unified archive for messages that were transmitted both in and out-of-band (e.g. SMS or email)</li>
@ -422,7 +435,7 @@
<p>A collection of messages and notes is uploaded to the server encapsulated in a &lt;save/&gt; element.</p>
<example caption='Storing messages in a collection'><![CDATA[
<iq type='set' id='up1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
thread='damduoeg08'
@ -453,7 +466,7 @@
<p>If the client specifies a new value for the 'subject' attribute of any existing collection then the server MUST update the existing value. Note: The client cannot specify new values for the 'with' or 'start' attributes. The only way to change these values is to delete the collection (see <link url='#manage-remove'>Removing a Collection</link>) and then create a new one.</p>
<example caption='Changing the subject of a collection without appending messages'><![CDATA[
<iq type='set' id='subject1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks twice!'/>
@ -465,7 +478,7 @@
<p>The client MAY specify an absolute time for any message by providing a longer 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>Jabber Date and Time Profiles</cite>) instead of a 'secs' attribute. The absolute time MAY be before the start time of the collection:</p>
<example caption='Storing offline messages in a collection'><![CDATA[
<iq type='set' id='up2'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'>
@ -478,15 +491,15 @@
]]></example>
</section2>
<section2 topic='Groupchat Messages' anchor='impl-muc'>
<p>A client MAY archive messages that it receives from &xep0045; rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each &lt;from/&gt; element to specify the room nickname of the message sender:</p>
<p>A client MAY archive messages that it receives from &xep0045; rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each &lt;from/&gt; element to specify the room nickname (and, if available, bare JID) of the message sender:</p>
<example caption='Storing groupchat messages in a collection'><![CDATA[
<iq type='set' id='up3'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<from secs='0' name='benvolio'><body>She will invite him to some supper.</body></from>
<from secs='5' name='mercutio'><body>A bawd, a bawd, a bawd! So ho!</body></from>
<from secs='11' name='romeo'><body>What hast thou found?</body></from>
<from secs='11' name='romeo' jid='romeo@montague.net'><body>What hast thou found?</body></from>
</chat>
</save>
</iq>
@ -496,7 +509,7 @@
<p>Collections MAY be linked together by including a &lt;previous/&gt; and/or &lt;next/&gt; element. Each such element MUST include both a 'with' and a 'start' element to identify the other collection to which the collection is linked. For example, the &lt;previous/&gt; and &lt;next/&gt; elements in the two examples below are being used to link a groupchat between Romeo, Benvolio and Mercutio to a private chat that Romeo was having with Benvolio before they invited Mercutio to join them. Note: Collections MAY be linked in only one direction, they are not required to be double-linked in the way the examples below are.</p>
<example caption='Private chat linked to later groupchat'><![CDATA[
<iq type='set' id='link1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<next with='balcony@house.capulet.com' start='1469-07-21T03:16:37Z'/>
@ -508,7 +521,7 @@
]]></example>
<example caption='Groupchat linked to earlier private chat'><![CDATA[
<iq type='set' id='link2'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<previous with='benvolio@capulet.com' start='1469-07-21T03:01:54Z'/>
@ -524,7 +537,7 @@
<p>&lt;previous/&gt; and &lt;next/&gt; elements MAY be removed from a collection simply by uploading a &lt;previous/&gt; and/or &lt;next/&gt; element without any 'with' or 'start' attributes. Note: The server SHOULD NOT return an error if it finds that a link to be deleted does not exist.</p>
<example caption='Deleting any links to other collections'><![CDATA[
<iq type='set' id='link3'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
<previous/>
@ -539,11 +552,11 @@
<p>A collection MUST NOT contain more than one x:data form. If a form is uploaded to a collection that already contains one then the older form element MUST be discarded. When a collection is retrieved (see <link url='#manage-retrieve'>Retrieving a Collection</link>) the x:data form MUST appear as the first element in the collection after any &lt;previous/&gt; or &lt;next/&gt; elements, whatever order it was uploaded in. Upon retrieval the 'type' attribute of the form MAY be 'submit' or 'form'.</p>
<example caption='Private chat with attributes form'><![CDATA[
<iq type='set' id='form1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'><value>urn:xmpp:archive</value></field>
<field var='FORM_TYPE'><value>http://www.xmpp.org/extensions/xep-0136.html#ns</value></field>
<field var='task'><value>1</value></field>
<field var='important'><value>1</value></field>
<field var='action_before'><value>1469-07-29T12:00:00Z</value></field>
@ -557,7 +570,7 @@
<p>The content of the uploaded x:data form MAY be encrypted (see <link url='#crypt'>Encryption</link>).</p>
<example caption='Private chat with encrypted attributes form'><![CDATA[
<iq type='set' id='form2'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'>
@ -585,7 +598,7 @@
<p>The x:data form MAY be removed from a collection simply by uploading an empty form. Note: The server SHOULD NOT return an error if it finds that the form to be deleted does not exist.</p>
<example caption='Deleting the attributes form'><![CDATA[
<iq type='set' id='form3'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'>
<x xmlns='jabber:x:data' type='submit'/>
@ -596,7 +609,7 @@
</section2>
</section1>
<section1 topic='Encryption' anchor='crypt'>
<p>The examples above are not encrypted for clarity. However, clients SHOULD encrypt manually-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later versions). Servers MUST support the manual-archiving of encrypted collections.</p>
<p>The examples above are not encrypted for clarity. However, clients SHOULD encrypt manually-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later releases). Servers MUST support the manual-archiving of encrypted collections.</p>
<p>Before uploading a sequence of messages to a collection, the client SHOULD select a symmetric data encryption algorithm, generate a suitable random encryption key, give the key a unique (for the user) name, encrypt the symmetric key with one of the user's public keys, and wrap the result inside one or more &lt;EncryptedKey/&gt; elements, as specified in &w3xmlenc;.</p>
<p>To ensure that all its user's clients will be able to decrypt the collection, the client SHOULD create one &lt;EncryptedKey/&gt; element for each of its user's public keys that are being published using &xep0189;. However, the client MUST NOT create an &lt;EncryptedKey/&gt; element for any public key until it has confirmed that it belongs to the user. Note: The fact that a public key is being published using <cite>Public Key Publishing</cite> is <em>not</em> sufficient proof of ownership, since the user's server may have been compromised at some stage. The method of confirmation is beyond the scope of this document.</p>
<p>The client SHOULD use the symmetric key to encrypt the joined sequence of &lt;to/&gt;, &lt;from/&gt; and &lt;note/&gt; elements, base64 encode the resulting sequence of bytes, and wrap it inside an &lt;EncryptedData/&gt; element, as described in <cite>XML Encryption</cite>.</p>
@ -605,7 +618,7 @@
<p>Note: A collection that contains &lt;EncryptedData/&gt; or &lt;EncryptedKey/&gt; elements MUST NOT contain &lt;to/&gt; or &lt;from/&gt; or &lt;note/&gt; elements.</p>
<example caption='Storing encrypted messages and keys in a collection'><![CDATA[
<iq type='set' id='crypt1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
subject='She speaks!'>
@ -664,19 +677,19 @@
</ul>
<example caption='Client enables auto archiving'><![CDATA[
<iq type='set' id='auto1'>
<auto save='true' xmlns='urn:xmpp:archive'/>
<auto save='true' xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
]]></example>
</section2>
<section2 topic='Enabling Auto-Archiving with Encryption' anchor='auto-crypt'>
<p>Servers (and clients) SHOULD support the encryption (and decryption) of automatically-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later versions).</p>
<p>Whenever the client enables auto-archiving it SHOULD set the optional 'encrypt' attribute to 'true'. After receiving such a request, if the server supports encryption (see <link url='#disco'>Determining Server Support</link>), it MUST encrypt all the messages that it archives automatically (including any message collections that are currently being recorded) by following exactly the same proceedure as clients use when manually archiving collections (see <link url='#crypt'>Encryption</link>).</p>
<p>Servers (and clients) SHOULD support the encryption (and decryption) of automatically-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later releases).</p>
<p>Whenever the client enables auto-archiving it SHOULD set the optional 'encrypt' attribute to 'true'. After receiving such a request, if the server supports encryption (see <link url='#disco'>Determining Server Support</link>), it MUST encrypt all the messages that it archives automatically (including any message collections that are currently being recorded) by following exactly the same procedure as clients use when manually archiving collections (see <link url='#crypt'>Encryption</link>).</p>
<p>The client MAY also specify one or more public keys (in addition to any public keys that the user may be publishing using <cite>Public Key Publishing</cite>). The server MUST use them all to encrypt all the symmetric keys it generates and add these to the collection wrapped in &lt;EncryptedKey/&gt; elements.</p>
<example caption='Client enables auto archiving with encryption'><![CDATA[
<iq type='set' id='auto2'>
<auto save='true'
encrypt='true'
xmlns='urn:xmpp:archive'>
xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
<KeyValue>
<KeyName>romeoPublicKey3fingerprint</KeyName>
@ -717,7 +730,7 @@
<p>The client SHOULD use <cite>Result Set Management</cite> to limit the number of collections returned by the server in a single stanza, taking care not to request a page of collections that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of a list with same JID'><![CDATA[
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -727,7 +740,7 @@
]]></example>
<example caption='Requesting the first page of a list with same JID between two times'><![CDATA[
<iq type='get' id='period1'>
<list xmlns='urn:xmpp:archive'
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
end='1479-07-21T04:00:00Z'>
@ -739,7 +752,7 @@
]]></example>
<example caption='Requesting the first page of a list after a time'><![CDATA[
<iq type='get' id='list1'>
<list xmlns='urn:xmpp:archive'
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -750,7 +763,7 @@
<p>The server MUST list the collections (empty &lt;chat/&gt; elements including all attributes) in chronological order when responding to any request. If the collection contains &lt;EncryptedData/&gt; or &lt;EncryptedKey/&gt; elements then the 'crypt' attribute of the &lt;chat/&gt; element MUST be set to 'true':</p>
<example caption='Receiving the first page of a list'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='urn:xmpp:archive'>
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'
@ -772,12 +785,12 @@
<p>If no collections correspond to the request the server MUST return an empty &lt;list/&gt; element:</p>
<example caption='Receiving an empty list'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='urn:xmpp:archive'/>
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
]]></example>
<example caption='Requesting the second page of a list'><![CDATA[
<iq type='get' id='list2'>
<list xmlns='urn:xmpp:archive'
<list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>30</max>
@ -793,7 +806,7 @@
<p>The client SHOULD use <cite>Result Set Management</cite> to limit the number of messages returned by the server in a single stanza, taking care not to request a page of messages that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of a collection'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='urn:xmpp:archive'
<retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -804,7 +817,7 @@
]]></example>
<example caption='Receiving the first page of a collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<chat xmlns='urn:xmpp:archive'
<chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'>
@ -826,7 +839,7 @@
<p>If the specified collection does not exist then the server MUST return an &notfound; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard' id='page1'>
<retrieve xmlns='urn:xmpp:archive'
<retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -841,7 +854,7 @@
<p>If the requested collection is empty the server MUST return an empty &lt;chat/&gt; element:</p>
<example caption='Receiving an empty collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<chat xmlns='urn:xmpp:archive'
<chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
subject='She speaks!'/>
@ -849,7 +862,7 @@
]]></example>
<example caption='Requesting the second page of a collection'><![CDATA[
<iq type='get' id='page2'>
<retrieve xmlns='urn:xmpp:archive'
<retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -862,7 +875,7 @@
<p>The items in encrypted collections are typically larger - since each &lt;EncryptedData/&gt; element typically contains many messages. So the client SHOULD take even more care not to request a page of &lt;EncryptedData/&gt; elements that is so big it might exceed karma limits.</p>
<example caption='Requesting the first page of an encrypted collection with all versions of keys'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='urn:xmpp:archive'
<retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
<set xmlns='http://jabber.org/protocol/rsm'>
@ -874,7 +887,7 @@
<p>In addition to the requested &lt;EncryptedData/&gt; elements, the server MUST return all the &lt;EncryptedKey/&gt; elements that it possesses for the user whose symmetric key name (wrapped in its &lt;CarriedKeyName/&gt; child) is referenced by the &lt;KeyName/&gt; child of the &lt;KeyInfo/&gt; child of any of the &lt;EncryptedData/&gt; elements in the returned page.</p>
<example caption='Receiving the first page of an encrypted collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<chat xmlns='urn:xmpp:archive'
<chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
subject='She speaks!'>
@ -940,7 +953,7 @@
<p>The client MAY limit the number of &lt;EncryptedKey/&gt; elements that it receives by specifying the name of one or more public keys for which it holds the associated private keys. The name of each public key MUST be wrapped in a &lt;KeyName/&gt; element.</p>
<example caption='Requesting the first page of an encrypted collection with specified version of keys'><![CDATA[
<iq type='get' id='page1'>
<retrieve xmlns='urn:xmpp:archive'
<retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
@ -957,7 +970,7 @@
<p>To request the removal of a single collection the client sends an empty &lt;remove/&gt; element. The 'with' (full JID) and 'start' attributes MUST be included to uniquely identify the collection.</p>
<example caption='Removing a single collection'><![CDATA[
<iq type='set' id='remove1'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
</iq>
@ -965,7 +978,7 @@
<p>The client may remove several collections at once. The 'start' and 'end' elements MAY be specified to indicate a date range. The 'with' attribute MAY be a full JID, bare JID or domain.</p>
<example caption='Removing all collections with a specified bare JID between two times'><![CDATA[
<iq type='set' id='remove2'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
end='1469-07-21T04:00:00Z'/>
@ -975,7 +988,7 @@
<p>If the end date is in the future then then all collections after the start date are removed.</p>
<example caption='Removing all collections after a date'><![CDATA[
<iq type='set' id='remove3'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
start='1469-07-21T02:00:00Z'
end='2038-01-01T00:00:00Z'/>
</iq>
@ -983,34 +996,34 @@
<p>If the start date is before all the collections in the archive then all collections prior to the end date are removed.</p>
<example caption='Removing all collections before a date'><![CDATA[
<iq type='set' id='remove4'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
start='0000-01-01T00:00:00Z'
end='1469-07-21T04:00:00Z'/>
</iq>
]]></example>
<example caption='Removing all collections'><![CDATA[
<iq type='set' id='remove5'>
<remove xmlns='urn:xmpp:archive'/>
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
]]></example>
<p>If the value of the optional 'open' attribute is set to 'true' then only collections that are currently being recorded automatically by the server (see <link url='#auto'>Automated Archiving</link>) are removed.</p>
<example caption='Removing a collection being recorded by the server'><![CDATA[
<iq type='set' id='remove6'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
open='true'/>
</iq>
]]></example>
<example caption='Removing all collections being recorded by the server'><![CDATA[
<iq type='set' id='remove7'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
open='true'/>
</iq>
]]></example>
<p>If the specified collection (or collections) do not exist then the server MUST return an &notfound; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard' id='remove1'>
<remove xmlns='urn:xmpp:archive'
<remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
<error code='404' type='cancel'>
@ -1025,7 +1038,7 @@
<p>The client first requests a list of the affected &lt;EncryptedKey/&gt; elements from all collections by sending a &lt;keys/&gt; element to the server:</p>
<example caption='Requesting the first page of a list of keys'><![CDATA[
<iq type='get' id='pubkey1'>
<keys xmlns='urn:xmpp:archive'>
<keys xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
@ -1036,7 +1049,7 @@
<p>The server MUST return only &lt;EncryptedKey/&gt; elements whose symmetric encryption key is encrypted with the obsolete public key specified in the &lt;KeyName/&gt; child of the request:</p>
<example caption='Receiving the first page of a list of keys'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='pubkey1'>
<keys xmlns='urn:xmpp:archive'>
<keys xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
@ -1070,7 +1083,7 @@
<p>The client decrypts each symmetric key with the obsolete private key and encrypts it again with the new public key. The client then wraps each symmetric key in an &lt;EncryptedKey/&gt; element and asks the server to archive it in its associated collection on the server (see <link url='#crypt'>Encryption</link>):</p>
<example caption='Storing encrypted keys in a collection'><![CDATA[
<iq type='set' id='crypt1'>
<save xmlns='urn:xmpp:archive'>
<save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<chat with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
@ -1099,7 +1112,7 @@
<p>Finally, the client asks the server to delete from each collection all &lt;EncryptedKey/&gt; elements whose symmetric encryption key is encrypted with the obsolete public key:</p>
<example caption='Deleting key(s) from a collection'><![CDATA[
<iq type='get' id='delete1'>
<delete xmlns='urn:xmpp:archive'
<delete xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
@ -1117,7 +1130,7 @@
<example caption='Requesting a page of modifications'>
<![CDATA[
<iq type='get' id='sync1'>
<modified xmlns='urn:xmpp:archive'>
<modified xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
<after>1469-07-21T01:14:47Z</after>
@ -1128,7 +1141,7 @@
<p>The server MUST return the changed collections in the chronological order that they were changed (most recent last). If a collection has been modified, created or removed <em>after</em> the time specified by the &lt;after/&gt; element then the server MUST include it in the returned result set page of collections (unless the specified maximum page size would be exceeded). Each &lt;changed/&gt; or &lt;removed/&gt; collection element (for modified/created, or removed collections respectively) in the returned list MUST include only 'with' and 'start' attribues. The server MUST set the content of the &lt;last/&gt; element to the UTC time (see <cite>Jabber Date and Time Profiles</cite>) that the last collection on the page was modified.</p>
<example caption='Receiving a page of modifications'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
<modified xmlns='urn:xmpp:archive'>
<modified xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<changed with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
.
@ -1152,7 +1165,7 @@
<p>So that clients can share archived messages, this document specifies a common format for storage on disk (similar to email formats like mbox and Maildir). The file format uses the same XML constructs as the protocol. Each file may contain messages exchanged with a single JID. Any number of &lt;chat/&gt; elements may be stored in an archive file.</p>
<example caption='Example file'><![CDATA[
<?xml version='1.0'?>
<archive xmlns='urn:xmpp:archive'
<archive xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
with='juliet@capulet.com'>
<chat start='1469-07-21T02:56:15Z' subject='She speaks!'>
<from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
@ -1174,9 +1187,21 @@
<p>Server implementations SHOULD give system administrators the option to disable support for both automated and manual archiving, since archived conversations can consume significant storage space.</p>
</section2>
</section1>
<section1 topic='Stream Feature' anchor='streamfeature'>
<p>Although message archiving is not negotiated between a client and its server as part of stream negotiation, a server MAY advertise a stream feature of "http://www.xmpp.org/extensions/xep-0136.html#ns" (see <link url='#ns'>Protocol Namespace</link>) during stream setup (via the &lt;feature/&gt; element, which MUST NOT contain a &lt;required/&gt; child), and MUST do so if automatic archiving is on by default (if so, the &lt;feature/&gt; element MUST include a &lt;default/&gt; child).</p>
<example caption='Stream Feature'><![CDATA[
<feature xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
]]></example>
<example caption='Stream Feature (Automatic Archiving on By Default)'><![CDATA[
<feature xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
<default/>
</feature>
]]></example>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<section2 topic='Automatic Archiving Defaulting to On' anchor='security-autoon'>
<p>If automatic archiving defaults to enabled then that creates serious privacy issues for users of legacy clients that do not support this protocol, and (more seriously) for those contacts who they unwittingly mislead by agreeing to disable logging (via the 'otr' field defined in XEP-0155).</p>
<p>If a server deployment enables automatic archiving by default, then it MUST return a stream feature containing an empty &lt;default/&gt; element (see the <link url='#streamfeature'>Stream Feature</link> section of this document).</p>
</section2>
<section2 topic='Plain Text Subject' anchor='security-encrypt'>
<p>Since the subject of each collection will not be encrypted, the client MUST warn its human user (if any) before including 'subject' attributes on encrypted collections.</p>
@ -1191,24 +1216,24 @@
<p>No interaction with &IANA; is required as a result of this document.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>The &REGISTRAR; shall include 'urn:xmpp:archive' in its registry of protocol namespaces (see &NAMESPACES;):</p>
<section2 topic='Protocol Namespace' anchor='ns'>
<p>Until this specification advances to a status of Draft, its associated namespace shall be "http://www.xmpp.org/extensions/xep-0155.html#ns"; upon advancement of this specification, the XMPP Registrar shall issue a permanent namespace in accordance with the process defined in Section 4 of &xep0053;.</p>
</section2>
<section2 topic='Service Discovery Features' anchor='registrar-features'>
<p>The XMPP Registrar shall include the following features in its registry of service discovery features (see &DISCOFEATURES;):</p>
<ul>
<li>urn:xmpp:archive#auto</li>
<li>urn:xmpp:archive#encrypt</li>
<li>urn:xmpp:archive#manage</li>
<li>urn:xmpp:archive#manual</li>
<li>urn:xmpp:archive#pref</li>
<li>http://www.xmpp.org/extensions/xep-0136.html#ns-auto</li>
<li>http://www.xmpp.org/extensions/xep-0136.html#ns-encrypt</li>
<li>http://www.xmpp.org/extensions/xep-0136.html#ns-manage</li>
<li>http://www.xmpp.org/extensions/xep-0136.html#ns-manual</li>
<li>http://www.xmpp.org/extensions/xep-0136.html#ns-pref</li>
</ul>
</section2>
<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. The following fields shall be registered for use in Message Archiving:</p>
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>urn:xmpp:archive</name>
<name>http://www.xmpp.org/extensions/xep-0136.html#ns</name>
<jep>XEP-0136</jep>
<desc>Attributes of a message collection</desc>
<field
@ -1236,8 +1261,8 @@
<xs:schema
xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='urn:xmpp:archive'
xmlns='urn:xmpp:archive'
targetNamespace='http://www.xmpp.org/extensions/xep-0136.html#ns'
xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
elementFormDefault='qualified'>
<xs:annotation>
@ -1513,6 +1538,14 @@
</xs:complexType>
</xs:element>
<xs:element name='feature'>
<xs:complexType>
<xs:sequence>
<xs:element ref='default' minOccurs='0' maxOccurs='1'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name='empty'>
<xs:restriction base='xs:string'>
<xs:enumeration value=''/>