auto-archiving warning for legacy clients

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@71 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Ian Paterson 2006-10-05 04:48:53 +00:00
parent 7f9ed6c852
commit 416fdaa3dc
1 changed files with 85 additions and 54 deletions

View File

@ -36,6 +36,12 @@
</author>
&stpeter;
&infiniti;
<revision>
<version>0.10</version>
<date>2006-10-04</date>
<initials>ip</initials>
<remark><p>Added auto-archiving warning for legacy clients; corrected examples</p></remark>
</revision>
<revision>
<version>0.9</version>
<date>2006-10-02</date>
@ -105,16 +111,14 @@
<p>A client discovers whether its server supports this protocol using &xep0030;.</p>
<example caption='Client Service Discovery request'>
<![CDATA[
<iq type='get' to='montague.net'>
<iq type='get' id='disco1'>
<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 'http://jabber.org/protocol/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>
<example caption='Server Service Discovery response'>
<![CDATA[
<iq type='result'
from='montague.net'
to='romeo@montague.net/orchard'>
<iq type='result' to='romeo@montague.net/orchard' id='disco1'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
...
<feature var='http://jabber.org/protocol/archive#auto'/>
@ -142,7 +146,7 @@
<section2 topic='Determining Preferences' anchor='pref-determine'>
<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' from='juliet@capulet.com/chamber'>
<iq type='get' id='pref1'>
<pref xmlns='http://jabber.org/protocol/archive'/>
</iq>
]]></example>
@ -185,7 +189,7 @@
<section2 topic='Setting Default Modes' anchor='pref-default'>
<p>A client may set the default Modes:</p>
<example caption='Client Sets Default Modes'><![CDATA[
<iq type='set' id='pref2' from='juliet@capulet.com/chamber'>
<iq type='set' id='pref2'>
<pref xmlns='http://jabber.org/protocol/archive'>
<default save='false' otr='try'/>
</pref>
@ -218,7 +222,7 @@
<section2 topic='Setting Modes for a Contact' anchor='pref-jid'>
<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' from='juliet@capulet.com/chamber'>
<iq type='set' id='pref3'>
<pref xmlns='http://jabber.org/protocol/archive'>
<item jid='romeo@montague.net' save='body' expire='604800' otr='allow'/>
</pref>
@ -244,7 +248,7 @@
</section2>
<section2 topic='Setting Archiving Method Preferences' anchor='pref-jid'>
<example caption='Client Sets Method Preferences'><![CDATA[
<iq type='set' id='pref4' from='juliet@capulet.com/chamber'>
<iq type='set' id='pref4'>
<pref xmlns='http://jabber.org/protocol/archive'>
<method type='auto' use='allow'/>
<method type='local' use='never'/>
@ -310,7 +314,7 @@
<section2 topic='Uploading Messages to a Collection' anchor='manual-upload'>
<p>The collection of messages and notes to be uploaded are encapsulated in the &lt;store/&gt; element.</p>
<example caption='Storing messages in a collection'><![CDATA[
<iq type='set' to='montague.net' id='up1'>
<iq type='set' id='up1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -329,7 +333,7 @@
]]></example>
<p>If the server cannot service a store request because the collection is too large then it MUST return a &notacceptable; error:</p>
<example caption='Unsuccessful reply'><![CDATA[
<iq type='error' to='romeo@montague.net/orchard'>
<iq type='error' to='romeo@montague.net/orchard' id='up1'>
<error code='406' type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -339,7 +343,7 @@
<section2 topic='Offline Messages' anchor='impl-muc'>
<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' to='montague.net' id='up2'>
<iq type='set' id='up2'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -354,7 +358,7 @@
<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>
<example caption='Storing groupchat messages in a collection'><![CDATA[
<iq type='set' to='montague.net' id='up3'>
<iq type='set' id='up3'>
<store xmlns='http://jabber.org/protocol/archive'
with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'>
@ -368,7 +372,7 @@
<section2 topic='Changing the Subject of a Collection' anchor='crypt'>
<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' to='montague.net' id='subject1'>
<iq type='set' id='subject1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -386,7 +390,7 @@
<p>When appending &lt;EncryptedData/&gt; elements to a collection, the client MAY reuse a symmetric KEY that has already been uploaded to the collection. In this case the client SHOULD NOT resend &lt;EncryptedKey/&gt; elements.</p>
<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' to='montague.net' id='crypt1'>
<iq type='set' id='crypt1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
@ -423,14 +427,31 @@
</section1>
<section1 topic='Automated Archiving' anchor='auto'>
<section2 topic='Toggling Auto-Archiving' anchor='auto-toggle'>
<p>A client MAY enable or disable automatic archiving for messages sent over its stream. Automatic archiving MUST default to disabled for each new stream that is opened, unless administrator policies <em>require</em> that every message is logged automatically (see <link url='#security'>Security Considerations</link>). Once automatic archiving is switched on then the server MUST automatically archive messages only according to the user's general <link url='#pref'>Archiving Preferences</link>.</p>
<p>Note: Both parties to an ESession (see &xep0116;) MUST either disable archiving or use an archiving method other than automatic, since ESession decryption keys are short-lived - making it impossible to decrypt automatically archived messages.</p>
<p>If server administration policies <em>require</em> that every message is logged automatically (see <link url='#security'>Security Considerations</link>) then:</p>
<ul>
<li>The server MUST enable automatic archiving when each stream is opened.</li>
<li>Clients MUST NOT be allowed to disable automatic archiving.</li>
<li>Automatic archiving MUST NOT be subject to users' <link url='#pref'>Archiving Preferences</link>.</li>
<li>If the server has not received a request from a client for its user's archiving preferences (see <link url='#pref-determine'>Determining Preferences</link>) within a few seconds of authenticating the client then the server MUST send a warning message to the client:</li>
</ul>
<example caption='Server warns user of a legacy client about compulsory archiving'><![CDATA[
<message to='juliet@capulet.com/chamber'>
<body>WARNING: All messages that you send or
receive will be recorded by the server.</body>
</message>
]]></example>
<p>Otherwise:</p>
<ul>
<li>Automatic archiving MUST default to disabled when each stream is opened.</li>
<li>A client MAY enable or disable automatic archiving for messages sent over its stream at any time. Note: If the client switches off all auto-archiving then the server MUST close and store all active collections.</li>
<li>Once automatic archiving is switched on then the server MUST automatically archive messages only according to the user's <link url='#pref'>Archiving Preferences</link>.</li>
<li>Note: Both parties to an ESession (see &xep0116;) SHOULD either disable archiving or use an archiving method other than automatic, since ESession decryption keys are short-lived - making it impossible to decrypt automatically archived messages.</li>
</ul>
<example caption='Client enables auto archiving'><![CDATA[
<iq type='set' id='auto1'>
<auto save='true' xmlns='http://jabber.org/protocol/archive'/>
</iq>
]]></example>
<p>If the client switches off all auto-archiving then the server MUST close and store all active collections.</p>
</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>
@ -480,7 +501,7 @@
<p>If the 'with' attribute is omitted then collections with any JID are returned. If only 'start' is specified then all collections on or after that date should be returned. If only 'end' is specified then all collections prior to that date should be returned.</p>
<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' to='montague.net' id='juliet1'>
<iq type='get' id='juliet1'>
<list xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -490,7 +511,7 @@
</iq>
]]></example>
<example caption='Requesting the first page of a list with same JID between two times'><![CDATA[
<iq type='get' to='montague.net' id='period1'>
<iq type='get' id='period1'>
<list xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
@ -502,7 +523,7 @@
</iq>
]]></example>
<example caption='Requesting the first page of a list after a time'><![CDATA[
<iq type='get' to='montague.net' id='list1'>
<iq type='get' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -513,7 +534,7 @@
]]></example>
<p>The server MUST list the collections (empty &lt;store/&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;store/&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' from='montague.net' id='list1'>
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'>
<store with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -535,12 +556,12 @@
<p>Note: In accordance with <cite>Result Set Management</cite>, the client MUST assume the unique IDs it receives in the &lt;first/&gt; and &lt;last/&gt; elements are opaque. Servers MAY adopt a unique ID format other than the one suggested in the example above.</p>
<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' from='montague.net' id='list1'>
<iq type='result' to='romeo@montague.net/orchard' id='list1'>
<list xmlns='http://jabber.org/protocol/archive'/>
</iq>
]]></example>
<example caption='Requesting the second page of a list'><![CDATA[
<iq type='get' to='montague.net' id='list2'>
<iq type='get' id='list2'>
<list xmlns='http://jabber.org/protocol/archive'
start='1469-07-21T02:00:00Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -556,7 +577,7 @@
<p>To request a page of messages from a collection the client sends a &lt;retrieve/&gt; element. The 'with' and 'start' attributes specify the participating full JID and the start time (see <cite>Jabber Date and Time Profiles</cite>). Both attributes MUST be included to uniquely identify a collection:</p>
<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' to='montague.net' id='page1'>
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
@ -567,7 +588,7 @@
</iq>
]]></example>
<example caption='Receiving the first page of a collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' from='montague.net' id='page1'>
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -589,7 +610,14 @@
<p>Note: In accordance with <cite>Result Set Management</cite>, the client MUST assume the unique IDs it receives in the &lt;first/&gt; and &lt;last/&gt; elements are opaque. Servers MAY adopt a unique ID format other than the one suggested in the example above.</p>
<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' from='montague.net' id='page1'>
<iq type='error' to='romeo@montague.net/orchard' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>100</max>
</set>
</retrieve>
<error code='404' type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -597,7 +625,7 @@
]]></example>
<p>If the requested collection is empty the server MUST return an empty &lt;store/&gt; element:</p>
<example caption='Receiving an empty collection'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' from='montague.net' id='page1'>
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
@ -605,7 +633,7 @@
</iq>
]]></example>
<example caption='Requesting the second page of a collection'><![CDATA[
<iq type='get' to='montague.net' id='page2'>
<iq type='get' id='page2'>
<retrieve xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'>
@ -618,7 +646,7 @@
]]></example>
<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' to='montague.net' id='page1'>
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
@ -630,7 +658,7 @@
]]></example>
<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' from='montague.net' id='page1'>
<iq type='result' to='romeo@montague.net/orchard' id='page1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'
@ -696,7 +724,7 @@
]]></example>
<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' to='montague.net' id='page1'>
<iq type='get' id='page1'>
<retrieve xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
@ -713,7 +741,7 @@
<section2 topic='Removing a Collection' anchor='manage-remove'>
<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' to='montague.net'>
<iq type='set' id='remove1'>
<remove xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
@ -721,7 +749,7 @@
]]></example>
<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' to='montague.net'>
<iq type='set' id='remove2'>
<remove xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com'
start='1469-07-21T02:00:00Z'
@ -731,7 +759,7 @@
<p>If the 'with' attribute is omitted then collections with any JID are removed.</p>
<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' to='montague.net'>
<iq type='set' id='remove3'>
<remove xmlns='http://jabber.org/protocol/archive'
start='1469-07-21T02:00:00Z'
end='2038-01-01T00:00:00Z'/>
@ -739,34 +767,37 @@
]]></example>
<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' to='montague.net'>
<iq type='set' id='remove4'>
<remove xmlns='http://jabber.org/protocol/archive'
start='0000-01-01T00:00:00Z'
end='1469-07-21T04:00:00Z'/>
</iq>
]]></example>
<example caption='Removing all collections'><![CDATA[
<iq type='set' to='montague.net'>
<iq type='set' id='remove5'>
<remove xmlns='http://jabber.org/protocol/archive'/>
</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' to='montague.net'>
<iq type='set' id='remove6'>
<remove xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
open='true'/>
</iq>
]]></example>
<example caption='Removing all collections being recorded by the server'><![CDATA[
<iq type='set' to='montague.net'>
<iq type='set' id='remove7'>
<remove xmlns='http://jabber.org/protocol/archive'
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'>
<iq type='error' to='romeo@montague.net/orchard' id='remove1'>
<remove xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
<error code='404' type='cancel'>
<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
@ -778,7 +809,7 @@
<p>If a private key becomes obsolete or compromised then it may be necessary for a client to replace all &lt;EncryptedKey/&gt; elements that contain symmetric keys encrypted with the public key that is associated with the obsolete private key.</p>
<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' to='montague.net' id='pubkey1'>
<iq type='get' id='pubkey1'>
<keys xmlns='http://jabber.org/protocol/archive'>
<KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
<set xmlns='http://jabber.org/protocol/rsm'>
@ -789,7 +820,7 @@
]]></example>
<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' from='montague.net' id='pubkey1'>
<iq type='result' to='romeo@montague.net/orchard' id='pubkey1'>
<keys xmlns='http://jabber.org/protocol/archive'>
<store with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
@ -823,7 +854,7 @@
]]></example>
<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 store 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' to='montague.net' id='crypt1'>
<iq type='set' id='crypt1'>
<store xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
@ -850,8 +881,8 @@
.
]]></example>
<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='Requesting the first page of a list of keys'><![CDATA[
<iq type='get' to='montague.net' id='pubkey1'>
<example caption='Deleting key(s) from a collection'><![CDATA[
<iq type='get' id='delete1'>
<delete xmlns='http://jabber.org/protocol/archive'
with='juliet@capulet.com/chamber'
start='1469-07-23T19:22:31Z'>
@ -869,7 +900,7 @@
<p>The client MUST request each page of the list using the <cite>Result Set Management</cite> protocol embeded in a &lt;modified/&gt; element. The content of the &lt;after/&gt; element SHOULD be a UTC time (see <cite>Jabber Date and Time Profiles</cite>) that it has previously received from the server (see below). When synchronizing for the first time, the client MAY choose a suitable time for the first page request (e.g. 1970-01-01T00:00:00Z).</p>
<example caption='Requesting a page of modifications'>
<![CDATA[
<iq type='get' to='montague.net' id='sync1'>
<iq type='get' id='sync1'>
<modified xmlns='http://jabber.org/protocol/archive'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
@ -880,7 +911,7 @@
]]></example>
<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' from='montague.net' id='sync1'>
<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
<modified xmlns='http://jabber.org/protocol/archive'>
<changed with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'/>
@ -997,7 +1028,7 @@
<xs:element name='auto'>
<xs:complexType>
<xs:sequence>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='encrypt' type='xs:boolean' use='optional'/>
<xs:attribute name='save' type='xs:boolean' use='required'/>
@ -1048,7 +1079,7 @@
<xs:element name='delete'>
<xs:complexType>
<xs:sequence>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='start' type='xs:dateTime' use='required'/>
<xs:attribute name='with' type='xs:string' use='required'/>
@ -1089,7 +1120,7 @@
<xs:complexType>
<xs:sequence>
<xs:element ref='store' minOccurs='0' maxOccurs='unbounded'/>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
@ -1098,7 +1129,7 @@
<xs:complexType>
<xs:sequence>
<xs:element ref='store' minOccurs='0' maxOccurs='unbounded'/>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='end' type='xs:dateTime' use='optional'/>
<xs:attribute name='start' type='xs:dateTime' use='optional'/>
@ -1130,7 +1161,7 @@
<xs:sequence>
<xs:element ref='changed' minOccurs='0' maxOccurs='unbounded'/>
<xs:element ref='removed' minOccurs='0' maxOccurs='unbounded'/>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
</xs:complexType>
</xs:element>
@ -1183,7 +1214,7 @@
<xs:element name='retrieve'>
<xs:complexType>
<xs:sequence>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='start' type='xs:dateTime' use='required'/>
<xs:attribute name='with' type='xs:string' use='required'/>
@ -1196,7 +1227,7 @@
<xs:element name='from' type='messageType'/>
<xs:element ref='note'/>
<xs:element name='to' type='messageType'/>
<any processContents='lax' namespace='##other'/>
<xs:any processContents='lax' namespace='##other'/>
</xs:choice>
<xs:attribute name='crypt' use='optional' type='xs:boolean'/>
<xs:attribute name='start' type='xs:dateTime' use='required'/>
@ -1208,7 +1239,7 @@
<xs:complexType name='messageType'>
<xs:sequence>
<xs:element name='body' type='xs:string' minOccurs='0' maxOccurs='1'/>
<any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
<xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
</xs:sequence>
<xs:attribute name='secs' type='xs:nonNegativeInteger' use='optional'/>
<xs:attribute name='utc' type='xs:dateTime' use='optional'/>