mirror of https://github.com/moparisthebest/xeps
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
466 lines
16 KiB
466 lines
16 KiB
<?xml version='1.0' encoding='UTF-8'?> |
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [ |
|
<!ENTITY % ents SYSTEM 'xep.ent'> |
|
<!ENTITY MOVED "<moved/>"> |
|
%ents; |
|
]> |
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?> |
|
<xep> |
|
<header> |
|
<title>Moved</title> |
|
<abstract>This document defines an XMPP protocol extension that enables a user to inform its contacts about a change in JID.</abstract> |
|
&LEGALNOTICE; |
|
<number>0283</number> |
|
<status>Deferred</status> |
|
<type>Standards Track</type> |
|
<sig>Standards</sig> |
|
<approver>Council</approver> |
|
<dependencies> |
|
<spec>XMPP Core</spec> |
|
</dependencies> |
|
<supersedes> |
|
</supersedes> |
|
<supersededby/> |
|
<shortname>moved</shortname> |
|
<author> |
|
<firstname>Tory</firstname> |
|
<surname>Patnoe</surname> |
|
<email>tpatnoe@cisco.com</email> |
|
<jid>tpatnoe@cisco.com</jid> |
|
</author> |
|
<revision> |
|
<version>0.1</version> |
|
<date>2010-06-16</date> |
|
<initials>psa</initials> |
|
<remark><p>Initial published version.</p></remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.7</version> |
|
<date>2010-06-09</date> |
|
<initials>tp</initials> |
|
<remark> |
|
<p>Modified syntax to use 'old' and 'new' attributes.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.6</version> |
|
<date>2010-06-07</date> |
|
<initials>tp</initials> |
|
<remark> |
|
<ul> |
|
<li>Update ordering so that it recommends sending the unsubscribe/unsubscribed, before, sending the subscribe</li> |
|
<li>Add section documenting what happens when a contact is offline when the unsubscribe/unsubscribed/subscribe stanzas are sent.</li> |
|
<li>Added an example about a hacker sending an unsolicited subscribe by guessing a roster entry.</li> |
|
</ul> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.5</version> |
|
<date>2010-06-02</date> |
|
<initials>tp</initials> |
|
<remark> |
|
<p>Added one-way subscription section</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.4</version> |
|
<date>2010-05-30</date> |
|
<initials>tp</initials> |
|
<remark> |
|
<p>Change MUST NOT to SHOULD NOT for clients auto-subscribing back; differentiate between inbound and outbound subscriptions.</p> |
|
</remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.3</version> |
|
<date>2010-06-02</date> |
|
<initials>tp</initials> |
|
<remark><p>Add one-way subscription comments.</p></remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.2</version> |
|
<date>2010-05-25</date> |
|
<initials>tp</initials> |
|
<remark><p>Minor tweaks.</p></remark> |
|
</revision> |
|
<revision> |
|
<version>0.0.1</version> |
|
<date>2010-05-22</date> |
|
<initials>tp</initials> |
|
<remark><p>First draft.</p></remark> |
|
</revision> |
|
</header> |
|
<section1 topic='Introduction' anchor='intro'> |
|
<p>There are a variety of reasons why a user may wish to change |
|
their JID. For example, a surname change because of marriage or simply |
|
an easier JID to remember. |
|
</p> |
|
|
|
<p>This XEP defines an approach for communicating that your JID has |
|
moved to a new JID, extending the existing subscription protocol documented |
|
in &xmppim;. The steps outlined here may be done either through a client |
|
or automated by a server. |
|
</p> |
|
</section1> |
|
|
|
<section1 topic='Requirements' anchor='reqs'> |
|
<ul> |
|
<li>The methods described here maintain compatibility with &xmppcore; and <cite>RFC 6121</cite>.</li> |
|
</ul> |
|
</section1> |
|
|
|
<section1 topic='The Move'> |
|
<p>In this scenario user@example.com moves to user2@example2.com. |
|
Both the user@example.com and user2@example2.com accounts have been |
|
created and still exist. The roster for user@example2.com is empty |
|
and the user wants to populate it with their entries from |
|
user@example.com.</p> |
|
|
|
<dl> |
|
<di> |
|
<dt>original JID</dt> |
|
<dd>user@example.com</dd> |
|
</di> |
|
<di> |
|
<dt>new JID</dt> |
|
<dd>user2@example2.com</dd> |
|
</di> |
|
</dl> |
|
|
|
<section2 topic='Unsubscribing the original JID from outbound subscriptions' |
|
anchor='unsubscribe'> |
|
<p>Because the original JID is no longer going to be used, the user SHOULD |
|
unsubscribe from all the outbound subscriptions user@example.com had. |
|
These can be identified as those in the 'to' or 'ask' states as |
|
defined in the 'jabber:iq:roster' protocol in <cite>RFC 6121</cite>.</p> |
|
|
|
<p>To unsubscribe all outbound subscriptions for the original JID send an |
|
unsubscribe &PRESENCE; stanza to all the old contacts with a &MOVED; |
|
element containing the new JID.</p> |
|
|
|
<p>There is the potential for other users to send a malicious unsubscribe |
|
containing a spoofed &MOVED; JID. Therefore, clients SHOULD NOT |
|
automatically subscribe to the JID contained in the &MOVED; stanza when |
|
receiving a subscribe &PRESENCE; stanza without displaying the &MOVED; |
|
JID to the user. See the Security Considerations section for |
|
details.</p> |
|
|
|
<example caption='Client unsubscribes outbound subscriptions from original JID'><![CDATA[ |
|
<presence from='user@example.com' to='contact@example.com' type='unsubscribe'> |
|
<status>I've changed JIDs from user@example.com to user2@example2.com</status> |
|
<moved xmlns='urn:xmpp:moved:0' new='user2@example2.com'/> |
|
</presence> |
|
]]></example> |
|
|
|
</section2> |
|
|
|
<section2 topic='Unsubscribing the original JID from inbound subscriptions' |
|
anchor='unsubscribed'> |
|
<p>Because the original JID is no longer going to be used, the user SHOULD |
|
unsubscribe from all contacts the user@example.com had an inbound |
|
subscription from. These can be identified as those in the 'from' |
|
subscription state as defined in in the 'jabber:iq:roster' protocol |
|
in <cite>RFC 6121</cite>.</p> |
|
|
|
<p>To unsubscribe all inbound subscriptions send an unsubscribed |
|
&PRESENCE; stanza to all the old contacts with a &MOVED; element |
|
containing the new JID.</p> |
|
|
|
<p>There is the potential for other users to send a malicious unsubscribed |
|
containing a spoofed &MOVED; JID. Therefore, clients SHOULD NOT |
|
automatically subscribe to the JID contained in the &MOVED; stanza |
|
without displaying the &MOVED; JID to the user. See the Security |
|
Considerations section for details.</p> |
|
|
|
<example caption='Client unsubscribes inbound subscriptions from original JID'> |
|
<![CDATA[ |
|
<presence from='user@example.com' to='contact@example.com' type='unsubscribed'> |
|
<status>I've changed JIDs from user@example.com to user2@example2.com</status> |
|
<moved xmlns='urn:xmpp:moved:0' new='user2@example2.com'/> |
|
</presence> |
|
]]> |
|
</example> |
|
|
|
</section2> |
|
<section2 topic='Subscribing the new JID to all your existing contacts' |
|
anchor='subscribe'> |
|
|
|
<p>Once the new JID has been created on a server it is possible for the |
|
new JID to subscribe to the contacts they had on the original JID's |
|
roster. This is done by sending a new subscription request with a |
|
&MOVED; element containing the new JID. |
|
</p> |
|
|
|
<p>The new subscription MUST come from the new JID's server.</p> |
|
|
|
<p>There is the potential for other users to send a malicious subscribe |
|
request and spoof the content of the &MOVED; element identifying an |
|
original JID. Therefore, clients SHOULD NOT automatically unsubscribe |
|
an existing roster entry if is listed as the target in the &MOVED; |
|
element when a subscribe is received. See the Security |
|
Consideration section for details.</p> |
|
|
|
<p>Clients accepting the moved subscription SHOULD indicate to the |
|
user that that this subscription request was the result of a move |
|
operation and because of potential malicious behavior SHOULD NOT |
|
auto-accept the subscription without displaying the &MOVED; JID to the |
|
user.</p> |
|
|
|
<example caption='Client requests subscription from new JID'> |
|
<![CDATA[ |
|
<presence from='user2@example2.com' to='contact@example.com' type='subscribe'> |
|
<status>I've changed JIDs from user@example.com to user2@example2.com</status> |
|
<moved xmlns='urn:xmpp:moved:0' old='user@example.com'/> |
|
</presence> |
|
]]> |
|
</example> |
|
|
|
</section2> |
|
|
|
<section2 topic='Contacts Offline at the Time the Rename Occurs' |
|
anchor='offline'> |
|
<p><cite>RFC 6120</cite> clarifies that an incoming subscribe &PRESENCE; stanza |
|
MUST be preserved by the server and &PRESENCE; stanzas of type |
|
unsubscribe and unsubscribed are not preserved on the server. |
|
Therefore, for a contact who is offline, their servers MAY have |
|
automatically removed the original roster entry when seeing the |
|
unsubscribe and unsubscribed stanzas. At the time of writing this XEP, |
|
NOT saving and forwarding the presence stanzas will be the default |
|
behavior of most servers. |
|
</p> |
|
|
|
<p>What this means is that a contact coming online after the rename |
|
outlined above MAY only see the &PRESENCE; of type 'subscribe' with |
|
the &MOVED; element. Clients should be aware of this behavior. |
|
</p> |
|
</section2> |
|
|
|
<section2 topic='Presence Ordering' anchor='ordering'> |
|
<p>In following the principle of least surprise, it is considered good |
|
practice to send the subscribe stanza after the unsubscribe and unsubscribed |
|
stanzas. |
|
</p> |
|
</section2> |
|
|
|
<section2 topic='Preservation of Groups' anchor='grouping'> |
|
<p>One of the side effects of this scheme is the potential for a contact |
|
to lose the groups to which it had organized the original JID. Clients |
|
aware of the &MOVED; element can mitigate this with the following rules. |
|
</p> |
|
|
|
<ul> |
|
<li>If the contacts client receives an unsubscribed with a &MOVED; |
|
element, remove the subscription but initiate a roster push for the |
|
original JID with the subscription set to 'none'. When the new |
|
subscription is received the new JID MAY be placed into the roster |
|
in the same groups as the original JID and the original JID can then be |
|
removed from the roster. |
|
</li> |
|
|
|
<li>If a subscribe is received with a &MOVED; element, the client MAY |
|
automatically place the new JID into the same groups as the original JID. |
|
</li> |
|
</ul> |
|
|
|
<p>As discussed in 'Contacts Offline at the Time the Rename Occurs', a |
|
server MAY automatically handle the unsubscribe and unsubscribed stanzas. |
|
If this occurs it will be impossible to preserve the original groups. |
|
</p> |
|
|
|
</section2> |
|
|
|
<section2 topic='One-way subcriptions and full roster state' anchor='one-way'> |
|
<section3 topic='One-way Inbound subscription' anchor='from_subs'> |
|
<p>If the original JID, user@example.com, had only an inbound subscription |
|
(from or pending in), then the contact will only receive an |
|
unsubscribed &PRESENCE; stanza. The contact's client, knowing the |
|
state of the subscription (which is 'to' or 'none' with 'ask='subscribe' |
|
from the contact's perspective), at that point MAY choose to prompt the |
|
user to subscribe to the new JID listed in the &MOVED; element.</p> |
|
|
|
<p>Because of the ability to spoof the &MOVED; element, the client SHOULD |
|
NOT automatically subscribe to the &MOVED; element target, but SHOULD |
|
present the new JID to the contact before sending out a subscription |
|
request.</p> |
|
</section3> |
|
|
|
<section3 topic='One-way Outbound subscription' anchor='to_subs'> |
|
<p>If the original JID, user@example.com, had only an outbound |
|
subscription (to or ask), then the contact SHOULD only receive an |
|
unsubscribe &PRESENCE; stanza. The contact's client, knowing the |
|
state of the subscription (which is 'from' from the contact's perspective), |
|
at that point MAY choose to prompt |
|
the user to subscribe to the new JID listed in the &MOVED; element.</p> |
|
|
|
<p>Because of the ability to spoof the &MOVED; element, the client SHOULD |
|
NOT automatically subscribe to the &MOVED; element target.</p> |
|
</section3> |
|
|
|
<section3 topic='Roster state and action table' anchor='actions'> |
|
<table caption="Roster states and actios from the renamed user's perspective"> |
|
<tr> |
|
<td>Server state</td> |
|
<td>Client state (jabber:iq:roster)</td> |
|
<td>Send unsubscribe from original JID</td> |
|
<td>Send unsubscribed from original JID</td> |
|
<td>Send subscribe from new JID</td> |
|
</tr> |
|
<tr> |
|
<td>none</td> |
|
<td>none</td> |
|
<td></td> |
|
<td></td> |
|
<td></td> |
|
</tr> |
|
<tr> |
|
<td>none + pending out</td> |
|
<td>none + ask='subscribe'</td> |
|
<td>yes</td> |
|
<td></td> |
|
<td>yes</td> |
|
</tr> |
|
<tr> |
|
<td>none + pending in</td> |
|
<td>n/a</td> |
|
<td></td> |
|
<td>yes - server only</td> |
|
<td></td> |
|
</tr> |
|
<tr> |
|
<td>none + pending in/out</td> |
|
<td>none + ask='subscribe'</td> |
|
<td>yes</td> |
|
<td>yes - server only</td> |
|
<td>yes</td> |
|
</tr> |
|
<tr> |
|
<td>to</td> |
|
<td>to</td> |
|
<td>yes</td> |
|
<td></td> |
|
<td>yes</td> |
|
</tr> |
|
<tr> |
|
<td>to + pending in</td> |
|
<td>to</td> |
|
<td>yes</td> |
|
<td>yes - server only</td> |
|
<td>yes</td> |
|
</tr> |
|
<tr> |
|
<td>from</td> |
|
<td>from</td> |
|
<td></td> |
|
<td>yes</td> |
|
<td></td> |
|
</tr> |
|
<tr> |
|
<td>from + pending out</td> |
|
<td>from/none + ask='subscribe'</td> |
|
<td>yes</td> |
|
<td>yes</td> |
|
<td>yes</td> |
|
</tr> |
|
<tr> |
|
<td>both</td> |
|
<td>both</td> |
|
<td>yes</td> |
|
<td>yes</td> |
|
<td>yes</td> |
|
</tr> |
|
</table> |
|
</section3> |
|
</section2> |
|
</section1> |
|
|
|
<section1 topic='Security Considerations' anchor='security'> |
|
<p>It is not intended for servers to strip any &MOVED; elements from |
|
&PRESENCE; stanzas sent in from a client. This allows clients as well as |
|
servers to implement these same procedures.</p> |
|
|
|
<p>In order to prevent other users from maliciously altering contacts |
|
the client SHOULD NOT automatically subscribe to a &MOVED; JID when it |
|
receives an unsubscribe and SHOULD NOT automatically unsubscribe to |
|
a &MOVED; JID when it receives a subscribe.</p> |
|
|
|
<p>The following illustrates an example malicious attack.</p> |
|
|
|
<ol> |
|
<li>userA@example.com subscribes to userB@example.com</li> |
|
<li>The userB@example.com automatically accepts the subscription from |
|
userA@example.com. (Automatically done by the client using a simple |
|
domain trust).</li> |
|
<li>userA@example.com unsubscribes with the &MOVED; 'new' JID set to |
|
companyCEO@example.com.</li> |
|
<li>The previous steps can be repeated and have userB@example.com subscribe |
|
to a large number of people.</li> |
|
</ol> |
|
|
|
<p>A similar attack can be done with a new subscribe request causing users |
|
by guessing which users are subscribed to a contact.</p> |
|
|
|
<ol> |
|
<li>hacker@example.com subscribes to userB@example.com guessing that |
|
userA@example.com is on userB's roster. |
|
<![CDATA[ |
|
<presence from='hacker@example.com' to='userB@example.com' type='subscribe'> |
|
<status>Subscribe to me!</status> |
|
<moved xmlns='urn:xmpp:moved:0' old='userA@example.com'/> |
|
</presence> |
|
]]> |
|
</li> |
|
<li>If userB's client automatically accepted the subscription without |
|
displaying at prompt to userB showing the new JID to be hacker@example.com, |
|
then the user has no idea that hacker@example.com was just added to |
|
the roster. |
|
</li> |
|
</ol> |
|
|
|
</section1> |
|
|
|
<section1 topic='IANA Considerations' anchor='iana'> |
|
<p>This document requires no interaction with &IANA;.</p> |
|
</section1> |
|
<section1 topic='XMPP Registrar Considerations' anchor='reg'> |
|
<section2 topic='Protocol Namespaces' anchor='registrar-ns'> |
|
<p>This specification defines the following XML namespace:</p> |
|
<ul> |
|
<li>urn:xmpp:moved:0</li> |
|
</ul> |
|
<p>Upon advancement of this specification from a status of Experimental |
|
to a status of Draft, the ®ISTRAR; shall add the foregoing namespace |
|
to the registry located at &NAMESPACES;, as described in Section 4 of |
|
&xep0053;. |
|
</p> |
|
</section2> |
|
<section2 topic='Protocol Versioning' anchor='registrar-versioning'> |
|
&NSVER; |
|
</section2> |
|
</section1> |
|
<section1 topic='XML Schema' anchor='schema'> |
|
<code><![CDATA[ |
|
<?xml version='1.0' encoding='UTF-8'?> |
|
|
|
<xs:schema |
|
xmlns:xs='http://www.w3.org/2001/XMLSchema' |
|
targetNamespace='urn:xmpp:moved:0' |
|
xmlns='urn:xmpp:moved:0' |
|
elementFormDefault='qualified'> |
|
|
|
<xs:element name='moved'> |
|
<xs:complexType> |
|
<xs:simpleContent> |
|
<xs:extension base='xs:string'> |
|
<xs:attribute name='new' type='xs:string' use='optional'/> |
|
<xs:attribute name='old' type='xs:string' use='optional'/> |
|
</xs:extension> |
|
</xs:simpleContent> |
|
</xs:complexType> |
|
</xs:element> |
|
|
|
</xs:schema> |
|
]]></code> |
|
</section1> |
|
<section1 topic='Acknowledgements' anchor='ack'> |
|
<p>The author wishes to thank Doug Abbink, Mikhail Belov, Peter Saint-Andre, and Peter Sheu for their feedback.</p> |
|
</section1> |
|
</xep>
|
|
|