-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathrfc6121.xml
3996 lines (3800 loc) · 270 KB
/
rfc6121.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc symrefs="yes"?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc rfcedstyle="yes"?>
<rfc number="6121" category="std" ipr="trust200902" obsoletes="3921" submissionType="IETF">
<front>
<title abbrev="XMPP IM">Extensible Messaging and Presence Protocol
(XMPP): Instant Messaging and Presence</title>
<author initials="P." surname="Saint-Andre" fullname="Peter Saint-Andre">
<organization>Cisco</organization>
<address>
<postal>
<street>1899 Wyknoop Street, Suite 600</street>
<city>Denver</city>
<region>CO</region>
<code>80202</code>
<country>USA</country>
</postal>
<phone>+1-303-308-3282</phone>
<email>psaintan@cisco.com</email>
</address>
</author>
<date year="2011" month="March"/>
<area>RAI</area>
<workgroup>XMPP</workgroup>
<keyword>XMPP</keyword>
<keyword>Extensible Messaging and Presence Protocol</keyword>
<keyword>Jabber</keyword>
<keyword>IM</keyword>
<keyword>Instant Messaging</keyword>
<keyword>Presence</keyword>
<keyword>XML</keyword>
<keyword>Extensible Markup Language</keyword>
<abstract>
<t>This document defines extensions to core features of the Extensible Messaging and Presence Protocol (XMPP) that provide basic instant messaging (IM) and presence functionality in conformance with the requirements in RFC 2779. This document obsoletes RFC 3921.</t>
</abstract>
</front>
<middle>
<section title="Introduction" anchor="intro">
<section title="Overview" anchor="intro-overview">
<t>The Extensible Messaging and Presence Protocol (XMPP) is an application profile of the Extensible Markup Language <xref target="XML"/> that enables the near-real-time exchange of structured yet extensible data between any two or more network entities. The core features of XMPP defined in <xref target="XMPP-CORE"/> provide the building blocks for many types of near-real-time applications, which can be layered on top of the core by sending application-specific data qualified by particular XML namespaces (refer to <xref target="XML-NAMES"/>). This document defines XMPP extensions that provide the basic functionality expected of an instant messaging (IM) and presence application as described in <xref target="IMP-REQS"/>.</t>
</section>
<section title="History" anchor="intro-history">
<t>The basic syntax and semantics of XMPP were developed originally within the Jabber open-source community, mainly in 1999. In late 2002, the XMPP Working Group was chartered with developing an adaptation of the core Jabber protocol that would be suitable as an IETF IM and presence technology in accordance with <xref target='IMP-REQS'/>. In October 2004, <xref target='RFC3920'/> and <xref target='RFC3921'/> were published, representing the most complete definition of XMPP at that time.</t>
<t>Since 2004 the Internet community has gained extensive implementation and deployment experience with XMPP, including formal interoperability testing carried out under the auspices of the XMPP Standards Foundation (XSF). This document incorporates comprehensive feedback from software developers and service providers, including a number of backward-compatible modifications summarized under <xref target='diffs'/>. As a result, this document reflects the rough consensus of the Internet community regarding the IM and presence features of XMPP 1.0, thus obsoleting RFC 3921.</t>
</section>
<section title="Requirements" anchor="intro-requirements">
<t>Traditionally, IM applications have combined the following factors:</t>
<t>
<list style='numbers'>
<t>The central point of focus is a list of one's contacts or "buddies" (in XMPP this list is called a "roster").</t>
<t>The purpose of using such an application is to exchange relatively brief text messages with particular contacts in close to real time -- often relatively large numbers of such messages in rapid succession, in the form of a one-to-one "chat session" as described under <xref target='message-chat'/>.</t>
<t>The catalyst for exchanging messages is "presence" -- i.e., information about the network availability of particular contacts (thus knowing who is online and available for a one-to-one chat session).</t>
<t>Presence information is provided only to contacts that one has authorized by means of an explicit agreement called a "presence subscription".</t>
</list>
</t>
<t>Thus at a high level this document assumes that a user needs to be able to complete the following use cases:</t>
<t>
<list style='symbols'>
<t>Manage items in one's contact list</t>
<t>Exchange messages with one's contacts</t>
<t>Exchange presence information with one's contacts</t>
<t>Manage presence subscriptions to and from one's contacts</t>
</list>
</t>
<t>Detailed definitions of these functionality areas are contained in RFC 2779 <xref target="IMP-REQS"/>, and the interested reader is referred to that document regarding in-depth requirements. Although the XMPP IM and presence extensions specified herein meet the requirements of RFC 2779, they were not designed explicitly with that specification in mind, since the base protocol evolved through an open development process within the Jabber open-source community before RFC 2779 was written. Although XMPP protocol extensions addressing many other functionality areas have been defined in the XMPP Standards Foundation's XEP series (e.g., multi-user text chat as specified in <xref target='XEP-0045'/>), such extensions are not specified in this document because they are not mandated by RFC 2779.</t>
<t><list style='empty'><t>Implementation Note: RFC 2779 stipulates that presence services must be separable from IM services and vice-versa; i.e., it must be possible to use the protocol to provide a presence service, a messaging service, or both. Although the text of this document assumes that implementations and deployments will want to offer a unified IM and presence service, it is not mandatory for an XMPP service to offer both a presence service and a messaging service, and the protocol makes it possible to offer separate and distinct services for presence and for messaging. (For example, a presence-only service could return a <service-unavailable/> stanza error if a client attempts to send a <message/> stanza.)</t></list></t>
</section>
<section title="Functional Summary" anchor="intro-summary">
<t>This non-normative section provides a developer-friendly, functional summary of XMPP-based IM and presence features; consult the sections that follow for a normative definition of these features.</t>
<t><xref target="XMPP-CORE"/> specifies how an XMPP client connects to an XMPP server. In particular, it specifies the preconditions that need to be fulfilled before a client is allowed to send XML stanzas (the basic unit of meaning in XMPP) to other entities on an XMPP network. These preconditions comprise negotiation of the XML stream and include exchange of XML stream headers, optional channel encryption via Transport Layer Security <xref target='TLS'/>, mandatory authentication via Simple Authentication and Security Layer <xref target='SASL'/>, and binding of a resource to the stream for client addressing. The reader is referred to <xref target="XMPP-CORE"/> for details regarding these preconditions, and knowledge of <xref target="XMPP-CORE"/> is assumed herein.</t>
<t><list style='empty'><t>Interoperability Note: <xref target='RFC3921'/> specified one additional precondition: formal establishment of an instant messaging and presence session. Implementation and deployment experience has shown that this additional step is unnecessary. However, for backward compatibility an implementation MAY still offer that feature. This enables older software to connect while letting newer software save a round trip.</t></list></t>
<t>Upon fulfillment of the preconditions specified in <xref target="XMPP-CORE"/>, an XMPP client has a long-lived XML stream with an XMPP server, which enables the user controlling that client to send and receive a potentially unlimited number of XML stanzas over the stream. Such a stream can be used to exchange messages, share presence information, and engage in structured request-response interactions in close to real time. After negotiation of the XML stream, the typical flow for an instant messaging and presence session is as follows:</t>
<t>
<list style='numbers'>
<t>Retrieve one's roster. (See <xref target='roster-login'/>.)</t>
<t>Send initial presence to the server for broadcast to all subscribed contacts, thus "going online" from the perspective of XMPP communication. (See <xref target='presence-initial'/>.)</t>
<t>Exchange messages, manage presence subscriptions, perform roster
updates, and in general process and generate other XML stanzas with particular
semantics throughout the life of the session. (See Sections <xref
target='message' format='counter'/>, <xref target='sub' format='counter'/>,
<xref target='roster' format='counter'/>, and <xref target='iq' format='counter'/>.)</t>
<t>Terminate the session when desired by sending unavailable presence and closing the underlying XML stream. (See <xref target='presence-unavailable'/>.)</t>
</list>
</t>
</section>
<section title="Terminology" anchor="intro-terms">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 <xref target='KEYWORDS'/>.</t>
<t>This document inherits the terminology defined in <xref target="XMPP-CORE"/>.</t>
<t>The terms "automated client" and "interactive client" are to be understood in the sense defined in <xref target="TLS-CERTS"/>.</t>
<t>For convenience, this document employs the term "user" to refer to the owner of an XMPP account; however, account owners need not be humans and can be bots, devices, or other automated applications.</t>
<t>Several other terms, such as "interested resource", are defined within the body of this document.</t>
<t>Following the "XML Notation" used in <xref target="IRI"/> to represent characters that cannot be rendered in ASCII-only documents, some examples in this document use the form "&#x...." as a notational device to represent <xref target='UNICODE'/> characters (e.g., the string "&#x0159;" stands for the Unicode character LATIN SMALL LETTER R WITH CARON); this form is definitely not to be sent over the wire in XMPP systems.</t>
<t>In examples, lines have been wrapped for improved readability, "[...]" means elision, and the following prepended strings are used (these prepended strings are not to be sent over the wire):</t>
<t>
<list style='symbols'>
<t>C: = client</t>
<t>CC: = contact's client</t>
<t>CS: = contact's server</t>
<t>S: = server</t>
<t>UC: = user's client</t>
<t>US: = user's server</t>
</list>
</t>
<t>Readers need to be aware that the examples are not exhaustive
and that, in examples for some protocol flows, the alternate
steps shown would not necessarily be triggered by the exact data
sent in the previous step; in all cases, the protocol definitions specified in this document or in normatively referenced documents rule over any examples provided here. All examples are fictional and the information exchanged (e.g., usernames and passwords) does not represent any existing users or servers.</t>
</section>
</section>
<section title="Managing the Roster" anchor="roster">
<t>In XMPP, a user's roster contains any number of specific contacts. A user's roster is stored by the user's server on the user's behalf so that the user can access roster information from any device. When the user adds items to the roster or modifies existing items, if an error does not occur then the server SHOULD store that data unmodified if at all possible and MUST return the data it has stored when an authorized client requests the roster.</t>
<t><list style='empty'><t>Security Warning: Because the user's roster can contain confidential data, the server MUST restrict access to this data so that only authorized entities (typically limited to the account owner) are able to retrieve, modify, or delete it.</t></list></t>
<t>RFC 3921 assumed that the only place where a user stores their roster is the server where the user's account is registered and at which the user authenticates for access to the XMPP network. This specification removes that strict coupling of roster storage to account registration and network authentication, with the result that a user could store their roster at another location, or could have multiple rosters that are stored in multiple locations. However, in the absence of implementation and deployment experience with a more flexible roster storage model, this specification retains the terminology of RFC 3921 by using the terms "client" and "server" (and "the roster" instead of "a roster"), rather than coining a new term for "a place where a user stores a roster". Future documents might provide normative rules for non-server roster storage or for the management of multiple rosters, but such rules are out of scope for this document.</t>
<section title="Syntax and Semantics" anchor="roster-syntax">
<t>Rosters are managed using <iq/> stanzas (see Section 8.2.3 of
<xref target="XMPP-CORE"/>), specifically by means of a <query/> child element qualified by the 'jabber:iq:roster' namespace. The detailed syntax and semantics are defined in the following sections.</t>
<section title="Ver Attribute" anchor="roster-syntax-ver">
<t>The 'ver' attribute is a string that identifies a particular version of the roster information. The value MUST be generated only by the server and MUST be treated by the client as opaque. The server can use any appropriate method for generating the version ID, such as a hash of the roster data or a strictly increasing sequence number.</t>
<t>Inclusion of the 'ver' attribute is RECOMMENDED.</t>
<t>Use of the 'ver' attribute is described more fully under <xref target='roster-versioning'/>.</t>
<t><list style='empty'><t>Interoperability Note: The 'ver' attribute of the <query/> element was not defined in RFC 3921 and is newly defined in this specification.</t></list></t>
</section>
<section title="Roster Items" anchor="roster-syntax-items">
<t>The <query/> element inside a <xref target='roster-syntax-actions-set'>roster set</xref> contains one <item/> child, and a <xref target='roster-syntax-actions-result'>roster result</xref> typically contains multiple <item/> children. Each <item/> element describes a unique "roster item" (sometimes also called a "contact").</t>
<t>The syntax of the <item/> element is described in the following sections.</t>
<section title="Approved Attribute" anchor="roster-syntax-items-approved">
<t>The boolean 'approved' attribute with a value of "true" is used to signal subscription pre-approval as described under <xref target='sub-preapproval'/> (the default is "false", in accordance with <xref target='XML-DATATYPES'/>).</t>
<t>A server SHOULD include the 'approved' attribute to inform the client of subscription pre-approvals. A client MUST NOT include the 'approved' attribute in the roster sets it sends to the server, but instead MUST use presence stanzas of type "subscribed" and "unsubscribed" to manage pre-approvals as described under <xref target='sub-preapproval'/>.</t>
<t><list style='empty'><t>Interoperability Note: The 'approved' attribute of the <item/> element was not defined in RFC 3921 and is newly defined in this specification.</t></list></t>
</section>
<section title="Ask Attribute" anchor="roster-syntax-items-ask">
<t>The 'ask' attribute of the <item/> element with a value of "subscribe" is used to signal various subscription sub-states that include a "Pending Out" aspect as described under <xref target='sub-request-outbound'/>.</t>
<t>A server SHOULD include the 'ask' attribute to inform the client of "Pending Out" sub-states. A client MUST NOT include the 'ask' attribute in the roster sets it sends to the server, but instead MUST use presence stanzas of type "subscribe" and "unsubscribe" to manage such sub-states as described under <xref target='sub-request-outbound'/>.</t>
</section>
<section title="JID Attribute" anchor="roster-syntax-items-jid">
<t>The 'jid' attribute of the <item/> element specifies the Jabber Identifier (JID) that uniquely identifies the roster item.</t>
<t>The 'jid' attribute is REQUIRED whenever a client or server adds, updates, deletes, or returns a roster item.</t>
</section>
<section title="Name Attribute" anchor="roster-syntax-items-name">
<t>The 'name' attribute of the <item/> element specifies the "handle" to be associated with the JID, as determined by the user (not the contact). Although the value of the 'name' attribute MAY have meaning to a human user, it is opaque to the server. However, the 'name' attribute MAY be used by the server for matching purposes within the context of various XMPP extensions (one possible comparison method is that described for XMPP resourceparts in <xref target='XMPP-ADDR'/>).</t>
<t>It is OPTIONAL for a client to include the 'name' attribute when adding or updating a roster item.</t>
</section>
<section title="Subscription Attribute" anchor="roster-syntax-items-subscription">
<t>The state of the presence subscription is captured in the 'subscription' attribute of the <item/> element. The defined subscription-related values are:</t>
<t>
<list style='hanging'>
<t hangText="none:">the user does not have a subscription to the contact's presence, and the contact does not have a subscription to the user's presence; this is the default value, so if the subscription attribute is not included then the state is to be understood as "none"</t>
<t hangText="to:">the user has a subscription to the contact's presence, but the contact does not have a subscription to the user's presence</t>
<t hangText="from:">the contact has a subscription to the user's presence, but the user does not have a subscription to the contact's presence</t>
<t hangText="both:">the user and the contact have subscriptions to each other's presence (also called a "mutual subscription")</t>
</list>
</t>
<t>In a <xref target='roster-syntax-actions-result'>roster result</xref>, the client MUST ignore values of the 'subscription' attribute other than "none", "to", "from", or "both".</t>
<t>In a <xref target='roster-syntax-actions-push'>roster push</xref>, the client MUST ignore values of the 'subscription' attribute other than "none", "to", "from", "both", or "remove".</t>
<t>In a <xref target='roster-syntax-actions-set'>roster set</xref>, the 'subscription' attribute MAY be included with a value of "remove", which indicates that the item is to be removed from the roster; in a roster set the server MUST ignore all values of the 'subscription' attribute other than "remove".</t>
<t>Inclusion of the 'subscription' attribute is OPTIONAL.</t>
</section>
<section title="Group Element" anchor="roster-syntax-items-group">
<t>The <group/> child element specifies a category or "bucket" into which the roster item is to be grouped by a client. An <item/> element MAY contain more than one <group/> element, which means that roster groups are not exclusive. Although the XML character data of the <group/> element MAY have meaning to a human user, it is opaque to the server. However, the <group/> element MAY be used by the server for matching purposes within the context of various XMPP extensions (one possible comparison method is that described for XMPP resourceparts in <xref target='XMPP-ADDR'/>).</t>
<t>It is OPTIONAL for a client to include the <group/> element when adding or updating a roster item. If a <xref target='roster-syntax-actions-set'>roster set</xref> includes no <group/> element, then the item is to be interpreted as being affiliated with no group.</t>
</section>
</section>
<section title="Roster Get" anchor="roster-syntax-actions-get">
<t>A "roster get" is a client's request for the server to return the roster; syntactically it is an IQ stanza of type "get" sent from client to server and containing a <query/> element qualified by the 'jabber:iq:roster' namespace, where the <query/> element MUST NOT contain any <item/> child elements.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='bv1bs71f'
type='get'>
<query xmlns='jabber:iq:roster'/>
</iq>
]]></artwork>
</figure>
<t>The expected outcome of sending a roster get is for the server to return a roster result.</t>
</section>
<section title="Roster Result" anchor="roster-syntax-actions-result">
<t>A "roster result" is the server's response to a roster get; syntactically it is an IQ stanza of type "result" sent from server to client and containing a <query/> element qualified by the 'jabber:iq:roster' namespace.</t>
<t>The <query/> element in a roster result contains one <item/> element for each contact and therefore can contain more than one <item/> element.</t>
<figure>
<artwork><![CDATA[
S: <iq id='bv1bs71f'
to='juliet@example.com/chamber'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver7'>
<item jid='nurse@example.com'/>
<item jid='romeo@example.net'/>
</query>
</iq>
]]></artwork>
</figure>
<t>If the roster exists but there are no contacts in the roster, then the server MUST return an IQ-result containing a child <query/> element that in turn contains no <item/> children (i.e., the server MUST NOT return an empty <iq/> stanza of type "error").</t>
<figure>
<artwork><![CDATA[
S: <iq id='bv1bs71f'
to='juliet@example.com/chamber'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver9'/>
</iq>
]]></artwork>
</figure>
<t>If the roster does not exist, then the server MUST return a stanza error with a condition of <item-not-found/>.</t>
<figure>
<artwork><![CDATA[
S: <iq id='bv1bs71f'
to='juliet@example.com/chamber'
type='error'>
<error type='cancel'>
<item-not-found
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
</section>
<section title="Roster Set" anchor="roster-syntax-actions-set">
<t>A "roster set" is a client's request for the server to modify (i.e., create, update, or delete) a roster item; syntactically it is an IQ stanza of type "set" sent from client to server and containing a <query/> element qualified by the 'jabber:iq:roster' namespace.</t>
<t>The following rules apply to roster sets:</t>
<t>
<list style='numbers'>
<t>The <query/> element MUST contain one and only one <item/> element.</t>
<t>The server MUST ignore any value of the 'subscription' attribute other than "remove" (see <xref target='roster-syntax-items-subscription'/>).</t>
</list>
</t>
<t><list style='empty'><t>Security Warning: Traditionally, the IQ stanza of the roster set included no 'to' address, with the result that all roster sets were sent from an authenticated resource (full JID) of the account whose roster was being updated. Furthermore, RFC 3921 required a server to perform special-case checking of roster sets to ignore the 'to' address; however, this specification has removed that special-casing, which means that a roster set might include a 'to' address other than that of the sender. Therefore, the entity that processes a roster set MUST verify that the sender of the roster set is authorized to update the roster, and if not return a <forbidden/> error.</t></list></t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='rs1'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'/>
</query>
</iq>
]]></artwork>
</figure>
</section>
<section title="Roster Push" anchor="roster-syntax-actions-push">
<t>A "roster push" is a newly created, updated, or deleted roster item that is sent from the server to the client; syntactically it is an IQ stanza of type "set" sent from server to client and containing a <query/> element qualified by the 'jabber:iq:roster' namespace.</t>
<t>The following rules apply to roster pushes:</t>
<t>
<list style='numbers'>
<t>The <query/> element in a roster push MUST contain one and only one <item/> element.</t>
<t>A receiving client MUST ignore the stanza unless it has no 'from' attribute (i.e., implicitly from the bare JID of the user's account) or it has a 'from' attribute whose value matches the user's bare JID <user@domainpart>.</t>
</list>
</t>
<figure>
<artwork><![CDATA[
S: <iq id='a78b4q6ha463'
to='juliet@example.com/chamber'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'/>
</query>
</iq>
]]></artwork>
</figure>
<t>As mandated by the semantics of the IQ stanza as defined in <xref target="XMPP-CORE"/>, each resource that receives a roster push from the server is supposed to reply with an IQ stanza of type "result" or "error" (however, it is known that many existing clients do not reply to roster pushes).</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='a78b4q6ha463'
type='result'/>
C: <iq from='juliet@example.com/chamber'
id='a78b4q6ha463'
type='result'/>
]]></artwork>
</figure>
<t><list style='empty'><t>Security Warning: Traditionally, a roster push included no 'from' address, with the result that all roster pushes were sent implicitly from the bare JID of the account itself. However, this specification allows entities other than the user's server to maintain roster information, which means that a roster push might include a 'from' address other than the bare JID of the user's account. Therefore, the client MUST check the 'from' address to verify that the sender of the roster push is authorized to update the roster. If the client receives a roster push from an unauthorized entity, it MUST NOT process the pushed data; in addition, the client can either return a stanza error of <service-unavailable/> error or refuse to return a stanza error at all (the latter behavior overrides a MUST-level requirement from <xref target='XMPP-CORE'/> for the purpose of preventing a presence leak).</t></list></t>
<t><list style='empty'><t>Implementation Note: There is no error case for client processing of roster pushes; if the server receives an IQ of type "error" in response to a roster push then it SHOULD ignore the error.</t></list></t>
</section>
</section>
<section title="Retrieving the Roster on Login" anchor="roster-login">
<t>Upon authenticating with a server and binding a resource (thus becoming a connected resource as defined in <xref target='XMPP-CORE'/>), a client SHOULD request the roster before sending initial presence (however, because receiving the roster is not necessarily desirable for all resources, e.g., a connection with limited bandwidth, the client's request for the roster is not mandatory). After a connected resource sends initial presence (see <xref target='presence-initial'/>), it is referred to as an "available resource". If a connected resource or available resource requests the roster, it is referred to as an "interested resource". The server MUST send roster pushes to all interested resources.</t>
<t><list style='empty'><t>Implementation Note: Presence subscription requests are sent to available resources, whereas the roster pushes associated with subscription state changes are sent to interested resources. Therefore, if a resource wishes to receive both subscription requests and roster pushes, it MUST both send initial presence and request the roster.</t></list></t>
<t>A client requests the roster by sending a roster get over its stream with the server.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='hu2bac18'
type='get'>
<query xmlns='jabber:iq:roster'/>
</iq>
]]></artwork>
</figure>
<figure>
<artwork><![CDATA[
S: <iq id='hu2bac18'
to='juliet@example.com/balcony'
type='result'>
<query xmlns='jabber:iq:roster' ver='ver11'>
<item jid='romeo@example.net'
name='Romeo'
subscription='both'>
<group>Friends</group>
</item>
<item jid='mercutio@example.com'
name='Mercutio'
subscription='from'/>
<item jid='benvolio@example.net'
name='Benvolio'
subscription='both'/>
</query>
</iq>
]]></artwork>
</figure>
<t>If the server cannot process the roster get, it MUST return an appropriate stanza error as described in <xref target='XMPP-CORE'/> (such as <service-unavailable/> if the roster namespace is not supported or <internal-server-error/> if the server experiences trouble processing or returning the roster).</t>
</section>
<section title="Adding a Roster Item" anchor="roster-add">
<section title="Request" anchor="roster-add-request">
<t>At any time, a client can add an item to the roster. This is done by sending a roster set containing a new item.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='ph1xaz53'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group>Servants</group>
</item>
</query>
</iq>
]]></artwork>
</figure>
</section>
<section title="Success Case" anchor="roster-add-success">
<t>If the server can successfully process the roster set for the new item (i.e., if no error occurs), it MUST create the item in the user's roster and proceed as follows.</t>
<t>The server MUST return an IQ stanza of type "result" to the connected resource that sent the roster set.</t>
<figure>
<artwork><![CDATA[
S: <iq id='ph1xaz53'
to='juliet@example.com/balcony'
type='result'/>
]]></artwork>
</figure>
<t>The server MUST also send a roster push containing the new roster item to all of the user's interested resources, including the resource that generated the roster set.</t>
<figure>
<artwork><![CDATA[
S: <iq to='juliet@example.com/balcony'
id='a78b4q6ha463'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver13'>
<item jid='nurse@example.com'
name='Nurse'
subscription='none'>
<group>Servants</group>
</item>
</query>
</iq>
S: <iq to='juliet@example.com/chamber'
id='x81g3bdy4n19'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver13'>
<item jid='nurse@example.com'
name='Nurse'
subscription='none'>
<group>Servants</group>
</item>
</query>
</iq>
]]></artwork>
</figure>
<t>As mandated by the semantics of the IQ stanza as defined in <xref target="XMPP-CORE"/>, each resource that receives a roster push from the server is supposed to reply with an IQ stanza of type "result" or "error" (however, it is known that many existing clients do not reply to roster pushes).</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='a78b4q6ha463'
type='result'/>
C: <iq from='juliet@example.com/chamber'
id='x81g3bdy4n19'
type='result'/>
]]></artwork>
</figure>
</section>
<section title="Error Cases" anchor="roster-add-errors">
<t>If the server cannot successfully process the roster set, it MUST return a stanza error. The following error cases are defined. Naturally, other stanza errors can occur, such as <internal-server-error/> if the server experiences an internal problem with processing the roster get, or even <not-allowed/> if the server only allows roster modifications by means of a non-XMPP method such as a web interface.</t>
<t>The server MUST return a <forbidden/> stanza error to the client if the sender of the roster set is not authorized to update the roster (where typically only an authenticated resource of the account itself is authorized).</t>
<t>The server MUST return a <bad-request/> stanza error to the client if the roster set contains any of the following violations:</t>
<t>
<list style='numbers'>
<t>The <query/> element contains more than one <item/> child element.</t>
<t>The <item/> element contains more than one <group/> element, but there are duplicate groups (one possible comparison method for determining duplicates is that described for XMPP resourceparts in <xref target='XMPP-ADDR'/>).</t>
</list>
</t>
<t>The server MUST return a <not-acceptable/> stanza error to the client if the roster set contains any of the following violations:</t>
<t>
<list style='numbers'>
<t>The length of the 'name' attribute is greater than a server-configured limit.</t>
<t>The XML character data of the <group/> element is of zero length (to remove an item from all groups, the client instead needs to exclude any <group/> element from the roster set).</t>
<t>The XML character data of the <group/> element is larger than a server-configured limit.</t>
</list>
</t>
<figure>
<preamble>Error: Roster set initiated by unauthorized entity</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='ix7s53v2'
to='romeo@example.net'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'/>
</query>
</iq>
S: <iq id='ix7s53v2'
to='juliet@example.com/balcony'
type='error'>
<error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<figure>
<preamble>Error: Roster set contains more than one item</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='nw83vcj4'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group>Servants</group>
</item>
<item jid='mother@example.com'
name='Mom'>
<group>Family</group>
</item>
</query>
</iq>
S: <iq id='nw83vcj4'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<figure>
<preamble>Error: Roster set contains item with oversized handle</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='yl491b3d'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='[ ... some-very-long-handle ... ]'>
<group>Servants</group>
</item>
</query>
</iq>
S: <iq id='yl491b3d'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<figure>
<preamble>Error: Roster set contains duplicate groups</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='tk3va749'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group>Servants</group>
<group>Servants</group>
</item>
</query>
</iq>
S: <iq id='tk3va749'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<figure>
<preamble>Error: Roster set contains empty group</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='fl3b486u'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group></group>
</item>
</query>
</iq>
S: <iq id='fl3b486u'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<figure>
<preamble>Error: Roster set contains oversized group name</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='qh3b4v19'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
name='Nurse'>
<group>[ ... some-very-long-group-name ... ]</group>
</item>
</query>
</iq>
S: <iq id='qh3b4v19'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
<t><list style='empty'><t>Interoperability Note: Some servers return a <not-allowed/> stanza error to the client if the value of the <item/> element's 'jid' attribute matches the bare JID <localpart@domainpart> of the user's account.</t></list></t>
</section>
</section>
<section title="Updating a Roster Item" anchor="roster-update">
<section title="Request" anchor="roster-update-request">
<t>Updating an existing roster item is done in the same way as adding a new roster item, i.e., by sending a roster set to the server. Because a roster item is atomic, the item MUST be updated exactly as provided in the roster set.</t>
<t>There are several reasons why a client might update a roster item:</t>
<t>
<list style='numbers'>
<t>Adding a group</t>
<t>Deleting a group</t>
<t>Changing the handle</t>
<t>Deleting the handle</t>
</list>
</t>
<t>Consider a roster item that is defined as follows:</t>
<figure>
<artwork><![CDATA[
<item jid='romeo@example.net'
name='Romeo'>
<group>Friends</group>
</item>
]]></artwork>
</figure>
<t>The user who has this item in her roster might want to add the item to another group.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='di43b2x9'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
name='Romeo'>
<group>Friends</group>
<group>Lovers</group>
</item>
</query>
</iq>
]]></artwork>
</figure>
<t>Sometime later, the user might want to remove the item from the original group.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='lf72v157'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
name='Romeo'>
<group>Lovers</group>
</item>
</query>
</iq>
]]></artwork>
</figure>
<t>The user might want to remove the item from all groups.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='ju4b62a5'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'/>
</query>
</iq>
]]></artwork>
</figure>
<t>The user might also want to change the handle for the item.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='gb3sv487'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
name='MyRomeo'/>
</query>
</iq>
]]></artwork>
</figure>
<t>The user might then want to remove the handle altogether.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='o3bx66s5'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
name=''/>
</query>
</iq>
]]></artwork>
</figure>
<t><list style='empty'><t>Implementation Note: Including an empty 'name' attribute is equivalent to including no 'name' attribute; both actions set the name to the empty string.</t></list></t>
</section>
<section title="Success Case" anchor="roster-update-success">
<t>As with adding a roster item, if the roster item can be successfully processed then the server MUST update the item in the user's roster, send a roster push to all of the user's interested resources, and send an IQ result to the initiating resource; details are provided under <xref target='roster-add'/>.</t>
</section>
<section title="Error Cases" anchor="roster-update-error">
<t>The error cases described under <xref target='roster-add-errors'/> also apply to updating a roster item.</t>
</section>
</section>
<section title="Deleting a Roster Item" anchor="roster-delete">
<section title="Request" anchor="roster-delete-request">
<t>At any time, a client can delete an item from his or her roster by sending a roster set and specifying a value of "remove" for the 'subscription' attribute.</t>
<figure>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='hm4hs97y'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='nurse@example.com'
subscription='remove'/>
</query>
</iq>
]]></artwork>
</figure>
</section>
<section title="Success Case" anchor="roster-delete-success">
<t>As with adding a roster item, if the server can successfully process the roster set then it MUST update the item in the user's roster, send a roster push to all of the user's interested resources (with the 'subscription' attribute set to a value of "remove"), and send an IQ result to the initiating resource; details are provided under <xref target='roster-add'/>.</t>
<t>In addition, the user's server might need to generate one or more subscription-related presence stanzas, as follows:</t>
<t>
<list style='numbers'>
<t>If the user has a presence subscription to the contact, then the user's server MUST send a presence stanza of type "unsubscribe" to the contact (in order to unsubscribe from the contact's presence).</t>
<t>If the contact has a presence subscription to the user, then the user's server MUST send a presence stanza of type "unsubscribed" to the contact (in order to cancel the contact's subscription to the user).</t>
<t>If the presence subscription is mutual, then the user's server MUST send both a presence stanza of type "unsubscribe" and a presence stanza of type "unsubscribed" to the contact.</t>
</list>
</t>
<figure>
<artwork><![CDATA[
S: <presence from='juliet@example.com'
id='lm3ba81g'
to='nurse@example.com'
type='unsubscribe'/>
S: <presence from='juliet@example.com'
id='xb2c1v4k'
to='nurse@example.com'
type='unsubscribed'/>
]]></artwork>
</figure>
</section>
<section title="Error Cases" anchor="roster-delete-error">
<t>If the value of the 'jid' attribute specifies an item that is not in the roster, then the server MUST return an <item-not-found/> stanza error.</t>
<figure>
<preamble>Error: Roster item not found</preamble>
<artwork><![CDATA[
C: <iq from='juliet@example.com/balcony'
id='uj4b1ca8'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='[ ... non-existent-jid ... ]'
subscription='remove'/>
</query>
</iq>
S: <iq id='uj4b1ca8'
to='juliet@example.com/balcony'
type='error'>
<error type='modify'>
<item-not-found
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></artwork>
</figure>
</section>
</section>
<section title="Roster Versioning" anchor="roster-versioning">
<section title="Stream Feature" anchor="roster-versioning-feature">
<t>If a server supports roster versioning, then it MUST advertise the following stream feature during stream negotiation.</t>
<figure>
<artwork><![CDATA[
<ver xmlns='urn:xmpp:features:rosterver'/>
]]></artwork>
</figure>
<t> The roster versioning stream feature is merely informative and
therefore is never mandatory-to-negotiate.</t>
</section>
<section title="Request" anchor="roster-versioning-request">
<t>If a client supports roster versioning and the server to which it has connected advertises support for roster versioning as described in the foregoing section, then the client SHOULD include the 'ver' element in its request for the roster. If the server does not advertise support for roster versioning, the client MUST NOT include the 'ver' attribute. If the client includes the 'ver' attribute in its roster get, it sets the attribute's value to the version ID associated with its last cache of the roster.</t>
<figure>
<artwork><![CDATA[
C: <iq from='romeo@example.net/home'
id='r1h3vzp7'
to='romeo@example.net'
type='get'>
<query xmlns='jabber:iq:roster' ver='ver14'/>
</iq>
]]></artwork>
</figure>
<t>If the client has not yet cached the roster or the cache is lost or corrupted, but the client wishes to bootstrap the use of roster versioning, it MUST set the 'ver' attribute to the empty string (i.e., ver="").</t>
<t>Naturally, if the client does not support roster versioning or does not wish to bootstrap the use of roster versioning, it will not include the 'ver' attribute.</t>
</section>
<section title="Success Case" anchor="roster-versioning-success">
<t>Whether or not the roster has been modified since the version ID enumerated by the client, the server MUST either return the complete roster as described under <xref target='roster-syntax-actions-result'/> (including a 'ver' attribute that signals the latest version) or return an empty IQ-result (thus indicating that any roster modifications will be sent via roster pushes, as described below). In general, unless returning the complete roster would (1) use less bandwidth than sending individual roster pushes to the client (e.g., if the roster contains only a few items) or (2) the server cannot associate the version ID with any previous version it has on file, the server SHOULD send an empty IQ-result and then send the modifications (if any) via roster pushes.</t>
<figure>
<artwork><![CDATA[
S: <iq from='romeo@example.net'
id='r1h3vzp7'
to='romeo@example.net/home'
type='result'/>
]]></artwork>
</figure>
<t><list style='empty'><t>Implementation Note: This empty IQ-result is different from an empty <query/> element, thus disambiguating this usage from an empty roster.</t></list></t>
<t>If roster versioning is enabled and the roster has not been modified since the version ID enumerated by the client, the server will simply not send any roster pushes to the client (until and unless some relevant event triggers a roster push during the lifetime of the client's session).</t>
<t>If the roster has been modified since the version ID enumerated by the client, the server MUST then send one roster push to the client for each roster item that has been modified since the version ID enumerated by the client. (We call a roster push that is sent for purposes of roster version synchronization an "interim roster push".)</t>
<t><list style='empty'><t>Definition: A "roster modification" is any change to the roster data that would result in a roster push to a connected client. Therefore, internal states related to roster processing within the server that would not result in a roster push to a connected client do not necessitate a change to the version.</t></list></t>
<figure>
<artwork><![CDATA[
S: <iq from='romeo@example.net'
id='ah382g67'
to='romeo@example.net/home'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver34'>
<item jid='tybalt@example.org' subscription='remove'/>
</query>
</iq>
S: <iq from='romeo@example.net'
id='b2gs90j5'
to='romeo@example.net/home'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver42'>
<item jid='bill@example.org' subscription='both'/>
</query>
</iq>
S: <iq from='romeo@example.net'
id='c73gs419'
to='romeo@example.net/home'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver72'>
<item jid='nurse@example.org'
name='Nurse'
subscription='to'>
<group>Servants</group>
</item>
</query>
</iq>
S: <iq from='romeo@example.net'
id='dh361f35'
to='romeo@example.net/home'
type='set'>
<query xmlns='jabber:iq:roster' ver='ver96'>
<item jid='juliet@example.org'
name='Juliet'
subscription='both'>
<group>VIPs</group>
</item>
</query>
</iq>
]]></artwork>
</figure>
<t>These "interim roster pushes" can be understood as follows:</t>
<t>
<list style='numbers'>
<t>Imagine that the client had an active presence session for the entire time between its cached roster version (say, "ver14") and the new roster version (say, "ver96").</t>
<t>During that time, the client might have received roster pushes related to various roster versions (which might have been, say, "ver51" and "ver79"). However, some of those roster pushes might have contained intermediate updates to the same roster item (e.g., modifications to the subscription state for bill@example.org from "none" to "to" and from "to" to "both").</t>
<t>The interim roster pushes would not include all of the intermediate steps, only the final result of all modifications applied to each item while the client was in fact offline (which might have been, say, "ver34", "ver42", "ver72", and "ver96").</t>
</list>
</t>
<t>The client MUST handle an "interim roster push" in the same way it handles any roster push (indeed, from the client's perspective it cannot tell the difference between an "interim" roster push and a "live" roster push and therefore it has no way of knowing when it has received all of the interim roster pushes). When requesting the roster after reconnection, the client SHOULD request the version associated with the last roster push it received during its previous session, not the version associated with the roster result it received at the start of its previous session.</t>
<t>When roster versioning is enabled, the server MUST include the updated roster version with each roster push. Roster pushes MUST occur in order of modification and the version contained in a roster push MUST be unique. Even if the client has not included the 'ver' attribute in its roster gets or sets, the server SHOULD include the 'ver' attribute on all roster pushes and results that it sends to the client.</t>
<t><list style='empty'><t>Implementation Note: Guidelines and more detailed examples for roster versioning are provided in <xref target='XEP-0237'/>.</t></list></t>
</section>
</section>
</section>
<section title="Managing Presence Subscriptions" anchor="sub">
<t>In order to protect the privacy of XMPP users, presence information is disclosed only to other entities that a user has approved. When a user has agreed that another entity is allowed to view its presence, the entity is said to have a "subscription" to the user's presence. An entity that has a subscription to a user's presence or to which a user has a presence subscription is called a "contact" (in this document the term "contact" is also used in a less strict sense to refer to a potential contact or any item in a user's roster).</t>
<t>In XMPP, a subscription lasts across presence sessions; indeed, it lasts until the contact unsubscribes or the user cancels the previously granted subscription. (This model is different from that used for presence subscriptions in the Session Initiation Protocol (SIP), as defined in <xref target='SIP-PRES'/>.)</t>
<t>Subscriptions are managed within XMPP by sending presence stanzas containing specially defined attributes ("subscribe", "unsubscribe", "subscribed", and "unsubscribed").</t>
<t><list style='empty'><t>Implementation Note: When a server processes or generates an outbound presence stanza of type "subscribe", "subscribed", "unsubscribe", or "unsubscribed", the server MUST stamp the outgoing presence stanza with the bare JID <localpart@domainpart> of the sending entity, not the full JID <localpart@domainpart/resourcepart>. Enforcement of this rule simplifies the presence subscription model and helps to prevent presence leaks; for information about presence leaks, refer to the security considerations of <xref target='XMPP-CORE'/>.</t></list></t>
<t>Subscription states are reflected in the rosters of both the user and the contact. This section does not cover every possible case related to presence subscriptions, and mainly narrates the protocol flows for bootstrapping a mutual subscription between a user and a contact. Complete details regarding subscription states can be found under <xref target='substates'/>.</t>
<section title="Requesting a Subscription" anchor="sub-request">
<t>A "subscription request" is a request from a user for authorization to permanently subscribe to a contact's presence information; syntactically it is a presence stanza whose 'type' attribute has a value of "subscribe". A subscription request is generated by a user's client, processed by the (potential) contact's server, and acted on by the contact via the contact's client. The workflow is described in the following sections.</t>
<t><list style='empty'><t>Implementation Note: Presence subscription requests are sent to available resources, whereas the roster pushes associated with subscription state changes are sent to interested resources. Therefore, if a resource wishes to receive both subscription requests and roster pushes, it MUST both send initial presence and request the roster.</t></list></t>
<section title="Client Generation of Outbound Subscription Request" anchor="sub-request-gen">
<t>A user's client generates a subscription request by sending a presence stanza of type "subscribe" and specifying a 'to' address of the potential contact's bare JID <contact@domainpart>.</t>
<figure>
<artwork><![CDATA[
UC: <presence id='xk3h1v69'
to='juliet@example.com'
type='subscribe'/>
]]></artwork>
</figure>
<t>When a user sends a presence subscription request to a potential instant messaging and presence contact, the value of the 'to' attribute MUST be a bare JID <contact@domainpart> rather than a full JID <contact@domainpart/resourcepart>, since the desired result is for the user to receive presence from all of the contact's resources, not merely the particular resource specified in the 'to' attribute. Use of bare JIDs also simplifies subscription processing, presence probes, and presence notifications by the user's server and the contact's server.</t>
<t>For tracking purposes, a client SHOULD include an 'id' attribute in a presence subscription request.</t>
<t><list style='empty'><t>Implementation Note: Many XMPP clients prompt the user for information about the potential contact (e.g., "handle" and desired roster group) when generating an outbound presence subscription request and therefore send a roster set before sending the outbound presence subscription request. This behavior is OPTIONAL, because a client MAY instead wait until receiving the initial roster push from the server before uploading user-provided information about the contact. A server MUST process a roster set and outbound presence subscription request in either order (i.e., in whatever order generated by the client).</t></list></t>
</section>
<section title="Server Processing of Outbound Subscription Request" anchor="sub-request-outbound">
<t>Upon receiving the outbound presence subscription request, the user's server MUST proceed as follows.</t>
<t>
<list style='numbers'>
<t>Before processing the request, the user's server MUST check the syntax of the JID contained in the 'to' attribute (however, it is known that some existing implementations do not perform this check). If the JID is of the form <contact@domainpart/resourcepart> instead of <contact@domainpart>, the user's server SHOULD treat it as if the request had been directed to the contact's bare JID and modify the 'to' address accordingly. The server MAY also verify that the JID adheres to the format defined in <xref target='XMPP-ADDR'/> and possibly return a <jid-malformed/> stanza error.</t>
<t>If the potential contact is hosted on the same server as the
user, then the server MUST adhere to the rules specified under <xref target="sub-request-inbound"/> when processing the subscription request and delivering it to the (local) contact.</t>
<t>If the potential contact is hosted on a remote server, subject to local service policies the user's server MUST then route the stanza to that remote domain in accordance with core XMPP stanza processing rules. (This can result in returning an appropriate stanza error to the user, such as <remote-server-timeout/>.)</t>
</list>
</t>
<t>As mentioned, before locally delivering or remotely routing the presence subscription request, the user's server MUST stamp the outbound subscription request with the bare JID <user@domainpart> of the user.</t>
<figure>
<artwork><![CDATA[
US: <presence from='romeo@example.net'
id='xk3h1v69'
to='juliet@example.com'
type='subscribe'/>
]]></artwork>
</figure>
<t>If the presence subscription request cannot be locally delivered or remotely routed (e.g., because the request is malformed, the local contact does not exist, the remote server does not exist, an attempt to contact the remote server times out, or any other error is determined or experienced by the user's server), then the user's server MUST return an appropriate error stanza to the user. An example follows.</t>
<figure>
<artwork><![CDATA[
US: <presence from='juliet@example.com'
id='xk3h1v69'
to='romeo@example.net'
type='error'>
<error type='modify'>
<remote-server-not-found
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</presence>
]]></artwork>
</figure>
<t>After locally delivering or remotely routing the presence subscription request, the user's server MUST then send a roster push to all of the user's interested resources, containing the potential contact with a subscription state of "none" and with notation that the subscription is pending (via an 'ask' attribute whose value is "subscribe").</t>
<figure>
<artwork><![CDATA[
US: <iq id='b89c5r7ib574'
to='romeo@example.net/foo'
type='set'>
<query xmlns='jabber:iq:roster'>
<item ask='subscribe'
jid='juliet@example.com'
subscription='none'/>
</query>
</iq>
US: <iq id='b89c5r7ib575'
to='romeo@example.net/bar'
type='set'>
<query xmlns='jabber:iq:roster'>
<item ask='subscribe'
jid='juliet@example.com'
subscription='none'/>
</query>
</iq>
]]></artwork>
</figure>
<t>If a remote contact does not approve or deny the subscription request within some configurable amount of time, the user's server SHOULD resend the subscription request to the contact based on an implementation-specific algorithm (e.g., whenever a new resource becomes available for the user, or after a certain amount of time has elapsed); this helps to recover from transient, silent errors that might have occurred when the original subscription request was routed to the remote domain. When doing so, it is RECOMMENDED for the server to include an 'id' attribute so that it can track responses to the resent subscription request.</t>
</section>
<section title="Server Processing of Inbound Subscription Request" anchor="sub-request-inbound">
<t>Before processing the inbound presence subscription request, the contact's server SHOULD check the syntax of the JID contained in the 'to' attribute. If the JID is of the form <contact@domainpart/resourcepart> instead of <contact@domainpart>, the contact's server SHOULD treat it as if the request had been directed to the contact's bare JID and modify the 'to' address accordingly. The server MAY also verify that the JID adheres to the format defined in <xref target='XMPP-ADDR'/> and possibly return a <jid-malformed/> stanza error.</t>
<t>When processing the inbound presence subscription request, the contact's server MUST adhere to the following rules:</t>
<t>
<list style='numbers'>
<t>Above all, the contact's server MUST NOT automatically approve subscription requests on the contact's behalf -- unless the contact has (a) pre-approved subscription requests from the user as described under <xref target='sub-preapproval'/>, (b) configured its account to automatically approve subscription requests, or (c) accepted an agreement with its service provider that allows automatic approval (for instance, via an employment agreement within an enterprise deployment). Instead, if a subscription request requires approval then the contact's server MUST deliver that request to the contact's available resource(s) for approval or denial by the contact.</t>
<t>If the contact exists and the user already has a subscription to the contact's presence, then the contact's server MUST auto-reply on behalf of the contact by sending a presence stanza of type "subscribed" from the contact's bare JID to the user's bare JID. Likewise, if the contact previously sent a presence stanza of type "subscribed" and the contact's server treated that as indicating "pre-approval" for the user's presence subscription (see <xref target='sub-preapproval'/>), then the contact's server SHOULD also auto-reply on behalf of the contact.
<figure>
<artwork><![CDATA[
CS: <presence from='juliet@example.com'
id='xk3h1v69'
to='romeo@example.net'
type='subscribed'/>
]]></artwork>
</figure>
</t>
<t>Otherwise, if there is at least one available resource associated with the contact when the subscription request is received by the contact's server, then the contact's server MUST send that subscription request to all available resources in accordance with <xref target="rules"/>.
As a way of acknowledging receipt of the presence subscription request, the contact's server MAY send a presence stanza of type "unavailable" from the bare JID of the contact to the bare JID of the user (the user's client MUST NOT assume that this acknowledgement provides presence information about the contact, since it comes from the contact's bare JID and is received before the subscription request has been approved).</t>
<t>Otherwise, if the contact has no available resources when the subscription request is received by the contact's server, then the contact's server MUST keep a record of the complete presence stanza comprising the subscription request, including any extended content contained therein (see Section 8.4 of <xref target='XMPP-CORE'/>), and then deliver the request when the contact next has an available resource. The contact's server MUST continue to deliver the subscription request whenever the contact creates an available resource, until the contact either approves or denies the request. (The contact's server MUST NOT deliver more than one subscription request from any given user when the contact next has an available resource; e.g., if the user sends multiple subscription requests to the contact while the contact is offline, the contact's server SHOULD store only one of those requests, such as the first request or last request, and MUST deliver only one of the requests when the contact next has an available resource; this helps to prevent "subscription request spam".)</t>
</list>
</t>
<t><list style='empty'><t>Security Warning: Until and unless the contact approves the subscription request as described under <xref target='sub-request-handle'/>, the contact's server MUST NOT add an item for the user to the contact's roster.</t></list></t>
<t><list style='empty'><t>Security Warning: The mandate for the contact's server to store the complete stanza of the presence subscription request introduces the possibility of an application resource exhaustion attack (see Section 2.1.2 of <xref target='DOS'/>), for example, by a rogue server or a coordinated group of users (e.g., a botnet) against the contact's server or particular contact. Server implementers are advised to consider the possibility of such attacks and provide tools for counteracting it, such as enabling service administrators to set limits on the number or size of inbound presence subscription requests that the server will store in aggregate or for any given contact.</t></list></t>
</section>
<section title="Client Processing of Inbound Subscription Request" anchor="sub-request-handle">
<t>When an interactive client receives a subscription request, it MUST present the request to the natural person controlling the client (i.e., the "contact") for approval, unless the contact has explicitly configured the client to automatically approve or deny some or all subscription requests as described above. An automated client that is not controlled by a natural person will have its own application-specific rules for approving or denying subscription requests.</t>
<t>A client approves a subscription request by sending a presence stanza of type "subscribed", which is processed as described under <xref target='sub-request-approvalout'/> for the contact's server and <xref target='sub-request-approvalin'/> for the user's server.</t>
<figure>
<artwork><![CDATA[
CC: <presence id='h4v1c4kj'
to='romeo@example.net'
type='subscribed'/>
]]></artwork>
</figure>
<t>A client denies a subscription request by sending a presence stanza of type "unsubscribed", which is processed as described under <xref target='sub-cancel'/> for both the contact's server and the user's server.</t>
<figure>
<artwork><![CDATA[
CC: <presence id='tb2m1b59'
to='romeo@example.net'
type='unsubscribed'/>
]]></artwork>
</figure>
<t>For tracking purposes, a client SHOULD include an 'id' attribute in a subscription approval or subscription denial; this 'id' attribute MUST NOT mirror the 'id' attribute of the subscription request.</t>
</section>
<section title="Server Processing of Outbound Subscription Approval" anchor="sub-request-approvalout">
<t>When the contact's client sends the subscription approval, the contact's server MUST stamp the outbound stanza with the bare JID <contact@domainpart> of the contact and locally deliver or remotely route the stanza to the user.</t>
<figure>
<artwork><![CDATA[
CS: <presence from='juliet@example.com'
id='h4v1c4kj'
to='romeo@example.net'
type='subscribed'/>
]]></artwork>
</figure>
<t>The contact's server then MUST send an updated roster push to all of the contact's interested resources, with the 'subscription' attribute set to a value of "from". (Here we assume that the contact does not already have a subscription to the user; if that were the case, the 'subscription' attribute would be set to a value of "both", as explained under <xref target='substates'/>.)</t>
<figure>
<artwork><![CDATA[
CS: <iq id='a78b4q6ha463'
to='juliet@example.com/balcony'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
subscription='from'/>
</query>
</iq>
CS: <iq id='x81g3bdy4n19'
to='juliet@example.com/chamber'
type='set'>
<query xmlns='jabber:iq:roster'>
<item jid='romeo@example.net'
subscription='from'/>
</query>
</iq>
]]></artwork>
</figure>
<t>From the perspective of the contact, there now exists a subscription from the user, which is why the 'subscription' attribute is set to a value of "from". (Here we assume that the contact does not already have a subscription to the user; if that were the case, the 'subscription' attribute would be set to a value of "both", as explained under <xref target='substates'/>.)</t>
<t>The contact's server MUST then also send current presence to the user from each of the contact's available resources.</t>
<figure>
<artwork><![CDATA[
CS: <presence from='juliet@example.com/balcony'
id='pw72bc5j'
to='romeo@example.net'/>
CS: <presence from='juliet@example.com/chamber'
id='ux31da4q'
to='romeo@example.net'/>
]]></artwork>
</figure>