10.8. Removing a Privacy List
In order to remove a privacy list, the user MUST send an IQ stanza of type "set" with a <query/> element qualified by the 'jabber:iq:privacy' namespace that contains one empty <list/> child element possessing a 'name' attribute whose value is set to the list name the user would like to remove. Example: Client removes a privacy list: <iq from='romeo@example.net/orchard' type='set' id='remove1'> <query xmlns='jabber:iq:privacy'> <list name='private'/> </query> </iq> Example: Server acknowledges success of list removal: <iq type='result' id='remove1' to='romeo@example.net/orchard'/>
If a user attempts to remove a list that is currently being applied to at least one resource other than the sending resource, the server MUST return a <conflict/> stanza error to the user; i.e., the user MUST first set another list to active or default before attempting to remove it. If the user attempts to remove a list but a list by that name does not exist, the server MUST return an <item-not-found/> stanza error to the user. If the user attempts to remove more than one list in the same request, the server MUST return a <bad request/> stanza error to the user.10.9. Blocking Messages
Server-side privacy lists enable a user to block incoming messages from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol. (Note: For the sake of brevity, IQ stanzas of type "result" are not shown in the following examples, nor are "privacy list pushes".) Example: User blocks based on JID: <iq from='romeo@example.net/orchard' type='set' id='msg1'> <query xmlns='jabber:iq:privacy'> <list name='message-jid-example'> <item type='jid' value='tybalt@example.com' action='deny' order='3'> <message/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive messages from the entity with the specified JID. Example: User blocks based on roster group: <iq from='romeo@example.net/orchard' type='set' id='msg2'> <query xmlns='jabber:iq:privacy'> <list name='message-group-example'> <item type='group' value='Enemies' action='deny' order='4'> <message/> </item>
</list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive messages from any entities in the specified roster group. Example: User blocks based on subscription type: <iq from='romeo@example.net/orchard' type='set' id='msg3'> <query xmlns='jabber:iq:privacy'> <list name='message-sub-example'> <item type='subscription' value='none' action='deny' order='5'> <message/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive messages from any entities with the specified subscription type. Example: User blocks globally: <iq from='romeo@example.net/orchard' type='set' id='msg4'> <query xmlns='jabber:iq:privacy'> <list name='message-global-example'> <item action='deny' order='6'> <message/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive messages from any other users.10.10. Blocking Inbound Presence Notifications
Server-side privacy lists enable a user to block incoming presence notifications from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol.
Note: Presence notifications do not include presence subscriptions, only presence information that is broadcasted to the user because the user is currently subscribed to a contact's presence information. Thus this includes presence stanzas with no 'type' attribute or of type='unavailable' only. Example: User blocks based on JID: <iq from='romeo@example.net/orchard' type='set' id='presin1'> <query xmlns='jabber:iq:privacy'> <list name='presin-jid-example'> <item type='jid' value='tybalt@example.com' action='deny' order='7'> <presence-in/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive presence notifications from the entity with the specified JID. Example: User blocks based on roster group: <iq from='romeo@example.net/orchard' type='set' id='presin2'> <query xmlns='jabber:iq:privacy'> <list name='presin-group-example'> <item type='group' value='Enemies' action='deny' order='8'> <presence-in/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive presence notifications from any entities in the specified roster group.
Example: User blocks based on subscription type: <iq from='romeo@example.net/orchard' type='set' id='presin3'> <query xmlns='jabber:iq:privacy'> <list name='presin-sub-example'> <item type='subscription' value='to' action='deny' order='9'> <presence-in/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive presence notifications from any entities with the specified subscription type. Example: User blocks globally: <iq from='romeo@example.net/orchard' type='set' id='presin4'> <query xmlns='jabber:iq:privacy'> <list name='presin-global-example'> <item action='deny' order='11'> <presence-in/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive presence notifications from any other users.10.11. Blocking Outbound Presence Notifications
Server-side privacy lists enable a user to block outgoing presence notifications to other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol. Note: Presence notifications do not include presence subscriptions, only presence information that is broadcasted to contacts because those contacts are currently subscribed to the user's presence information. Thus this includes presence stanzas with no 'type' attribute or of type='unavailable' only.
Example: User blocks based on JID: <iq from='romeo@example.net/orchard' type='set' id='presout1'> <query xmlns='jabber:iq:privacy'> <list name='presout-jid-example'> <item type='jid' value='tybalt@example.com' action='deny' order='13'> <presence-out/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not send presence notifications to the entity with the specified JID. Example: User blocks based on roster group: <iq from='romeo@example.net/orchard' type='set' id='presout2'> <query xmlns='jabber:iq:privacy'> <list name='presout-group-example'> <item type='group' value='Enemies' action='deny' order='15'> <presence-out/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not send presence notifications to any entities in the specified roster group. Example: User blocks based on subscription type: <iq from='romeo@example.net/orchard' type='set' id='presout3'> <query xmlns='jabber:iq:privacy'> <list name='presout-sub-example'> <item type='subscription' value='from' action='deny' order='17'> <presence-out/>
</item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not send presence notifications to any entities with the specified subscription type. Example: User blocks globally: <iq from='romeo@example.net/orchard' type='set' id='presout4'> <query xmlns='jabber:iq:privacy'> <list name='presout-global-example'> <item action='deny' order='23'> <presence-out/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not send presence notifications to any other users.10.12. Blocking IQ Stanzas
Server-side privacy lists enable a user to block incoming IQ stanzas from other entities based on the entity's JID, roster group, or subscription status (or globally). The following examples illustrate the protocol. Example: User blocks based on JID: <iq from='romeo@example.net/orchard' type='set' id='iq1'> <query xmlns='jabber:iq:privacy'> <list name='iq-jid-example'> <item type='jid' value='tybalt@example.com' action='deny' order='29'> <iq/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from the entity with the specified JID.
Example: User blocks based on roster group: <iq from='romeo@example.net/orchard' type='set' id='iq2'> <query xmlns='jabber:iq:privacy'> <list name='iq-group-example'> <item type='group' value='Enemies' action='deny' order='31'> <iq/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any entities in the specified roster group. Example: User blocks based on subscription type: <iq from='romeo@example.net/orchard' type='set' id='iq3'> <query xmlns='jabber:iq:privacy'> <list name='iq-sub-example'> <item type='subscription' value='none' action='deny' order='17'> <iq/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any entities with the specified subscription type.
Example: User blocks globally: <iq from='romeo@example.net/orchard' type='set' id='iq4'> <query xmlns='jabber:iq:privacy'> <list name='iq-global-example'> <item action='deny' order='1'> <iq/> </item> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive IQ stanzas from any other users.10.13. Blocking All Communication
Server-side privacy lists enable a user to block all stanzas from and to other entities based on the entity's JID, roster group, or subscription status (or globally). Note that this includes subscription-related presence stanzas, which are excluded by Blocking Inbound Presence Notifications (Section 10.10). The following examples illustrate the protocol. Example: User blocks based on JID: <iq from='romeo@example.net/orchard' type='set' id='all1'> <query xmlns='jabber:iq:privacy'> <list name='all-jid-example'> <item type='jid' value='tybalt@example.com' action='deny' order='23'/> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, the entity with the specified JID. Example: User blocks based on roster group: <iq from='romeo@example.net/orchard' type='set' id='all2'> <query xmlns='jabber:iq:privacy'> <list name='all-group-example'> <item type='group' value='Enemies'
action='deny' order='13'/> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any entities in the specified roster group. Example: User blocks based on subscription type: <iq from='romeo@example.net/orchard' type='set' id='all3'> <query xmlns='jabber:iq:privacy'> <list name='all-sub-example'> <item type='subscription' value='none' action='deny' order='11'/> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any entities with the specified subscription type. Example: User blocks globally: <iq from='romeo@example.net/orchard' type='set' id='all4'> <query xmlns='jabber:iq:privacy'> <list name='all-global-example'> <item action='deny' order='7'/> </list> </query> </iq> As a result of creating and applying the foregoing list, the user will not receive any communications from, nor send any stanzas to, any other users.10.14. Blocked Entity Attempts to Communicate with User
If a blocked entity attempts to send message or presence stanzas to the user, the user's server SHOULD silently drop the stanza and MUST NOT return an error to the sending entity.
If a blocked entity attempts to send an IQ stanza of type "get" or "set" to the user, the user's server MUST return to the sending entity a <service-unavailable/> stanza error, since this is the standard error code sent from a client that does not understand the namespace of an IQ get or set. IQ stanzas of other types SHOULD be silently dropped by the server. Example: Blocked entity attempts to send IQ get: <iq type='get' to='romeo@example.net' from='tybalt@example.com/pda' id='probing1'> <query xmlns='jabber:iq:version'/> </iq> Example: Server returns error to blocked entity: <iq type='error' from='romeo@example.net' to='tybalt@example.com/pda' id='probing1'> <query xmlns='jabber:iq:version'/> <error type='cancel'> <service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq>10.15. Higher-Level Heuristics
When building a representation of a higher-level privacy heuristic, a client SHOULD use the simplest possible representation. For example, the heuristic "block all communications with any user not in my roster" could be constructed in any of the following ways: o allow communications from all JIDs in my roster (i.e., listing each JID as a separate list item), but block communications with everyone else o allow communications from any user who is in one of the groups that make up my roster (i.e., listing each group as a separate list item), but block communications from everyone else o allow communications from any user with whom I have a subscription of 'both' or 'to' or 'from' (i.e., listing each subscription value separately), but block communications from everyone else
o block communications from anyone whose subscription state is 'none' The final representation is the simplest and SHOULD be used; here is the XML that would be sent in this case: <iq type='set' id='heuristic1'> <query xmlns='jabber:iq:privacy'> <list name='heuristic-example'> <item type='subscription' value='none' action='deny' order='437'/> </list> </query> </iq>11. Server Rules for Handling XML Stanzas
Basic routing and delivery rules for servers are defined in [XMPP-CORE]. This section defines additional rules for XMPP-compliant instant messaging and presence servers.11.1. Inbound Stanzas
If the hostname of the domain identifier portion of the JID contained in the 'to' attribute of an inbound stanza matches a hostname of the server itself and the JID contained in the 'to' attribute is of the form <user@example.com> or <user@example.com/resource>, the server MUST first apply any privacy lists (Section 10) that are in force, then follow the rules defined below: 1. If the JID is of the form <user@domain/resource> and an available resource matches the full JID, the recipient's server MUST deliver the stanza to that resource. 2. Else if the JID is of the form <user@domain> or <user@domain/ resource> and the associated user account does not exist, the recipient's server (a) SHOULD silently ignore the stanza (i.e., neither deliver it nor return an error) if it is a presence stanza, (b) MUST return a <service-unavailable/> stanza error to the sender if it is an IQ stanza, and (c) SHOULD return a <service-unavailable/> stanza error to the sender if it is a message stanza. 3. Else if the JID is of the form <user@domain/resource> and no available resource matches the full JID, the recipient's server (a) SHOULD silently ignore the stanza (i.e., neither deliver it
nor return an error) if it is a presence stanza, (b) MUST return a <service-unavailable/> stanza error to the sender if it is an IQ stanza, and (c) SHOULD treat the stanza as if it were addressed to <user@domain> if it is a message stanza. 4. Else if the JID is of the form <user@domain> and there is at least one available resource available for the user, the recipient's server MUST follow these rules: 1. For message stanzas, the server SHOULD deliver the stanza to the highest-priority available resource (if the resource did not provide a value for the <priority/> element, the server SHOULD consider it to have provided a value of zero). If two or more available resources have the same priority, the server MAY use some other rule (e.g., most recent connect time, most recent activity time, or highest availability as determined by some hierarchy of <show/> values) to choose between them or MAY deliver the message to all such resources. However, the server MUST NOT deliver the stanza to an available resource with a negative priority; if the only available resource has a negative priority, the server SHOULD handle the message as if there were no available resources (defined below). In addition, the server MUST NOT rewrite the 'to' attribute (i.e., it MUST leave it as <user@domain> rather than change it to <user@domain/ resource>). 2. For presence stanzas other than those of type "probe", the server MUST deliver the stanza to all available resources; for presence probes, the server SHOULD reply based on the rules defined in Presence Probes (Section 5.1.3). In addition, the server MUST NOT rewrite the 'to' attribute (i.e., it MUST leave it as <user@domain> rather than change it to <user@domain/resource>). 3. For IQ stanzas, the server itself MUST reply on behalf of the user with either an IQ result or an IQ error, and MUST NOT deliver the IQ stanza to any of the available resources. Specifically, if the semantics of the qualifying namespace define a reply that the server can provide, the server MUST reply to the stanza on behalf of the user; if not, the server MUST reply with a <service-unavailable/> stanza error. 5. Else if the JID is of the form <user@domain> and there are no available resources associated with the user, how the stanza is handled depends on the stanza type:
1. For presence stanzas of type "subscribe", "subscribed", "unsubscribe", and "unsubscribed", the server MUST maintain a record of the stanza and deliver the stanza at least once (i.e., when the user next creates an available resource); in addition, the server MUST continue to deliver presence stanzas of type "subscribe" until the user either approves or denies the subscription request (see also Presence Subscriptions (Section 5.1.6)). 2. For all other presence stanzas, the server SHOULD silently ignore the stanza by not storing it for later delivery or replying to it on behalf of the user. 3. For message stanzas, the server MAY choose to store the stanza on behalf of the user and deliver it when the user next becomes available, or forward the message to the user via some other means (e.g., to the user's email account). However, if offline message storage or message forwarding is not enabled, the server MUST return to the sender a <service-unavailable/> stanza error. (Note: Offline message storage and message forwarding are not defined in XMPP, since they are strictly a matter of implementation and service provisioning.) 4. For IQ stanzas, the server itself MUST reply on behalf of the user with either an IQ result or an IQ error. Specifically, if the semantics of the qualifying namespace define a reply that the server can provide, the server MUST reply to the stanza on behalf of the user; if not, the server MUST reply with a <service-unavailable/> stanza error.11.2. Outbound Stanzas
If the hostname of the domain identifier portion of the address contained in the 'to' attribute of an outbound stanza matches a hostname of the server itself, the server MUST deliver the stanza to a local entity according the rules for Inbound Stanzas (Section 11.1). If the hostname of the domain identifier portion of the address contained in the 'to' attribute of an outbound stanza does not match a hostname of the server itself, the server MUST attempt to route the stanza to the foreign domain. The recommended order of actions is as follows:
1. First attempt to resolve the foreign hostname using an [SRV] Service of "xmpp-server" and Proto of "tcp", resulting in resource records such as "_xmpp-server._tcp.example.com.", as specified in [XMPP-CORE]. 2. If the "xmpp-server" address record resolution fails, attempt to resolve the "_im" or "_pres" [SRV] Service as specified in [IMP-SRV], using the "_im" Service for <message/> stanzas and the "_pres" Service for <presence/> stanzas (it is up to the implementation how to handle <iq/> stanzas). This will result in one or more resolutions of the form "_im.<proto>.example.com." or "_pres.<proto>.example.com.", where "<proto>" would be a label registered in the Instant Messaging SRV Protocol Label registry or the Presence SRV Protocol Label registry: either "_xmpp" for an XMPP-aware domain or some other IANA-registered label (e.g., "_simple") for a non-XMPP-aware domain. 3. If both SRV address record resolutions fail, attempt to perform a normal IPv4/IPv6 address record resolution to determine the IP address using the "xmpp-server" port of 5269 registered with the IANA, as specified in [XMPP-CORE]. Administrators of server deployments are strongly encouraged to keep the _im._xmpp, _pres._xmpp, and _xmpp._tcp SRV records properly synchronized, since different implementations might perform the "_im" and "_pres" lookups before the "xmpp-server" lookup.12. IM and Presence Compliance Requirements
This section summarizes the specific aspects of the Extensible Messaging and Presence Protocol that MUST be supported by instant messaging and presence servers and clients in order to be considered compliant implementations. All such applications MUST comply with the requirements specified in [XMPP-CORE]. The text in this section specifies additional compliance requirements for instant messaging and presence servers and clients; note well that the requirements described here supplement but do not supersede the core requirements. Note also that a server or client MAY support only presence or instant messaging, and is not required to support both if only a presence service or an instant messaging service is desired.12.1. Servers
In addition to core server compliance requirements, an instant messaging and presence server MUST additionally support the following protocols:
o All server-related instant messaging and presence syntax and semantics defined in this document, including presence broadcast on behalf of clients, presence subscriptions, roster storage and manipulation, privacy lists, and IM-specific routing and delivery rules12.2. Clients
In addition to core client compliance requirements, an instant messaging and presence client MUST additionally support the following protocols: o Generation and handling of the IM-specific semantics of XML stanzas as defined by the XML schemas, including the 'type' attribute of message and presence stanzas as well as their child elements o All client-related instant messaging syntax and semantics defined in this document, including presence subscriptions, roster management, and privacy lists o End-to-end object encryption as defined in End-to-End Object Encryption in the Extensible Messaging and Presence Protocol (XMPP) [XMPP-E2E] A client MUST also handle addresses that are encoded as "im:" URIs as specified in [CPIM], and MAY do so by removing the "im:" scheme and entrusting address resolution to the server as specified under Outbound Stanzas (Section 11.2).13. Internationalization Considerations
For internationalization considerations, refer to the relevant section of [XMPP-CORE].14. Security Considerations
Core security considerations for XMPP are defined in the relevant section of [XMPP-CORE]. Additional considerations that apply only to instant messaging and presence applications of XMPP are defined in several places within this memo; specifically:
o When a server processes an inbound stanza of any kind whose intended recipient is a user associated with one of the server's hostnames, the server MUST first apply any privacy lists (Section 10) that are in force (see Server Rules for Handling XML Stanzas (Section 11)). o When a server processes an inbound presence stanza of type "probe" whose intended recipient is a user associated with one of the server's hostnames, the server MUST NOT reveal the user's presence information if the sender is an entity that is not authorized to receive that information as determined by presence subscriptions (see Client and Server Presence Responsibilities (Section 5.1)). o When a server processes an outbound presence stanza with no type or of type "unavailable", it MUST follow the rules defined under Client and Server Presence Responsibilities (Section 5.1) in order to ensure that such presence information is not broadcasted to entities that are not authorized to know such information. o When a server generates an error stanza in response to receiving a stanza for a user who does not exist, the use of the <service-unavailable/> error condition helps protect against well-known dictionary attacks, since this is the same error condition that is returned if, for instance, the namespace of an IQ child element is not understood, or if offline message storage or message forwarding is not enabled for a domain.15. IANA Considerations
For a number of related IANA considerations, refer to the relevant section of [XMPP-CORE].15.1. XML Namespace Name for Session Data
A URN sub-namespace for session-related data in the Extensible Messaging and Presence Protocol (XMPP) is defined as follows. (This namespace name adheres to the format defined in The IETF XML Registry [XML-REG].) URI: urn:ietf:params:xml:ns:xmpp-session Specification: RFC 3921 Description: This is the XML namespace name for session-related data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3921. Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>
15.2. Instant Messaging SRV Protocol Label Registration
Address Resolution for Instant Messaging and Presence [IMP-SRV] defines an Instant Messaging SRV Protocol Label registry for protocols that can provide services that conform to the "_im" SRV Service label. Because XMPP is one such protocol, the IANA registers the "_xmpp" protocol label in the appropriate registry, as follows: Protocol label: _xmpp Specification: RFC 3921 Description: Instant messaging protocol label for the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3921. Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>15.3. Presence SRV Protocol Label Registration
Address Resolution for Instant Messaging and Presence [IMP-SRV] defines a Presence SRV Protocol Label registry for protocols that can provide services that conform to the "_pres" SRV Service label. Because XMPP is one such protocol, the IANA registers the "_xmpp" protocol label in the appropriate registry, as follows: Protocol label: _xmpp Specification: RFC 3921 Description: Presence protocol label for the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3921. Registrant Contact: IETF, XMPP Working Group, <xmppwg@jabber.org>16. References
16.1. Normative References
[CPIM] Peterson, J., "Common Profile for Instant Messaging (CPIM)", RFC 3860, August 2004. [IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, "Instant Messaging/Presence Protocol Requirements", RFC 2779, February 2000. [IMP-SRV] Peterson, J., "Address Resolution for Instant Messaging and Presence", RFC 3861, August 2004. [SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782, February 2000. [TERMS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, "Extensible Markup Language (XML) 1.0 (2nd ed)", W3C REC-xml, October 2000, <http://www.w3.org/TR/REC-xml>. [XML-NAMES] Bray, T., Hollander, D., and A. Layman, "Namespaces in XML", W3C REC-xml-names, January 1999, <http://www.w3.org/TR/REC-xml-names>. [XMPP-CORE] Saint-Andre, P., "Extensible Messaging and Presence Protocol (XMPP): Core", RFC 3920, October 2004. [XMPP-E2E] Saint-Andre, P., "End-to-End Object Encryption in the Extensible Messaging and Presence Protocol (XMPP)", RFC 3923, October 2004.16.2. Informative References
[IMP-MODEL] Day, M., Rosenberg, J., and H. Sugano, "A Model for Presence and Instant Messaging", RFC 2778, February 2000. [IRC] Oikarinen, J. and D. Reed, "Internet Relay Chat Protocol", RFC 1459, May 1993. [JEP-0054] Saint-Andre, P., "vcard-temp", JSF JEP 0054, March 2003. [JEP-0077] Saint-Andre, P., "In-Band Registration", JSF JEP 0077, August 2004. [JEP-0078] Saint-Andre, P., "Non-SASL Authentication", JSF JEP 0078, July 2004. [JSF] Jabber Software Foundation, "Jabber Software Foundation", <http://www.jabber.org/>. [VCARD] Dawson, F. and T. Howes, "vCard MIME Directory Profile", RFC 2426, September 1998. [XML-REG] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004.
Appendix A. vCards
Sections 3.1.3 and 4.1.4 of [IMP-REQS] require that it be possible to retrieve out-of-band contact information for other users (e.g., telephone number or email address). An XML representation of the vCard specification defined in RFC 2426 [VCARD] is in common use within the Jabber community to provide such information but is out of scope for XMPP (documentation of this protocol is contained in [JEP-0054], published by the Jabber Software Foundation [JSF]).Appendix B. XML Schemas
The following XML schemas are descriptive, not normative. For schemas defining the core features of XMPP, refer to [XMPP-CORE].B.1 jabber:client
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='jabber:client' xmlns='jabber:client' elementFormDefault='qualified'> <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/> <xs:element name='message'> <xs:complexType> <xs:sequence> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element ref='subject'/> <xs:element ref='body'/> <xs:element ref='thread'/> </xs:choice> <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> <xs:element ref='error' minOccurs='0'/>
</xs:sequence> <xs:attribute name='from' type='xs:string' use='optional'/> <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/> <xs:attribute name='to' type='xs:string' use='optional'/> <xs:attribute name='type' use='optional' default='normal'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='chat'/> <xs:enumeration value='error'/> <xs:enumeration value='groupchat'/> <xs:enumeration value='headline'/> <xs:enumeration value='normal'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='body'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='subject'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='thread' type='xs:NMTOKEN'/> <xs:element name='presence'>
<xs:complexType> <xs:sequence> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element ref='show'/> <xs:element ref='status'/> <xs:element ref='priority'/> </xs:choice> <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> <xs:element ref='error' minOccurs='0'/> </xs:sequence> <xs:attribute name='from' type='xs:string' use='optional'/> <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/> <xs:attribute name='to' type='xs:string' use='optional'/> <xs:attribute name='type' use='optional'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='error'/> <xs:enumeration value='probe'/> <xs:enumeration value='subscribe'/> <xs:enumeration value='subscribed'/> <xs:enumeration value='unavailable'/> <xs:enumeration value='unsubscribe'/> <xs:enumeration value='unsubscribed'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='show'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='away'/> <xs:enumeration value='chat'/> <xs:enumeration value='dnd'/> <xs:enumeration value='xa'/> </xs:restriction> </xs:simpleType>
</xs:element> <xs:element name='status'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='priority' type='xs:byte'/> <xs:element name='iq'> <xs:complexType> <xs:sequence> <xs:any namespace='##other' minOccurs='0'/> <xs:element ref='error' minOccurs='0'/> </xs:sequence> <xs:attribute name='from' type='xs:string' use='optional'/> <xs:attribute name='id' type='xs:NMTOKEN' use='required'/> <xs:attribute name='to' type='xs:string' use='optional'/> <xs:attribute name='type' use='required'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='error'/> <xs:enumeration value='get'/> <xs:enumeration value='result'/> <xs:enumeration value='set'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='error'> <xs:complexType> <xs:sequence xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'>
<xs:group ref='err:stanzaErrorGroup'/> <xs:element ref='err:text' minOccurs='0'/> </xs:sequence> <xs:attribute name='code' type='xs:byte' use='optional'/> <xs:attribute name='type' use='required'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='auth'/> <xs:enumeration value='cancel'/> <xs:enumeration value='continue'/> <xs:enumeration value='modify'/> <xs:enumeration value='wait'/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>B.2 jabber:server
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='jabber:server' xmlns='jabber:server' elementFormDefault='qualified'> <xs:import namespace='urn:ietf:params:xml:ns:xmpp-stanzas'/> <xs:element name='message'> <xs:complexType> <xs:sequence> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element ref='subject'/> <xs:element ref='body'/> <xs:element ref='thread'/> </xs:choice> <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> <xs:element ref='error' minOccurs='0'/> </xs:sequence>
<xs:attribute name='from' type='xs:string' use='required'/> <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/> <xs:attribute name='to' type='xs:string' use='required'/> <xs:attribute name='type' use='optional' default='normal'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='chat'/> <xs:enumeration value='error'/> <xs:enumeration value='groupchat'/> <xs:enumeration value='headline'/> <xs:enumeration value='normal'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='body'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='subject'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='thread' type='xs:NMTOKEN'/> <xs:element name='presence'> <xs:complexType>
<xs:sequence> <xs:choice minOccurs='0' maxOccurs='unbounded'> <xs:element ref='show'/> <xs:element ref='status'/> <xs:element ref='priority'/> </xs:choice> <xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> <xs:element ref='error' minOccurs='0'/> </xs:sequence> <xs:attribute name='from' type='xs:string' use='required'/> <xs:attribute name='id' type='xs:NMTOKEN' use='optional'/> <xs:attribute name='to' type='xs:string' use='required'/> <xs:attribute name='type' use='optional'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='error'/> <xs:enumeration value='probe'/> <xs:enumeration value='subscribe'/> <xs:enumeration value='subscribed'/> <xs:enumeration value='unavailable'/> <xs:enumeration value='unsubscribe'/> <xs:enumeration value='unsubscribed'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='show'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='away'/> <xs:enumeration value='chat'/> <xs:enumeration value='dnd'/> <xs:enumeration value='xa'/> </xs:restriction> </xs:simpleType> </xs:element>
<xs:element name='status'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:string'> <xs:attribute ref='xml:lang' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='priority' type='xs:byte'/> <xs:element name='iq'> <xs:complexType> <xs:sequence> <xs:any namespace='##other' minOccurs='0'/> <xs:element ref='error' minOccurs='0'/> </xs:sequence> <xs:attribute name='from' type='xs:string' use='required'/> <xs:attribute name='id' type='xs:NMTOKEN' use='required'/> <xs:attribute name='to' type='xs:string' use='required'/> <xs:attribute name='type' use='required'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='error'/> <xs:enumeration value='get'/> <xs:enumeration value='result'/> <xs:enumeration value='set'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute ref='xml:lang' use='optional'/> </xs:complexType> </xs:element> <xs:element name='error'> <xs:complexType> <xs:sequence xmlns:err='urn:ietf:params:xml:ns:xmpp-stanzas'> <xs:group ref='err:stanzaErrorGroup'/> <xs:element ref='err:text'
minOccurs='0'/> </xs:sequence> <xs:attribute name='code' type='xs:byte' use='optional'/> <xs:attribute name='type' use='required'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='auth'/> <xs:enumeration value='cancel'/> <xs:enumeration value='continue'/> <xs:enumeration value='modify'/> <xs:enumeration value='wait'/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>B.3 session
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:ietf:params:xml:ns:xmpp-session' xmlns='urn:ietf:params:xml:ns:xmpp-session' elementFormDefault='qualified'> <xs:element name='session' type='empty'/> <xs:simpleType name='empty'> <xs:restriction base='xs:string'> <xs:enumeration value=''/> </xs:restriction> </xs:simpleType> </xs:schema>B.4 jabber:iq:privacy
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='jabber:iq:privacy'
xmlns='jabber:iq:privacy' elementFormDefault='qualified'> <xs:element name='query'> <xs:complexType> <xs:sequence> <xs:element ref='active' minOccurs='0'/> <xs:element ref='default' minOccurs='0'/> <xs:element ref='list' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name='active'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:NMTOKEN'> <xs:attribute name='name' type='xs:string' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='default'> <xs:complexType> <xs:simpleContent> <xs:extension base='xs:NMTOKEN'> <xs:attribute name='name' type='xs:string' use='optional'/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name='list'> <xs:complexType> <xs:sequence> <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence>
<xs:attribute name='name' type='xs:string' use='required'/> </xs:complexType> </xs:element> <xs:element name='item'> <xs:complexType> <xs:sequence> <xs:element name='iq' minOccurs='0' type='empty'/> <xs:element name='message' minOccurs='0' type='empty'/> <xs:element name='presence-in' minOccurs='0' type='empty'/> <xs:element name='presence-out' minOccurs='0' type='empty'/> </xs:sequence> <xs:attribute name='action' use='required'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='allow'/> <xs:enumeration value='deny'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name='order' type='xs:unsignedInt' use='required'/> <xs:attribute name='type' use='optional'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='group'/> <xs:enumeration value='jid'/> <xs:enumeration value='subscription'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name='value' type='xs:string' use='optional'/> </xs:complexType> </xs:element>
<xs:simpleType name='empty'> <xs:restriction base='xs:string'> <xs:enumeration value=''/> </xs:restriction> </xs:simpleType> </xs:schema>B.5 jabber:iq:roster
<?xml version='1.0' encoding='UTF-8'?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='jabber:iq:roster' xmlns='jabber:iq:roster' elementFormDefault='qualified'> <xs:element name='query'> <xs:complexType> <xs:sequence> <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name='item'> <xs:complexType> <xs:sequence> <xs:element ref='group' minOccurs='0' maxOccurs='unbounded'/> </xs:sequence> <xs:attribute name='ask' use='optional'> <xs:simpleType> <xs:restriction base='xs:NCName'> <xs:enumeration value='subscribe'/> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name='jid' type='xs:string' use='required'/> <xs:attribute name='name' type='xs:string' use='optional'/> <xs:attribute name='subscription' use='optional'> <xs:simpleType> <xs:restriction base='xs:NCName'>
<xs:enumeration value='both'/> <xs:enumeration value='from'/> <xs:enumeration value='none'/> <xs:enumeration value='remove'/> <xs:enumeration value='to'/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name='group' type='xs:string'/> </xs:schema>Appendix C. Differences Between Jabber IM/Presence Protocols and XMPP
This section is non-normative. XMPP has been adapted from the protocols originally developed in the Jabber open-source community, which can be thought of as "XMPP 0.9". Because there exists a large installed base of Jabber implementations and deployments, it may be helpful to specify the key differences between the relevant Jabber protocols and XMPP in order to expedite and encourage upgrades of those implementations and deployments to XMPP. This section summarizes the differences that relate specifically to instant messaging and presence applications, while the corresponding section of [XMPP-CORE] summarizes the differences that relate to all XMPP applications.C.1 Session Establishment
The client-to-server authentication protocol developed in the Jabber community assumed that every client is an IM client and therefore initiated an IM session upon successful authentication and resource binding, which are performed simultaneously (documentation of this protocol is contained in [JEP-0078], published by the Jabber Software Foundation [JSF]). XMPP maintains a stricter separation between core functionality and IM functionality; therefore, an IM session is not created until the client specifically requests one using the protocol defined under Session Establishment (Section 3).
C.2 Privacy Lists
The Jabber community began to define a protocol for communications blocking (privacy lists) in late 2001, but that effort was deprecated once the XMPP Working Group was formed. Therefore the protocol defined under Blocking Communication (Section 10) is the only such protocol defined for use in the Jabber community.Contributors
Most of the core aspects of the Extensible Messaging and Presence Protocol were developed originally within the Jabber open-source community in 1999. This community was founded by Jeremie Miller, who released source code for the initial version of the jabberd server in January 1999. Major early contributors to the base protocol also included Ryan Eatmon, Peter Millard, Thomas Muldowney, and Dave Smith. Work specific to instant messaging and presence by the XMPP Working Group has concentrated especially on IM session establishment and communication blocking (privacy lists); the session establishment protocol was mainly developed by Rob Norris and Joe Hildebrand, and the privacy lists protocol was originally contributed by Peter Millard.Acknowledgements
Thanks are due to a number of individuals in addition to the contributors listed. Although it is difficult to provide a complete list, the following individuals were particularly helpful in defining the protocols or in commenting on the specifications in this memo: Thomas Charron, Richard Dobson, Schuyler Heath, Jonathan Hogg, Craig Kaes, Jacek Konieczny, Lisa Dusseault, Alexey Melnikov, Keith Minkler, Julian Missig, Pete Resnick, Marshall Rose, Jean-Louis Seguineau, Alexey Shchepin, Iain Shigeoka, and David Waite. Thanks also to members of the XMPP Working Group and the IETF community for comments and feedback provided throughout the life of this memo.Author's Address
Peter Saint-Andre (editor) Jabber Software Foundation EMail: stpeter@jabber.org
Full Copyright Statement Copyright (C) The Internet Society (2004). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intellectual Property The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the IETF's procedures with respect to rights in IETF Documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr. The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf- ipr@ietf.org. Acknowledgement Funding for the RFC Editor function is currently provided by the Internet Society.