可扩展的消息和出席信息协议 (XMPP): 核心协议 关于本文的说明
本文为互联网社区定义了一个互联网标准跟踪协议,并且申请讨论协议和提出了改进的建议。请参照“互联网官方协议标准”的最新版本(STD 1)获得这个协议的标准化进程和状态。本文可以不受限制的分发。 版权声明
本文版权属于互联网社区 (C) The Internet Society (2004). 摘要
本文定义了可扩展消息和出席信息协议(XMPP)的核心功能,这个协议采用XML流实现在任意两个网络终端接近实时的交换结构化信息。XMPP提供一个通用的可扩展的框架来交换XML数据,它主要用来建立即时消息和出席信息应用以实现 RFC 2779 的需求。
目录
1. 绪论
2. 通用的架构 3. 地址空间 4. XML流
5. TLS的使用 6. SASL的使用 7. 资源绑定 8. 服务器回拨 9. XML节
10. 服务器处理XML节的规则 11. XMPP中的XML用法 12. 核心的兼容性要求 13. 国际化事项 14. 安全性事项 15. IANA事项 16. 参考
1. 绪论
1.1. 概览
XMPP是一个开放式的XML协议,设计用于准实时消息和出席信息以及请求-响应服务。其基本的语法和语义最初主要是由Jabber开放源代码社区于1999年开发的。2002年,XMPP工作组被授权接手开发和改编Jabber协议以适应IETF的消息和出席信息技术。作为XMPP工作组的成果,本文定义了 XMPP 1.0 的核心功能;在 RFC 2779 [IMP-REQS] 中指定的提供即时消息和出席信息功能的扩展,定义在 XMPP-IM 协议 [the Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence] 中。
1.2. 术语
本文中大写的关键字 \"MUST\\"MUST NOT\\"REQUIRED\\"SHALL\\"SHALL NOT\\"SHOULD\符合 BCP 14, RFC 2119 [TERMS].
2. 通用的架构
2.1. 概览
尽管XMPP没有结合任何特定的网络结构,通常认为它是 客户-服务器 架构的一种实现,在这里客户端用XMPP的方式访问服务器采用的是TCP连接,服务器之间的通信也是TCP连接。
以下是这一架构的抽象的示意图 (这里 \"-\" 表示使用 XMPP 通讯, \"=\" 表示可使用任何协议通讯)。 C1----S1---S2---C3 |
C2----+---G1===FN1===FC1 符号代表的意思如下:
C1, C2, C3 = XMPP 客户端 S1, S2 = XMPP 服务器
G1 = 一个XMPP和外部(非XMPP)消息网络之间进行“翻译”的网关 FN1 = 一个外部消息网络
FC1 = 外部消息网络上的一个客户端
2.2. 服务器
服务器充当XMPP通信的一个智能抽象层,它主要负责:
管理发出的连接或其他实体的会话,在XML流(第四章)的表单中接收和发送给授权的客户端,服务器和其他实体。
用XML流通过实体转发特定地址的XML消息(第九章)
大部分 XMPP 兼容的服务器也负责存储客户端使用的数据 (比如基于XMPP应用的联系人名单); 在这种情况下, XML 数据直接由服务器代替客户端处理而不需要转发到其他实体。
2.3. 客户端
大部分客户端通过 TCP 连接直接连到服务器,并通过XMPP获得由服务器和任何相关的服务所提供的全部功能。多个不同资源(比如不同的设备和地点)的客户端可以同时登陆并且并发的连接到一个服务器,每个不同资源的客户端通过XMPP地址的资源标识符来区分(比如 2.4. 网关 网关是一个特殊用途的服务器端的服务,主要功能是把 XMPP 翻译成外部(非XMPP)消息系统,并把返回的消息翻译成 XMPP 。例如到 email(参见 [SMTP] ),IRC(参见 [IRC] ),SIMPLE(参见 [SIMPLE] ),SMS 的网关;还有和别的消息服务的网关,比如AIM,ICQ,MSN Messenger,Yahoo! Instant Messenger。网关和服务器之间的通信,网关和外部消息系统的通信,不在本文描述范围之内。 2.5. 网络 因为每个服务器都是由一个网络地址来标识的并且服务器之间的通信是 客户-服务器 协议的直接扩展,实际上整个系统是由很多互通的服务器构成的。例如, 3. 地址空间 3.1. 概览 一个实体可以是任何一个被认为是一个网络端点的东西(例如网络上的一个 ID ),而且它是通过XMPP进行通信的。所有这些实体都有一个具有唯一性的地址,并符合 RFC 2396 [URI]规范要求的格式。由于历史原因,一个 XMPP 实体的地址被称为 Jabber Identifier 或 JID 。一个合法的 JID 包括一组排列好的元素,包括域名(domain identifier),节点名(node identifier),和资源名(resource identifier)。 JID的语法定义,使用 [ABNF] 中的 Augmented Backus-Naur 格式。(IPv4 地址和 IPv6地址规则在 附录B 中的 [IPv6] 中定义;确定节点规则的合法字符顺序由 附录A 的 [STRINGPREP] 的 Nodeprep 部分来定义;确定资源规则的合法字符顺序由 附录B 的 [STRINGPREP] 的Resourceprep 部分来定义;子域名规则参考 [IDNA] 中关于国际域名标签的描述。)。 jid = [ node \"@\" ] domain [ \"/\" resource ] domain = fqdn / address-literal fqdn = (sub-domain 1*(\".\" sub-domain)) sub-domain = (internationalized domain label) address-literal = IPv4address / IPv6address 所有 JID 都是基于上述的结构。类似 一个 JID 的每个合法部分(节点名,域名,资源名)的长度不能(MUST NOT)超过 1023 字节。也就是整体长度(包括 '@' 和 '/' )不能超过 3071 字节。 3.2. 域名 域名是一个主要的ID并且是 JID 中唯一必需(REQUIRED)的元素(一个纯粹的域名也是一个合法的 JID)。它通常代表网络的网关或者“主”服务器,其他实体通过连接它来实现 XML 转发和数据管理功能。然而,由一个域名标识引用的实体,并非总是一个服务器,它也可能是一个服务器的子域地址,提供额外的功能(比如多用户聊天服务,用户目录,或一个到外部消息系统的网关)。 每个服务器或者服务的域名,可以(MAY)是一个 IP 地址,但应该(SHOULD)是一个完全合法的域名(参见 [DNS]).一个域名ID必须(MUST)是 [IANA] 里定义的“国际化域名”,并且按 [STRINGPREP]中的 [NAMEPREP] profile进行成 功的字符转换。在比较两个域名ID之前,服务器必须(MUST),客户端应该(SHOULD)首先按照 Nameprep profile(定义在[IANA]中) 来转换每个域名的字符。 3.3. 节点名 节点名是一个可选(OPTIONAL)的第二 ID,放在域名之前并用符号\"@\"分开.它通常表示一个向服务器或网关请求和使用网络服务的实体(比如一个客户端),当然它也能够表示其他的实体(比如在多用户聊天系统中的一个房间). 节点名所代表的实体,它的地址依赖于一个特定的域名;在 XMPP 的即时消息和出席信息应用系统中,这个地址是“纯 JID” 一个节点名必须按 [STRINGPREP] 中的 Nodeprep profile 进行成功的字符转换。在比较两个节点ID之前,服务器必须(MUST),客户端应该(SHOULD)首先按 Nodeprep profile 转换每个ID的字符。 3.4. 资源名 资源名是一个可选的第三 ID,它放在域名的后面并由符号\"/\"分开。资源名可以跟在 一个资源名必须(MUST)按 [STRINGPREP] 中的 Resourceprep profile 进行成功的格式化。在比较两个资源ID之前,服务器必须(MUST),客户端应该(SHOULD)首先按 Resourceprep profile 转换每个ID的字符。 3.5. 地址的确认 在 SASL (见第六章)握手之后(如果必要的话,也在资源绑定(见第七章)之后),正在接收流信息的实体必须(MUST)确认初始实体的 ID 。 对于服务器间的通信,在 SASL 握手时,如果没有指明授权的ID,这个初始的实体应该(SHOULD)是经过认证实体(参见 简单认证和安全层协议 [SASL] 中的定义)授权的ID(见第六章)。 对于客户端和服务器的通信,在 SASL 握手时,如果没有指明授权的ID,“纯 JID” ( 义)授权的ID,“全 JID” ( 4. XML流 4.1. 概览 两个基本概念,XML流和XML节,使得在出席信息已知的实体之间,异步交换低负载的结构化信息成为可能。这两个术语定义如下: XML流的定义:一个XML流是一个容器,包含了两个实体之间通过网络交换的XML元素。一个XML流是由一个XML打开标签 XML节的定义: 一个XML节是一个实体通过 XML 流向另一个实体发送的结构化信息中的一个离散的语义单位。一个XML直接存在于根元素 设想一个客户端和服务器会话的例子。为了连接一个服务器,一个客户端必须(MUST)发送一个打开标签 作为另一个选择,可能由服务器关闭这个流)。然后,客户端和服务器都应该(SHOULD)彻底地终止这个连接(通常是一个TCP连接)。 那些习惯认为XML是一个以文本为中心风格的人可能希望看看一个与服务器连接的客户端会话,包含两个 打开-关闭 XML文档:一个是从客户端到服务器,一个是从服务器到客户端。下图中,根元素 基本上,一个XML流相当于一个会话期间所有XML节的一个信封。我们可以简单的把它描述成下图: |---------------------------- | |---------------------------- | |---------------------------- | |---------------------------- | |---------------------------- | … |---------------------------- | |---------------------------- 4.2. 绑定到TCP 虽然有很多非必需的连接使用XML流来绑定[TCP]连接(两个实体可以通过别的机制来互联,比如通过[HTPP]连接轮询),本规范只定义了 XMPP 到 TCP 的绑定。在客户和服务器通信的过程中,服务器必须(MUST)允许客户端共享一个TCP连接来传输XML节,包括从客户端传到服务器和从服务器传到客户端。在服务器之间的通信过程中,服务器必须(MUST)用一个 TCP连接 向对方发送 XML节,另一个 TCP连接(由对方初始化)接收对方的XML节,一共两个 TCP连接。 4.3. 流的安全 在XMPP 1.0中,当XML流开始握手时,TLS应该(SHOULD)按 第五章:TLS的使用 中的规定来使用,SASL必须(MUST)按 第六章:SASL的使用 中的规定来使用。尽管可能(MAY)存在某种共有的机制能够保证双向安全,但是“初始化流”(比如从初始化实体发给接收实体的流)和“应答流”(比如从接收实体发给初始化实体的流)还是必须(MUST)安全的分开。在流被验证之间,实体不应该(SHOULD NOT) 尝试通过流发送XML节(第九章);就算它这样做了,对方的实体也不能(MUST NOT)接受这些XML节,并且应该(SHOULD)返回一个 4.4. 流属性 流元素的属性如下: to -- 'to'属性应该(SHOULD)仅用于从初始化实体到接收实体的 XML流的头,并且必须(MUST)设成为接收实体提供服务的主机名。注意,不应该(SHOULD NOT)有 'to'属性出现在接收实体应答初始实体的 XML流的头中;无论如何,如果'to'属性出现在应答流中,初始化实体应该(SHOULD)忽略它。 from -- 'from'属性应该(SHOULD)仅用于接收实体应答初始化实体的 XML流的头,并且必须(MUST)设成为接收实体(正在给初始实体授权)提供服务的主机名。注意,不应该(SHOULD NOT)有 'from'属性出现在初始实体发送给接收实体的 XML流的头中;无论如何,如果'from'属性出现在初始化流中,接收实体应该(SHOULD)忽略它。 id -- 'id'属性应该(SHOULD)仅用于接收实体发送给初始化实体 XML流的头。这个属性是一个由接收实体创建的具有唯一性的ID,一个初始实体和接收实体之间的会话ID,并且它在接收方的应用程序中(通常是一个服务器)必须(MUST)是唯一的。注意,这个流 ID 必须是足够安全的,所以它必须是不可预知的和不可重复的(参见 RANDOM 了解如何获得随机性以保证安全性)。不应该(SHOULD NOT)有 'id'属性出现在初始实体发送给接收实体的 XML流的头中;无论如何,如果'id'属性出现在初始化流中,接收实体应该(SHOULD)忽略它。 xml:lang -- 'xml:lang'属性(定义在[XML]中的第二章第十二节)应该(SHOULD)包含在初始化实体发给接收实体的 XML流的头中,以指定在流中传输的可读XML字符所使用的缺省语言。如果这个属性出现了,接收实体应该(SHOULD)记住它的值,作为初始化流和应答流的缺省属性;如果这个属性没有出现,接收实体应该(SHOULD)用一个可配置的缺省值用于双方的流,这个属性值必须(MUST)在应答流的头中传达。对于所有初始化流中传输的节,如果初始实体没有提供'xml:lang'属性,接收实体应该(SHOULD)应用缺省值;如果初始实体提供了'xml:lang'属性,接收实体不能(MUST NOT)修改或删除它(参见第九章第一节第五小节 xml:lang)。'xml:lang'属性的值必须(MUST)是一个 NMTOKEN (定义在 [XML]的第二章第三节) 并且必须(MUST)遵守 RFC 3066 [LANGTAGS] 规定的格式。 version -- version属性(最少需要\"1.0\")为本规范中和流相关的协议提供了支持。关于这个属性的生成和处理的详细规则将在下文中定义。 我们现在可以总结如下: 初始化方发给接收方接收方发给初始化方to 接收方的主机名 忽略 from 忽略 接收方的主机名 id 忽略 会话键值 xml:lang缺省语言 缺省语言 version 支持XMPP 1.0 支持XMPP 1.0 4.4.1. 版本支持 在这里XMPP的版本是\"1.0\";准确地说,这里囊括了和流相关的所有协议(TLS的使用 (第五章),SASL的使用(第六章), 和流错误(第四章第七节)),以及三个定义好的XML节类型( 如果流和节的格式或者必需的处理方式有了显著的改变,以至于老版本的实体如果只是简单的忽略它不理解的节和属性并且继续像老版本一样的处理方式,会使得老版本的实体不能够和新版本的实体交互,只有在这时候主版本号才应该(SHOULD)增加。副版本号显示新的性能,它必须(MUST)被副版本号更低的实体忽略,但被高(副)版本号的实体用于了解信息。例如,一个副版本号显示处理某种新定义的\"type\"属性的值(用于message,presence或IQ节)的能力;副版本号高的实体将会了解到与之通信的对方不能够理解这个\"type\"属性的值,所以将不会发送它。 以下规则是用于'版本'属性在实现流的头信息时如何生成和处理: 1. 初始化实体必须(MUST)在初始化流的头信息中把'版本'的值设置成它所支持的最高版本。(比如,如果最高版本支持就是本规范,那么它必须(MUST)设置成\"1.0\"). 2. 接收实体必须(MUST)在应答流的头信息中把'版本'的值设置成初始化实体所提供的版本或它所支持的最高版本,取其中版本号较低的那一个。接收实体必须(MUST)把主版本号和副版本号作为数字来比较,而不是对\"主版本号.副版本号\"这个字符串进行比较. 3. 如果在应答流的头信息的版本号中至少有一个主版本号低于初始化流的头信息的版本号,并且如前所述,新版本的实体不能够和旧版本实体交互,初始化实体应该(SHUOULD)生成一个 4. 如果一个实体收到一个头信息中没有'version'属性的流,这个实体必须(MUST)把对方实体的'version'当成'0.0'并且在它发送的应答流的头中也不应该(SHOULD NOT)包含'version'属性. 4.5. 名字空间声明 流的元素必须(MUST)同时满足一个流名字空间声明和一个缺省名字空间声明(\"名字空间声明\"定义在 XML 名字空间定义 [XML-NAMES]中).关于流名字空间和缺省名字空间的详细信息,参考 名字空间的名字和前缀(第十一章第二节). 4.6. 流的特性 如果初始化的实体在初始化流的头信息中设置'version'属性的信息为\"1.0\收实体必须(MUST)向初始化实体发送一个 4.7. 流错误 流的根元素可以(MAY)包含一个 4.7.1. 规则 以下规则适用于流级别的错误: 它假定所有流级别的错误都是不可恢复的;所以,如果一个错误发生在流级别,发现这个错误的实体必须(MUST)发送一个流错误信息给另一个实体,发送一个关闭标签 ,并终止这个流所在的TCP连接。 如果这个错误发生在流刚开始设置的时候,接收实体必须(MUST)仍然发送一个开放标签 4.7.2. 语法 流错误的语法如下: [OPTIONAL application-specific condition element] 必须(MUST)包含一个子元素以描述一个下文定义的节错误条件;这个子元素必须(MUST)符合'urn:ietf:params:xml:ns:xmpp-streams'名字空间. 可以(MAY)包含一个 可以(MAY)包含一个子元素用于描述一个明确的应用程序错误条件;这个元素必须(MUST)符合一个应用程序定义的名字空间,并且它的结构是由那个名字空间定义的。 4.7.3. 已定义的条件 以下流级别的错误条件是已定义的: \"http://etherx.jabber.org/streams\" 不相同或回拨名字空间和 \"jabber:server:dialback\" 不相同.(参考 XML Namespace Names and Prefixes (第十一章第二节)). 4.7.4. 应用程序定义条件 大家知道,应用程序可以(MAY)在error元素中包含一个适当名字空间的子元素来提供一个应用程序定义流错误信息.\"应用程序定义\"元素应该(SHOULD)补充或甚至限定一个已定义的元素.所以 4.8. 简化的流示例 这里包含两个简化的例子,描述了基于流的客户端在服务器上的“会话”(这里\"C\"表示从客户端发给服务器,\"S\"表示从服务器发给客户端);这些例子只是用于举例说明原理. 一个基本的 \"会话\": C: xmlns:stream='http://etherx.jabber.org/streams' version='1.0'> … encryption, authentication, and resource binding ... C: C: S: S: C: xmlns:stream='http://etherx.jabber.org/streams' version='1.0'> … encryption, authentication, and resource binding ... C: S: 5. TLS 的使用 5.1. 概览 XMPP包含的一个保证流安全的方法来防止篡改和偷听.这个传输层安全协议 [TLS]的频道加密方法, 模拟了类似的其他\"STARTTLS\"(见RFC 2595 [USINGTLS])的扩展,如 IMAP [IMAP], POP3 [POP3], and ACAP [ACAP].\"STARTTLS\"的扩展名字空间是'urn:ietf:params:xml:ns:xmpp-tls'. 一个给定域的管理员可以(MAY)要求客户端和服务器通信以及服务器之间通信时使用TLS,或者两者都要求。客户端应该(SHOULD)在尝试完成 SASL (第六章)握手之前使用 TLS,服务器应该(SHOULD)在两个域之间使用 TLS 以保证服务器间通信的安全。 以下是使用规则: 1. 一个遵守本协议的初始化实体必须(MUST)在初始化流的头信息中包含一个'version'属性并把值设为“1.0”。 2. 如果TLS握手发生在两个服务器之间,除非服务器声称的DNS主机名已经被解析(见第十四章第四节 Server-to-Server Communications),通信不能(MUST NOT)继续进行。 3. 当一个遵守本协议的接收实体接收了一个初始化流(它的头信息中包含一个'version'属性并且值设为“1.0”),在发送应答流的的头信息(其中包含版本标记)之后,它必须发送(MUST) 5. TLS握手期间,一个实体不能(MUST NOT)在流的根元素中发送任何空格符号作为元素的分隔符(在下面的TLS示例中的任何空格符都仅仅是为了便于阅读);这个禁令用来帮助确保安全层字节精度。 6. 接收实体必须(MUST)在发送 7. 初始化实体必须(MUST)验证接收实体出示的证书;关于证书验证流程参见Certificate Validation ( 第十四章第二节)。 8. ??证书必须(MUST)检查初始化实体(比如一个用户)提供的主机名;而不是通过DNS系统解析出来的主机名;例如,如果用户指定一个主机名\"example.com\"而一个DNS SRV [SRV]查询返回\"im.example.com\",证书必须(MUST)检查\"example.com\".如果任何种类的XMPP实体(例如客户端或服务器)的JID出现在一个证书里,它必须(MUST)表现为一个别名 实体里面的UTF8字符串,存在于subjectAltName之中。如何使用 [ASN.1] 对象标识符 \"id-on-xmppAddr\" 定义在本文的第五章第一节第一小节。 9. 如果 TLS 握手成功了,接收实体必须(MUST) 丢弃TLS 生效之前从初始化实体得到的任何不可靠的信息. 10.如果 TLS 握手成功了,初始化实体必须(MUST) 丢弃TLS 生效之前从接收实体得到的任何不可靠的信息. 11.如果 TLS 握手成功了,接收实体不能(MUST NOT)在流重新开始的时候通过提供其他的流特性来向初始化实体提供 STARTTLS 扩展. 12.如果 TLS 握手成功了,初始化实体必须(MUST)继续进行SASL握手。 13.如果 TLS 握手失败了,接收实体必须(MUST)终止XML流和相应的TCP连接。 14.关于必须(MUST)支持的机制,参照 Mandatory-to-Implement Technologies (第十四章第七节) 。 5.1.1. 用于 XMPP 地址的 ASN.1 对象标识符 上文提到的[ASN.1] 对象标识符 \"id-on-xmppAddr\"定义如下: id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) } id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 } XmppAddr ::= UTF8String 对象标识符也可以(MAY)使用点分隔的格式,如 \"1.3.6.1.5.5.7.8.5\". 5.2. 叙述 当一个初始化实体用TLS保护一个和接收实体之间的流,其步骤如下: 1. 初始化实体打开一个TCP连接,发送一个打开的XML流头信息(其'version'属性设置为\"1.0\")给接收实体以初始化一个流。 2. 接收实体打开一个TCP连接,发送一个XML流头信息(其'version'属性设置为\"1.0\")给初始化实体作为应答。 3. 接收实体向初始化实体提议STARTTLS范围(包括其他支持的流特性),如果TLS对于和接收实体交互是必需的,它应该(SHOULD)在 4. 初始化实体发出STARTTLS命令(例如, 一个符合 'urn:ietf:params:xml:ns:xmpp-tls'名字空间的 5. 接收实体必须(MUST)以'urn:ietf:params:xml:ns:xmpp-tls'名字空间中的 6. 初始化实体和接收实体尝试完成TLS握手。(要符合[TLS]规范) 7. 如果 TLS 握手不成功, 接收实体必须(MUST)终止 TCP 连接. 如果 TLS 握手成功, 初始化实体必须(MUST)发送给接收实体一个打开的XML流头信息来初始化一个新的流(先发送一个关闭标签是不必要的,因为接收实体和初始化实体必须(MUST)确保原来的流在TLS握手成功之后被关闭) 。 8. 在从初始化实体收到新的流头信息之后,接收实体必须(MUST)发送一个新的XML流头信息给初始化实体作为应答,其中应包含可用的特性但不包含STATRTTLS特性。 5.3. 客户端-服务器 示例 以下例子展示一个客户端使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的). 步骤 1: 客户端初始化流给服务器: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 2: 服务器发送一个流标签给客户端作为应答: xmlns:stream='http://etherx.jabber.org/streams' id='c2s_123' from='example.com' version='1.0'> 步骤 3: 服务器发送 STARTTLS 范围给客户端(包括验证机制和任何其他流特性): 步骤 4: 客户端发送 STARTTLS 命令给服务器: 步骤 5 (或者): 服务器通知客户端 TLS 握手失败并关闭流和TCP连接: 步骤 6: 客户端和服务器尝试通过已有的TCP连接完成 TLS 握手. 步骤 7: 如果 TLS 握手成功, 客户端初始化一个新的流给服务器: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 7 (或者): 如果 TLS 握手不成功, 服务器关闭 TCP 连接. 步骤 8: 服务器发送一个流头信息应答客户端,其中包括任何可用的流特性: xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'> 步骤 9: 客户端继续 SASL 握手 (第六章). 5.4. 服务器-服务器示例 以下例子展示两个服务器之间使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的). 步骤 1: Server1 初始化流给 Server2: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 2: Server2 发送一个流标签给 Server1 作为应答: xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_123' version='1.0'> 步骤 3: Server2 发送 STARTTLS 范围给 Server1 ,包括验证机制和任何其他流特性: 步骤 4: Server1 发送 STARTTLS 命令给 Server2: 步骤 6: Server1 和 Server2 尝试通过 TCP 完成 TLS 握手. 步骤 7: 如果 TLS 握手成功, Server1 初始化一个新的流给 Server2: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 7 (或者): 如果 TLS 握手不成功, Server2 关闭 TCP 连接. 步骤 8: Server2 发送一个包含任何可用流特性的流头信息给 Server1 : xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_234' version='1.0'> 步骤 9: Server1 继续进行 SASL 握手(第六章). 6. SASL 的使用 6.1. 概览 XMPP 有一个验证流的方法,即XMPP特定的SASL(简单验证和安全层)[SASL]。SASL提供了一个通用的方法为基于连接的协议增加验证支持,而XMPP使用了一个普通的XML名字空间来满足SASL的需要。 以下规则应用于: 1. 如果SASL协商发生在两台服务器之间,除非服务器宣称的DNS主机名得到解析,不能(MUST NOT)进行通信。(参见 服务器间的通信(第十四章第四节)). 2. 如果初始化实体有能力使用 SASL 协商, 它必须(MUST)在初始化流的头信息中包含一个值为\"1.0\"的属性'version'。 3. 如果接收实体有能力使用 SASL 协商, 它必须(MUST)在应答从初始化实体收到的打开流标签时(如果打开的流标签包含一个值为\"1.0\"的 'version'属性),通过'urn:ietf:params:xml:ns:xmpp-sasl'名字空间中的 5. 当SASL握手时,在XML元素中使用的任何 XML 字符数据必须被编码成 base64, 编码遵循 RFC 3548 第三章的规定。 6. ??如果一个 简单名字\"simple username\" 规范被选定的SASL机制所支持,(比如, 这被 DIGEST-MD5 和 CRAM-MD5 机制支持但不被 EXTERNAL 和 GSSAPI 机制支持), 验证的时候初始化实体应该(SHOULD)在服务器间通信时提供 简单名字 自身的发送域(IP地址或包含在一个域标识符中的域名全称),在客户端与服务器之间通信时提供注册用户名(包含在一个XMPP节点标识符中的用户或节点名)。 7. 如果初始化实体希望以另一个实体的身份出现并且SASL机制支持授权ID的传输,初始化实体在SASL握手时必须(MUST)提供一个授权ID。如果初始化实体不希望以另一个实体的身份出现,初始化实体在SASL握手时不能(MUST NOT)提供一个授权ID。在 [SASL] 的定义中,除非授权ID不同于从验证ID(详见[SASL])中得到的缺省的授权ID,初始化实体不能(MUST NOT)提供授权ID。如果提供了,这个授权ID的值必须(MUST)是 8. 在成功进行包括安全层的SASL握手之后,接收实体必须(MUST)丢弃任何从初始化实体得到的而不是从SASL协商本身获得的信息。 9. 在成功进行包括安全层的SASL握手之后,初始化实体必须(MUST)丢弃任何从接收实体得到的而不是从SASL协商本身获得的信息。 10.参看 强制执行的技术 (第十四章第七届) ,了解关于必须(MUST)支持的机制. 6.2. 叙述 一个初始化实体使用SASL和接收实体做验证的步骤如下: 1. 初始化实体请求SASL验证,它发送一个打开的XML流头信息给接收实体,其'version'属性的值为\"1.0\". 2. 在发送一个XML流头回复之后,接收实体声明一个可用的SASL验证机制清单;每个机制作为一个 'urn:ietf:params:xml:ns:xmpp-sasl')中,而 3. 初始化实体发送一个符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空间的 'urn:ietf:params:xml:ns:xmpp-sasl'名字空间的 5. 初始化实体向接收实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空间的 2. 接收实体向初始化实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空间的 许一个可配置的但是合理的重试次数(至少2次), 然后它必须(MUST)终止TCP连接;这使得初始化实体(如一个最终用户客户端)能够容忍可能不正确的credentials(如密码输入错误)而不用强制重新连接。 3. 接收实体向初始化实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空间的 6.3. SASL 定义 [SASL]的必要条件要求通过协议定义来提供以下信息: service name(服务名): \"xmpp\" initiation sequence(开始序列): 当初始化实体提供一个打开的XML流头信息并且接收实体善意回应之后,接收实体提供一个可接受的验证方法清单。初始化实体从这个清单中选择一个方法,把它作为 security layer negotiation(安全层协商): 安全层在接收实体发送 use of the authorization identity(授权ID的使用): 授权ID可在xmpp中用于表示一个客户端的非缺省的 6.4. SASL 错误 SASL相关的错误条件定义如下: 6.5. 客户端-服务器 示例 以下例子展示了一个客户端和一个服务器使用SASL作验证的数据流,通常是在成功的TLS握手之后(注意:以下显示的替代步骤仅用于举例说明协议的失败情形;它们不够详尽也不需要由例子中的数据传送来触发)。 步骤 1: 客户端初始化流给服务器: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 2: 服务器向客户端发送流标签作为应答: xmlns:stream='http://etherx.jabber.org/streams' id='c2s_234' from='example.com' version='1.0'> 步骤 3: 服务器通知客户端可用的验证机制: 步骤 4: 客户端选择一个验证机制: 步骤 5: 服务器发送一个 [BASE64] 编码的挑战给客户端: cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg== 解码后的挑战信息是: realm=\"somerealm\ qop=\"auth\步骤 5 (替代): 服务器返回一个错误给客户端: 步骤 6: 客户端发送一个[BASE64]编码的回应这个挑战: dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo YXJzZXQ9dXRmLTgK 解码后的回应信息是: username=\"somenode\ nonce=\"OA6MG9tEQGm2hh\ nc=00000001,qop=auth,digest-uri=\"xmpp/example.com\ response=d388dad90d4bbd760a152321f2143af7,charset=utf-8 步骤 7: 服务器发送另一个[BASE64]编码的挑战给客户端: cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo= rspauth=ea40f60335c427b5527b84dbabcdfffd 步骤 7 (或者): 服务器返回一个错误给客户端: 步骤 8: 客户端应答这个挑战: 步骤 10: 客户端发起一个新的流给服务器: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 11: 服务器发送一个流头信息回应客户端,并附上任何可用的特性(或空的features元素): xmlns:stream='http://etherx.jabber.org/streams' id='c2s_345' from='example.com' version='1.0'> 6.6. 服务器-服务器 示例 以下例子展示了一个服务器和另一个服务器使用SASL作验证的数据流,通常是在成功的TLS握手之后(注意:以下显示的替代步骤仅用于举例说明协议的失败情形;它们不够详尽也不需要由例子中的数据传送来触发)。 步骤 1: 服务器1 发起一个流给 服务器2 : xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> 步骤 2: 服务器2 回应一个流标签给 服务器1: xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_234' version='1.0'> 步骤 3: 服务器2 通知 服务器1 可用的验证机制: 步骤 4: 服务器1 选择一个验证机制: 步骤 5: 服务器2 发送一个[BASE64]编码的挑战给 服务器1: cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9 ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz realm=\"somerealm\ qop=\"auth\步骤 5 (替代): 服务器2 返回一个错误给 服务器1: 步骤 6: 服务器1 发送一个[BASE64]编码的回应这个挑战: dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3 LGNoYXJzZXQ9dXRmLTgK 解码后的应答信息是: username=\"example.org\ nonce=\"OA6MG9tEQGm2hh\ nc=00000001,qop=auth,digest-uri=\"xmpp/example.org\ response=d388dad90d4bbd760a152321f2143af7,charset=utf-8 步骤 7: 服务器2 发送另外一个[BASE64]编码的挑战给 服务器1: cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo= 解码后的挑战信息是: rspauth=ea40f60335c427b5527b84dbabcdfffd 步骤 7 (或者): 服务器2 返回一个错误给 服务器1: 步骤 8: 服务器1 回应挑战: 步骤 10: 服务器1 重新发起一个新的流给 服务器2: xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'> Step 11: 服务器2 发送一个流头信息应答 服务器1 ,并附上任何可用的特性(或一个空的features元素).: xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_345' version='1.0'> 7. 资源绑定 在和接收实体完成 SASL 协商(第六章)之后,初始化实体可能(MAY)想要或者需要绑定一个特定的资源到流上.通常这仅适用于客户端: 为了满足本文定义的寻址格式(第三章)和节传输规则(第十章),客户端 接收到一个成功的SASL握手之后,客户端必须(MUST)发送一个新的流头信息给服务器,服务器必须(MUST)返回一个包含可用的流特性列表的头信息。特别是,在成功的SASL握手之后如果服务器需要客户端绑定一个资源,它必须(MUST) 在握手成功之后(而不是之前)发送给客户端的应答流特性中包含一个空的符合'urn:ietf:params:xml:ns:xmpp-bind'名字空间的 xmlns:stream='http://etherx.jabber.org/streams' id='c2s_345' from='example.com' version='1.0'> 收到要求资源绑定的通知后,客户端必须(MUST)通过发送一个符合 'urn:ietf:params:xml:ns:xmpp-bind'名字空间的“set”类型的IQ节(参见 IQ 语义 (第九章第二节第三小节))给服务器来绑定一个资源到流中。 如果客户端端希望允许服务器给自己生成一个资源ID,它可以发送一个包含空的 一个支持资源绑定的服务器必须(MUST)自动生成一个资源ID给客户端。一个由服务器生成的资源ID对于那个 一旦服务器为客户端生成了一个资源ID或接受了客户端自己提供的资源ID,它必须(MUST)返回一个“result”类型的 IQ 节给客户端,这个节必须包含一个指明全JID的 一个服务器应该(SHOULD)接受客户端提供的资源ID,但是可以(MAY)用服务器生成的资源ID覆盖它;在这种情况下,服务器不应该(SHOULD NOT)返回一个错误信息 (如 当一个客户端自行提供资源ID时,可能发生以下的节错误(参见 Stanza Errors (第九章第三节)): 提供的资源ID服务器无法处理,因为不符合资源字符规范Resourceprep(附录B)。 客户端不被允许绑定一个资源(如节点或用户已经达到允许连接的资源数限制)。 提供的资源ID已经被使用但是服务器不允许以同一个资源ID绑定多个连接。 协议对这些错误条件规定如下. 资源ID不能处理: 客户端不允许绑定一个资源: 资源ID已经在使用: 如果,在完成资源绑定步骤之前,客户端试图以符合 'urn:ietf:params:xml:ns:xmpp-bind'名字空间的 8. 服务器回拨 8.1. 概览 Jabber协议接受的来自XMPP的包括“服务器回拨”方法,用于防治域名欺骗,使得欺骗XML节更为困难。服务器回拨不是一个安全机制,并且它的服务器身份认证结果很弱(参见服务器之间的通信(第十四章第四节)中关于这个方法的安全特性)。需要健壮的安全性的域名应该(SHOULD)使用TLS或SASL;细节参见服务器间的通信(第十四章第四节)。如果SASL用于服务器间通信,回拨就不需要用了(SHOULD NOT)。本文描述回拨的好处在于向后兼容现存的实现和部署。 服务器回拨方法由现存的DNS系统的存在而成为可能,因为一个服务器(通常)可以查询给定域的授权服务器。由于服务器回拨依赖于DNS,除非服务器宣称的DNS主机得到解析,域之间的通信无法进行(参见服务器间的通信(第十四章第四节))。 服务器回拨是单向性的,可在单一方向上对一个流进行(微弱的)身份验证.因为服务器回拨不是一个验证机制,通过回拨获得相互的认证是不可能的.因此,为了使得服务器之间的双向通信,服务器回拨必须(MUST)在每个方向上完成。 在服务器回拨中生成和检验密钥的方法必须(MUST)考虑计算被使用的主机名,由接收服务器生成的流ID,和只有授权服务器网络才知道的秘密。在服务器回拨中流ID是安全性的关键所以必须(MUST)是不可预知的和不可重复的(见[RANDOM]中关于使用随机数获得安全性的建议). 任何回拨协商过程中发生的错误必须(MUST)被当成一个流错误,并导致流以及相关的TCP连接的终止.可能发生的错误情况协议中描述如下. 以下术语适用: 发起服务器 -- 尝试在两个域之间建立连接的那个服务器. 接收服务器 -- 尝试验证发起服务器声称的域名的那台服务器. 授权(权威?Authoritative) 服务器 -- 回答发起服务器声称的DNS主机名的服务器;基本上这应该是那台发起服务器,但是它也可能是一个在发起服务器网络中独立的服务器。 8.2. 事件顺序 以下是回拨中的事件顺序的简介: 1. 发起服务器和接收服务器建立一个连接。 2. 发起服务器通过到连接发送一个 'key' 值给接收服务期。 3. 接收服务器建立一个连接到授权服务器。 4. 接收服务器发送一个相同的 'key' 值给授权服务器。 5. 授权服务器回答这个key是否合法。 6. 接收服务器通知发起服务器是否被验证通过。 我们用用以下图形展示这个事件流程(见附件s2s.png): 8.3. 协议 服务器之间互动的细节协议如下: 1. 发起服务器和接受服务器建立TCP连接. 2. 发起服务器发送流头信息给接收服务器: xmlns:db='jabber:server:dialback'> 注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 其中包含的 xmlns:db名字空间向接收服务器声明了发起服务器支持回拨. 如果名字空间不正确,接收实体必须(MUST)生成一个 3. 接收服务器应该(SHOULD)回送一个流头信息给发起服务器,为这次交互生成一个唯一性的ID : xmlns:db='jabber:server:dialback' id='457F9224A0...'> 注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 如果名字空间不正确,发起服务器必须生成一个 from='Originating Server'> 98AF014EDC0… 注意: 这个密钥不由接收服务器检查,因为接收服务器在会话之间(between sessions)不保存发起服务器的信息. 这个由发起服务器生成的密钥必须(MUST)是基于接收服务器在上一步骤中提供的ID值,以及发起服务器与授权服务器共享的安全机制生成的。 如果 'to' 地址的值和接收服务器知道的主机名不匹配,接收服务器必须(MUST)生成一个 6. 接收服务器发送一个流头信息给授权服务器: xmlns:db='jabber:server:dialback'> 注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 如果名字空间不正确,授权服务器必须生成一个 7. 授权服务器发送流头信息给接收服务器: xmlns:db='jabber:server:dialback' id='1251A342B...'> 注意: 如果名字空间不正确,接收服务器必须生成一个 8. 接收服务器发送一个密钥检查请求给授权服务器: 98AF014EDC0… 注意: 现在这里已经有了主机名,第三步中接收服务器发送给发起服务器的原始,第四步中发起服务器发送给接收服务器的密钥. 基于这些信息, 加上授权服务器网络共享的安全信息, 这个密钥被证实了.任何可用于验证的办法都可以(MAY)用于生成密钥. 如果 'to' 地址的值和授权服务器知道的主机名不匹配,授权服务器必须(MUST)生成一个 id='457F9224A0...'/> 或 id='457F9224A0...'/> 注意: 如果 ID 和第三步中接收服务器提供的不符,接收服务器必须(MUST)生成一个 10. 接收服务器通知发起服务器结果: 注意: 在这一个点上, 连接已经由 type='valid' 确认验证是通过了,还是没通过. 如果连接是非法的,接收服务器必须(MUST)终止XML流和相应的TCP连接. 如果连接是合法的, 数据可以从发起服务器发送由接收服务器读取;在此之前,所有发送给接收服务器的XML节应该(SHOULD)被丢弃. 进一步的结果是,接收服务器已经验证了发起服务器的ID,所以通过初始化流(\"initial stream\",例如从发起服务器到接收服务器的流)发起服务器可以发送,接收服务器可以接受XML节. 为了使用应答流(\"response stream\",例如从接收服务器到发起服务器的流)验证实体ID,回拨必须(MUST)在相对的两个方向上都完成. 在成功的回拨协商之后, 接收服务器应该(SHOULD)接受接下来发起服务器通过当前的合法连接发送的 即使回拨协商成功了, 服务器仍然必须(MUST)检查从其他服务器接收的所有XML节的'from'和'to'属性; 如果一个节不符合这些限定, 收到这些节的服务器必须(MUST)生成一个 9. XML节 在 TLS 协商(第五章) (如果想要), SASL 协商(第六章), 和资源绑定(第七章)(如果需要)之后, XML节就可以通过流发送了. 在'jabber:client'和 'jabber:server'名字空间中定义了三种XML节: 9.1. 通用属性 以下五种属性通用于 message, presence, 和 IQ 节: 9.1.1. to 'to' 属性表示节的预期接收者的JID. 在'jabber:client'名字空间中, 一个节应该(SHOULD)处理一个'to'属性, 尽管由服务器处理的从客户端发给服务器的节(如, 发送给服务器用于广播给其他实体的出席信息) 应该不(SHOULD NOT)处理'to'属性. 在'jabber:server'名字空间中, 一个节必须(MUST)处理一个'to'属性; 如果一个服务器收到一个不符合此限定的节, 它必须(MUST)生成一个 如果'to'属性的值非法或无法联络, 发现这个事实的实体(通常是发送者或接收者的服务器)必须(MUST)返回一个适当的错误给发送者, 错误节的'from'属性设置成非法节的提供的'to'属性的值. 9.1.2. from 'from' 属性表示发送者的 JID . 当一个服务器接收了一个符合'jabber:client'名字空间的合法流的XML节, 它必须(MUST)做以下步骤中的一步: 1. 验证客户端提供的'from'属性值就是那个相关实体连接的资源 2. 为生成这个节的已连接的资源增加一个'from'地址(由服务器决定是纯JID或全JID)(参见 地址的决定 Determination of Addresses (第三章第五节)) 如果一个客户端试图发送一个XML节,而它的'from'属性和这个实体已连接的资源不符, 服务器应该(SHOULD)返回一个 (SHOULD)返回一个 当一个服务器从服务器自身生成一个节用于一个已连接的客户端的信息发布(例如, 在服务器为客户端提供数据存储服务的情况下), 这个节必须(MUST) (1) 不包含 'from' 属性 或 (2) 包含一个'from'属性,它的值是这个账号的纯 JID ( 在'jabber:server'名字空间, 一个节必须(MUST)处理一个'from'属性; 如果一个服务器接收到一个不符合此限定的节, 它必须(MUST)生成一个 9.1.3. id 可选的'id' 属性可以(MAY)用于为节的内部跟踪发送实体,从IQ节 语义来讲,就是通过发送和接收这些节来跟踪“请求-应答”型的交互行为。这个可选的(OPTIONAL)'id'属性值在一个域或一个流中是全局唯一的。IQ节语义学中对此有附加限定;见IQ Semantics (第九章第二节第三小节)。 9.1.4. type 'type' 属性指明消息、出席信息或IQ节的意图或上下文的详细信息。'type'属性所允许的值依据节的类型是消息、出席信息还是IQ而有很大不同; 用于消息和出席信息节的值定义在即时消息和出席信息应用中,所以在XMPP-IM中定义,反之用于IQ节的值定义了在一个 请求-应答 的“会话”中IQ节的角色,所以定义在IQ语义学中(第九章第二节第三小节)。 所有三种节的通用'type'值是\"error\";见Stanza Errors (第九章第三节)。 9.1.5. xml:lang 如果一个节包含用于显示给人human user看的XML字符数据(在RFC 2277中有所解释[CHARSET],\"internationalization is for humans\"),这个节应该(SHOULD)处理一个'xml:lang'属性(定义在第二章第十二节[XML])。 'xml:lang'属性的值指明任何一个人类可读的XML字符数据的缺省语言, 它可以(MAY)被特定的子元素的'xml:lang'值重载。 如果一个节不处理一个 'xml:lang'属性,一个实现必须(MUST)认为缺省的语言就是流属性中定义的语言(第四章第四节). 'xml:lang'属性值必须(MUST)是一个 NMTOKEN 并且必须(MUST)遵守 RFC 3066 [LANGTAGS]中定义的格式. 9.2. 基本语义学 9.2.1. 消息语义学 9.2.2. 出席信息语义学 行实体应该(SHOULD)不带'to'属性发送一个出席信息,这时这个实体所连接的服务器应该(SHOULD)广播或多播(multiplex?)那个节给所有订阅的实体.无论如何,一个发行实体也可以(MAY)带'to'属性发送一个出席信息节,这时服务器应该(SHOULD)路由或递送这个节给预定的接收者.见 Server Rules for Handling XML Stanzas (第十章)的XML节相关的通用路由和递送规则,以及XMPP-IM中即时消息和出席信息应用中出席信息的特定规则. 9.2.3. IQ语义学 信息/查询(Info/Query),或曰IQ,是一个 请求-回应 机制,某些情况下类似[HTTP].IQ语义学使一个实体能够向另一个实体做出请求并做出应答. 请求和应答所包含的数据定义在IQ元素的一个直接的子元素的名字空间声明中, 并且由请求实体用'id'属性来跟踪这一交互行为. 因而,IQ交互伴随着一个结构化的数据交换的通用模式例如 get/result 或 set/result (尽管有时候会以一个错误信息应答某个请求): 以下是IQ的流程图,参见附件iq.png 为了强制执行这些语义学,要应用以下规则: 1. 对于IQ节来说'id'属性是必需的(REQUIRED). 2. 对于IQ节来说'type'属性是必需的(REQUIRED). 它的值必须(MUST)是以下之一: get -- 这个节是一个对信息或需求的请求. set -- 这个节提供需要的数据, 设置新的值, 或取代现有的值. result -- 这个节是一个对一个成功的 get 或 set 请求的应答. error -- 发生了一个错误,关于处理或递送上次发送的 get 或 set的(参见 节错误 Stanza Errors(第九章第三节)). 3. 一个接收到\"get\" 或 \"set\" 类型的IQ请求的实体必须(MUST)回复一个\"result\"或\"error\"类型的IQ应答(这个应答必须(MUST)保留相关请求的'id'属性). 4. 一个接收到\"result\"或\"error\"类型的IQ节的实体不能(MUST NOT)再发送更多的\"result\"或\"error\"类型的IQ应答; 无论如何, 如上所述, 请求实体可以(MAY)发送另一个请求(如, 一个\"set\"类型的IQ,通过get/result对提供查询(discovery)所需的信息). 5. 一个\"get\" 或 \"set\" 类型的IQ节必须(MUST)包含并只包含一个子元素指明特定请求或应答的语义. 6. 一个\"result\"类型的IQ节必须(MUST)包含零或一个子元素. 7. 一个\"error\"类型的IQ节应该(SHOULD)包含和\"get\"或\"set\"相关联的那个子元素并且必须(MUST)包含一个 9.3. 节错误 节相关的错误的处理方式类似流错误(第四章第七节). 无论如何, 不像流错误, 节错误是可恢复的;所以错误节包含了暗示原来的发送者可以采取什么行动来补救这个错误. 9.3.1. 规则 以下规则适用于节相关的错误: 接收或处理实体察觉到一个节相关的错误条件时应该(MUST)返回给发送实体一个同类型的节(消息,出席信息,或IQ),这个节的'type'属性值则设置为\"error\"(这里这样的节称之为\"error stanza\"). 生成一个错误节的实体应该(SHOULD)包含原来发送的XML,这样发送者可以检查它,并且如果必要,在尝试重新发送之前纠正它. 一个错误节必须(MUST)包含一个 接收到一个错误节的实体不能(MUST NOT)应答这个节更多的错误节; 这有助于防止死循环. 9.3.2. 语法 节相关错误的语法如下: [OPTIONAL application-specific condition element] stanza-kind 是 message, presence, 或 iq 中的一个. cancel -- 不重试(这个错误是不可恢复的) continue -- 继续进行(这个条件只是一个警告) modify -- 改变数据之后重试 auth -- 提供证书之后重试 wait -- 等待之后重试(错误是暂时的) 必须(MUST)包含一个子元素,符合以下定义的节错误条件之一;这个元素(MUST)符合'urn:ietf:params:xml:ns:xmpp-stanzas'名字空间. 可以(MAY)包含一个 'urn:ietf:params:xml:ns:xmpp-stanzas'名字空间并且应该(SHOULD)处理'xml:lang'属性. 可以(MAY)包含一个应用程序定义的错误条件子元素;这个元素必须(MUST)符合一个应用程序定义的名字空间,并且它的结构由这个名字空间定义. 最后,为了维护向后兼容性, 这个schema (定义在XMPP-IM)允许可选的在 9.3.3. 已定义的条件 以下条件定义用于节错误. 9.3.4. 应用程序定义条件 大家知道,一个应用程序可以(MAY)通过在错误元素里包含一个适当名字空间的字元素来提供应用程序定义的节错误信息. 应用程序定义的元素应该(SHOULD)补充或进一步限定一个已定义的元素. 因而, 10. 服务器处理XML节的规则 兼容的服务器实现必须(MUST)确保两个实体之间的XML节按次序处理. 在按次序处理的需求之外, 每个服务器实现将包含它自己的递送树\"delivery tree\"以处理它接收到的节.这个树决定一个节是否需要路由到其他域, 在内部处理, 还是递送到和一个已连接的节点相关的资源. 以下规则适用: 10.1. 没有'to'地址 如果这个节没有'to'属性, 服务器应该(SHOULD)为发送它的实体处理这个节. 因为所有从其他服务器收到的节必须(MUST)拥有'to'属性, 这个规则仅适用于从一个连接到这台服务器的已注册实体(如一个客户端)收到的节.如果这个服务器收到一个没有'to'属性的出席信息节, 服务器应该(SHOULD)向那些订阅了这个发送实体的出席信息的所有实体广播它, 如果可能的话(即时消息和出席信息应用程序中出席信息广播的语义定义在XMPP-IM). 如果服务器接收到一个类型为\"get\" 或 \"set\" 的没有'to'属性的节并且它理解这个节的名字空间下的内容, 它必须(MUST)为这个发送实体处理节(在这里\"process\"的含义是由相关的名字空间的语义所决定的)或返回一个错误给发送实体. 10.2. 外部域 如果'to'属性中的JID的域ID部分的主机名和服务器自身或其子域配置的主机名不匹配, 服务器应该(SHOULD)路由这个节到外部域(取决于本地服务规定或安全策略关于域间通信的规定).有两种可能的情况: - 一个服务器之间的流已经存在于两个域之间: 发送者的服务器通过这个已存在的流为这个外部域路由这个节到授权服务器 - 两个域之间不存在服务器间的流: 发送者服务器 (1) 解析这个外部域的主机名(定义在服务器间的通信Server-to-Server Communications (第十四章第四 节)), (2) 在两个域之间进行服务器到服务器的流协商(定义在 Use of TLS (第五章) 和 Use of SASL (第六章)), 然后 (3) 通过这个新建的流为外部域路由这个节到授权服务器 如果路由到接收者的服务器不成功, 发送者的服务器必须(MUST)返回一个错误给发送者; 如果接收者的服务器联系上了但是从接收者的服务器递送到接收者不成功, 接收者服务器必须(MUST)通过发送者的服务器返回一个错误给发送者. 10.3. 子域 如果'to'属性中的JID的域ID部分的主机名和服务器自身配置的主机名的一个子域名匹配,服务器必须(MUST)自己处理这个节或路由这个节到专门负责这个子域的特定服务(如果子域被配置了),或者返回一个错误给发送者(如果子域没有配置). 10.4. 纯粹的域或特定的资源 如果'to'属性中的JID的域ID部分的主机名和服务器自身配置的主机名本身匹配,并且'to'属性中的JID类型是 10.5. 同一域中的节点 如果'to'属性中的JID的域ID部分的主机名和服务器自身配置的主机名本身匹配,并且'to'属性中的JID类型是 1. 如果这个JID包含一个资源ID(例如, 格式是 2. 如果这个JID包含一个资源ID(例如, 格式是 11. XMPP中的XML用法 11.1. 限制 XMPP是一个简单的流式XML元素的专用协议用于接近实时地交换结构化信息. 因为XMPP不需要任意的解析和所有的XML文档, 所以XMPP不需要支持[XML]的所有功能. 特殊的, 适用以下限制. 关于XML生成, 一个XMPP实现不能(MUST NOT)在XML流中注入以下任何东西: 注释 (第二章第五节[XML]) 处理指示(第二章第六节 同上) 内部或外部的 DTD 子集 (第二章第八节 同上) 内部或外部的实体参考 (第四章第二节 同上) 除了预定实体以外(第四章第六节 同上) 字符数据或属性值包含和预定实体列表中吻合的未逃逸的unescaped字符(第四章第六节 同上); 这些字符必须(MUST)逃逸 关于XML处理, 如果一个XMPP实现接收到这些受限的XML数据,它必须(MUST)忽略这些数据. 11.2. XML 名字空间的名字和前缀 XML名字空间[XML-NAMES]为所有XMPP兼容的XML建立数据所有权的严格界限. 这个名字空间的基本功能是把结构上混合在一起的XML元素区分出不同的词汇. 确保XMPP兼容的XML有名字空间的感知能力使得任何允许的XML可以被结构化的混合到任何XMPP数据元素中. XML名字空间的名字和前缀的规则在下一小节中. 11.2.1. 流名字空间 在所有的XML流头中必须声明一个流名字空间. 流名字空间必须(MUST)是 'http://etherx.jabber.org/streams'. 元素名 11.2.2. 缺省名字空间 在所有的XML流中必须声明一个缺省的流名字空间用于定义允许的流根元素的一级子元素. 这个名字空间声明对于初始化流和应答流必须(MUST)是相同的使得双方的流都是合格一致的. 缺省的名字空间声明适用于流和所有在流中发送的节(除非由流名字空间或回拨名字空间的前缀显式的符合另一个名字空间). 一个服务器实现必须(MUST)支持以下两个缺省名字空间(由于历史原因, 一些实现可能(MAY)只支持这两个缺省名字空间): jabber:client -- 当流用于客户端和服务器的通信时声明这个缺省名字空间 jabber:server -- 当流用于两个服务器间的通信时声明这个缺省名字空间 一个客户端实现必须(MUST)支持'jabber:client'缺省名字空间,并且由于历史原因可以(MAY)只支持这个缺省名字空间. 如果缺省名字空间是'jabber:client'或'jabber:server',一个实施不能(MUST NOT)在这个名字空间下为元素生成名字空间前缀. 一个实现不应该(SHOULD NOT)按照元素的内容(可能和流相反)生成不同于'jabber:client'和'jabber:server'名字空间前缀. 注意: 'jabber:client' 和 'jabber:server' 名字空间接近于相同但是用于不同的上下文(客户端服务器通信用'jabber:client' 而服务器间通信用 'jabber:server'). 这两者之间仅有的不同在于在'jabber:client'中被发送的节中'to'和'from'属性是可选的(OPTIONAL),而在'jabber:server'中被发送的节中它们是必需的(REQUIRED). 如果兼容的实施接受一个符合'jabber:client'或'jabber:server'名字空间的流, 它必须(MUST)支持通用属性(第九章第一节)和三个核心节类型(message, presence, 和IQ)的基本语义(第九章第二节). 11.2.3. 回拨名字空间 所有用于服务器回拨的(第八章)元素都必须声明一个回拨名字空间. 回拨名字空间的名字必须(MUST)是'jabber:server:dialback'. 所有符合此名字空间的元素必须(MUST)有前缀. 一个实现应该(SHOULD)只为这些元素生成'db:'前缀并且只可以(MAY)接受'db:'前缀. 11.3. 确认 除了注意'jabber:server'名字空间中关于节中'to'和'from'地址的规定,一个服务器不需要为转发到客户端或其他服务器负责检查XML元素;一个实现可以(MAY)选择仅提供有效数据元素但这是可选的(OPTIONAL)(尽管一个实现不能(MUST NOT)接受不规范的XML). 客户端不应该(SHOULD NOT)滥用发送不符合schema的数据的能力, 并且应该(SHOULD)忽略接收到的XML流中任何和schema不一致的元素或属性值. XML流和节的有效性确认是可选的(OPTIONAL),并且在这里提到的schemas仅用于描述的用途. 11.4. 文本声明的包含 实现应该(SHOULD)在发送一个流头信息之前发送一个文本声明. 应用程序必须(MUST)遵守[XML]中关于环境(那里对文本声明做了规定)的规则. 11.5. 字符编码 实现必须(MUST)支持通用字符集Universal Character Set (ISO/IEC 10646-1 [UCS2])字符到UTF-8(RFC 3629 [UTF-8])的转换, 必须符合 RFC 2277 [CHARSET]. 实现不能(MUST NOT)试图使用任何其他的编码. 12. 核心的兼容性要求 本章总结了可扩展的消息和出席信息协议中的某些方面,为了实施的兼容性,它们必须(MUST)被服务器和客户端支持,当然协议的其他方面也应该(SHOULD)被支持. 为了兼容的目的, 我们在核心协议(它必须(MUST)被任何服务器或客户端支持, 无论是什么特定的应用)和即时消息协议(仅仅是在核心协议之上的即时消息和出席信息应用必须(MUST)支持它)之间划了一个级别. 在本章中定义了所有服务器和客户端的兼容性要求; 即时消息服务器和客户端的兼容性要求在XMPP-IM的相关章节中定义. 12.1. 服务器 除了所有已定义的关于安全, XML使用, 和国际化的要求之外, 一个服务器还必须(MUST)支持以下核心协议以保证兼容性: 在地址中应用[STRINGPREP] 的 [NAMEPREP], Nodeprep (附录 A),和 Resourceprep (附录 B) profiles (包括确保域ID是[IDNA]中定义的国际化域名) XML流(第四章), 包括Use of TLS(第五章), Use of SASL(第六章), 和Resource Binding (第七章) 三个在stanza semantics(第九章第二节)中已定义的节类型(即, 生成错误的语法及相关的流, TLS, SASL, 和 XML节的语义 另外, 一个服务器可以(MAY)支持以下核心协议: 服务器回拨 (第八章) 12.2. 客户端 一个客户端必须(MUST)支持以下核心协议以满足兼容性: XML流(第四章), 包括Use of TLS(第五章), Use of SASL(第六章), 和Resource Binding (第七章) 三个在stanza semantics(第九章第二节)中已定义的节类型(即, 处理(并且, 如果可能, 生成) 错误的语法及相关的流, TLS, SASL, 和 XML节的语义 另外, 一个客户端应该(SHOULD)支持以下核心协议: 地址的生成应用[STRINGPREP] 的 [NAMEPREP], Nodeprep (附录 A),和 Resourceprep (附录 B) profiles 13. 国际化事项 XML流在Character Encoding(第十一章第五节)中定义为必须(MUST)被编码成UTF-8. 在Stream Attributes(第四章第四节)中特别定义了, 一个XML流应该(SHOULD)包含一个'xml:lang'属性,它被认为是通过这个用于人类用户解读的流发送的任何XML字符数据的缺省语言. 在 xml:lang (第九章第一节第五小节)特别定义了, 如果一个XML节是用来给人类用户解读,这个节应该(SHOULD)包含一个'xml:lang'属性. 服务器在为连接的实体路由或递送节的时候应该(SHOULD)应用缺省的'xml:lang'属性, 并且不能(MUST NOT)修改或删除它从其他实体收到的节的'xml:lang'属性. 14. 安全性事项 14.1. 高安全性 为了XMPP通信的目的(客户端-服务器 和 服务器-服务器), \"高安全性\"条款谈的是相互验证和完整性检查安全性技术的使用; 特别是, 当使用基于证书的验证来提供高安全性, 应该( SHOULD)建立一个带外的信任链,尽管一个共享签名证书可能允许以前不知道的证书在带内建立信任关系. 参见以下第十四章第二节关于证书确认程序. 实施必须(MUST)支持高安全性. 服务提供者应该(SHOULD)基于本地安全策略使用高安全性. 14.2. 证书确认 当一个XMPP点和另一个XMPP点安全的地通信, 它必须(MUST)确认对方终端的证书.有三种可能的情况: 情形 #1: 点包含一个终端实体证书,以根证书的证书链中一环出现(见[X509]中的第六章第一节). 情形 #2: 点的证书由一个对方不知道的证书授权. 情形 #3: 点的证书由自己签名. 在情形#1, 确认方必须(MUST)做以下两条之一: 1. 根据[X509]的规则确认对方证书.然后证书应该(SHOULD)被对方接下来在[HTTP-TLS]中描述的规则反向确认预期的身份。但如果\"xmpp\"是 subjectAltName扩展类型,则必须(MUST)使用证书中的显示的身份。如果这两项检查之一失败,用户导向的客户端必须(MUST)通知用户(客户端可以(MAY)给用户机会继续连接)或以一个坏证书的错误终止连接。自动客户端应该(SHOULD)终止连接(以一个坏证书错误)并在适当的日志中记录这个错误。自动客户端可以(MAY)提供一个配置设置成禁止检查,但同时必须(MUST)提供一个激活检查的配置。 2. 点应该(SHOULD)出示证书给一个用户用于批准,包括完整的证书链.点必须(MUST)缓存这个证书(或一些其他不会忘记的表达方式比如一个哈希值).在将来的连接中,点必须(MUST)展示相同的证书并且如果改变了证书必须(MUST)通知用户. 在情形#2 和情形#3, 实现应该(SHOULD)执行上述第二条. 14.3. 客户端-服务器通信 一个兼容的客户端实现必须(MUST)支持TLS和SASL用于连接到服务器. 用于加密XML流的TLS协议(在 Use of TLS(第五章)定义)提供可信的机制帮助确保机密性和实体之间数据交换的完整性. 用于验证XML流的SASL协议(在 Use of SASL(第六章)定义)提供可靠的机制用于确认一个连接到服务器的客户端确实是它自己所声明的那个客户端. 服务器宣称的DNS主机名被解析之前,客户端-服务器通信不能(MUST NOT)继续进行。应该首先尝试解析[SRV]记录,其服务名为\"xmpp-client\",协议名为\"tcp\",整个资源记录类似\"_xmpp-client._tcp.example.com.\"(使用字符 \"xmpp-client\"表示服务ID是经过IANA注册).如果SRV查找失败,退而求其次,将查找一个正规的IPv4/IPv6地址记录来决定IP地址,使用\"xmpp-client\"端口5222,这个端口是在IANA注册了的。 客户端的IP地址和访问方法不能(MUST NOT)被服务器公开, 也不能被被任何原始服务器之外的服务器索取。这帮助保护客户端的服务器避免受到直接攻击(译者注:似乎应该是客户避免受到直接攻击,但原文如此)或被第三方知道它的身份。 14.4. 服务器-服务器通信 一个兼容的服务器实现必须(MUST)支持TLS和SASL,用于域间的通信.因为历史原因,一个兼容的实施也应该(SHOULD)支持服务器回拨(第八章). 因为服务提供者是一个策略问题,对于任何给定域和其他域的通信中,它是可选的(OPTIONAL),服务器之间的通信可以(MAY)被任何特定部署的管理员禁止。如果一个特殊的域允许域间的通信,它应该(SHOULD)允许高安全性。 管理员可能想在服务器间使用SASL来通信,以确保双方的验证和保密性(比如在机构的私有网络).兼容实施应该(SHOULD)为这个目的支持SASL. 服务器宣称的DNS主机名被解析之前,服务器-服务器通信不能(MUST NOT)继续进行。应该首先尝试解析[SRV]记录,其服务名为\"xmpp-server\",协议名为\"tcp\",整个资源记录类似\"_xmpp-server._tcp.example.com.\"(使用字符\"xmpp-server\"表示服务ID是经过IANA注册的,注意要用\"xmpp-server\"取代以前用的\"jabber\希望保持向后兼容的实现可以继续查找或应答\"jabber\"服务ID).如果SRV查找失败,退而求其次,将查找一个正规的IPv4/IPv6地址记录来决定IP地址,使用\"xmpp-server\"端口5269,这个端口是在IANA注册了的。 服务器回拨防止域欺骗,从而使得伪造XML节更为困难.它和SASL和TLS不一样,它不是一个用于验证、安全或加密服务器之间的流的机制, 所以只是服务器身份的微弱确认而已。而且除非它使用了DNSSec [DNSSEC]否则它 容易受到DNS中毒攻击,即使DNS信息是正确的,如果攻击者劫持了远程域,回拨也不能防止它的攻击.需要健壮的安全性的域应该(SHOULD)使用TLS和SASL.如果服务器间的验证使用了SASL,回拨就不应该(SHOULD NOT)使用了,因为它是多余的. 14.5. 层的次序 协议中的层的次序必须(MUST)如下堆积: 1. TCP 2. TLS 3. SASL 4. XMPP 这个次序的原理是,[TCP]是基于连接的层,被所有使用,所以处于最上层, [TLS]经常是由操作系统层提供,[SASL]经常由应用程序层提供, XMPP则是应用程序本身. 14.6. 缺乏绑定到TLS的SASL通道 SASL构架不提供一个机制来绑定SASL验证到一个提供机密性和完整性保护的安全层。这一通道绑定\"channel binding\"的缺乏阻碍了SASL确认低层安全性所绑定的源和目标终端和SASL所验证的结果是否一致。如果终端不一致, 低层安全性不能被信任用来保护SASL验证的实体之间的数据传输。在这种情况下,一个SASL安全层进行握手的时候应该有效的忽略低层安全性的存在。 14.7. 强制实现的技术 最低要求, 所有实现必须(MUST)支持以下机制: 对于验证: SASL [DIGEST-MD5] 机制 对于机密性: TLS (使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 密码) 对于两者: TLS 加 SASL EXTERNAL(使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 密码支持客户端证书) 14.8. 防火墙 使用XMPP通信通常是通过[TCP]连接到5222端口(客户端-服务器)或5269端口(服务器-服务器), 正如在IANA注册的那样(见 IANA Considerations (第十五章)). 使用这些广为人知的端口允许管理员很容易的通过一般的防火墙来激活或禁止XMPP活动. 14.9. 在SASL中使用base64 客户端和服务器都必须(MUST)确认在SASL协商中收到的任何[BASE64]数据. 一个实现必须(MUST)拒绝(不是忽略)任何非显式允许base64字母的字符串; 这有助于预防建立隐蔽通道泄漏信息的行为。一个实现不能(MUST NOT)在非法输入处中断,如果那个('=')被包含在一些和最后的数据字符(如, \"=AAA\" or \"BBBB=CCC\")不同的东西里面,必须(MUST)拒绝接下来的任何包含('=')的base64字符;这有助于防止对这个实现的缓存溢出攻击和其他攻击。Base 64编码从外表看隐藏了容易辨认的信息,例如密码,但是不提供任何算法机密性。Base 64编码必须(MUST)按照RFC 3548[BASE64]第三章的定义执行。 14.10. Stringprep Profiles 为了处理域ID,XMPP使用了[STRINGPREP]中的[NAMEPREP] profile; 和Nameprep有关的安全性考虑, 参考[NAMEPREP]中的相关章节. 另外, XMPP 定义了两个[STRINGPREP]的 profiles: 用于node identifiers的Nodeprep(附录 A)和用于resource identifiers的Resourceprep(附录 B). Unicode 和 ISO/IEC 10646 集有许多字符看起来相似. 在许多时候, 安全协议的使用者可能看起来吻合,比如当比较信任的第三方的名字的时候. 因为没有很多上下文的时候不可能映射看起来相似的字符,比如知道所用的字符集, stringprep不匹配相似字符串,也不因为一些字符串象看起来象别的字符串而禁止它们. 一个节点ID可能被作为一个实体的XMPP地址的一部分. 一个通常的用途是作为一个即时消息用户的用户名;另一个用途是作为一个多用途聊天室的名字; 很多其他种类的实体可能使用节点ID作为他们的地址的一部分。 这些服务的安全性可能会受到国际化节点ID的不同表达的威胁;例如, 一个用户键入一个单独的国际化的节点ID可能访问了另一个用户的帐号信息, 或一个用户可能获得访问一个受限的聊天室或服务的访问权限. 一个资源ID可能被作为一个实体的XMPP地址的一部分。一个通常的用户是即时消息用户所连接的资源(激活的会话)的名字; 另一个是作为多用户聊天室的某用户的昵称; 许多其他种类的实体可能使用资源ID作为他们地址的一部分.这些服务的安全性可能会受到国际化资源ID的不同表达的威胁;例如, 一个用户可能尝试以同一个名字初始化多个会话,或一个用户可能发送一个消息给多用户聊天室的一个人但实际上发给了另外一个人. 15. IANA 事项 15.1. 用于TLS数据的XML名字空间名 XMPP中用于TLS相关数据的 URN 子名字空间定义如下. (这个名字空间的名字遵守The IETF XML Registry [XML-REG]定义的格式.) URI: urn:ietf:params:xml:ns:xmpp-tls Specification: RFC 3920 Description: This is the XML namespace name for TLS-related data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920. Registrant Contact: IETF, XMPP Working Group, 15.2. 用于SASL数据的XML名字空间名 XMPP中用于SASL相关数据的 URN 子名字空间定义如下. (这个名字空间的名字遵守The IETF XML Registry [XML-REG]定义的格式.) URI: urn:ietf:params:xml:ns:xmpp-sasl Specification: RFC 3920 Description: This is the XML namespace name for SASL-related data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920. Registrant Contact: IETF, XMPP Working Group, 15.3. 用于流错误的XML名字空间名 XMPP中用于流相关错误的 URN 子名字空间定义如下. (这个名字空间的名字遵守The IETF XML Registry [XML-REG]定义的格式.) URI: urn:ietf:params:xml:ns:xmpp-streams Specification: RFC 3920 Description: This is the XML namespace name for stream-related error data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920. Registrant Contact: IETF, XMPP Working Group, 15.4. 用于资源绑定的XML名字空间名 XMPP中用于资源绑定的 URN 子名字空间定义如下. (这个名字空间的名字遵守The IETF XML Registry [XML-REG]定义的格式.) URI: urn:ietf:params:xml:ns:xmpp-bind Specification: RFC 3920 Description: This is the XML namespace name for resource binding in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920. Registrant Contact: IETF, XMPP Working Group, 15.5. 用于节错误的XML名字空间名 XMPP中用于节相关错误数据的 URN 子名字空间定义如下. (这个名字空间的名字遵守The IETF XML Registry [XML-REG]定义的格式.) URI: urn:ietf:params:xml:ns:xmpp-stanzas Specification: RFC 3920 Description: This is the XML namespace name for stanza-related error data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920. Registrant Contact: IETF, XMPP Working Group, 15.6. Nodeprep Profile of Stringprep The Nodeprep profile of stringprep是在Nodeprep(附录 A)定义的. IANA已经在stringprep profile registry中注册了 Nodeprep. Name of this profile: Nodeprep RFC in which the profile is defined: RFC 3920 Indicator whether or not this is the newest version of the profile: This is the first version of Nodeprep 15.7. Resourceprep Profile of Stringprep The Resourceprep profile of stringprep是在Resourceprep(附录 B)定义的. IANA已经在stringprep profile registry中注册了Resourceprep. Name of this profile: Resourceprep RFC in which the profile is defined: RFC 3920 Indicator whether or not this is the newest version of the profile: This is the first version of Resourceprep 15.8. GSSAPI 服务名 IANA已经注册了 \"xmpp\" 作为一个 GSSAPI [GSS-API] 服务名, 在SASL Definition (第六章第三节)定义了. 15.9. 端口号 IANA已经注册了\"xmpp-client\" 和 \"xmpp-server\" 作为[TCP]端口号5222和5269的关键字. 这些端口应该(SHOULD)用于客户端-服务器 和 服务器-服务器通信,但它们的使用是可选的(OPTIONAL). 16. 参考 16.1. 标准化参考 [ABNF] Crocker, D. and P. Overell, \"Augmented BNF for Syntax Specifications: ABNF\ [BASE64] Josefsson, S., \"The Base16, Base32, and Base64 Data Encodings\RFC 3548, July 2003. [CHARSET] Alvestrand, H., \"IETF Policy on Character Sets and Languages\BCP 18, RFC 2277, January 1998. [DIGEST-MD5] Leach, P. and C. Newman, \"Using Digest Authentication as a SASL Mechanism\ [DNS] Mockapetris, P., \"Domain names - implementation and specification\STD 13, RFC 1035, November 1987. [GSS-API] Linn, J., \"Generic Security Service Application Program Interface Version 2, Update 1\[HTTP-TLS] Rescorla, E., \"HTTP Over TLS\[IDNA] Faltstrom, P., Hoffman, P., and A. Costello, \"Internationalizing Domain Names in Applications (IDNA)\ [IPv6] Hinden, R. and S. Deering, \"Internet Protocol Version 6 (IPv6) Addressing Architecture\ [LANGTAGS] Alvestrand, H., \"Tags for the Identification of Languages\BCP 47, RFC 3066, January 2001. [NAMEPREP] Hoffman, P. and M. Blanchet, \"Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)\[RANDOM] Eastlake 3rd, D., Crocker, S., and J. Schiller, \"Randomness Recommendations for Security\ [SASL] Myers, J., \"Simple Authentication and Security Layer (SASL)\RFC 2222, October 1997. [SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, \"A DNS RR for specifying the location of services (DNS SRV)\[STRINGPREP] Hoffman, P. and M. Blanchet, \"Preparation of Internationalized Strings (\"stringprep\")\[TCP] Postel, J., \"Transmission Control Protocol\September 1981. [TERMS] Bradner, S., \"Key words for use in RFCs to Indicate Requirement Levels\ [TLS] Dierks, T. and C. Allen, \"The TLS Protocol Version 1.0\January 1999. [UCS2] International Organization for Standardization, \"Information Technology - Universal Multiple-octet coded Character Set (UCS) - Amendment 2: UCS Transformation Format 8 (UTF-8)\Addendum 2, October 1996. [UTF-8] Yergeau, F., \"UTF-8, a transformation format of ISO 10646\63, RFC 3629, November 2003. [X509] Housley, R., Polk, W., Ford, W., and D. Solo, \"Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile\ [XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, \"Extensible Markup Language (XML) 1.0 (2nd ed)\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>. 16.2. 信息参考 [ACAP] Newman, C. and J. Myers, \"ACAP -- Application Configuration Access Protocol\ [ASN.1] CCITT, \"Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1)\ [DNSSEC] Eastlake 3rd, D., \"Domain Name System Security Extensions\RFC 2535, March 1999. [HTTP] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, \"Hypertext Transfer Protocol -- HTTP/1.1\RFC 2616, June 1999. [IMAP] Crispin, M., \"INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1\RFC 3501, March 2003. [IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, \"Instant Messaging / Presence Protocol Requirements\[IRC] Oikarinen, J. and D. Reed, \"Internet Relay Chat Protocol\RFC 1459, May 1993. [JEP-0029] Kaes, C., \"Definition of Jabber Identifiers (JIDs)\0029, October 2003. [JEP-0078] Saint-Andre, P., \"Non-SASL Authentication\JSF JEP 0078, July 2004. [JEP-0086] Norris, R. and P. Saint-Andre, \"Error Condition Mappings\JSF JEP 0086, February 2004. [JSF] Jabber Software Foundation, \"Jabber Software Foundation\http://www.jabber.org/>. [POP3] Myers, J. and M. Rose, \"Post Office Protocol - Version 3\STD 53, RFC 1939, May 1996. [SIMPLE] SIMPLE Working Group, \"SIMPLE WG\ http://www.ietf.org/html.charters/simple-charter.html>. [SMTP] Klensin, J., \"Simple Mail Transfer Protocol\RFC 2821, April 2001. [URI] Berners-Lee, T., Fielding, R., and L. Masinter, \"Uniform Resource Identifiers (URI): Generic Syntax\ [USINGTLS] Newman, C., \"Using TLS with IMAP, POP3 and ACAP\June 1999. [XML-REG] Mealling, M., \"The IETF XML Registry\BCP 81, RFC 3688, January 2004. XMPP-IM Saint-Andre, P., Ed., \"Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence\ 附录 A. Nodeprep A.1. 介绍 这个附录定义了 \"Nodeprep\" profile of [STRINGPREP]. 它定义了处理规则让用户能够在XMPP中输入国际化节点标识符并尽可能正确的获取正确的字符内容. (一个XMPP节点标识符是XMPP地址的可选部分,它在域名标识符和那个'@'分隔符之前;它经常但不是专门用来关联一个即时消息用户名)这些处理规则仅仅适用于XMPP节点标识符但不适用于任意文本或任何XMPP的其他方面. 这个脚本定义了以下这些, 正如 [STRINGPREP]要求的: 脚本预期的适用性: XMPP的国际化节点标识符 用于stringprep的输入输出字符集: Unicode 3.2, 定义在本附录的第二章 使用的映射: 定义在第三章 Unicode正规化使用: 定义在第四章 禁止输出的字符串: 定义在第五章 双字节字符处理: 定义在第六章 A.2. 字符集 本脚本使用Unicode 3.2的未分配编码列表,指向 Table A.1, 也定义在 [STRINGPREP]的附录 A 中. A.3. 映射 本脚本指定使用[STRINGPREP]的以下表: Table B.1 Table B.2 A.4. 正规化 本脚本指定 Unicode正规化使用 form KC, 定义在 [STRINGPREP]中. A.5. 禁止输出 本脚本指定使用以下的[STRINGPREP]表禁止输出. Table C.1.1 Table C.1.2 Table C.2.1 Table C.2.2 Table C.3 Table C.4 Table C.5 Table C.6 Table C.7 Table C.8 Table C.9 另外, 以下Unicode字符也被禁止: #x22 (\") #x26 (&) #x27 (') #x2F (/) #x3A (:) #x3C (<) #x3E (>) #x40 (@) A.6. 双字节 本脚本指定按照[STRINGPREP]第六章检查双字节. 附录 B. Resourceprep B.1. 介绍 这个附录定义了 \"Resourceprep\" profile of [STRINGPREP]. 它定义了处理规则让用户能够在XMPP中输入国际化资源标识符并尽可能正确的获取正确的字符内容. (一个XMPP资源标识符是XMPP地址的可选部分,它在域名标识符和'/@'分隔符之后;它经常但不是专门用来关联一个即时消息会话名)这些处理规则仅仅适用于XMPP资源标识符但不适用于任意文本或任何XMPP的其他方面. 这个脚本定义了以下这些, 正如 [STRINGPREP]要求的: 脚本预期的适用性: XMPP的国际化节点标识符 用于stringprep的输入输出字符集: Unicode 3.2, 定义在本附录的第二章 使用的映射: 定义在第三章 Unicode正规化使用: 定义在第四章 禁止输出的字符串: 定义在第五章 双字节字符处理: 定义在第六章 B.2. 字符集 本脚本使用Unicode 3.2的未分配编码列表,指向 Table A.1, 也定义在 [STRINGPREP]的附录 B.3. 映射 本脚本指定使用[STRINGPREP]的以下表: Table B.1 B.4. 正规化 本脚本指定使用 Unicode normalization form KC, 定义在 [STRINGPREP]中. B.5. 禁止输出 本脚本指定使用以下的[STRINGPREP]表禁止输出. Table C.1.2 Table C.2.1 Table C.2.2 Table C.3 Table C.4 Table C.5 Table C.6 Table C.7 Table C.8 Table C.9 B.6. 双字节 本脚本指定按照[STRINGPREP]第六章检查双字节. 附录 C. XML 规划 以下 XML schemas 是描述性的, 不是标准的. 'jabber:client' 和 'jabber:server' 名字空间的标准定义, 参照 XMPP-IM. C.1. Streams namespace C.2. Stream error namespace targetNamespace='urn:ietf:params:xml:ns:xmpp-streams' xmlns='urn:ietf:params:xml:ns:xmpp-streams' elementFormDefault='qualified'> C.3. TLS namespace C.4. SASL namespace C.5. Resource binding namespace C.6. Dialback namespace C.7. Stanza error namespace targetNamespace='urn:ietf:params:xml:ns:xmpp-stanzas' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' elementFormDefault='qualified'> 附录 D. 核心Jabber协议和XMPP的不同 本章是非标准的. 译者注:附录D对于新接触XMPP的人没有什么意义,就不翻译了,免得浪费时间。因为现在RFC公布已经很久了,以前的Jabber实现很多都进化到XMPP了。 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 core differences, while the corresponding section of XMPP-IM summarizes the differences that relate specifically to instant messaging and presence applications. D.1. Channel Encryption It was common practice in the Jabber community to use SSL for channel encryption on ports other than 5222 and 5269 (the convention is to use ports 5223 and 5270). XMPP uses TLS over the IANA-registered ports for channel encryption, as defined under Use of TLS (Section 5) herein. D.2. Authentication The client-server authentication protocol developed in the Jabber community used a basic IQ interaction qualified by the 'jabber:iq:auth' namespace (documentation of this protocol is contained in [JEP-0078], published by the Jabber Software Foundation [JSF]). XMPP uses SASL for authentication, as defined under Use of SASL (Section 6) herein. The Jabber community did not develop an authentication protocol for server-to-server communications, only the Server Dialback (Section 8) protocol to prevent server spoofing. XMPP supersedes Server Dialback with a true server-to-server authentication protocol, as defined under Use of SASL (Section 6) herein. D.3. Resource Binding Resource binding in the Jabber community was handled via the 'jabber:iq:auth' namespace (which was also used for client authentication with a server). XMPP defines a dedicated namespace for resource binding as well as the ability for a server to generate a resource identifier on behalf of a client, as defined under Resource Binding (Section 7). D.4. JID Processing JID processing was somewhat loosely defined by the Jabber community (documentation of forbidden characters and case handling is contained in [JEP-0029], published by the Jabber Software Foundation [JSF]). XMPP specifies the use of [NAMEPREP] for domain identifiers and supplements Nameprep with two additional [STRINGPREP] profiles for JID processing: Nodeprep (Appendix A) for node identifiers and Resourceprep (Appendix B) for resource identifiers. D.5. Error Handling Stream-related errors were handled in the Jabber community via XML character data text in a Stanza-related errors were handled in the Jabber community via HTTP-style error codes. In XMPP, stanza-related errors are handled via an extensible mechanism defined under Stanza Errors (Section 9.3) herein. (Documentation of a mapping between Jabber and XMPP error handling mechanisms is contained in [JEP-0086], published by the Jabber Software Foundation [JSF].) D.6. Internationalization Although use of UTF-8 has always been standard practice within the Jabber community, the community did not define mechanisms for specifying the language of human-readable text provided in XML character data. XMPP specifies the use of the 'xml:lang' attribute in such contexts, as defined under Stream Attributes (Section 4.4) and xml:lang (Section 9.1.5) herein. D.7. Stream Version Attribute The Jabber community did not include a 'version' attribute in stream headers. XMPP specifies inclusion of that attribute as a way to signal support for the stream features (authentication, encryption, etc.) defined under Version Support (Section 4.4.1) herein. 贡献者 XMPP的大部分核心方面是由1999年开始的Jabber开源社区开发的. 这个社区是由 Jeremie Miller建立的, 他于1999年1月发布了最初版的jabber server源代码. 主要的基础协议的早期贡献者还包括 Ryan Eatmon, Peter Millard, Thomas Muldowney,和 Dave Smith. XMPP工作组的工作主要集中在安全性和国际化方面; 在这些领域, 使用 TLS 和 SASL 的协议最初是由 Rob Norris贡献的, stringprep profiles 最初是由 Joe Hildebrand贡献的. The error code syntax 是由Lisa Dusseault建议的. 致谢 感谢许多在贡献者名单之外的人们. 尽管很难提供一个完整的名单, 以下个人对于定义协议或评论标准提供了很多帮助: Thomas Charron, Richard Dobson, Sam Hartman, Schuyler Heath, Jonathan Hogg, Cullen Jennings, Craig Kaes, Jacek Konieczny, Alexey Melnikov, Keith Minkler, Julian Missig, Pete Resnick, Marshall Rose, Alexey Shchepin, Jean-Louis Seguineau, Iain Shigeoka, Greg Troxel, and David Waite. 也感谢 XMPP工作组的成员和 IETF 社区在本文的成文过程中一直提供的评论和反馈。 作者地址 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. 感谢 目前为RFC编辑活动提供资金的Internet Society. 因篇幅问题不能全部显示,请点此查看更多更全内容