RFC6122
"本文的英文原文来自RFC 6122
互联网工程任务组(IETF) | P. Saint-Andre |
申请讨论: 6122 | Cisco |
更新: 3920 | 2011年3月 |
类别: 标准跟踪 | |
ISSN: 2070-1721 |
- 可扩展的消息和出席信息协议 (XMPP): 地址格式
摘要
- 本文定义了可扩展的消息和出席信息协议(XMPP)中使用的地址的格式, 包括支持非ASCII的字符串. 本文更新了 RFC 3920.
本文的状态
- 这是一个互联网标准跟踪文档.
- 本文是互联网工程工作组(IETF)的一个成果. 它代表了IETF社区的一致意见. 它已经公开审核并由互联网工程控制组(IESG)批准发布了. 更多关于互联网标准的信息请参见RFC 5741第2章.
- 关于本文当前状态的信息, 任何错误, 以及如何对它提出反馈,请到 http://www.rfc-editor.org/info/rfc6122 .
版权通知
- Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.
- This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
目录 |
序论
概述
可扩展的消息和出席信息协议(XMPP)是一个 XML 应用规范,用于在任意两个或多个网络实体之间接近实时的传输XML数据流. XMPP实体的地址格式在1999年就已经 由Jabber开源社区开发出来, 第一次出现在 XEP‑0029 中是2002年, 规范化定义是2004年的 RFC3920 .
正如RFC 3920中所定义的, XMPP地址格式重用了 "stringprep" 技术来预备非ASCII字符串 STRINGPREP , 包括用于国际化域名的名字空间规范,定义于 NAMEPREP 和 IDNA2003 ,对应于两个XMPP特有的用于 localpart(本地部分) 和resourcepart(资源部分)的规范.
由于RFC 3920的发布, IDNA2003被IDNA2008取代 (见 IDNA‑PROTO , 它不是基于stringprep的. 随着IDNA社区的倡导, 其他使用stringprep的技术社区开始讨论从stringprep迁移到更"现代的"方法. XMPP社区(主要是 PRECIS 工作组)为了寻找RFC3920中定义的stringprep中的Nodeprep和Resourceprep的替代品,参与了那些讨论. 因为XMPP修订文档的所有其他问题都合并到 XMPP 了, XMPP工作组决定暂时分离出XMPP地址格式到一个独立的文档,这样不会延迟改进的XMPP文档的发布. 一旦新的国际化地址的预备和比较方法被完成,预期本文将被废弃.
所以, 本协议提供更正过的XMPP地址格式文档,使用2004年可用的国际化技术(当时RFC 3920发布了). 尽管本文主要参考了 IDNA2003 和 NAMEPREP , 但是鼓励XMPP软件开发者开始迁移到IDNA2008 (见 IDNA‑PROTO 以及相关文档) ,因为将来取代本协议的新协议将使用IDNA2008而不是IDNA2003.
本文更新了RFC 3920.
术语
本文使用的很多重要术语定义于 IDNA2003 , [RFC6122#STRINGPREP|STRINGPREP]] , UNICODE , 和XMPP .
本文的关键字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 和 "OPTIONAL" 的解释参见 RFC 2119 关键字 .
地址
基础
一个XMPP实体就是任何可网址化并能使用XMPP通讯的东西. 由于历史原因, 一个XMPP实体的本地地址叫Jabber身份或JID. 一个合法的JID就是一个 UNICODE 代码所代表的字符串, 使用 UTF‑8 编码, 结构顺序是 localpart(本地部分), domainpart(域部分), 和resourcepart (资源部分)(这里前两个部分使用 '@' 字符分割, 而后两个部分使用 '/' 字符分割).
JID的语法定义如下,使用增强巴科斯-诺尔范式(ABNF).
jid = [ 本地部分 "@" ] 域部分 [ "/" 资源部分 ] 本地部分 = 1*(节点) ; ; 一个 "节点" 就是一个UTF-8编码的Unicode代码点 ; 这个点满足 stringprep 中的 Nodeprep 范例 ; 域部分 = IP文字 / IPv4地址 / 合法域名ifqdn ; ; "IPv4地址" 和 "IP文字" 规则 定义于 RFC 3986, ; 匹配过程应用 RFC 3986 定义的 ; 先到先得匹配(又名 "贪婪的") 机制 ; ; 注意从RFC 3986中对于 IP文字规则的重用 ; 意味着 IPv6地址由方括号包住 ; (也就是, 用 '[' 开始用 ']' 结束), ; 这个 RFC 3920 不管了 ; ifqdn = 1*(名字点) ; ; 一个 "名字点" 就是一个UTF-8编码的Unicode码点, ; 符合 stringprep 的 Nameprep 规范 ; resourcepart = 1*(资源点) ; ; 一个 "资源点" 就是一个UTF-8编码的Unicode码, ; 符合 stringprep 的 Resourceprep 规范 ;
所有JID都是基于上述结构.
一个JID的每个允许的部分 (本地部分, 域部分, 和资源部分) 的字节数必须不(MUST NOT)为零并且必须不(MUST NOT)大于1023, 也就是总的最大字节数 (包含 '@' 和 '/' 分割符) 为3071.
为了达到通过一个XMPP网络(例如, 一个XMPP节的 'to' 或 'from' 地址)来通讯的目的, 实体的地址必须(MUST)展现为一个JID, 而不是统一资源标识符 URI 或 国际化资源标识符 IRI . 一个 XMPP‑URI 本质上是一个JID带上一个 'xmpp:' 前缀; 无论如何, 用于XMPP的本地地址格式仅仅是一个不带URI方案的JID. XMPP‑URI 仅被用于XMPP自身的上下文在外部的标识和交互, 例如当从一个web页面连接到一个JID. XMPP‑URI 描述了这个如何安全的从一个XMPP URI 或 IRI 提取出一个JID的过程.
- 实现备注: 当把一个JID分解成它的各个部分时, 一个应用在使用任何转换机制之前需要匹配分隔符 '@' 和 '/' , 因为转换可能导致把特定的Unicode码点分解成分隔符(例如, U+FE6B SMALL COMMERCIAL AT 可能分解成 U+0040 COMMERCIAL AT).
域部分
一个JID的域部分就是 '@' 符号(如果有这个符号)后面和 '/' 符号(如果有)前面的部分; 它是一个主要的标识符并且是一个JID唯一必需的(REQUIRED)元素(仅仅是域部分就可以成为一个合法的JID). 一个典型的域部分标识了客户端连接的 "家" 服务器,它用来做XML路由和数据管理功能. 无论如何, 一个XMPP域部分不一定就是标识一个提供核心XMPP服务功能的实体 (例如, 一个域部分可能标识其他实体,例如一个多用户聊天服务, 一个发行-订阅服务, 或一个用户目录).
每个XMPP服务的域部分必须(MUST)是一个完全规范的域名(FQDN; 见 DNS ), IPv4地址, IPv6地址, 或自定义的主机名(也就是说, 一个文本标签,可在本地网络解析).
- 互操作性备注: 域部分是IP地址,可能无法被其他服务接受来进行服务器到服务器的通讯, 域部分是自定义的主机名不能用于公共网络,因为它只能被本地网络解析.
如果域部分的最后一个字符被认为是 IDNA2003 或 DNS 中的分隔标签 (点) , 在使用JID的域部分来路由一个XML节,和另一个JID做比较,或构建一个 XMPP‑URI 之前,必须把这个字符从域部分剥离出来. 特别是, 在进行任何其他规范化步骤 (例如应用 STRINGPREP 的 NAMEPREP 范本,或完成 IDNA2003 描述的转化成ASCII的操作)之前,这个字符必须剥离出来.
包含完全合格域名的域部分必须是一个IDNA2003定义的"国际化的域名"; 就是说, 它必须是"一个每个标签都是国际化标签的域名"并且必须遵循IDNA2003定义的国际化域名构造规则. 当准备一个文本标签(包括一系列的UTF-8编码的Unicode代码点)用于在构造XMPP域部分或比较两个XMPP域部分的过程中展示一个国际化标签, 应用必须确保每个文本标签可能应用于设置UseSTD3ASCIIRules标志(从而禁止除了字母,数字,和连字符的ASCII代码点)而不会出现IDNA2003定义的失败的ToASCII操作. 如果该ToASCII操作能被应用而不失败, 那么该标签是一个国际化标签. (注意: 该ToASCII操作包括STRINGPREP的NAMEPREP范本的应用并且编码使用PUNYCODE定义的机制; 详细信息参见IDNA2003.) 尽管XMPP应用通讯在线上的输出不会超出ToASCII操作(所谓一个"ACE标签"), 它必须有可能应用那个操作而不会导致每个国际化标签的失败. 如果一个XMPP应用接收ACE标签输入, 它应该在把该标签包含进一个将在一个XMPP网络上进行线上通讯的XMPP域部分之前使用ToUnicode操作(见IDNA2003)把那个ACE标签转化为一个国际化标签(无论如何, 除了转换标签, 有合理的理由一个应用可以拒绝输入并返回一个错误给提供这些唐突数据的实体).
域部分的长度不能(MUST NOT)为零并且不能(MUST NOT)超过1023个字节. 在从stringprep的Nameprep范本的应用得到任何映射或正规结果之后,这个规则是强制的. 很自然, DNS的长度限制也适用, 并且本文中的解释没有覆写更多的根本限制.
在 IDNA2008 IDNA‑DEFS的术语中, JID的域部分是一个"域名插槽".
本地部分
JID的本地部分是一个可选的标识符,放在域部分的前面并且用'@'字符分隔开. 一个典型的本地部分唯一性地标识由服务器提供的请求和使用网络访问的实体(即, 一个本地帐号), 尽管它也代表其他种类的实体(例如, 一个和多用户聊天服务相关的聊天室). 由一个XMPP本地部分代表的实体的寻址则要看具体的域上下文(即, <localpart@domainpart>).
一个本地部分必须被格式化,使得STRINGPREP的Nodeprep范本能被应用而不失败(见 附录A). 在比较两个本地部分之前, 应用必须首先确保Nodeprep范本被应用于每一个标识符(该范本不需要每次做比较的时候应用, 因为在比较之前它已经被应用了).
本地部分的长度不能(MUST NOT)为零并且不能(MUST NOT)超过1023个字节. 在从stringprep的Nodeprep范本的应用得到任何映射或正规结果之后,这个规则是强制的. (例如, 在Nodeprep中,一些字符串可能被映射为空, 这可能产生一个长度为零的字符).
资源部分
JID的资源部分是一个可选的标识符,放在域部分的后面,以'/'符号分隔. 一个资源部分能改变<localpart@domainpart>地址或纯<domainpart>地址. 典型的一个资源部分唯一性地标识一个属于某域的某个本地部分相关实体的特定连接(例如, 一个设备或地点)或对象(例如, 一个多用户聊天室中的某个房客)(即, <localpart@domainpart/resourcepart>).
一个资源部分必须被格式化,使得STRINGPREP的Resourceprep范本能被应用而不失败(见 附录B). 在比较两个资源部分之前, 应用必须首先确保Resourceprep范本被应用于每一个标识符(该范本不需要每次做比较的时候应用, 因为在比较之前它已经被应用了).
资源部分的长度不能(MUST NOT)为零并且不能(MUST NOT)超过1023个字节. 在从stringprep的Resourceprep范本的应用得到任何映射或正规结果之后,这个规则是强制的. (例如, 在Resourceprep,一些字符串可能被映射为空, 这可能产生一个长度为零的字符).
- 信息备注: 由于历史原因, 术语 "资源标识符" 在XMPP中经常被用于代表一个XMPP地址的可选部分,跟随在域部分之后的"/"分隔符后面; 为了帮助防止混淆XMPP "资源标识符" 和 URI的的章节1.1中的"资源" 的含义以及 "标识符"的含义, 本协议使用术语"资源部分"来替代之前的"资源标识符" (在RFC 3920中).
XMPP实体应该把资源部分当成不透明的字符串并且不应该(SHOULD NOT)推诿含义给任何给定的资源部分. 特别是:
- 在域部分和资源部分之间使用'/'符号作为分隔符不代表XMPP地址是以那种方式分层的, 也就是说像HTTP地址那样分层; 所以,举例来说,一个格式为<localpart@domainpart/foo/bar>的XMPP地址不代表一个资源"bar"在一个和实体"localpart@domain"相关的资源层级中位于一个资源"foo"之下.
- '@'符号被允许出现在资源部分并且经常在XMPP聊天室中被用于显示"昵称". 例如, JID <room@chat.example.com/user@host> 描述了一个实体,它是房间<room@chat.example.com>的房客,(声称的)昵称为<user@host>. 无论如何, 聊天室服务不必要怎对该房客的真实JID来检查这样一个被声称的昵称.
国际化事项
XMPP服务器必须, XMPP客户端应该, 对域部分支持IDNA2003(包括STRINGPREP的NAMEPREP范本), 对本地部分支持STRINGPREP的Nodeprep范本, 以及对资源部分支持STRINGPREP的Resourceprep范本; 这使得XMPP地址能包含各种超出US-ASCII范围的字符串. XMPP地址的强制性规则在XMPP中提供.
安全事项
Stringprep的重用
STRINGPREP中描述的安全性事项适用于本文中定义的XMPP本地部分和资源部分的Nodeprep和 Resourceprep范本. STRINGPREP和NAMEPREP中描述的适用于Nameprep范本的安全性事项在这里被重用于XMPP域部分.
Unicode的重用
在UNICODE‑SEC中描述的安全性事项适用于在XMPP地址中使用Unicode字符串.
地址欺骗
有两种形式的地址欺骗: 锻造和模仿.
地址锻造
在XMPP技术的上下文中, 当某个实体能够生成一个XML节,而该节的'from'地址和该实体网络验证的帐号凭证(或在XMPP所述的SASL验证SASL的协商过程中提供的一个授权身份)不符的时候,就发生了地址锻造. 例如, 如果一个被验证为"juliet@im.example.com"的实体能从"nurse@im.example.com"或"romeo@example.net"发送XML节,就发生了地址锻造.
在XMPP系统中地址锻造是很难的, 根据需求,发送的服务器会标记'from'地址,并且对于接收服务器来说是通过服务器-服务器验证(见XMPP)来验证发送的域. 无论如何, 地址锻造在以下情况下可能发生:
- 一个实现得差劲的服务器忽略了标记'from'地址需求. 这将使得验证到该服务器的任何实体从任何localpart@domainpart发送节,只要域部分和该服务器的发送域匹配.
- 一个活跃的恶意服务器代表任何已注册的帐号生成节.
所以, 一个超出某特定服务器的安全边界的实体不能可靠地辨别那台服务器的格式为<localpart@domainpart>的各个JIDs,从而在任何担保级别上只能验证这些JIDs的域部分. 本协议不定义发现或对抗这类差劲实现或流氓服务器的方法. 无论如何, 端到端的验证或XMPP节的签名有助于减轻这个风险, 因为它将要求该流氓服务器除了修改'from'地址之外生成假凭证.
此外, 如果没有使用DNS安全扩展DNSSEC, 攻击者可能通过所谓DNS污染攻击来锻造其他域的JIDs.
地址模仿
当一个实体提供了合法的验证身份并且从一个其JID看起来是一个自然人并和另一个JID相同的帐号发送XML节, 就发生了地址模仿.例如, 在一些XMPP客户端里地址"ju1iet@example.org"(本地部分的第三个字符是数字1)可能看起来和"juliet@example.org (小写的字母"L")相同, 特别是在非正式的目测检查的情况下; 这种现象有时被称为"输入注入". 一个更复杂的地址模仿的例子可能包括使用Unicode代码点的非常用Latin扩展A区的字符串, 比如来自Cherokee区的类似字符串 U+13DA U+13A2 U+13B5 U+13AC U+13A2 U+13AC U+13D2 来取代看起来类似的 US-ASCII 字符串"STPETER".
在一些地址模仿的例子中, 普通用户不会说得出真实JID和假JID的差别. (实际上, 没有编程的办法来完全肯定地区分哪个是假JID哪个是真JID; 在一些通信上下文中, Cherokee字符串格式的JID可能是真JID而US-ASCII字符串格式的JID可能才是假JID.) 因为JIDs能包含几乎任何正确编码的Unicode代码点, 在XMPP系统中能很容易地模仿某些JIDs. 地址模仿的可能性介绍了这种安全漏洞,它也困扰着国际互联网, 特别是网络钓鱼的现象.
这些问题的出现是因为Unicode和ISO/IEC 10646的条目有很多字符看起来相似(所谓"易混淆的字符"或"易混淆的"). 在很多情景下, XMPP用户可以执行目视匹配, 例如当比较通讯伙伴的JIDs时. 因为没有大量上下文(例如知道使用的字体)不可能映射看起来相似的字符, stringprep和基于stringprep的技术,例如 Nameprep, Nodeprep, 以及 Resourceprep, 对于把看起来相似的字符映射在一起不做任何干涉, 它们也不会因为字符之间相似而禁止一些字符. 结果是, XMPP本地部分和资源部分可能包含易混淆的字符, 使得其JIDs看起来像模仿的其他JIDs并且因而导致安全漏洞如下:
- 在XMPP中一个本地部分可以被当成一个实体的地址的一部分. 一个常见的用法是用作一个即时消息用户的用户名; 另一个是用作一个多用户聊天室的名字; 并且很多其他种类的实体可以把本地部分作为它们的地址的一部分. 这类服务的安全性可能基于国际化的本地部分的不同诠释而做出妥协; 例如, 一个进入单一国际化本地部分的用户可以访问另一个用户的帐号信息, 或一个用户可以获得对某个隐藏或受限的聊天室或服务的访问权.
- 在XMPP中一个资源部分可以被当成一个实体的地址的一部分. 一个常见的用法是用作一个即时消息的用户的已连接资源的名字; 另一个是在一个多用户聊天室中用作一个用户的昵称; 并且很多其他种类的实体可以把资源部分作为它们的地址的一部分. 这类服务的安全性可能基于国际化的资源部分的不同诠释而做出妥协; 例如, 两个或更多易混淆的资源可能在同一时间同一个帐号上绑定 (在一个使用全JIDs的XMPP应用中导致不符的授权决策), 或在一个多用户聊天中一个用户可以发送消息给非预期的其他人.
尽管事实上在Unicode安全事项 UNICODE‑SEC中提到了关于易混淆字符的识别和处理的一些具体建议, "对于易混淆字符的问题没有全面的解决方案"(如IDNA‑DEFS提到的)也是真的. 被模仿的JIDs涉及的字符,仅来自一个脚本, 或来自被特定用户或特定语言用户社区所使用的脚本, 是不容易对抗的(例如, 前述的简单输入注入攻击, 它依赖于字符"1"和"l"在一些展示中表面上的相似). 无论如何, 被模仿的地址设计的字符,来自多个脚本, 或来自一个不是典型地被特定用户或特定语言用户社区所使用的脚本, 能通过在XMPP服务上应用适当的注册策略和在XMPP客户端软件上应用适当的展示策略而有所缓解. 所以, 以下策略是被鼓励的:
Because an XMPP service that allows registration of XMPP user accounts (localparts) plays a role similar to that of a registry for DNS domain names, such a service SHOULD establish a policy about the scripts or blocks of characters it will allow in localparts at the service. Such a policy is likely to be informed by the languages and scripts that are used to write registered account names; in particular, to reduce confusion, the service MAY forbid registration of XMPP localparts that contain characters from more than one script and to restrict registrations to characters drawn from a very small number of scripts (e.g., scripts that are well-understood by the administrators of the service). Such policies are also appropriate for XMPP services that allow temporary or permanent registration of XMPP resourceparts, e.g., during resource binding [XMPP] or upon joining an XMPP-based chat room [XEP‑0045]. For related considerations in the context of domain name registration, refer to Section 4.3 of [IDNA‑PROTO] and Section 3.2 of [IDNA‑RATIONALE]. Note well that methods for enforcing such restrictions are out of scope for this document. Because every human user of an XMPP client presumably has a preferred language (or, in some cases, a small set of preferred languages), an XMPP client SHOULD gather that information either explicitly from the user or implicitly via the operating system of the user's device. Furthermore, because most languages are typically represented by a single script (or a small set of scripts) and most scripts are typically contained in one or more blocks of characters, an XMPP client SHOULD warn the user when presenting a JID that mixes characters from more than one script or block, or that uses characters outside the normal range of the user's preferred language(s). This recommendation is not intended to discourage communication across different communities of language users; instead, it recognizes the existence of such communities and encourages due caution when presenting unfamiliar scripts or characters to human users.