本文是基于http://wiki.jabbercn.org/RFC3920 基础上校验调整。
过段时间会同步更新到jabbercn wiki。
"本文的英文原文来自RFC 3920
网络工作组 P. Saint-Andre, Ed.
申请讨论: 3920 Jabber软件基金会
类别: 标准跟踪 2004年10月
可扩展的消息和现场协议 (XMPP): 核心
本备忘录的状态
本文为互联网社区定义了一个互联网标准跟踪协议,并且申请讨论协议和提出了改进的建议。请参照“互联网官方协议标准”的最新版本(STD 1)获得本协议标准说明和最新进度。本文可以不受限制的分发。
版权声明
版权所有(C)因特网协会(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 参考
附录 A. Nodeprep
附录 B. Resourceprep
附录 C. XML Schemas
附录 D. 核心Jabber协议和XMPP的差异
贡献者
致谢
作者地址
完整的版权声明
1. 介绍
1.1. 概述
可扩展消息和现场协议(XMPP)是开放XML协议,用于实现准实时消息、到场信息以及请求-响应服务。其基本的语法和语义最初主要是由Jabber开放源代码社区于1999年开发。2002年,XMPP工作组被授权接手开发和改编Jabber协议以适应IETF的即时消息和现场信息技术。作为XMPP工作组的成果,本文定义了 XMPP 1.0 的核心功能;而即时消息和现场协议的扩展功能在RFC 2779 [IMP-REQS]中定义。
1.2. 术语
本文中大写的关键字 "MUST(必须)", "MUST NOT(不能)", "REQUIRED(必需)", "SHALL(将会)", "SHALL NOT(将不会)", "SHOULD(应该)", "SHOULD NOT(不应该)", "RECOMMENDED(建议)", "MAY(可以)", 和 "OPTIONAL(可选)" 的确切含义符合 BCP 14, RFC 2119 [TERMS]规范.
2. 通用的架构
2.1. 概述
尽管XMPP没有指定任何特定的网络结构,但它通常是采用 客户端-服务器 架构进行实现,其中客户端通过TCP连接方式使用XMPP协议来访问服务器,服务器之间也采用TCP方式进行通信。
以下是这一架构的抽象示意图 (这里 "-" 表示使用 XMPP 协议通讯, "=" 表示可使用任何协议通讯)。
C1----S1---S2---C3
|
C2----+--G1===FN1===FC1
符号的含义如下:
o C1, C2, C3 = XMPP 客户端
o S1, S2 = XMPP 服务器
o G1 = 一个XMPP和外部(非XMPP)消息网络之间进行“翻译”的网关
o FN1 = 一个外部消息网络
o FC1 = 外部消息网络上的一个客户端
2.2. 服务器
服务器充当XMPP通信的一个智能抽象层,它主要负责:
o 对受验证的客户端、服务器以及其他实体之间以XML流(第4章)的连接和会话进行管理。
o 对实体之间使用XML流合理编址的XML节(参见章节 9)进行路由。
大部分提供XMPP协议的服务器也负责存储客户端使用的数据(比如联系人列表); 在这种情
况下, XML数据直接由服务器来处理,而不需要转发到其他实体。
2.3. 客户端
大部分客户端通过TCP直接连到服务器,并通过XMPP获得由服务器以及联合服务器所提供的全部功能。多个不同资源(比如不同的设备和地点)的客户端可以同时登录到同一个服务器,每个不同资源的客户端通过XMPP地址的资源标识符来区分(比如
2.4. 网关
网关是一个特殊用途的服务器端服务,主要功能是把XMPP翻译成外部(非XMPP)消息系统,并把返回的消息翻译成XMPP。例如到Email(参见[SMTP])、IRC(参见[IRC])、SIMPLE(参见[SIMPLE])、短消息(SMS)、还有流行的IM协议比如AIM、ICQ、MSN、Yahoo!Instant Messenger等。
注意:网关和服务器之间的通信、网关和外部消息系统的通信,不在本文描述范围之内。
2.5. 网络
因为每个服务器都是由一个网络地址来标识,并且server-to-server通信是由client-server协议直接扩展的,实际上整个系统是由很多互通的服务器构成的。例如,
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字节。即JID整体长度(包括'@'和'/')不能超过3071字节。
3.2. 域名
域名是一个主要的ID并且是JID中唯一必需(REQUIRED)的元素(一个纯粹的域名也是一个合法的JID)。它通常代表网络的网关或者“主”服务器,其他实体通过连接它来实现XML转发和数据管理功能。然而,由一个域名标识的实体,并非总是一个服务器,它也有可能是一个服务器的子域地址,提供额外的功能(比如多用户聊天服务、用户目录或一个到外部消息系统的网关)。
每个服务器或者服务的域名,可以(MAY)是一个IP地址,但最好(SHOULD)是一个完全合法的域名(参见[DNS])。一个域名标识必须(MUST)是[IANA]里定义的“国际化域名”,并且按[STRINGPREP]中的[NAMEPREP] profile进行格式化。在比较两个域名ID之前,服务器必须(客户端应该)首先按照Nameprep profile(参见[IANA])来转换每个域名的字符。
3.3. 节点标识
节点标识是可选(OPTIONAL)的,放在域名之前并用"@"分开。它通常表示一个向服务器或网关请求和使用网络服务的实体(比如一个客户端),当然它也能够表示其他的实体(比如在多用户聊天系统中的一个房间)。节点名所代表的实体地址依赖于一个特定的域名;在XMPP的即时消息和现场信息应用系统中,这个地址是“纯JID”
一个节点标识必须按[STRINGPREP]中的 Nodeprep profile 进行格式化。在比较两个节点ID之前,服务器必须(客户端应该)先按Nodeprep profile转换每个ID的字符。
3.4. 资源标识
资源表示也是一个可选(OPTIONAL)的,它放在域名的后面并由"/"分开。资源名可以跟在
一个资源标识必须(MUST)按 [STRINGPREP] 中的 Resourceprep profile 进行格式化。在比较两个资源ID之前,服务器必须(客户端应该)先按 Resourceprep profile 转换每个ID的字符。
3.5. 地址规则
在SASL(参加章节 6)握手成功之后,接收流信息的实体必须(MUST)确认初始实体的JID。如果必要的话,在资源绑定(参见章节 7)之后也可以再次确认该实体JID。
对于server-to-server通信,在SASL握手时,如果没有指定授权JID,那么这个初始的实体应该(SHOULD)是经过认证的授权JID(参见章节 6)。(参见 简单认证和安全层协议 [SASL])
对于client-to-server通信,在SASL握手时,如果没有指明授权JID,“纯JID” (
接收的实体必须(MUST)确保结果JID(包括节点名、域名、资源名以及分隔符)与本章前面部分描述的规则和格式相一致;为了满足这些约束条件,接收实体可能(MAY)需要把初始实体的发送方JID替换成接收实体认可的规范JID。
4. XML流
4.1. 概述
两个基本概念,XML流和XML节,使得在现场信息已知的实体之间,异步交换低负载的结构化信息成为可能。这两个术语定义如下:
XML流的定义:一个XML流是一个容器,包含了两个实体之间通过网络交换的XML元素。一个XML流是由一个XML打开标签
XML节的定义:一个XML节是一个实体通过XML流向另一个实体发送的结构化信息中一个不连续的语义单位。一个XML节位于根元素
设想一个客户端和服务器会话的例子。一个客户端为了连接到服务器,它必须(MUST)发送一个打开标签
那些习惯认为XML是一个以文本为中心风格的人可能希望看看一个与服务器连接的客户端会话,包含两个open-endedXML文档:一个是从客户端到服务器,一个是从服务器到客户端。下图中,根元素
基本上,一个XML流相当于一个会话期间所有XML节的一个信封。我们可以简单的把它描述成下图:
|--------------------|
|
|--------------------|
|
|
|
|--------------------|
|
|
| |
|--------------------|
|
|
|
|--------------------|
| ... |
|--------------------|
|
|--------------------|
4.2. 绑定到TCP
虽然有很多非必需的连接使用XML流来绑定[TCP]连接(两个实体可以通过别的机制来互联,比如通过[HTPP]连接),本规范只定义了 XMPP 到 TCP 的绑定。在客户和服务器通信的过程中,服务器必须(MUST)允许客户端共享一个TCP连接来传输XML节,包括从客户端传到服务器和从服务器传到客户端。在服务器之间的通信过程中,服务器必须(MUST)用一个 TCP连接向对方发送XML节,另一个TCP连接(由对方初始化)接收对方的XML节,一共两个TCP连接。
4.3. 流的安全
在XMPP1.0中,当XML流开始握手时,TLS应该按(章节 5)规定来使用,SASL必须按(章节 6)规定
来使用。尽管可能(MAY)存在某种共有的机制能够保证双向安全,但是“初始化流”(比如从初始化实体
发给接收实体的流)和“应答流”(比如从接收实体发给初始化实体的流)还是必须(MUST)要安全的分
开。在流被验证时,实体不应该(SHOULD NOT)在这个时候尝试通过流发送XML节;就算它这样做了,
对方的实体也不能(MUST NOT)接受这些XML节,并且应该(SHOULD)返回一个
空间中的
4.4. stream 属性
stream 元素的属性如下:
o to -- 'to'属性应该(SHOULD)仅出现在初始化实体发给接收实体的XML流的头当中,并且
它的值必须(MUST)是接收实体所在的主机名。在接收实体发送给初始化实体的XML流的头中不
应该(SHOULD NOT)出现'to'属性。若'to'属性出现在应答流中,则初始化实体应(SHOULD)
忽略它。
o from -- 'from'属性应(SHOULD)仅出现在接收实体发给初始化实体的 XML 流的头当中,并
且它的值必须(MUST)是为当前初始化实体授权的接收实体所在的主机名。注意,不应该(SHOULD
NOT)有 'from'属性出现在初始实体发送给接收实体的 XML流的头中;无论如何,如果'from'
属性出现在初始化流中,接收实体应该(SHOULD)忽略它。
o id -- 'id'属性应该(SHOULD)仅用于接收实体发送给初始化实体的XML流的头信息。这个属性
是一个由接收实体创建的具有唯一性的ID,一个初始实体和接收实体之间的会话ID,并且它在接收方
的应用程序中(通常是一个服务器)必须(MUST)是唯一的。注意,这个流ID必须是足够安全的,
所以它必须是不可预知的和不可重复的(参见[RANDOM]了解如何获得随机性以保证安全性)。不应
该(SHOULD NOT)有'id'属性出现在初始实体发送给接收实体的XML流的头信息中;无论如何,
如果'id'属性出现在初始化流中,接收实体应该(SHOULD)忽略它。
o xml:lang -- 'xml:lang'属性(参见[XML] 2.12)应该(SHOULD)包含在初始化实体发给
接收实体的XML流的头信息中,以指定在流中传输的XML字符所使用的缺省语言。如果这个属性出现
了,接收实体应该(SHOULD)记住它的值,作为初始化流和应答流的缺省属性;如果这个属性没有
出现,接收实体应该(SHOULD)用一个可配置的缺省语言用于双方的流,这个属性值必须(MUST)
在应答流的头信息中传达。对于所有初始化流中传输的节,如果初始实体没有提供'xml:lang'属
性,接收实体应该(SHOULD)应用缺省语言;如果初始实体提供了'xml:lang'属性,接收实体不
能(MUST NOT)修改或删除它(参见9.1.5)。'xml:lang'属性的值必须(MUST)是一个
NMTOKEN(参见[XML] 2.3)并且必须(MUST)遵守 RFC 3066 [LANGTAGS]的规定。
o version -- version属性(最少需要"1.0")为本规范中和流相关的协议提供了支持。关于这个
属性的生成和处理的详细规则将在下文中定义。
我们现在可以总结如下:
| 初始化方 --> 接收方 | 接收方 --> 初始化方
---------+---------------------------+-----------------------
to | 接收方的主机名 | 忽略
from | 忽略 | 接收方的主机名
id | 忽略 | session key
xml:lang | 默认语言 | 默认语言
version | 支持XMPP1.0标识 | 支持XMPP 1.0标识
4.4.1 版本支持
在这里XMPP的版本是"1.0";准确地说,这里囊括了和流相关的所有协议(TLS、SASL、流错误
(章节4.7)、以及三个定义好的XML节类型(
的编号规则是“<主版本号>.<副版本号>”。主版本和副版本号必须(MUST)是独立的整数并且每个号
码可以(MAY)单独以阿拉伯数字增长。这样,"XMPP 2.4"的版本将比"XMPP 2.13"更低。号码前
面的“0”(比如XMPP 6.01中的“0”)必须(MUST)被接收方忽略并且不能(MUST NOT)被发送出去。
如果流和节的格式或者必须的处理方法有了显著的改变,以至于老版本的实体只是简单的忽略它不
能理解的节和属性并继续以老版本规范处理,会使老版本的实体不能够和新版本的实体交互,在这时候
主版本号才应该(SHOULD)增加。副版本号用于标识新的特性,它必须(MUST)被副版本号更低的实
体忽略,但被高(副)版本号的实体用于了解信息。例如,一个副版本号标识该版本有处理"type"属
性的新值(用于message、presence或IQ节)的能力;副版本号高的应该注意到对方不能够理解
"type"属性的新值,所以将不会发送它。
以下规则是用于'version'属性实现流的头信息时如何生成和处理:
1. 初始化实体必须(MUST)在初始化流的头信息中把'version'的值设置成它所支持的最高版
本。(比如,如果最高版本支持就是本规范,那么它必须(MUST)设置成"1.0")。
2. 接收实体必须(MUST)在应答流的头信息中把'version'的值设置成初始化实体所提供的版
本或它所支持的最高版本,取其中版本号较低的那一个。接收实体必须(MUST)把主版本号和副
版本号作为 数字来比较,而不是对"主版本号.副版本号"这个字符串进行比较。
3. 如果在应答流的版本号中至少有一个主版本号低于初始化流的头信息的版本号,并且如前所
述,新版本的实体不能够和旧版本实体交互,初始化实体应该(SHUOULD)生成一个
4. 如果一个实体收到一个头信息中没有'version'属性的流,这个实体必须(MUST)把对方实
体的'version'当成'0.0',并且在回复的应答流的头中也不应该(SHOULD NOT)包含
'version'属性。
4.5. 声明命名空间
流的元素必须(MUST)同时声明流命名空间和缺省命名空间("声明命名空间"定义在XML命名空间定
义[XML-NAMES])。关于流命名空间和缺省命名空间的详细信息,参考命名空间的命名和前缀(参见
11.2)。
4.6. 流的特性
如果初始化的实体在初始化流的头信息中设置'version'属性的为"1.0",接收实体必须(MUST)
向初始化实体发送一个
特性)。目前,这仅用于声明本文中定义的TLS、SASL和资源绑定(参见章节 7),以及XMPP-IM中定义
的会话的建立;无论如何,流特性这一功能将来可以用于声明任何可协商的特性。如果一个实体不理解
或支持安全特性,它应该(SHOULD)忽略它。在一个非安全相关的特性(比如资源绑定)被提议之前,如
果有一个或多个安全特性(比如TLS和SASL)的协商,那么这个非安全相关的特性不应该(SHOULD
NOT)在相应的安全特性协商完毕之前被声明。
4.7. 流错误
流的根元素可以(MAY)包含一个
错误子元素必须(MUST)由感知到发生了流级别错误的实体发送(通常是一个服务器而不是一个客
户端)。
4.7.1. 规则
以下规则适用于流级别的错误:
o 它假定所有流级别的错误都是不可恢复的;所以,如果一个错误发生在流级别,发现这个错误
的实体必须(MUST)发送一个流错误信息给另一个实体,一个关闭标签 ,并终止
这个流所在的TCP连接。
o 如果这个错误发生在流刚开始设置的时候,接收实体必须(MUST)继续发送一个打开标签
终止相应的TCP连接。在这种情况下,如果初始化实体在'to'属性中提供一个未知的主机名,
服务器应该(SHOULD)在终止连接之前,先在流的头信息的 'from' 属性中提供一个服务器
认证的主机名。
4.7.2. 语法
流错误的语法如下:
OPTIONAL descriptive text
[OPTIONAL application-specific condition element]
o 必须(MUST)包含一个子元素以描述下文定义的节错误条件;这个子元素必须(MUST)符合
'urn:ietf:params:xml:ns:xmpp-streams'命名空间.
o 可以(MAY)包含一个
符合'urn:ietf:params:xml:ns:xmpp-streams'命名空间并且应该(SHOULD)拥有
'xml:lang'属性表明XML字符的语言。
o 可以(MAY)包含一个子元素用于描述应用程序的错误信息;这个元素必须(MUST)符合一个应
用程序定义的命名空间,并且它的结构是由那个命名空间定义的。
或调试信息以补充一个已定义条件的或应用程序的条件。它不应该(SHOULD NOT)被一个应用程序
当成一个可编程的信息。它不应该(SHOULD NOT)被用于向用户表达错误信息,但是可以(MAY)
作为和条件元素相关的错误信息的附加说明。
4.7.3. 触发流错误的条件
已定义的触发流级别错误的条件如下:
o
的XML相关的错误替换,比如
当然更多应该使用首选的特定错误。
o
前缀的元素中没有发送一个命名空间前缀(参见 XML Namespace Names and Prefixes
(参见 11.2)).
o
新的流已经被初始化。
o
由一个本地服务策略来配置).
o
由这台服务器提供服务.
o
的主机名不一致.
o
(或者这个属性没有值).
o
器无法提供流服务.
o
配或服务器之间无法通过SASL(或回拨)协商出合法的域名、或客户端和服务器之间无法通过
它进行认证和资源绑定。
o
o
"不相同或回拨命名空间和"jabber:server:dialback"不相同.(参考 XML Namespace
Names and Prefixes (参见11.2)).
o
(参见 11.3)).
o
关的动作,接收实体在发送错误信息之前不允许(MUST NOT)处理违法的节。
o
o
o
o
实体引用、或保留的字符(参考 Restrictions (参见 11.1))。
o
(SHOULD)在
必须(MUST)是合法的域名标识)。
o
o
应该(SHOULD)仅用于"应用程序定义的错误条件"元素.
o
(参照Character Encoding (11.5)).
o
o
所指定的版本不被服务器支持;服务器可以(MAY)在
o
4.7.4. 应用程序定义条件
大家知道,应用程序可以(MAY)在error元素中包含一个命名空间的子元素,用来提供一个应用程
序定义流错误信息。"应用程序定义错误条件"元素应该(SHOULD)补充或甚至限定一个已定义的元素.
所以
Some special application diagnostic information!
4.8 简化的流示例
这里包含两个简化的例子,描述了基于流的客户端在服务器上的“会话”(这里"C"表示从客户端发给
服务器,"S"表示从服务器发给客户端);这些例子只是用于举例说明原理。
一个基本的 "会话":
C:
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
S:
id='someid'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
... encryption, authentication, and resource binding ...
C:
xml:lang='en'>
C: Art thou not Romeo, and a Montague?
C:
S:
xml:lang='en'>
S: Neither, fair saint, if either thee dislike.
S:
C:
S:
一个不成功的 "会话" :
C:
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
S:
id='someid'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
... encryption, authentication, and resource binding ...
C:
Bad XML, no closing body tag!
S:
S:
5. TLS 的使用
5.1. 概述
XMPP包含一个方法用以防止流被篡改和偷窥。这个通道使用了传输层安全协议[TLS]加密方法,随着"STARTTLS"(见RFC 2595 [USINGTLS])的延伸,类似的还有如 IMAP [IMAP]、POP3 [POP3]、ACAP [ACAP]。"STARTTLS"的扩展命名空间是'urn:ietf:params:xml:ns:xmpp-tls'。
一个给定域的管理员可以(MAY)要求client-to-server通信、server-to-server通信时使用TLS,或者两者都要求。客户端应该(SHOULD)在SASL(参见章节 6)握手之前先使用TLS加密,服务器应该(SHOULD)在两个域之间使用TLS以保证服务器间通信的安全。
以下是使用规则:
1. 一个遵守本协议的初始化实体必须(MUST)在初始化流的头信息中包含'version'属性并把值设为“1.0”。
2. 如果TLS握手发生在两个服务器之间,除非服务器声明的DNS主机名已经被解析(参见 14.4),否则通信不能(MUST NOT)继续进行。
3. 当一个遵守本协议的接收实体接收了一个初始化流(初始化流的头信息中包含'version'属性且值为“1.0”),接受实体在发送应答流的头信息(其中包含版本标记)之后,它必须发送(MUST)
4. 如果初始化实体选择使用TLS,那么TLS握手必须在SASL握手之前完成;这个顺序有助于保护SASL握手时的信息安全,同时可以在必要的时候于TLS握手之前,为SASL外部机制提供证书。
5. TLS握手期间,一个实体不能(MUST NOT)在流的根元素中发送空格作为元素的分隔符(在下面的TLS示例中的空格都仅仅是为了便于阅读);这个禁令用来帮助确保安全层字节精度。
6. 接收实体必须(MUST)在发送
7. 初始化实体必须(MUST)验证接收实体提供的证书;关于证书验证流程参见Certificate Validation (参见 14.2)。
8.证书必须(MUST)检查初始化实体(比如一个用户)提供的主机名;而不是通过DNS解析出来的主机名;例如,如果用户指定一个主机名"example.com"而一个DNS SRV [SRV]查询返回"im.example.com",证书必须(MUST)检查"example.com"。如果任何种类的XMPP实体(例如客户端或服务器)的JID出现在证书里,它必须(MUST)是UTF8字符串,存在于subjectAltName之中。如何使用 [ASN.1] 对象标识符 "id-on-xmppAddr" 定义在本文章节 5.1.1。
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 (参见 14.7) 。
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. client-to-server 示例
以下例子展示一个客户端使用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: 服务器通知客户端可以继续进行:
步骤 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 握手 (参见章节 6).
5.4. server-to-server示例
以下例子展示两个服务器之间使用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:
步骤 5: Server2 通知 Server1 允许继续进行:
步骤 5 (或者): Server2 通知 Server1 TLS握手失败并关闭流:
步骤 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).
6. SASL的使用
6.1. 概述
XMPP有一个验证流的方法,即XMPP特定的SASL(简单验证和安全层)[SASL]。SASL提供了一个通用的方法为基于连接的协议增加验证支持,而XMPP使用了一个普通的XML命名空间来满足SASL的需要。
以下为使用规则:
1. 如果SASL协商发生在两台服务器之间,除非服务器宣称的DNS主机名得到解析,否则不能(MUST NOT)进行通信。(参见 14.4).
2. 如果初始化实体有能力使用 SASL 协商, 它必须(MUST)在初始化流的头信息中包含值为"1.0"的'version'属性。
3. 如果接收实体有能力使用 SASL 协商, 它必须(MUST)在应答从初始化实体收到的打开流标签时(如果打开的流标签包含一个值为"1.0"的'version'属性),通过'urn:ietf:params:xml:ns:xmpp-sasl'命名空间中的
4. 当 SASL 协商时, 一个实体不能(MUST NOT)在流的根元素中发送任何空格符号(参考 production [3] content of [XML])作为元素之间的分隔符(在以下的SASL例子中任何空格符号的出现仅仅是为了增加可读性); 这条禁令帮助确保安全层字节的精确度。
5. 当SASL握手时,在XML元素中使用的任何 XML 字符数据必须被编码成 base64, 编码遵循 RFC 3548 第三章的规定。
6. 如果一个"simple username" 被选定的SASL机制所支持,(比如,DIGEST-MD5 和 CRAM-MD5 机制支持,但EXTERNAL 和 GSSAPI 机制不支持), 验证的时候,初始化实体应该(SHOULD)在与服务器通信时提供 “simple username” 自身的发送域(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. 参看强制执行的技术 (参见 14.7) ,了解关于必须(MUST)支持的机制.
6.2. 叙述
一个初始化实体使用SASL和接收实体做验证的步骤如下:
1. 初始化实体请求SASL验证,它发送一个打开的XML流头信息给接收实体,其'version'属性的值为"1.0".
2. 在回复一个XML流头的之后,接收实体声明一份可用的SASL验证机制清单;每个机制作为一个
3. 初始化实体发送一个符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
4. 如有必要,接收实体向初始化实体发送一个符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
5. 初始化实体向接收实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
6. 如有必要,接收实体发送更多的挑战给初始化实体,初始化实体发送更多的回应。
这一系列的 挑战/应答 组,持续进行直到发生以下三件事中的一件为止:
1. 初始化实体向接收实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
2. 接收实体向初始化实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
3. 接收实体向初始化实体发送符合'urn:ietf:params:xml:ns:xmpp-sasl'命名空间的
6.3. SASL 定义
[SASL]的必要条件是要求通过协议定义来提供以下信息:
service name(服务名): "xmpp"
initiation sequence(开始序列): 当初始化实体提供一个打开的XML流头信息并且接收实体正常回应之后,接收实体提供一个有效的验证方法清单。初始化实体从这个清单中选择一个方法,把它作为
exchange sequence(交换序列): 挑战和回应的交换,从接收实体发送给初始化实体的
security layer negotiation(安全层协商): 安全层在接收实体发送
use of the authorization identity(授权ID的使用): 授权ID可在xmpp中用于表示一个客户端的非缺省
6.4. SASL 错误
SASL相关的错误条件定义如下:
o
o
o
o
o
o
o
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",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
步骤 5 (替代): 服务器返回一个错误给客户端:
步骤 6: 客户端发送一个[BASE64]编码的回应这个询问:
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
解码后的回应信息是:
username="somenode",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.com",\
response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
步骤 7: 服务器发送另一个[BASE64]编码的询问给客户端:
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
解码后的询问信息是:
rspauth=ea40f60335c427b5527b84dbabcdfffd
步骤 7 (或者): 服务器返回一个错误给客户端:
步骤 8: 客户端应答这个询问:
步骤 9: 服务器通知客户端验证成功:
步骤 9 (或者): 服务器通知客户端验证失败:
步骤 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. 服务器-服务器 示例
以下例子展示了server-to-server使用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",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
步骤 5 (替代): 服务器2 返回一个错误给 服务器1:
步骤 6: 服务器1 发送一个[BASE64]编码的回应这个询问:
dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v
cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3
LGNoYXJzZXQ9dXRmLTgK
解码后的应答信息是:
username="example.org",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
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 回应挑战:
步骤 8 (或者): 服务器1 中止协商:
步骤 9: 服务器2 通知 服务器1 验证成功:
步骤 9 (或者): 服务器2 通知 服务器1 验证失败:
步骤 10: 服务器1 重新发起一个新的流给 服务器2:
xmlns:stream='http://etherx.jabber.org/streams'
to='example.com'
version='1.0'>
步骤 11: 服务器2 发送一个流头信息应答 服务器1 ,并附上可用的特性(或一个空的features元素).:
xmlns:stream='http://etherx.jabber.org/streams'
from='example.com'
id='s2s_345'
version='1.0'>
7. 资源绑定
在和接收实体完成 SASL 协商(参见章节 6)之后,初始化实体可能(MAY)想要或者需要绑定一个特定的资源到流上.通常这仅适用于客户端: 为了满足本文定义的寻址格式(参见 3.)和节传输规则(参见 10.),客户端
接收到一个成功的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 语义(9.2.3))给服务器来绑定一个资源到流中。
如果客户端端希望允许服务器给自己生成一个资源ID,它可以发送一个包含空的
客户端请求服务器绑定资源:
一个支持资源绑定的服务器必须(MUST)自动生成一个资源ID给客户端。一个由服务器生成的资源ID对于那个
如果客户端希望指定资源ID,它发送一个包含期望资源ID的“set”类型的 IQ节,把资源ID作为
客户端绑定一个资源:
一旦服务器为客户端生成了一个资源ID或接受了客户端自己提供的资源ID,它必须(MUST)返回一个“result”类型的 IQ 节给客户端,这个节必须包含一个指明全JID的
服务器通知客户端资源绑定成功:
一个服务器应该(SHOULD)接受客户端提供的资源ID,但是可以(MAY)用服务器生成的资源ID覆盖它;在这种情况下,服务器不应该(SHOULD NOT)返回错误信息(如
当一个客户端自行提供资源ID时,可能发生以下的节错误(参见 Stanza Errors (参见 9.3)):
o 服务器无法处理客户端提供的资源ID,因为不符合资源字符规范Resourceprep(附录B)。
o 客户端不被允许绑定一个资源(如节点或用户已经达到允许连接的资源数限制)。
o 提供的资源ID已经被使用但是服务器不允许以同一个资源ID绑定多个连接。
协议对这些错误条件规定如下:
资源ID不能处理:
客户端不允许绑定一个资源:
资源ID已经在使用:
如果,在完成资源绑定步骤之前,客户端试图以符合'urn:ietf:params:xml:ns:xmpp-bind'命名空间的
8. 服务器回拨
8.1. 概述
Jabber协议接受的来自XMPP的包括“服务器回拨”方法,用于防治域名欺骗,使得欺骗XML节更为困难。服务器回拨不是一个安全机制,并且它的服务器身份认证结果很弱(参见服务器之间的通信(14.4)中关于这个方法的安全特性)。需要健壮的安全性的域名应该(SHOULD)使用TLS或SASL;细节参见服务器间的通信。如果SASL用于服务器间通信,就不需要用回拨了(SHOULD NOT)。本文描述回拨的好处在于向后兼容现存的实现和部署。
服务器回拨方法使现存的DNS系统的继续使用而成为可能,因为一个服务器(通常)可以查询给定域的授权服务器。由于服务器回拨依赖于DNS,除非服务器宣称的DNS主机得到解析,否则域之间的通信无法进行(参见服务器间的通信(14.4))。
服务器回拨是单向性的,可在单一方向上对一个流进行(微弱的)身份验证.因为服务器回拨不是验证机制,不可能通过回拨获得相互的认证.因此,为了使得服务器之间的双向通信,服务器回拨必须(MUST)在往来的每个方向上都进行。
在服务器回拨中生成和检验密钥的方法必须(MUST)考虑被使用的主机名,由接收服务器生成的流ID,和只有授权服务器才知道的秘密。在服务器回拨中流ID是安全性的关键,所以必须(MUST)是不可预知的和不可重复的(见[RANDOM]中关于使用随机数获得安全性的建议).
任何回拨协商过程中发生的错误必须(MUST)被当成一个流错误,并导致流以及相关的TCP连接的终止.可能发生的错误情况协议中描述如下.
以下术语适用:
o 发起服务器 -- 尝试在两个域之间建立连接的那个服务器.
o 接收服务器 -- 尝试验证发起服务器声明的域名的那台服务器.
o 授权服务器 -- 应答发起服务器声称的DNS主机名的服务器;基本上这应该是那台发起服务器,但是它也可能是一个在发起服务器网络中独立的服务器。
8.2. 事件顺序
以下是回拨中的事件顺序:
1. 发起服务器和接收服务器建立连接。
2. 发起服务器通过连接发送一个 'key' 值给接收服务器。
3. 接收服务器与授权服务器建立连接。
4. 接收服务器发送相同的 'key' 值给授权服务器。
5. 授权服务器回答这个key是否合法。
6. 接收服务器通知发起服务器是否被验证通过。
我们用用以下图形展示这个事件流程:
发起服务器 接收服务器
----------- ---------
| |
| 先建立连接 |
| ----------------------> |
| |
| 发流头信息 |
| ----------------------> |
| |
| 发流头信息 |
| <---------------------- |
| |
| 发key信息 | 授权服务器
| ----------------------> | -------------
| | |
| 先建立连接 |
| ----------------------> |
| |
| 发流头信息 |
| ----------------------> |
| |
| 发流头信息 |
| <---------------------- |
| |
| 发验证请求 |
| ----------------------> |
| |
| 发验证响应 |
| <---------------------- |
|
| 报告回拨结果 |
| <---------------------- |
| |
8.3. 协议
服务器之间互动的细节协议如下:
1. 发起服务器和接收服务器建立TCP连接.
2. 发起服务器发送流头信息给接收服务器:
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'>
注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 其中包含的xmlns:db命名空间向接收服务器声明了发起服务器支持回拨. 如果命名空间不正确,接收实体必须(MUST)生成一个
3. 接收服务器应该(SHOULD)回送一个流头信息给发起服务器,为这次交互生成一个唯一性的ID :
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
id='457F9224A0...'>
注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 如果命名空间不正确,发起服务器必须生成一个
4. 发起服务器发送一个回拨密钥给接收服务器:
from='Originating Server'>
98AF014EDC0...
注意:这个密钥不由接收服务器检查,因为接收服务器在会话之间(between sessions)不保存发起服务器的信息。这个由发起服务器生成的密钥必须(MUST)是基于接收服务器在上一步骤中提供的ID值,以及发起服务器与授权服务器共享的安全机制生成的。如果'to'地址的值和接收服务器知道的主机名不匹配,接收服务器必须(MUST)生成一个
5. 接收服务器向发起服务器声明的那个域建立一个 TCP 连接,作为结果它连接到授权服务器. (注意: 为了优化性能, 在这里一个实现可以(MAY)重用现有的连接.)
6. 接收服务器发送一个流头信息给授权服务器:
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'>
注意: 'to'和'from'属性在流的根元素是可选的(OPTIONAL). 如果命名空间不正确,授权服务器必须生成一个
7. 授权服务器发送流头信息给接收服务器:
xmlns='jabber:server'
xmlns:db='jabber:server:dialback'
id='1251A342B...'>
注意: 如果命名空间不正确,接收服务器必须生成一个
8. 接收服务器发送一个密钥检查请求给授权服务器:
to='Originating Server'
id='457F9224A0...'>
98AF014EDC0...
注意: 现在这里已经有了主机名,第三步中接收服务器发送给发起服务器的ID,第四步中发起服务器发送给接收服务器的密钥. 基于这些信息, 加上授权服务器网络共享的安全信息。这个密钥被证实了,任何可用于验证的办法都可以(MAY)用于生成密钥. 如果 'to' 地址的值和授权服务器知道的主机名不匹配,授权服务器必须(MUST)生成一个
9. 授权服务器检查密钥是否合法:
to='Receiving Server'
type='valid'
id='457F9224A0...'/>
或
to='Receiving Server'
type='invalid'
id='457F9224A0...'/>
注意: 如果 ID 和第三步中接收服务器提供的不符,接收服务器必须(MUST)生成一个
10. 接收服务器通知发起服务器结果:
to='Originating Server'
type='valid'/>
注意: 在这一个点上, 连接已经由 type='valid' 确认验证是通过还是没通过. 如果连接是非法的,接收服务器必须(MUST)终止XML流和相应的TCP连接. 如果连接是合法的, 数据可以从发起服务器发送由接收服务器读取;在此之前,所有发送给接收服务器的XML节应该(SHOULD)被丢弃.
进一步的结果是,接收服务器已经验证了发起服务器的ID,所以通过初始化流("initial stream",例如从发起服务器到接收服务器的流)发起服务器可以发送,并且接收服务器可以接受XML节. 为了使用应答流("response stream",例如从接收服务器到发起服务器的流)验证实体ID,回拨必须(MUST)在相对的两个方向上都完成.
在成功的回拨协商之后, 接收服务器应该(SHOULD)接受接下来发起服务器通过当前的合法连接发送的
即使回拨协商成功了, 服务器仍然必须(MUST)检查从其他服务器接收的所有XML节的'from'和'to'属性; 如果一个节不符合这些限定, 收到这些节的服务器必须(MUST)生成一个
9. XML节
在 TLS 协商(参见 5.)、SASL 协商(参见 6.)、资源绑定(参见 7.)之后, 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或全ID)(参见 地址的决定 Determination of Addresses (3.5.))
如果一个客户端试图发送一个XML节,而它的'from'属性和这个实体已连接的资源不符, 服务器应该(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.2.3)。
9.1.4. type
'type' 属性指明消息、现场信息或IQ节的意图或上下文的详细信息。'type'属性所允许的值根据节的类型是消息、现场信息还是IQ而有很大不同; 用于消息和现场信息节的值定义在即时消息和现场信息应用中,所以在[XMPP-IM|XMPP文档列表/XMPP正式RFC标准/RFC3921]中定义,反之用于IQ节的值定义了在一个 请求-应答 的“会话”中IQ节的角色,所以定义在IQ语义学中(参见 9.2.3)。 所有三种节的通用'type'值是"error";见Stanza Errors (参见 9.3.)。
9.1.5 xml:lang
如果一个节包含用于显示给人看的XML字符数据(在RFC 2277中有所解释[CHARSET],"internationalization is for humans"),这个节应该(SHOULD)处理一个'xml:lang'属性(定义在2.12[XML])。 'xml:lang'属性的值指明任何一个人类可读的XML字符数据的缺省语言, 它可以(MAY)被特定的子元素的'xml:lang'值重载。 如果一个节不处理一个'xml:lang'属性,一个实现必须(MUST)认为缺省的语言就是流属性中定义的语言(参见 4.4). 'xml:lang'属性值必须(MUST)是一个 NMTOKEN 并且必须(MUST)遵守 RFC 3066 [LANGTAGS]中定义的格式.
9.2. 基本语义学
9.2.1. 消息语义学
9.2.2. 现场信息语义学
9.2.3. IQ语义学
信息/查询(Info/Query),或曰IQ,是一个 请求-回应 机制,某些情况下类似[HTTP].IQ语义学使一个实体能够向另一个实体做出请求并做出应答. 请求和应答所包含的数据定义在IQ元素的一个直接的子元素的命名空间中声明, 并且由请求实体用'id'属性来跟踪这一交互行为. 因而,IQ交互伴随着一个结构化的数据交换的通用模式例如 get/result 或 set/result (尽管有时候会以一个错误信息应答某个请求):
请求实体 响应实体
---------- ----------
| |
|
| ------------------------> |
| |
|
| <------------------------ |
| |
|
| ------------------------> |
| |
|
| <------------------------ |
| |
为了强制执行这些语义学,要应用以下规则:
1. 对于IQ节来说'id'属性是必需的(REQUIRED).
2. 对于IQ节来说'type'属性是必需的(REQUIRED). 它的值必须(MUST)是以下之一:
* get -- 这个节是一个对信息或需求的请求.
* set -- 这个节提供需要的数据, 设置新的值, 或取代现有的值.
* result -- 这个节是对一个成功的 get 或 set 请求的应答.
* error -- 发生了一个错误,关于处理或递送上次发送的 get 或 set的(参见 节错误 Stanza Errors(参见 9.3)).
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. 节错误
节相关错误的处理方式类似流错误(参见 4.7). 但是它不像流错误, 节错误是可恢复的;所以错误节响应数据暗示发送者可以采取什么行动来补救这个错误.
9.3.1. 规则
以下规则适用于节相关的错误:
o 接收或处理实体察觉到一个节相关的错误条件时应该(MUST)返回给发送实体一个同类型的节(消息,出席信息,或IQ),这个节的'type'属性值则设置为"error"(这里这样的节称之为"error stanza").
o 生成一个错误节的实体应该(SHOULD)包含原来发送的XML,这样发送者可以检查它,并且如果必要,在尝试重新发送之前纠正它.
o 一个错误节必须(MUST)包含一个
o 如果'type'属性值不是"error"(或没有"type"属性),节不能(MUST NOT)包含一个
o 接收到一个错误节的实体不能(MUST NOT)应答这个节更多的错误节; 这有助于防止死循环.
9.3.2. 语法
节相关错误的语法如下:
[RECOMMENDED to include sender XML here]
OPTIONAL descriptive text
[OPTIONAL application-specific condition element]
stanza-kind 是 message, presence, 或 iq 中的一个.
o cancel -- 不重试(这个错误是不可恢复的)
o continue -- 继续进行(这个条件只是一个警告)
o modify -- 改变数据之后重试
o auth -- 提供证书之后重试
o wait -- 等待之后重试(错误是暂时的)
o 必须(MUST)包含一个子元素,符合以下定义的节错误条件之一;这个元素(MUST)符合'urn:ietf:params:xml:ns:xmpp-stanzas'命名空间.
o 可以(MAY)包含一个
o 可以(MAY)包含一个应用程序定义的错误条件子元素;这个元素必须(MUST)符合一个应用程序定义的命名空间,并且它的结构由这个命名空间定义.
o
最后,为了维护向后兼容性, 这个schema (定义在[XMPP-IM|XMPP文档列表/XMPP正式RFC标准/RFC3921])允许可选的在
9.3.3. 已定义的条件
以下条件定义用于节错误.
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
9.3.4. 应用程序定义条件
大家知道,一个应用程序可以(MAY)通过在错误元素里包含一个适当命名空间的子元素来提供应用程序定义的节错误信息. 应用程序定义的元素应该(SHOULD)补充或进一步限定一个已定义的元素. 因而,
Some special application diagnostic information...
10. 服务器处理XML节的规则
兼容的服务器必须(MUST)确保两个实体之间的XML节按次序处理.
在按次序处理的需求之外, 每个服务器实现将包含它自己的递送树"delivery tree"以处理它接收到的节.这个树决定一个节是否需要路由到其他域, 在内部处理, 还是递送到和一个已连接的节点相关的资源. 以下规则适用:
10.1. 没有'to'地址
如果这个节没有'to'属性, 服务器应该(SHOULD)为发送它的实体处理这个节. 因为所有从其他服务器收到的节必须(MUST)拥有'to'属性, 这个规则仅适用于从一个连接到这台服务器的已注册实体(如一个客户端)收到的节.如果这个服务器收到一个没有'to'属性的现场信息节, 服务器应该(SHOULD)向那些订阅了这个发送实体的出席信息的所有实体广播它, 如果可能的话(即时消息和现场信息应用程序中现场信息广播的语义定义在[XMPP-IM|XMPP文档列表/XMPP正式RFC标准/RFC3921]). 如果服务器接收到一个类型为"get" 或 "set" 的没有'to'属性的节并且它理解这个节的命名空间下的内容, 它必须(MUST)为这个发送实体处理节(在这里"process"的含义是由相关的命名空间的语义所决定的)或返回一个错误给发送实体.
10.2. 外部域
如果'to'属性中的JID的域ID部分的主机名和服务器自身或其子域配置的主机名不匹配, 服务器应该(SHOULD)路由这个节到外部域(取决于本地服务规定或安全策略关于域间通信的规定).有两种可能的情况:
一个服务器之间的流已经存在于两个域之间: 发送者的服务器通过这个已存在的流为这个外部域路由这个节到授权服务器。
两个域之间不存在服务器间的流: 发送者服务器 (1) 解析这个外部域的主机名(定义在服务器间的通信Server-to-Server Communications (14.4)), (2) 在两个域之间进行服务器到服务器的流协商(定义在 Use of TLS (参见 5.) 和 Use of SASL (参见 6.)), 然后 (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(例如, 格式是
3. 如果这个JID的格式是
11. XMPP中的XML用法
11.1. 限制
XMPP是一个简单的流式XML元素的专用协议,用于接近实时地交换结构化信息. 因为XMPP不需要任意的解析和所有的XML文档, 所以XMPP不需要支持[XML]的所有功能. 属于特殊情况, 需要符合以下限制.
关于XML生成, 一个XMPP实现不能(MUST NOT)在XML流中注入以下任何东西:
o 注释 (参见 2.5 )
o 处理指示(参见 2.6)
o 内部或外部的 DTD 子集 (参见 2.8)
o 内部或外部的实体参考 (参见 4.2 ) 除了预定实体以外(参见 4.6)
o 字符数据或属性值包含和预定实体列表中吻合的未逃逸的unescaped字符(参见 4.6); 这些字符必须(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)只支持这两个缺省命名空间):
o jabber:client -- 当流用于客户端和服务器的通信时声明这个缺省命名空间
o 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)支持通用属性(参见 9.1)和三个核心节类型(message, presence, 和IQ)的基本语义(参见 9.2).
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|XMPP文档列表/XMPP正式RFC标准/RFC3921]的相关章节中定义.
12.1. 服务器
除了所有已定义的关于安全、XML使用和国际化的要求之外, 一个服务器还必须(MUST)支持以下核心协议以保证兼容性:
o 应用寻址[STRINGPREP] 的 [NAMEPREP]、Nodeprep (附录 A)和Resourceprep (附录 B) profiles (包括确保域ID是[IDNA]中定义的国际化域名)
o XML流、TLS、SASL和资源绑定
o 节基本语义(参见 9.2)中已定义的节类型(即,
o 生成错误的语法及相关的流, TLS, SASL, 和 XML节的语义
另外, 一个服务器可以(MAY)支持以下核心协议:
o 服务器回拨
12.2. 客户端
一个客户端必须(MUST)支持以下核心协议以满足兼容性:
o XML流、TLS、SASL和资源绑定
o 节基本语义(参见 9.2)中已定义的节类型(即,
o 处理(并且, 如果可能, 生成) 错误的语法及相关的流, TLS, SASL, 和 XML节的语义
另外, 一个客户端应该(SHOULD)支持以下核心协议:
o 应用寻址[STRINGPREP] 的 [NAMEPREP], Nodeprep (附录 A),和 Resourceprep (附录 B) profiles
13. 国际化事项
XML流在Character Encoding(参见 11.5)中定义为必须(MUST)被编码成UTF-8. 在Stream Attributes(参见 4.4)中特别定义了, 一个XML流应该(SHOULD)包含一个'xml:lang'属性,它被认为是通过这个用于人类用户解读的流发送的任何XML字符数据的缺省语言. 在 xml:lang (参见 9.1.5)特别定义了, 如果一个XML节是用来给人类用户解读,这个节应该(SHOULD)包含一个'xml:lang'属性. 服务器在为连接的实体路由或递送节的时候应该(SHOULD)应用缺省的'xml:lang'属性, 并且不能(MUST NOT)修改或删除它从其他实体收到的节的'xml:lang'属性.
14. 安全性事项
14.1. 高安全性
对于XMPP通信的目的(client-to-server 和 server-to-server), "高安全性"条款谈的是相互验证和完整性检查的安全技术使用; 特别是, 当使用基于证书的验证来提供高安全性, 应该(SHOULD)建立一个的信任链的波段,尽管一个共享签名证书可能允许以前未知的证书在波段内建立信任关系. 参见以下章节 14.2 关于证书确认程序.
必须(MUST)支持高安全性. 服务提供者应该(SHOULD)基于本地安全策略使用高安全性.
14.2. 证书验证
当一个XMPP peer和另一个XMPP peer进行安全通信, 它必须(MUST)确认对方终端的证书.有三种可能的情况:
Case #1: peer包含一个终端实体证书,以根证书的证书链中一环出现(见[X509]中的章节 6.1.).
Case #2: peer的证书由一个对方未知的证书授权.
Case #3: peer的证书由自己签名.
在Case #1, 确认方必须(MUST)做以下两条之一:
1. 根据[X509]的规则验证对方证书.然后证书应该(SHOULD)被对方在[HTTP-TLS]中描述的规则反向验证预期的身份。但如果"xmpp"是subjectAltName扩展类型,则必须(MUST)使用证书中的显示的身份。如果这两项验证之一失败,用户导向的客户端必须(MUST)通知用户(客户端可以(MAY)给用户机会重新连接)或以一个坏证书的错误终止连接。自动客户端应该(SHOULD)终止连接(以一个坏证书错误)并在适当的日志中记录这个错误。自动客户端可以(MAY)提供一个配置设置成禁止检查,但同时必须(MUST)提供一个激活检查的配置。
2. peer应该(SHOULD)出示证书给用户用于验证,包括完整的证书链.peer必须(MUST)缓存这个证书(或一些其他不会忘记的方式比如一个哈希值).在将来的连接中,peer必须(MUST)展示相同的证书并且如果改变了证书必须(MUST)通知用户.
在Case#2 和 Case #3, 实现应该(SHOULD)上述第二条.
14.3. 客户端-服务器通信
一个兼容的客户端必须(MUST)支持TLS和SASL用于连接到服务器.
用于加密XML Stream 的TLS协议(在 Use of TLS(章节 5.)定义)提供可信的机制帮助确保机密性和实体之间数据交换的完整性.
用于验证XML Stream 的SASL协议(在 Use of SASL(章节 6.)定义)提供可靠的机制用于确认一个连接到服务器的客户端确实是它自己所声明的那个客户端.
服务器宣称的DNS主机名被解析之前,client-to-server 通信不能(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)支持服务器回拨(章节 8.).
因为服务提供者是一个策略问题,对于任何给定域和其他域的通信中,它都是可选的(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",因为以前的用法不符合[SRV]标准;希望保持向后兼容的实现可以继续查找或应答"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 (参见 15.)). 使用这些广为人知的端口允许管理员很容易的通过一般的防火墙来激活或禁止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]章节 3 的定义执行。
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 (章节 6.3.)定义了.
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", RFC 2234, November 1997.
[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", RFC 2831, May 2000.
[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", RFC 2743, January 2000.
[HTTP-TLS] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.
[IDNA] Faltstrom, P., Hoffman, P., and A. Costello, "Internationalizing Domain Names in Applications (IDNA)", RFC 3490, March 2003.
[IPv6] Hinden, R. and S. Deering, "Internet Protocol Version 6 (IPv6) Addressing Architecture", RFC 3513, April 2003.
[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)", RFC 3491, March 2003.
[RANDOM] Eastlake 3rd, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750, December 1994.
[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)", RFC 2782, February 2000.
[STRINGPREP] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002.
[TCP] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981.
[TERMS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
[TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246, January 1999.
[UCS2] International Organization for Standardization, "Information Technology - Universal Multiple-octet coded Character Set (UCS) - Amendment 2: UCS Transformation Format 8 (UTF-8)", ISO Standard 10646-1 Addendum 2, October 1996.
[UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 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", RFC 3280, April 2002.
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, "Extensible Markup Language (XML) 1.0 (2nd ed)", W3C REC-xml, October 2000,
[XML-NAMES] Bray, T., Hollander, D., and A. Layman, "Namespaces in XML", W3C REC-xml-names, January 1999,
16.2. 信息参考
[ACAP] Newman, C. and J. Myers, "ACAP -- Application Configuration Access Protocol", RFC 2244, November 1997.
[ASN.1] CCITT, "Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1)", 1988.
[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", RFC 2779, February 2000.
[IRC] Oikarinen, J. and D. Reed, "Internet Relay Chat Protocol", RFC 1459, May 1993.
[JEP-0029] Kaes, C., "Definition of Jabber Identifiers (JIDs)", JSF JEP 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",
[POP3] Myers, J. and M. Rose, "Post Office Protocol - Version 3", STD 53, RFC 1939, May 1996.
[SIMPLE] SIMPLE Working Group, "SIMPLE WG",
[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", RFC 2396, August 1998.
[USINGTLS] Newman, C., "Using TLS with IMAP, POP3 and ACAP", RFC 2595, June 1999.
[XML-REG] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, January 2004.
RFC3921 Saint-Andre, P., Ed., "Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence", RFC 3921, October 2004.
附录 A. Nodeprep
A.1. 介绍
这个附录定义了 "Nodeprep" profile of [STRINGPREP]. 它定义的规则能让用户能够在XMPP中输入国际化节点标识符并尽可能正确的获取正确的字符内容. (一个XMPP节点标识符是XMPP地址的可选部分,它在域名标识符和那个'@'分隔符之前;它经常但不是专门用来关联一个即时消息用户名)这些处理规则仅仅适用于XMPP节点标识符但不适用于任意文本或任何XMPP的其他方面.
这个脚本定义了以下这些, 正如 [STRINGPREP]要求的:
o 脚本预期的适用性: XMPP的国际化节点标识符
o 用于stringprep的输入输出字符集: Unicode 3.2, 定义在附录 A.2
o 使用的映射: 定义在章节 3.
o Unicode正规化使用: 定义在章节 4.
o 禁止输出的字符串: 定义在章节 5.
o 双字节字符处理: 定义在章节 6.
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, 定义在附录B.2
使用的映射: 定义在章节 3.
Unicode正规化使用: 定义在章节 4.
禁止输出的字符串: 定义在章节 5.
双字节字符处理: 定义在章节 6.
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' 命名空间的标准定义, 参照 RFC3921.
C.1. Streams namespace
targetNamespace='http://etherx.jabber.org/streams'
xmlns='http://etherx.jabber.org/streams'
elementFormDefault='unqualified'>
xmlns:db='jabber:server:dialback'>
maxOccurs='unbounded'/>
maxOccurs='unbounded'/>
xmlns:bind='urn:ietf:params:xml:ns:xmpp-bind'
xmlns:sess='urn:ietf:params:xml:ns:xmpp-session'>
maxOccurs='1'/>
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
targetNamespace='urn:ietf:params:xml:ns:xmpp-tls'
xmlns='urn:ietf:params:xml:ns:xmpp-tls'
elementFormDefault='qualified'>
minOccurs='0'
maxOccurs='1'
type='empty'/>
C.4. SASL namespace
targetNamespace='urn:ietf:params:xml:ns:xmpp-sasl'
xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
elementFormDefault='qualified'>
type='xs:string'/>
use='optional'/>
C.5. Resource binding namespace
targetNamespace='urn:ietf:params:xml:ns:xmpp-bind'
xmlns='urn:ietf:params:xml:ns:xmpp-bind'
elementFormDefault='qualified'>
C.6. Dialback namespace
targetNamespace='jabber:server:dialback'
xmlns='jabber:server:dialback'
elementFormDefault='qualified'>
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 RFC3921 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
protocol to prevent server poofing. 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
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: [email protected]
完整的版权声明
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 [email protected].
感谢
目前为RFC编辑活动提供资金的Internet Society.