Extensible Messaging and Presence Protocol (XMPP):
Core
RFC 3920
摘要:
1.1 概要
XMPP是一個(gè)開(kāi)放的可擴展標記語(yǔ)言[XML]協(xié)議,用于近實(shí)時(shí)的消息、出席與請求-響應服務(wù)?;菊Z(yǔ)法語(yǔ)義最初是由Jabber開(kāi)源社區在1999年開(kāi)發(fā)的。2002年,XMPP工作組授權開(kāi)發(fā)一個(gè)Jabber協(xié)議的改寫(xiě)本,將適用于IETF的即時(shí)消息(IM)與出席技術(shù)。
作為XMPP工作組的成果,此文檔定義了XMPP 1.0的核心內容;提供即時(shí)消息與出席功能的擴展需求定義在RFC2779[IM-REQS]中,由XMPP:即時(shí)消息與出席[XMPP-IM]指定。
1.2 術(shù)語(yǔ)
文檔中的大寫(xiě)關(guān)鍵字:"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL"在BCP14, 在RFC 2119 [TERMS]中描述。
2 一般架構
2.1 概述
雖然XMPP并未與任何特定網(wǎng)絡(luò )架構結合,但到目前為止,它大致上已經(jīng)由一個(gè)客戶(hù)-服務(wù)器的架構實(shí)現了。其中,客戶(hù)端利用XMPP訪(fǎng)問(wèn)基于[TCP]連接的一個(gè)服務(wù)器,并且,服務(wù)器間也通過(guò)TCP連接進(jìn)行彼此間的通信。
XMPP
Client------------Server------------Server
TCP TCP
下圖為此架構的高層視圖(“-”表示使用XMPP通信,“=”表示使用任何其它協(xié)議通信)
C1----S1---S2---C3
|
C2----+--G1===FN1===FC1
符號表示如下:
1) C1,C2,C3 = XMPP客戶(hù)端
2) S1,S2 = XMPP服務(wù)器
3) G1 = 網(wǎng)關(guān):在XMPP與外部協(xié)議(非XMPP)的消息網(wǎng)絡(luò )間轉換。
4) FN1 = 外部消息網(wǎng)絡(luò )
5) C1 = 外部消息網(wǎng)絡(luò )的客戶(hù)端
2.2 服務(wù)器
服務(wù)器作為XMPP通信擔當智能抽象層。它的主要責任是:
1) 管理連接其它實(shí)體的會(huì )話(huà),以XML流格式(第4節)在已授權的客戶(hù)端、服務(wù)器以及其它實(shí)體間來(lái)回傳送。
2) 通過(guò)XML流在實(shí)體間路由具有合適地址的XML節(第9節)。
大多數與XMPP兼容的服務(wù)器設想有能力存儲客戶(hù)端的數據(例:基于XMPP即時(shí)消息與出席應用的用戶(hù)的聯(lián)系列表);在這種情況下,XML數據由服務(wù)器自身代表客戶(hù)端直接處理,并不路由到其它實(shí)體。
2.3 客戶(hù)端
大多數客戶(hù)端通過(guò)[TCP]連接直接連到服務(wù)器,并且使用XMPP,充分利用由服務(wù)器及任何相關(guān)服務(wù)所提供的功能。多種資源(例如:設備或位置)可能代表每個(gè)被授權客戶(hù)端同時(shí)連到服務(wù)器上。每個(gè)資源均由定義在地址方案(第3節)下的XMPP地址的資源標識符來(lái)區別(例如:<node@domain/home> vs. <node@domain/work>)。客戶(hù)端與服務(wù)器的推薦連接端口為5222,已由IANA注冊(參考端口編號(15.9節))。
2.4 網(wǎng)關(guān)
網(wǎng)關(guān)是服務(wù)器端的一種特殊服務(wù),它的主要功能是將XMPP翻譯成外部消息系統所使用的協(xié)議(非XMPP),也可將數據翻譯回XMPP。例如EMAIL網(wǎng)關(guān)(參考[SMTP]),Internet Relay Chat(參考[IRC]),SIMPLE(參考[SIIMPLE],Session Initiation Protocol for Instant Messaging and Presence Leveraging Extensions),短消息服務(wù)(SMS),遺留即時(shí)消息服務(wù),諸如AIM,ICQ,MSN Messenger,Yahoo! Instant Messenger。網(wǎng)關(guān)與服務(wù)器間的通信,網(wǎng)關(guān)與外部消息系統間的通信,均未在此文檔中定義。
2.5 網(wǎng)絡(luò )
由于每個(gè)服務(wù)器由網(wǎng)絡(luò )地址指定,并且由于服務(wù)器與服務(wù)器間的通信是客戶(hù)與服務(wù)器協(xié)議的直接擴展,實(shí)際上,系統由互相通信的服務(wù)器網(wǎng)絡(luò )組成。舉個(gè)例子,<juliet@example.com>能與<romeo@example.net>交換消息、出席,以及其它信息。這是使用網(wǎng)絡(luò )尋址標準的消息協(xié)議(例如[SMTP])所熟悉的模式。任意兩服務(wù)器間的通信是可選的。如果可通信,此類(lèi)通信就應當發(fā)生在綁定到[TCP]連接的XML流上。服務(wù)器間連接的推薦端口為5269,由IANA注冊(參考端口編號(15.9節))
3 尋址方案
3.1 概述
實(shí)體可被看作是使用XMPP進(jìn)行通信的任意網(wǎng)絡(luò )端點(diǎn)(例如:一個(gè)網(wǎng)絡(luò )上的ID)。任意此類(lèi)實(shí)體均以與RFC2396[URI]一致的格式來(lái)唯一設定地址。由于歷史原因,XMPP實(shí)體的地址稱(chēng)作Jabber標識符或JID。一個(gè)有效JID包含一套有序元素:域標識符,結點(diǎn)標識符,資源標識符。
JID的語(yǔ)法定義如下,使用增廣巴斯科范式[ABNF](Augmented Backus-Naur Form)。(Ipv4地址與Ipv6地址規則定義在[Ipv6]的附錄B;符合結點(diǎn)規則的允許字符序列由Nodeprep profile of [STRINGPREP]定義,編入本文檔的附錄A;符合資源規則的允許字符序列由Resourceprep profile of [STRINGPREP]定義,編入本文檔的附錄B;子域規則參考國際化域標識的概念,在[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均基于前述規則。此結構最普通的用法就是用戶(hù)以<user@host/resource>形式標識一個(gè)即時(shí)消息用戶(hù)、用戶(hù)連接的服務(wù)器、用戶(hù)連接的資源(例如:特別的客戶(hù)端)。
然而,結點(diǎn)類(lèi)型可能不僅是客戶(hù)端,舉個(gè)例子,一個(gè)提供多用戶(hù)聊天服務(wù)的特別聊天室,可以以<room@service>(“room”是聊天室名,“service”是多用戶(hù)聊天服務(wù)的主機名)作為地址。并且,此聊天室的特別擁有者可能以<room@service/nick>(“nick”是此擁有者的房間昵稱(chēng))作地址,許多其它JID類(lèi)型均有可能(例如:<domain/resource>可能是一個(gè)服務(wù)器端腳本或服務(wù))。
JID(結點(diǎn)標識符,域標識符,資源標識符)的每個(gè)可允許部分長(cháng)度不準超過(guò)1023字節,結果,最大總長(cháng)度(包括‘@’,‘/’分隔符)為3071字節。
3.2 域標識符
域標識符是基本標識符,且是JID中僅有的一個(gè)必須的元素(僅有域標識符的JID是有效的)。它通常表示網(wǎng)絡(luò )網(wǎng)關(guān)與“主要的”服務(wù)器,具有為其它實(shí)體間的連接進(jìn)行XML路由與數據管理的能力。然而,由域標識符作為參考的實(shí)體并不總是服務(wù)器,它可能是一項以服務(wù)器子域為地址的服務(wù),提供多于服務(wù)器(例:多用戶(hù)聊天服務(wù),用戶(hù)目錄,或外部消息系統的一個(gè)網(wǎng)關(guān))的功能。
每個(gè)服務(wù)器或服務(wù)的域標識符將通過(guò)網(wǎng)絡(luò )進(jìn)行通信,它可能是IP地址,并應當是完全合法的域名(參考[DNS])。域標識符必須是一個(gè)“國際化的域名”,定義在[IDNA],Nameprep [NAMEPREP] profile of stringprep [STRINGPREP]可以無(wú)錯應用。比較兩個(gè)域標識符之前,服務(wù)器必須(客戶(hù)端是應該)首先對標簽(定義在[IDNA])應用Nameprep profile,以補足每個(gè)標識符。
3.3 節點(diǎn)標識符
結點(diǎn)標識符是一個(gè)可選的輔助標識符,放在域標識符之前,后以‘@’字符分隔。它通常表示實(shí)體請求與使用由服務(wù)器或網(wǎng)關(guān)(例如:一個(gè)客戶(hù)端)提供的網(wǎng)絡(luò )訪(fǎng)問(wèn),雖然它也能表示其它種類(lèi)的實(shí)體(例如:有多用戶(hù)聊天服務(wù)功能的聊天室)。由結點(diǎn)標識符表示的實(shí)體,在特定域上下文中,在XMPP即時(shí)消息與出席應用中被加以地址,此類(lèi)地址稱(chēng)作“bare JID”,形式為<node@domain>
結點(diǎn)標識符必須像the Nodeprep profile of [STRINGPREP]這樣格式化,可以無(wú)錯應用。比較兩個(gè)結點(diǎn)標識符之前,服務(wù)器必須(客戶(hù)端應該)首先對每個(gè)標識符應用Nameprep profile。
3.4 資源標識符
資源標識符是一個(gè)可選的第三位標識符,位于域標識符之后,后跟‘/’作為分隔符。資源標識符可以修改<node@domain>也可以只是<domain>地址。它通常表示一個(gè)特別的會(huì )話(huà)、連接(例如:一個(gè)設備或位置),或屬于帶有節點(diǎn)標識符的對象(例如:在多用戶(hù)聊天室的一個(gè)參與者)。當提供必要的信息來(lái)完成資源綁定(第7節)時(shí),資源標識符對服務(wù)器與其它客戶(hù)端均不透明,并且由客戶(hù)端實(shí)現來(lái)定義,以后,它作為一個(gè)“已連接資源”參考。實(shí)體可能同時(shí)維護多連接,每個(gè)已連接的資源均由資源標識符來(lái)進(jìn)行區別。
資源標識符必須按Resourceprep profile of [STRINGPREP]格式化,才能無(wú)錯應用。比較兩個(gè)資源標識符前,服務(wù)器必須(客戶(hù)端應該)首先為每個(gè)標識符應用Resourceprep profile。
3.5 決定地址
SASL協(xié)商后(第6節),如果正確,資源綁定(第7節),流接收實(shí)體必須決定初始實(shí)體的JID。
如果SASL協(xié)商(第6節)期間未指定授權身份,對服務(wù)器與服務(wù)器間的通信,初始實(shí)體的JID應當被授權身份,派生于認證身份,在SASL(Simple Authentication and Security Layer簡(jiǎn)單授權與安全層)說(shuō)明[SASL]中定義。
如果SASL協(xié)商(第6節)期間未指定授權身份,對客戶(hù)端到服務(wù)器的通信,“bare JID”(<node@domain>)應該被授權身份,被派生于授權認證,定義在[SASL]。在資源綁定期間(第7節)“full JID”(<node@domain/resource>)的資源標識符部分應當是客戶(hù)端與服務(wù)器間協(xié)商的資源標識符。
接收實(shí)體必須確保結果JID(包括結點(diǎn)標識符,域標識符,資源標識符,分隔符)遵從此節中前面所定義的規則與格式;為滿(mǎn)足此限制,接收實(shí)體可能需要替代由接收實(shí)體所決定的規范的JID初始實(shí)體所發(fā)送的JID。
4 XML流
4.1概述
使presence-aware實(shí)體間能夠相互迅速的、異步交換相關(guān)的小負載的結構化信息有兩種基本元素:XML流與XML節。術(shù)語(yǔ)定義如下:
XML流定義:XML流是一個(gè)容器,用于網(wǎng)絡(luò )上任意兩實(shí)體間交換XML元素。XML流的開(kāi)始是以一個(gè)起始的XML<stream>標記(有合適的屬性與命名空間聲明)表示,XML流的結尾以一個(gè)結束的XML</stream>標記表示。在流的生命周期中,初始化它的實(shí)體能夠通過(guò)流發(fā)送極多的XML元素,元素與XML節(定義在此,<message/>, <presence/>, 或 <iq/>元素由缺省命名空間驗證)都用于協(xié)商流(例:協(xié)商使用TLS(第5節)或使用SASL(第6節))。“初始流”是從初始實(shí)體(通常是一個(gè)客戶(hù)端或服務(wù)器)到接收實(shí)體(通常是一個(gè)服務(wù)器)的協(xié)商,并被看作與從初始實(shí)體到接收實(shí)體的會(huì )話(huà)一致。初始流能從初始實(shí)體到接收實(shí)體單向通信;為了能夠從接收實(shí)體到初始實(shí)體的信息交換,接收實(shí)體必須在反方向協(xié)商一個(gè)流(“響應流”)。
XML節定義:XML節是一個(gè)不連續的結構化信息語(yǔ)義單元,通過(guò)XML流從一個(gè)實(shí)體發(fā)送到另一個(gè)實(shí)體。XML節以根</stream>的直接子層存在,如果它匹配產(chǎn)品[43]內容[XML],則可以很好的平衡。
任何XML節的開(kāi)始都由深度為1的XML流(例如:<presence>)的開(kāi)始標記元素來(lái)清楚的表示,XML節的結尾由相應的深度為1的關(guān)閉標記來(lái)清楚的表示。為傳送想要的信息,一個(gè)XML節可能包含必要的子元素(帶有屬性,元素,XML字符數據)。在此定義的僅有的XML節是<message/>,<presence/>,<iq/>元素,由流的缺省命名空間驗證,在XML節(第9節)中描述;為傳輸層安全(TLS:Transport Layer Security)協(xié)商,SASL協(xié)商,或服務(wù)器回叫(第8節)而發(fā)送的XML元素,并不會(huì )當作XML節來(lái)考慮。
考慮一個(gè)客戶(hù)端與服務(wù)器的會(huì )話(huà)例子。為了連接到服務(wù)器,客戶(hù)端必須初始化一個(gè)XML流:發(fā)送一個(gè)起始的<stream>標記給服務(wù),可選先于一個(gè)指定XML版本的文本聲明與字符編碼支持(參考文本聲明的內容(11.4);也可參考字符編碼(11.5))。服從本地策略與所提供的服務(wù),服務(wù)器接下來(lái)應該回復另一個(gè)XML流給客戶(hù)端,再次可選先于一個(gè)文本聲明。一但客戶(hù)端完成了SASL協(xié)商(第6節),客戶(hù)端可以通過(guò)流發(fā)送極多的XML節給網(wǎng)絡(luò )上的任意容器。當客戶(hù)端想關(guān)閉流時(shí),它簡(jiǎn)單發(fā)送一個(gè)關(guān)閉</stream>標記給服務(wù)器(也可以由服務(wù)器來(lái)關(guān)閉流),從這以后,客戶(hù)端與服務(wù)器都應終止潛在的連接(通常是一個(gè)TCP連接)。
習慣于將XML考慮成以文檔為中心的人可能希望看到客戶(hù)端與服務(wù)器的會(huì )話(huà)作為兩個(gè)末端開(kāi)口的(自由回答的)XML文檔的組成部分:一個(gè)從客戶(hù)端到服務(wù)器,另一個(gè)從服務(wù)器到客戶(hù)端。從這個(gè)觀(guān)點(diǎn)看,根<stream/>元素可被認為是每個(gè)“文檔”的文檔實(shí)體,兩個(gè)“文檔”都由通過(guò)兩個(gè)XML流發(fā)送的XML節的集聚來(lái)建立。然而,這種觀(guān)點(diǎn)僅是一種方便;XMPP并不以文檔處理,而是以XML流或XML節來(lái)處理。
本質(zhì)上,那么,一個(gè)XML流充當了所有通過(guò)會(huì )話(huà)發(fā)送的XML節的信封??捎脠D簡(jiǎn)單表示如下:
|--------------------|
| <stream> |
|--------------------|
| <presence> |
| <show/> |
| </presence> |
|--------------------|
| <message to=‘foo‘> |
| <body/> |
| </message> |
|--------------------|
| <iq to=‘bar‘> |
| <query/> |
| </iq> |
|--------------------|
| ... |
|--------------------|
| </stream> |
|--------------------|
4.2 綁定到TCP
雖然將一個(gè)XML流結合到一個(gè)[TCP]連接上不是必須的(例如:兩個(gè)實(shí)體能通過(guò)其它諸如[HTTP]投票選舉機制而彼此互連),此說(shuō)明也只定義了XMPP到TCP的綁定。在客戶(hù)端到服務(wù)器端通信的上下文中,服務(wù)器必須允許客戶(hù)端為了從客戶(hù)端到服務(wù)器與服務(wù)器到客戶(hù)端的XML節發(fā)送共享的一個(gè)單TCP連接。在服務(wù)器到服務(wù)器的通信上下文中,服務(wù)器必須使用一條TCP連接用于從服務(wù)器到其對等服務(wù)器的XML節傳送,另一條TCP連接(由對等初始化)用于對其等服務(wù)器到服務(wù)器的XML節傳送,總共有兩條TCP連接。
4.3 流安全
當在XMPP1.0中協(xié)商XML流時(shí),TLS應當按TLS應用(第5節)所定義的來(lái)使用,SASL必須按SASL(第6節)所定義的來(lái)使用。“初始流”(例如:從初始實(shí)體到接收實(shí)體的流)與“響應流”(例如:從接收實(shí)體到初始實(shí)體的流)必須被分別保護,即使雙向安全可能已通過(guò)相互的認證機制所建立。實(shí)體不應當在流被認證之前,嘗試通過(guò)流發(fā)送XML節(第9節),但如果這樣做了,那么,其它實(shí)體不準接受此類(lèi)節,并應當返回一個(gè)<non-authorized/>流錯誤,然后終止兩端的XML流與潛在的TCP連接;注意,這只適用于XML節(例如:<message/>, <presence/>, <iq/>元素,由缺省命名空間檢查)并不適用于流協(xié)商(例如:用于協(xié)商使用TLS(第5節)或使用SASL(第6節))的XML元素。
4.4 流屬性
流元素屬性如下:
1) to—‘ to’屬性應當僅用于從初始實(shí)體到接收實(shí)體的XML流頭中,并且必須被設成一個(gè)接收實(shí)體服務(wù)的主機名。‘to’屬性不應當設在接收實(shí)體回應初始實(shí)體的XML流頭中;然而,如果‘to’屬性包括在內,它應當被初始實(shí)體默默忽略。
2) from—‘ from’屬性應當僅用于從接收實(shí)體到初始實(shí)體的XML流頭中,并且必須被設成一個(gè)接收實(shí)體服務(wù)的主機名,此接收實(shí)體正授權訪(fǎng)問(wèn)初始實(shí)體。‘from’屬性不應在初始實(shí)體發(fā)送到接收實(shí)體的流頭中;然而,如果‘from’屬性包括在內,它應當被接收實(shí)體忽略。
3) id—‘ id’屬性應當僅用于從接收實(shí)體到初始實(shí)體的XML流頭中。此屬性是唯一一個(gè)由接收實(shí)體創(chuàng )建的,作為初始實(shí)體流與接收實(shí)體間會(huì )話(huà)的密鑰,并且,在接收應用(通常是一個(gè)服務(wù)器)中是唯一的。注意:流ID可能是嚴格安全的,并且因此必須是即不能預測也不能重復的(參考[RANDOM]推薦關(guān)于隨機安全觀(guān)點(diǎn))。‘id’屬性不應在初始實(shí)體到接收實(shí)體的XML流頭中;然而,如果‘id’屬性包含在內,應被接收實(shí)體忽略。
4) xml:lang—‘ xml:lang’屬性(定義在[XML]的12.2)應當包含在初始實(shí)體的初始流頭中,用于指定缺省語(yǔ)言,此語(yǔ)言可以是任何通過(guò)流發(fā)送的人類(lèi)可讀的XML字符數據。如果屬性包含在內,接收實(shí)體應當記住此值并做為初始流與響應流的缺省值;如果此屬性不包含在內,接收實(shí)體應當為兩個(gè)流使用一個(gè)可配置的缺省值,它必須為響應流在頭中通信。對所有通過(guò)初始化流發(fā)送的節,如果初始實(shí)體不包含‘xml:lang’屬性,接收實(shí)體應當應用缺省值;如果初始實(shí)體包含‘xml:lang’屬性,接收實(shí)體不準修改或刪除它(參考xml:lang(9.1.5))。‘xml:lang’屬性值必須是一個(gè)NMTOKEN(定義在[XML](2.3)),并且必須與定義在RFC3006[LANGTAGS]中的格式一致。
5) version—版本屬性出現設到至少是“1.0”信號值,支持定義在說(shuō)明書(shū)中的相關(guān)流協(xié)議(包括流特征)。有關(guān)代與屬性處理的具體規則定義如下:
可總結如下:
| initiating to receiving | receiving to initiating
---------+---------------------------+-----------------------
to | hostname of receiver | silently ignored
from | silently ignored | hostname of receiver
id | silently ignored | session key
xml:lang | default language | default language
version | signals XMPP 1.0 support | signals XMPP 1.0 support
4.4.1版本支持
XMPP版本在此指定為“1.0”,特別的,這封裝了流相關(guān)協(xié)議(TLS應用(5),SASL應用(6),流錯誤(4.7)),還有三個(gè)已定義的XML節類(lèi)型(<message/>, <presence/>, and <iq/>)的語(yǔ)義。XMPP版本的編號方案是“<major>.<minor>”。Major與minor數字必須作為分離的整數對待,并且每個(gè)數字可能并不按單數字增加。因此"XMPP 2.4"是一個(gè)比"XMPP 2.13"低的版本,依次低于"XMPP 12.3"。前導零(例如:"XMPP 6.01")必須被接收者忽略并不準發(fā)送。
Major版本號應當增加,只要流與節格式或是所需行為已很大程度上改變,以至于老版本如果對它不理解的并采取在舊版說(shuō)明中指定的動(dòng)作時(shí),只簡(jiǎn)單忽略元素與屬性時(shí)無(wú)法與新版本實(shí)體互操作,就要增加主版本號。次版本號指新能力,并且必須被有一個(gè)更小次版本號的實(shí)體所忽略,但被有更大次版本號的實(shí)體作信息目的用。舉例:次版本號可能指處理消息,出席,或IQ節新近定義的‘type’屬性值;有更大次版本號的實(shí)體將簡(jiǎn)單注意它的通信者不理解此‘type’屬性值,并因此而不發(fā)送它。
以下規則由實(shí)現應用于產(chǎn)生與處理在流頭中的‘版本’屬性:
1) 初始實(shí)體必須在初始流頭中將版本屬性值設到它所支持的最高版本號(例如:如果它所支持的最高版本號定義在此說(shuō)明中,必須設值為“1.0”)
2) 接收實(shí)體必須在響應流頭中設置版本屬性值或者是初始實(shí)體提供的值,或者是接收實(shí)體所支持的最高版本號,無(wú)論哪一個(gè)更低。接收實(shí)體必須對主、次版本號做數字比較,而不是"<major>.<minor>"字符串匹配。
3) 如果包含在響應流頭中的版本號至少一個(gè)主版本號低于包含在初始流頭中的版本號,并且新版本實(shí)體不能像上述那樣與舊版本互操作,初始實(shí)體應當產(chǎn)生一個(gè)<unsupported-version/>流錯誤,并終止XML流與潛在的TCP連接。
4) 如果每個(gè)實(shí)體都收到一個(gè)帶有“無(wú)版本號”屬性的流頭,實(shí)體必須考慮由其它實(shí)體支持版本將是“0.0”并不應當在發(fā)送響應流時(shí)包括‘version’屬性。
4.5 命名空間聲明
流元素必須擁有流命名空間聲明和一個(gè)缺省的命名空間聲明(命名空間聲明定義在XML命名空間說(shuō)明文檔[XML-NAMES]中)。對有關(guān)流命名空間與缺省命名空間的更細節的信息,看命名空間名稱(chēng)與前綴(11.2)。
4.6 流特征
如果初始化實(shí)體包含版本屬性,并在初始流頭中,其值至少設為“1.0”,那么接收實(shí)體必須發(fā)送一個(gè)<features/>子元素(由流命名空間前綴作前綴)給初始實(shí)體,以宣布任何可被協(xié)商的(或另外需要被廣告的能力)流級別的特征。當前,這僅用于廣告在此定義的TLS應用(5),SASL應用(6)和資源綁定(7),并且,會(huì )話(huà)按照[XMPP-IM]中所定義的來(lái)建立;然而,流特征的功能性可被用于廣告其它將來(lái)可協(xié)商的特征。如果實(shí)體不理解或不支持某些特征,那么它應當默默的忽略。如果一個(gè)或多個(gè)安全特征(例如:TLS與SASL)需要在非安全特征(例如:資源綁定)被提供之前成功被協(xié)商,非安全相關(guān)特征不應當在相關(guān)安全特征被協(xié)商之前包含在流特征中被廣告。
4.7 流錯誤
根流元素可能包含一個(gè)<error/>子元素,此元素由流命名空間前綴來(lái)加前綴。如果錯誤子元素感覺(jué)到一個(gè)流級別錯誤發(fā)生,它必須由一個(gè)兼容實(shí)體(通常是一個(gè)服務(wù)器而不是一個(gè)客戶(hù)端)來(lái)發(fā)送。
4.7.1 規則
以下規則應用于流級別錯誤:
1) 設想所有流級別錯誤均是不可恢復的;因此,如果一個(gè)錯誤在流級別層發(fā)生,那么檢測錯誤的實(shí)體必須發(fā)送一個(gè)流錯誤給其它實(shí)體,發(fā)送一個(gè)關(guān)閉</stream>標記,并終止潛在的TCP連接。
2) 如果在流被建立期間發(fā)生錯誤,接收實(shí)體必須一直發(fā)送起始<stream>標記,將<error/>元素作為流元素的子元素,發(fā)送關(guān)閉</stream>標記,并終止潛在的TCP連接。此種情況下,如果初始實(shí)體在‘to’屬性(或根本沒(méi)提供‘to’屬性)中提供了一個(gè)未知主機,服務(wù)器應當在流頭的‘from’屬性中提供服務(wù)器的授權主機名,并在終止前發(fā)送。
4.7.2 語(yǔ)法
流錯誤語(yǔ)法如下:
<stream:error>
<defined-condition xmlns=‘urn:ietf:params:xml:ns:xmpp-streams‘/>
<text xmlns=‘urn:ietf:params:xml:ns:xmpp-streams‘
xml:lang=‘langcode‘>
OPTIONAL descriptive text
</text>
[OPTIONAL application-specific condition element]
</stream:error>
<error/>元素:
1) 必須包含一個(gè)子元素,此子元素與以下定義的已定義的節錯誤條件之一相一致;此元素必須被‘urn:ietf:params:xml:ns:xmpp-streams‘命名空間認為是合格的。
2) 可能包含一個(gè)<text/>子元素,此子元素包含了更詳細描述錯誤的XML字符數據;此元素必須被‘urn:ietf:params:xml:ns:xmpp-streams‘命名空間認為是合格的,并且,應當擁有一個(gè)‘xml:lang‘屬性來(lái)指明XML字符數據的自然語(yǔ)言。
3) 可能包含一個(gè)用于說(shuō)明特殊應用錯誤條件的子元素;此元素必須由一個(gè)已定義應用命名空間來(lái)認證,并且,它的結構由那個(gè)命名空間來(lái)定義。
<text/>元素是可選的。如果包含了此元素,它應當僅用于提供描述性或診斷性的信息,來(lái)補充一個(gè)已定義的條件或特殊應用條件的意思;它不應當由一個(gè)應用以程序化的形式敘述。它不應當作為錯誤消息展示給一個(gè)用戶(hù),但可能另外顯示與包含條件元素(或元素們)相關(guān)的錯誤消息。
4.7.3 已定義條件
以下定義了流級別錯誤條件:
1)<bad-format/>--已經(jīng)發(fā)送XML的實(shí)體不能被處理;此錯誤可能用于代替更特殊的XML相關(guān)錯誤,例如:<bad-namespace-prefix/>, <invalid-xml/>,
<restricted-xml/>, <unsupported-encoding/>, <xml-not-well-formed/>,雖然更特殊的錯誤是首選。
2)<bad-namespace-prefix/>--實(shí)體已經(jīng)發(fā)送了一個(gè)不被支持的名空間前綴,或在一個(gè)需要那樣一個(gè)前綴的元素中發(fā)送了沒(méi)有命名空間的前綴(參考XML命名空間名與前綴(11.2))。
3)<conflict/>--服務(wù)器正為實(shí)體關(guān)閉活動(dòng)流,因為一個(gè)已經(jīng)被初始化的新流與現存流沖突。
4)<connection-timeout/>--一段時(shí)間內(可根據本地服務(wù)策略配置)實(shí)體并不通過(guò)流產(chǎn)生任何通信。
5)<host-gone/>--由初始實(shí)體在流頭中提供的‘to’屬性值對應于一個(gè)主機名,而此主機名已不再被一個(gè)服務(wù)器當作主機了。
6)<host-unknown/>--由初始實(shí)體在流頭中提供的‘to’屬性值于服務(wù)器所擁有的主機名不一致。
7)<improper-addressing/>--一個(gè)在兩個(gè)服務(wù)器間發(fā)送的節,缺少‘to’或‘from’屬性(或此屬性無(wú)值)
8)<internal-server-error/>--服務(wù)器經(jīng)歷了錯誤配置或其它未定義內部錯誤使其無(wú)法提供服務(wù)。
9)<invalid-from/>--在‘from’地址中提供的JID或主機名與已授權的JID或有效域協(xié)商不匹配,此有效域協(xié)商為通過(guò)SASL或回叫服務(wù)器間的協(xié)商,或通過(guò)授權與資源綁定的客戶(hù)端與服務(wù)器間的協(xié)商。
10)<invalid-id/>--流ID或回叫ID是無(wú)效的或與以前提供的ID不匹配。
11)<invalid-namespace/>--流命名空間名不只是 12)<invalid-xml/>--實(shí)體通過(guò)流向執行驗證的服務(wù)器發(fā)送了無(wú)效的XML(參考驗證(11.3))。
13)<not-authorized/>--實(shí)體試圖在流被認證前發(fā)送數據,或不授權執行一個(gè)相關(guān)流協(xié)商的活動(dòng);接收實(shí)體在發(fā)送流錯誤前不準處理違規節。
14)<policy-violation/>--實(shí)體違反了某些本地策略;服務(wù)器可能選擇在<text/>元素或特殊-應用條件元素中指定策略。
15)<remote-connection-failed/>服務(wù)器不能適當的連接到遠程實(shí)體,需要認證或授權。
16)<resource-constraint/>服務(wù)器缺少提供服務(wù)給流的必要的系統資源。
17)<restricted-xml/>實(shí)體試圖發(fā)送受限的XML特征,例如評注、處理介紹,DTD,實(shí)體參考,或保留字符(參考(11.1))。
18)<see-other-host/>服務(wù)器將不提供服務(wù)給初始實(shí)體,但正重定向傳輸給另一個(gè)主機;服務(wù)器應當指定替換的主機名或IP地址(必須是有效域標識符),作為<see-other-host/>元素的XML字符數據。
19)<system-shutdown/>服務(wù)器被關(guān)閉,并且所有的活動(dòng)流被關(guān)閉。
20)<undefined-condition/> 錯誤條件是由此列表中的其它已定義條件中的一個(gè);此錯誤條件應當僅用在與特殊-應用條件相結合。
21)<unsupported-encoding/>初始實(shí)體已在不被服務(wù)器支持的編碼中為流編碼(11.5)
22)<unsupported-stanza-type/>初始實(shí)體已發(fā)送了一個(gè)不被服務(wù)器支持的第一級子流。
23)<unsupported-version/>由初始實(shí)體在流頭提供的版本屬性值指定了一個(gè)不被服務(wù)器支持的XMPP版本;服務(wù)器可能在<text/>元素中指定它支持的版本。
24)<xml-not-well-formed/>初始實(shí)體已經(jīng)發(fā)送了不標準的XML,標準的XML由[XML]定義。
4.7.4 特殊應用條件
注意,一個(gè)應用可能通過(guò)在錯誤元素中包含一個(gè)合適的命名空間子元素來(lái)提供特殊應用流錯誤信息。特殊應用元素應當補充或進(jìn)一步驗證一個(gè)已定義元素。因此,<error/>元素將包含兩到三個(gè)子元素:
<stream:error>
<xml-not-well-formed
xmlns=‘urn:ietf:params:xml:ns:xmpp-streams‘/>
<text xml:lang=‘en‘ xmlns=‘urn:ietf:params:xml:ns:xmpp-streams‘>
Some special application diagnostic information!
</text>
<escape-your-data xmlns=‘a(chǎn)pplication-ns‘/>
</stream:error>
</stream:stream>
4.8簡(jiǎn)化的流例子
此部分包含兩個(gè)簡(jiǎn)化的客戶(hù)端與服務(wù)器(“C”行是從客戶(hù)端發(fā)送到服務(wù)器,而“S”行是由服務(wù)器發(fā)送到客戶(hù)端)間基于流會(huì )話(huà)的例子;這些例子解釋進(jìn)一步的概念。
A basic "session":
C: <?xml version=‘1.0‘?>
<stream:stream
to=‘example.com‘
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
version=‘1.0‘>
S: <?xml version=‘1.0‘?>
<stream:stream
from=‘example.com‘
id=‘someid‘
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
version=‘1.0‘>
... encryption, authentication, and resource binding ...
C: <message from=‘juliet@example.com‘
to=‘romeo@example.net‘
xml:lang=‘en‘>
C: <body>Art thou not Romeo, and a Montague?</body>
C: </message>
S: <message from=‘romeo@example.net‘
to=‘juliet@example.com‘
xml:lang=‘en‘>
S: <body>Neither, fair saint, if either thee dislike.</body>
S: </message>
C: </stream:stream>
S: </stream:stream>
A "session" gone bad:
C: <?xml version=‘1.0‘?>
<stream:stream
to=‘example.com‘
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
version=‘1.0‘>
S: <?xml version=‘1.0‘?>
<stream:stream
from=‘example.com‘
id=‘someid‘
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
version=‘1.0‘>
... encryption, authentication, and resource binding ...
C: <message xml:lang=‘en‘>
<body>Bad XML, no closing body tag!
</message>
S: <stream:error>
<xml-not-well-formed
xmlns=‘urn:ietf:params:xml:ns:xmpp-streams‘/>
</stream:error>
S: </stream:stream>
5 使用TLS
5.1 概述
XMPP包含一個(gè)方法,用于保護流不被篡改和偷聽(tīng)。此信道加密方法利用傳輸層安全(TLS)協(xié)議[TLS],連同“STARTTLS”擴展,在為描述在RFC 2595[USINGTLS]中的IMAP[IMAP],POP3[POP3],ACAP[ACAP]等相似協(xié)議擴展模型。用于STARTTLS擴展的命名空間名是‘urn:ietf:params:xml:ns:xmpp-tls‘。
一個(gè)給定域的管理者可能需要使用TLS來(lái)進(jìn)行客戶(hù)端到服務(wù)器的通信,服務(wù)器到服務(wù)器的通信,或二者兼有??蛻?hù)端應使用TLS去保護流,在企圖完成SASL協(xié)商之前,而且,服務(wù)器出于保護服務(wù)器到服務(wù)器的通信的考慮,應在兩個(gè)域間使用TLS。
應用以下規則:
1) 遵從此說(shuō)明的初始實(shí)體必須包含版本屬性,并在初始流頭中將其值設為“1.0”。
2) 如果兩服務(wù)器間的TLS協(xié)商發(fā)生,直到服務(wù)器宣稱(chēng)的域名系統(DNS)主機名被決定(參考服務(wù)器到服務(wù)器的通信(14.4))后,才能處理通信。
3) 當與此說(shuō)明一致的接收實(shí)體收到一個(gè)包含版本屬性設為至少“1.0”的初始化流時(shí),發(fā)送一個(gè)流頭作響應(包含版本標記)后,必須包含一個(gè)<starttls/>元素(由‘urn:ietf:params:xml:ns:xmpp-tls‘命名空間認證)并帶有它所支持的其它流特征的列表。[服務(wù)器以<starttls/>響應]
4) 如果初始實(shí)體選擇使用TLS,TLS協(xié)商必須在SASL協(xié)商處理之前完成;這種協(xié)商順序是必要的,用于幫助保護SASL協(xié)商期間發(fā)送認證信息,并在TLS協(xié)商之前這段時(shí)間,使基于使用認證的SASL EXTERNAL機制成為可能。
5) 在TLS協(xié)商期間,實(shí)體不準在根流元素中發(fā)送任何空白字符(匹配[XML]內容,產(chǎn)品[3])作為元素間(任何在TLS例子中的空白字符都只是為了便于閱讀)的分隔符;這種限制有助于確保合適的安全層字節精度。
6) 接收實(shí)體必須考慮TLS協(xié)商在發(fā)送<proceed/>元素的關(guān)閉“>”字符之后立即開(kāi)始。初始實(shí)體必須考慮TLS協(xié)商在收到來(lái)自于接收實(shí)體的<proceed/>元素的關(guān)閉“>”字符之后立即開(kāi)始。
7) 初始實(shí)體必須驗證由接收實(shí)體表示的證書(shū);參考證書(shū)驗證(14.2)相關(guān)證書(shū)驗證步驟。
8) 證書(shū)必須根據初始實(shí)體(例如:一個(gè)用戶(hù))提供的主機名來(lái)檢查,而不是通過(guò)域名系統解析的主機名;例如:如果用戶(hù)指定一個(gè)"example.com"的主機名,而DNS SRV[SRV]查找并返回"im.example.com",證書(shū)必須作為"example.com"被檢查。如果對任何此種XMPP實(shí)體(例如,客戶(hù)端或服務(wù)器)的一個(gè)JID在一個(gè)證書(shū)中被表示,它必須作為一個(gè)UTF8String來(lái)表示,UTF8String在位于subjiectAltName中的一個(gè)otherName實(shí)體中,使用[ASN.1]對象標識符"id-on-xmppAddr",在本文檔5.1.1中說(shuō)明。
9) 如果TLS協(xié)商成功,接收實(shí)體必須拋棄TLS生效之前,來(lái)自初始實(shí)體的任何非安全格式的知識。
10) 如果TLS協(xié)商成功,初始實(shí)體必須拋棄TLS生效之前,來(lái)自接收實(shí)體的任何非安全格式知識。
11) 如果TLS協(xié)商成功,接收實(shí)體不準提供STARTTLS擴展給當流重新開(kāi)如時(shí)被提供的帶有其他流特征的初始實(shí)體。
12) 如果TLS協(xié)商成功,初始實(shí)體必須繼續SASL協(xié)商。
13) 如果TLS協(xié)商結果失敗,接收實(shí)體必須終止XML流與潛在的TCP連接。
14) 參考強制實(shí)施技術(shù)(14.7)相關(guān)的必須被支持的機制。
5.1.1 ASN.1用于XMPP地址的對象標識符
上述[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
對象標識符可能也以點(diǎn)分制顯示,格式為"1.3.6.1.5.5.7.8.5"
5.2 敘述
當初始實(shí)體使用TLS保護一個(gè)帶有接收實(shí)體的流時(shí),步驟如下:
1) 初始實(shí)體打開(kāi)一個(gè)TCP連接,靠發(fā)送開(kāi)放XML流頭給接收實(shí)體,此流頭包含版本屬性,并設其值至少為“1.0”,來(lái)初始化流。
2) 接收實(shí)體以打開(kāi)一個(gè)TCP連接并發(fā)送一個(gè)XML流頭給初始實(shí)體作為響應,此流頭包含值至少為“1.0”版本屬性。
3) 接收實(shí)體靠包含帶有其它支持流特征(如果TLS需要與接收實(shí)體交互,它應當靠包含一個(gè)<required/>元素作為<starttls/>的子元素來(lái)標記此事實(shí))的列表來(lái)為初始實(shí)體提供STARTTLS擴展。
4) 初始實(shí)體發(fā)起STARTTLS命令(例:由 ‘urn:ietf:params:xml:ns:xmpp-tls‘ 命名空間確認的<starttls/>元素)去指導希望開(kāi)始TLS協(xié)商去保護流的接收實(shí)體。
5) 接收實(shí)體必須以由命名空間‘urn:ietf:params:xml:ns:xmpp-tls‘認證了的<proceed/>元素或<failure/>元素響應。如果有失敗情況發(fā)生,接收實(shí)體必須終止雙方的XML流與潛在的TCP連接。如果接著(zhù)向下進(jìn)行,實(shí)體必須嘗試通過(guò)TCP連接完成TLS協(xié)商,并不準發(fā)送任何進(jìn)一步的XML數據,直到TLS協(xié)商完成。
6) 初始實(shí)體與接收實(shí)體嘗試依據[TLS]完成TLS協(xié)商。
7) 如果TLS協(xié)商不成功,接收實(shí)體必須終止TCP連接。如果TLS協(xié)商成功,初始實(shí)體必須靠發(fā)送一個(gè)開(kāi)始XML流頭給接收實(shí)體(它并不需要先發(fā)送一個(gè)關(guān)閉</stream>標記,因為接收實(shí)體與初始實(shí)體必須考慮到原始流根據成功的TLS協(xié)商而被關(guān)閉),以初始一個(gè)新流。
8) 根據從初始實(shí)體接收的新流頭,接收實(shí)體必須靠發(fā)送一個(gè)新XML流頭給有可利用特征(不包括STARTTLS特征)的初始實(shí)體來(lái)響應。
5.3客戶(hù)端到服務(wù)器的例子
下面例子顯示了一個(gè)客戶(hù)端保護使用STARTTLS(注:替換步驟顯示在下一行,用來(lái)解釋協(xié)議失敗的情況;他們在本例中并不詳盡也不是必須的由數據發(fā)送而觸發(fā))流的數據流。
1步:客戶(hù)端初始流給服務(wù)器:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步2:服務(wù)器以發(fā)送給客戶(hù)端一個(gè)流標記作為響應:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
id=‘c2s_123‘
from=‘example.com‘
version=‘1.0‘>
步3:服務(wù)器發(fā)送STARTTLS擴展給客戶(hù)端,并帶有認證機制與任何其它流特征:
<stream:features>
<starttls xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘>
<required/>
</starttls>
<mechanisms xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
步4:客戶(hù)端發(fā)送STARTTLS命令給服務(wù)器:
<starttls xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
步5:服務(wù)器通知客戶(hù)端它被允許處理
<proceed xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
步5(替代):服務(wù)器通知客戶(hù)端TLS協(xié)商失敗,并關(guān)閉流與TCP連接:
<failure xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
</stream:stream>
步6:客戶(hù)端與服務(wù)器試圖協(xié)商通過(guò)現存的TCP連接 完成TLS協(xié)商。
步7:如果TLS協(xié)商成功,客戶(hù)端初始化一個(gè)新流給服務(wù)器:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步7(代替 ):如果TLS協(xié)商不成功,服務(wù)器關(guān)閉TCP連接。
步8:服務(wù)器靠發(fā)送帶有任何可利用流特征的流頭給客戶(hù)端作為響應。
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
from=‘example.com‘
id=‘c2s_234‘
version=‘1.0‘>
<stream:features>
<mechanisms xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
<mechanism>EXTERNAL</mechanism>
</mechanisms>
</stream:features>
步9:客戶(hù)端繼續SASL協(xié)商(6)
5.4 服務(wù)器到服務(wù)器的例子
以下例子顯示兩服務(wù)器保護使用STARTTLS(注:替換步驟顯示在下一行,用來(lái)解釋協(xié)議失敗的情況;他們在本例中并不詳盡也不是必須的由數據發(fā)送而觸發(fā))流的數據流。
步1:Server1初始化流給Server2:
<stream:stream
xmlns=‘jabber:server‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步2:Server2發(fā)送一個(gè)流標記給Server1作為響應:
<stream:stream
xmlns=‘jabber:server‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
from=‘example.com‘
id=‘s2s_123‘
version=‘1.0‘>
步3:Server2發(fā)送帶有認證機制與任何其它流特征的STARTTLS擴展給Server1
<stream:features>
<starttls xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘>
<required/>
</starttls>
<mechanisms xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
</mechanisms>
</stream:features>
步4:Server1發(fā)送STARTTLS命令給Server2:
<starttls xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
步5:Server2通知Server1允許被處理:
<proceed xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
步5(替代):Server2通知Server1TLS協(xié)商失敗并關(guān)閉流:
<failure xmlns=‘urn:ietf:params:xml:ns:xmpp-tls‘/>
</stream:stream>
步6:Server1與Server2試圖通過(guò)TCP完成TLS協(xié)商。
步7:如果TLS協(xié)商成功,Server1初始一個(gè)新流給Server2:
<stream:stream
xmlns=‘jabber:server‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步7(替代):如果TLS協(xié)商不成功,Server2關(guān)閉TCP連接。
步8:Server2靠發(fā)送一個(gè)帶有任何可利用流特征的流頭給Server1:
<stream:stream
xmlns=‘jabber:server‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
from=‘example.com‘
id=‘s2s_234‘
version=‘1.0‘>
<stream:features>
<mechanisms xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>KERBEROS_V4</mechanism>
<mechanism>EXTERNAL</mechanism>
</mechanisms>
</stream:features>
步9:Server1繼續SASL協(xié)商(6)
6.使用SASL
6.1 概述
XMPP包含一個(gè)認證流的方法,此方法依靠一個(gè)簡(jiǎn)單認證與安全層(SASL)協(xié)議[SASL]的XMPP-specific profile。SASL提供一個(gè)一般化方法,用于給基于連接的協(xié)議加認證支持,并且,XMPP使用一個(gè)一般化XML命名空間profile,用于SASL,遵從[SASL]的profiling需求。
以下規則應用:
1) 如果兩個(gè)服務(wù)器間發(fā)生SASL協(xié)商,直到由服務(wù)器宣稱(chēng)的域名系統(DNS)主機名被解析了(參考服務(wù)器到服務(wù)器通信(14.4)),通信才可處理。
2) 如果實(shí)始實(shí)體能夠進(jìn)行SASL協(xié)商,,它必須在初始流頭中包含值至少為“1.0”的版本屬性。
3) 如果接收實(shí)體能夠進(jìn)行SASL協(xié)商,它必須在一個(gè)<mechanisms/>元素中廣告一個(gè)或多個(gè)認證機制,此元素靠‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間響應從初始實(shí)體(如果開(kāi)放流標記包含所設值至少為“1.0”的版本屬性)接收的開(kāi)放流標記認證。
4) 在SASL協(xié)商期間,實(shí)體不準在根流元素中發(fā)送任何空白字符(匹配[XML]內容,產(chǎn)品[3])作為元素間(任何在SASL例子中的空白字符都只是為了便于閱讀)的分隔符;這種限制有助于確保合適的安全層字節精度。
5) 任何包含在XML元素中的XML字符數據,在SASL協(xié)商期間使用,必須使用base64編碼,編碼在RFC3548第三節有定義。
6) 如果所提供的一個(gè)“簡(jiǎn)單用戶(hù)名”能夠被選定SASL機制(例:由DIGEST-MD5與CRAM-MD5機制所支持,但不靠EXTERNAL與GSSAPI機制所支持)所支持,在認證期間,初始實(shí)體應當作為簡(jiǎn)單用戶(hù)名提供它的發(fā)送域(IP地址或包含在域標識符中的全認證域名)在服務(wù)器對服務(wù)器的通信情況下,或是它的已注冊帳戶(hù)名(包含在XMPP結點(diǎn)標識符中的用戶(hù)或結點(diǎn)名)在客戶(hù)到服務(wù)器的通信情況下。
7) 如果初始實(shí)體希望代表其它實(shí)體與支持授權身份傳輸的被選SASL機制來(lái)行動(dòng),初始實(shí)體在SASL協(xié)商期間必須提供一個(gè)授權身份。如果初始實(shí)體不希望代表另一個(gè)實(shí)體行動(dòng),它不準提供一個(gè)授權身份。正如[SASL]中指定的,初始實(shí)體不準提供一個(gè)授權身份,除非一個(gè)授權身份不同于缺省授權身份,此缺省授權身份派生于描述在[SASL]中的認證身份。如果提供了,授權身份值對服務(wù)器來(lái)說(shuō)必須是<domain>值形式(例:只有一個(gè)域標識符),對客戶(hù)端來(lái)說(shuō),必須是<node@domain>值形式(例:結點(diǎn)標識符與域標識符)。
8) 靠涉及到安全層協(xié)商的SASL協(xié)商的成功,接收實(shí)體必須拋棄來(lái)自本身沒(méi)有獲得SASL協(xié)商的初始實(shí)體的任何知識。
9) 靠涉及到安全層協(xié)商的SASL協(xié)商的成功,初始實(shí)體必須拋棄來(lái)自本身沒(méi)有獲得SASL協(xié)商的接收實(shí)體的任何知識。
10) 參考必須被支持的相關(guān)機制的強制實(shí)施技術(shù)(14.7)。
6.2敘述
當初始實(shí)體使用SASL認證接收實(shí)體時(shí),步驟如下:
1) 初始實(shí)體請求SASL認證,通過(guò)在開(kāi)放XML流頭中包含版本屬性,并將其發(fā)送給接收實(shí)體,屬性值設為“1.0”。
2) 發(fā)送一個(gè)XML流頭作為回應后,接收實(shí)體廣告一個(gè)可利用的SASL認證機制列表;列表中每一項都是一個(gè)<mechanism/>元素,作為<mechanism/>容器元素的子元素,由‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間認證,在流命名空間中,依次是<features/>元素的子元素。如果使用TLS(5)需要在一個(gè)特別認證機制可能使用之間建立,接收實(shí)體不準提供在TLS協(xié)商之前的可利用SASL認證機制列表中的機制。如果初始實(shí)體在TLS協(xié)商之前出示了有效證書(shū),接收實(shí)體應當在SASL協(xié)商(參考[SASL])之間,提供SASL EXTERNAL機制給初始實(shí)體,雖然EXTERNAL機制可能在其它環(huán)境下被提供了。
3) 初始實(shí)體選擇一個(gè)機制,靠發(fā)送一個(gè)已被‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間認定為合格的<auth/>元素給接收實(shí)體,并為‘mechanism’屬性包含一個(gè)合適的值。如果此機制需要XML字符數據,此元素可能包含XML字符數據(在SASL術(shù)語(yǔ)中,“初始響應”);如果初始實(shí)體需要發(fā)送一個(gè)0長(cháng)度的初始響應,它必須按一個(gè)單等號符號(“=”)傳輸此響應,意味著(zhù)響應出現,但不包含數據。
4) 如果需要,接收實(shí)體靠發(fā)送一個(gè)<chanllenge/>元素來(lái)挑戰實(shí)始實(shí)體,此元素由給初始實(shí)體的‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間來(lái)限定;此元素可能包含XML字符數據(必須根據由初始實(shí)體選擇的SASL機制的定義一致的來(lái)計算)。
5) 初始實(shí)體響應此挑戰,靠發(fā)送由‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間限定的<response/>元素給接收實(shí)體;此元素可能包含XML字符數據(必須根據由初始實(shí)體選擇的SASL機制的定義一致的來(lái)計算)。
6) 如果需要,接收實(shí)體發(fā)送更多的挑戰,初始實(shí)體發(fā)送更多的響應。
Challenge/response序列對繼續,直到以下三種事情之一發(fā)生:
1) 初始實(shí)體終止握手,靠發(fā)送一個(gè)由‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間限定的<abort/>元素給接收實(shí)體。根據接收一個(gè)<abort/>元素,接收實(shí)體應當允許一個(gè)可配置的但合理的重試號(至少2),之后,必須終止TCP連接;這使初始實(shí)體(例:一個(gè)終端用戶(hù)客戶(hù)端)能夠忍受已提供的不正確的信任(例:一個(gè)錯誤類(lèi)型的password)而不用被迫重連。
2) 接收實(shí)體報告握手失敗,靠發(fā)送一個(gè)由‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間限定的<failure/>元素給初始實(shí)體(失敗的特殊原因應當以<failure/>元素的子元素進(jìn)行通信,<failure/>元素定義在SASL錯誤中(6.4))。如果錯誤情況發(fā)生,接收實(shí)體應當允許一個(gè)可配置的,但合理的重試號(至少2),之后,它必須終止TCP連接;這使初始實(shí)體(例:一個(gè)終端用戶(hù)客戶(hù)端)能夠忍受已提供的不正確的信任(例:一個(gè)錯誤類(lèi)型的password)而不用被迫重連。
3) 接收實(shí)體報告握手成功,靠發(fā)送一個(gè)由‘urn:ietf:params:xml:ns:xmpp-sasl‘命名空間限定的<success/>元素給初始實(shí)體;此元素可能包含XML字符數據(在SASL術(shù)語(yǔ)中,“additional data with success”),如果需要靠選定的SASL機制。根據接收的<success/>元素,初始實(shí)體必須靠發(fā)送一個(gè)開(kāi)放的XML流頭去初始化一個(gè)新流給接收實(shí)體(它不必事先發(fā)送一個(gè)關(guān)閉</stream>標記,因為接收實(shí)體與初始實(shí)體必須考慮源流根據發(fā)送或接收<success/>元素而將被關(guān)閉)。根據從初始實(shí)體接收的新流頭,接收實(shí)體必須發(fā)送一個(gè)新XML流頭給初始實(shí)體作為響應,并帶有任何可利用的特征(但并不包含STARTTLS與SASL特征)或一個(gè)空<features/>元素(重要表示沒(méi)有其它特征可利用);任何那種其它在此未定義的特征必須由XMPP的相關(guān)擴展來(lái)定義。
6.3 SASL定義
[SASL]的profiling需求要求協(xié)議定義提供以下信息:
服務(wù)名:“xmpp”
初始序列:初始實(shí)體提供一個(gè)開(kāi)放XML流頭后,并且接收實(shí)體按此響應后,接收實(shí)體提供一個(gè)可接收的認證方法列表。初始實(shí)體從列表中選擇一個(gè)方法并作為‘machanism’屬性值發(fā)送給接收實(shí)體,此屬性被<auth/>元素擁有,隨意的包括一個(gè)初始響應以避免環(huán)路。
交換序列:挑戰與響應通過(guò)由接收實(shí)體到初始實(shí)體<challenge/>元素的交換與由初始實(shí)體到接收實(shí)體的<response/>元素的交換而執行。接收實(shí)體靠發(fā)送一個(gè)<failure/>元素報告錯誤,發(fā)送一個(gè)<success/>元素報告成功;初始實(shí)體靠發(fā)送<abort/>元素終止交換。根據成功協(xié)商,兩端都認為源XML流將被關(guān)并且新流頭由兩端實(shí)體發(fā)送。
安全層協(xié)商:安全層在為接收實(shí)體發(fā)送<success/>元素的關(guān)閉“>”字符后立即有效,安全層在為初始實(shí)體發(fā)送<success/>元素的關(guān)閉“>”字符后立即有效。層順序為:首先是[TCP],然后是[TLS],然后是[SASL],然后是XMPP。
使用授權身份:授權身份可以被XMPP用于指示客戶(hù)端非缺省<node@domain>或服務(wù)器發(fā)送<domain>。
6.4 SASL錯誤
以下是SASL相關(guān)錯誤條件的定義:(略)
1)<aborted/>--
2)<incorrect-encoding/>--
3)<invalid-authzid/>--
4)<invalid-mechanism/>--
5)<mechanism-too-weak/>--
6)<not-authorized/>--
7)<temporary-auth-failure/>--
6.5 客戶(hù)端到服務(wù)器的例子
以下例子顯示了使用SASL授權的客戶(hù)端與服務(wù)器端的數據流,正常情況下,是在TLS協(xié)商(注:顯示在下面的替換步驟用于顯示錯誤情況的協(xié)議;他們并不詳盡也不是必要的由本例中數據發(fā)送而觸發(fā)。)成功之后。
步1:客戶(hù)端初始流給服務(wù)器:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步2:服務(wù)器使用一個(gè)流標記作為響應發(fā)送給客戶(hù)端:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
id=‘c2s_234‘
from=‘example.com‘
version=‘1.0‘>
步3:服務(wù)器通知客戶(hù)端可利用的認證機制:
<stream:features>
<mechanisms xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<mechanism>DIGEST-MD5</mechanism>
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>
步4:客戶(hù)端選擇一個(gè)認證機制:
<auth xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘
mechanism=‘DIGEST-MD5‘/>
步5:服務(wù)器發(fā)送一個(gè)[BASE64]編碼挑戰給客戶(hù)端:
<challenge xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘> cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
解碼挑戰是:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
步5(替換):服務(wù)器返回錯誤給客戶(hù)端:
<failure xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<incorrect-encoding/>
</failure>
</stream:stream>
步6:客戶(hù)端發(fā)送一個(gè)[BASE64]編碼響應挑戰:
<response xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNoYXJzZXQ9dXRmLTgK
</response>
步7:服務(wù)器發(fā)送另一個(gè)[BASE64]編碼挑戰給客戶(hù)端:
<challenge xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
解碼挑戰是:
rspauth=ea40f60335c427b5527b84dbabcdfffd
步7(替換):服務(wù)器返回錯誤給客戶(hù)端:
<failure xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<temporary-auth-failure/>
</failure>
</stream:stream>
步8:客戶(hù)端響應挑戰:
<response xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘/>
步9:服務(wù)器通知客戶(hù)端認證成功:
<success xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘/>
步9(替換):服務(wù)器通知客戶(hù)端認證失?。?br> <failure xmlns=‘urn:ietf:params:xml:ns:xmpp-sasl‘>
<temporary-auth-failure/>
</failure>
</stream:stream>
步10:客戶(hù)端初始化一個(gè)新流給服務(wù)器:
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
to=‘example.com‘
version=‘1.0‘>
步11:服務(wù)器通過(guò)發(fā)送流頭來(lái)響應客戶(hù)端,伴隨有任意另外的特征(或空特征元素):
<stream:stream
xmlns=‘jabber:client‘
xmlns:stream=‘http://etherx.jabber.org/streams‘
id=‘c2s_345‘
from=‘example.com‘
version=‘1.0‘>
<stream:features>
<bind xmlns=‘urn:ietf:params:xml:ns:xmpp-bind‘/>
<session xmlns=‘urn:ietf:params:xml:ns:xmpp-session‘/>
</stream:features>
8.服務(wù)器回叫
8.1概述
Jabber協(xié)議來(lái)自于XMPP適用的,包含一個(gè)“服務(wù)器回叫”方法,用以保護免受域哄騙,因此,使哄騙XML節更困難。服務(wù)器回叫并不是一個(gè)安全機制,并且僅導致服務(wù)器身份弱驗證(參考服務(wù)器到服務(wù)器的通信(14.4)相關(guān)方法的安全特性)。域需要健壯的安全性,應當使用TLS與SASL;參考服務(wù)器到服務(wù)器通信(4.4)細節。如果SASL用于服務(wù)器到服務(wù)器的認證,回叫不應當使用,因為它是不必要的。包含回叫文檔主要是出于與現存實(shí)現與部署向后兼容的原因。
服務(wù)器回叫方法因域名系統(DNS)存在而成為可能,由于一個(gè)服務(wù)器能夠(正常的)對一個(gè)給定域發(fā)現授權服務(wù)器。因為回叫依靠DNS,域內通信不準處理,直到由服務(wù)器宣稱(chēng)的域名系統(DNS)的主機名被解析(參考服務(wù)器到服務(wù)器的通信(14.4))。
服務(wù)器回叫是單向的,導致一個(gè)方向上一個(gè)流身份的(弱)驗證。因為服務(wù)器回叫不是一個(gè)認證機制,通過(guò)回叫是不可能進(jìn)行雙向認證的。因此,服務(wù)器回叫必須在每個(gè)方向上完成,為了使在兩個(gè)域間進(jìn)行雙向通信成為可能。
產(chǎn)生與驗證密鑰的方法用于服務(wù)器回叫,必須考慮被用的主機名,由接收服務(wù)器產(chǎn)生的流ID,和由授權服務(wù)器的網(wǎng)絡(luò )秘密知道。流ID在服務(wù)器回叫中是嚴格安全的,并且因此必須是即不可預測也不可重復的(參考[RANDOM]推薦資料相關(guān)用于安全觀(guān)點(diǎn)的隨機性。)
任何在回叫協(xié)商期間發(fā)生的錯誤必須考慮一個(gè)流錯誤,導致終止流與潛在的TCP連接。協(xié)議描述中說(shuō)明的可能的錯誤條件如下。
以下術(shù)語(yǔ)應用:
1) 源服務(wù)器——試圖在兩個(gè)域間建立連接的服務(wù)器。
2) 接收服務(wù)器——嘗試認證源服務(wù)器是否按它聲明的那樣去表達。
3) 授權服務(wù)器——回答由源服務(wù)器宣稱(chēng)的DNS主機名;對基本環(huán)境來(lái)說(shuō)是源服務(wù)器,但在源服務(wù)器網(wǎng)絡(luò )中可以是一個(gè)分離的機器。
8.2事件順序
以下是回叫事件順序的簡(jiǎn)單總結:
1) 源服務(wù)器建立到接收服務(wù)器的連接。
2) 源服務(wù)器通過(guò)連接,給接收服務(wù)器發(fā)送‘key’值。
3) 接收服務(wù)器建立到認證服務(wù)器的連接。
4) 接收服務(wù)器向授權服務(wù)器發(fā)送相同的‘key’值。
5) 授權服務(wù)器回答密鑰值是否有效。
6) 接收服務(wù)器通知源服務(wù)器授權是否通過(guò)。
我們可以將事件順序以下圖表示:
Originating Receiving
Server Server
----------- ---------
| |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| | Authoritative
| send dialback key | Server
| ----------------------> | -------------
| | |
| establish connection |
| ----------------------> |
| |
| send stream header |
| ----------------------> |
| |
| send stream header |
| <---------------------- |
| |
| send verify request |
| ----------------------> |
| |
| send verify response |
| <---------------------- |
|
| report dialback result |
| <---------------------- |
| |
8.3協(xié)議
服務(wù)器間具體協(xié)議交互如下:
1) 源服務(wù)器建立TCP連接到接收服務(wù)器。
2) 源服務(wù)器發(fā)送流頭給接收服務(wù)器:
<stream:stream
xmlns:stream=‘http://etherx.jabber.org/streams‘
xmlns=‘jabber:server‘
xmlns:db=‘jabber:server:dialback‘>
注:‘to’與‘from’屬性在根流元素中是可選的。包含xmlns:db命名空間聲明,名字顯示向接收實(shí)體指示源服務(wù)器支持回叫。如果命名空間名不正確,那么,接收服務(wù)器必須產(chǎn)生一個(gè)<invalid-namespace/>流錯誤條件并終止XML流與TCP連接。
3) 接收服務(wù)器應當發(fā)送一個(gè)流頭返回給源服務(wù)器,包含一個(gè)用于交互的唯一的ID:
<stream:stream
xmlns:stream=‘http://etherx.jabber.org/streams‘
xmlns=‘jabber:server‘
xmlns:db=‘jabber:server:dialback‘
id=‘457F9224A0...‘>
注:‘to’與‘from’屬性在根流元素中是可選的。如果命名空間名不正確,那么源服務(wù)器必須產(chǎn)生一個(gè)<invalid-namespace/>流錯誤條件,并終止XML流與TCP連接。而且,接收服務(wù)器應當回應,但可能根據適當的安全策略默默終止XML流與TCP連接。然而,如果接收服務(wù)器想要處理,它必須發(fā)送一個(gè)流頭返回給源服務(wù)器。
4) 源服務(wù)器發(fā)送一個(gè)回叫密鑰給接收服務(wù)器:
<db:result
to=‘Receiving Server‘
from=‘Originating Server‘>
98AF014EDC0...
</db:result>
注:此密鑰并不被接收服務(wù)器所檢查,因為接收服務(wù)器并不保存相關(guān)源服務(wù)器間會(huì )話(huà)信息。由源服務(wù)器產(chǎn)生的密鑰必須部分基于接收服務(wù)器在先前步驟提供的ID值,并部分基于源服務(wù)器與授權服務(wù)器的保密共享。如果‘to’地址值并不與接收服務(wù)器所識別的主機名匹配,那么,接收服務(wù)器必須產(chǎn)生一個(gè)<host-unknown/>流錯誤條件并終止XML流與潛在的TCP連接。如果‘from’地址值與帶有接收服務(wù)器已經(jīng)建立的連接的域匹配,那么,接收服務(wù)器可能選擇為新連接產(chǎn)生一個(gè)<not-authorized/>流錯誤條件,然后終止XML流與潛在的與新請求相關(guān)的TCP連接。
5) 接收服務(wù)器建立一個(gè)TCP連接支持由源服務(wù)器宣稱(chēng)的域,作為它連接到授權服務(wù)器的結果。(注意:作為優(yōu)化,一個(gè)實(shí)現可能重用一個(gè)現存的連接。)
6) 接收服務(wù)器發(fā)送給授權服務(wù)器一個(gè)流頭:
<stream:stream
xmlns:stream=‘http://etherx.jabber.org/streams‘
xmlns=‘jabber:server‘
xmlns:db=‘jabber:server:dialback‘>
注:在根流元素中,‘to’與‘from’屬性是可選的。如果命名空間名不正確,則授權服務(wù)器必須產(chǎn)生一個(gè)<invalid-namespace/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。
7) 授權服務(wù)器發(fā)送給接收服務(wù)器一個(gè)流頭:
<stream:stream
xmlns:stream=‘http://etherx.jabber.org/streams‘
xmlns=‘jabber:server‘
xmlns:db=‘jabber:server:dialback‘
id=‘1251A342B...‘>
注:如果命名空間名不正確,則接收服務(wù)器必須產(chǎn)生一個(gè)<invalid-namespace/>流錯誤條件并終止它與授權服務(wù)器間的兩個(gè)XML流與潛在的TCP連接。如果流錯誤發(fā)生在接收服務(wù)器與授權服務(wù)器間,則接收服務(wù)器必須產(chǎn)生一個(gè)<remote-connection-failed/>流錯誤條件并終止它與發(fā)起服務(wù)器間的兩個(gè)XML流與潛在的TCP連接。
8) 接收服務(wù)器發(fā)給授權服務(wù)器要求認證密鑰的請求:
<db:verify
from=‘Receiving Server‘
to=‘Originating Server‘
id=‘457F9224A0...‘>
98AF014EDC0...
</db:verify>
注:經(jīng)過(guò)這兒的是來(lái)自接收服務(wù)器的流頭的主機名、源標識符,到步驟3中的發(fā)起服務(wù)器,源服務(wù)器發(fā)送給接收服務(wù)器的密鑰在步驟4。根據這些信息,還有授權服務(wù)器網(wǎng)絡(luò )中的共享密鑰信息,密鑰被驗證。任何驗證方法可能用于產(chǎn)生密鑰。如果‘to’地址值與授權服務(wù)器識別的主機名不匹配,那么,授權服務(wù)器必須產(chǎn)生一個(gè)<host-unknown/>流錯誤條件并終止兩個(gè)XML與潛在的TCP連接。如果‘from’地址值與源服務(wù)器打開(kāi)TCP連接時(shí)(或任意相關(guān)有效域,例如接收服務(wù)器的主機名或其它有效域一個(gè)有效子域)所表示的主機名不匹配,則授權服務(wù)器必須產(chǎn)生一個(gè)<invalid-from/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。
9) 授權服務(wù)器驗證密鑰是否有效
<db:verify
from=‘Originating Server‘
to=‘Receiving Server‘
type=‘valid‘
id=‘457F9224A0...‘/>
或
<db:verify
from=‘Originating Server‘
to=‘Receiving Server‘
type=‘invalid‘
id=‘457F9224A0...‘/>
注:如果ID與步驟3中的接收服務(wù)器不匹配,那么接收服務(wù)器必須產(chǎn)生一個(gè)<invalid-id/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。如果‘to’地址值與接收服務(wù)器所識別的主機名不匹配,則接收服務(wù)器必須產(chǎn)生一個(gè)<host-unknown/>流錯誤條件并終止兩個(gè)XML流與潛在的TXP連接。如果‘from’地址值與源服務(wù)器打開(kāi)TCP連接時(shí)(或任意相關(guān)有效域,例如接收服務(wù)器的主機名或其它有效域一個(gè)有效子域)所表示的主機名不匹配,則接收服務(wù)器必須產(chǎn)生一個(gè)<invalid-from/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。返回認證信息給接收服務(wù)器之后,授權服務(wù)器應當終止他們之間的流。
10) 接收服務(wù)器通知源服務(wù)器結果:
<db:result
from=‘Receiving Server‘
to=‘Originating Server‘
type=‘valid‘/>
注:在這里,連接可通過(guò)一個(gè)type=‘valid‘或報告為無(wú)效來(lái)被認證。如果連接無(wú)效,則接收服務(wù)器必須終止兩個(gè)XML流與潛在的TCP連接。如果連接被認證,數據可被源服務(wù)器發(fā)送并被接收服務(wù)器讀??;在此這前,所有發(fā)送給接收服務(wù)器的XML節應該默默被扔掉。
前述結果是接收服務(wù)器已經(jīng)認證了源服務(wù)器的身份,為了節通過(guò)“初始流”(如,從源服務(wù)器到接收服務(wù)器的流)的XML能被源服務(wù)器發(fā)送與接收服務(wù)器能接收,為了驗證使用“響應流”(如,從接收服務(wù)器到源服務(wù)器)實(shí)體的身份,回叫必須以相反方向完成。
成功回叫協(xié)調后,接收服務(wù)器應當接收來(lái)自通過(guò)現存已認證連接的源服務(wù)器的子序列<db:result/>包(例如,認證需求發(fā)送到子域或其它由接收服務(wù)器服務(wù)主機名);這使在一個(gè)方向上的原來(lái)的已認證連接的"piggybacking"成為可能。
即使回叫協(xié)調成功,服務(wù)器必須認證從其它服務(wù)器接收的XML節,包括‘from’屬性與‘to’屬性;如果一個(gè)節并不滿(mǎn)足此限制,接收節的服務(wù)器必須產(chǎn)生一個(gè)<improper-addressing/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。進(jìn)一步講,服務(wù)器必須認證從其它服務(wù)器,包括流的一個(gè)已驗證域的‘from’屬性;如果節并不滿(mǎn)足此限制,收到節的服務(wù)器必須產(chǎn)生一個(gè)<invalid-from/>流錯誤條件并終止兩個(gè)XML流與潛在的TCP連接。這兩個(gè)檢查有助于阻止關(guān)聯(lián)到特別節的哄騙。
9.XML節
TLS協(xié)商(5節)后,如果需要SASL協(xié)商(6節)與資源綁定(7節),XML節可通過(guò)流來(lái)發(fā)送。定義了三種XML節用于‘jabber:client‘與‘jabber:server‘命名空間:<message/>, <presence/>, and <iq/>。另外,這種節有五個(gè)通用屬性。這些通用屬性,像三種節的基本語(yǔ)義一樣,都定義在此;與即時(shí)消息與表示應用相關(guān)的XML節的更詳細信息在[XMPP-IM]中提供。
9.1通用屬性
以下五個(gè)屬性對message, presence與IQ均通用:
9.1.1 to
‘to’屬性指定接收節的JID。
在‘jabber:client’命名空間中,節應當處理‘to’屬性,雖然,由服務(wù)器處理的從客戶(hù)端到服務(wù)器端的節不應該擁有‘to’屬性。
在‘jabber:server‘命名空間中,節必須擁有‘to’屬性;如果服務(wù)器收到一個(gè)不滿(mǎn)足此限制的節,它必須產(chǎn)生一個(gè)<improper-addressing/>流錯誤條件并終止兩個(gè)XML流與錯誤服務(wù)器的潛在連接。
如果‘to’屬性無(wú)效或不能連接,發(fā)現此事實(shí)的(通常是發(fā)送的或接收的服務(wù)器)實(shí)體必須返回一個(gè)合適的錯誤給發(fā)送者,設置錯誤節的‘from’屬性為錯誤服務(wù)器提供的‘to’屬性值。
9.1.2 from
‘from’屬性指明發(fā)送者的IID。
當服務(wù)器收到一個(gè)在由‘jabber:client‘命名空間認證的已授權流的上下文中的XML節,它必須做以下事件之一:
1) 驗證客戶(hù)端提供的‘from’屬性值就是用于聯(lián)合實(shí)體的已連接資源的值。
2) 加一個(gè)‘from’地址值給節,此節的值是裸JID(<node@domain>)或全JID(<node@domain/resource>),這些JID由服務(wù)器決定用于產(chǎn)生節的已聯(lián)接資源(看地址決定(3.5節))。
如果一個(gè)客戶(hù)端試圖發(fā)送‘from’屬性并不匹配實(shí)體的已聯(lián)接資源的XML節,服務(wù)器應該返回一個(gè)<invalid-from/>流錯誤給客戶(hù)端。如果一個(gè)客戶(hù)端試圖通過(guò)一個(gè)流來(lái)發(fā)送一個(gè)還未授權的XML節,服務(wù)器應當返回一個(gè)<not-authorized/>流錯誤給客戶(hù)端。如果產(chǎn)生了,這些條件都必須關(guān)閉流并終止潛在的TCP連接;這有助于阻止來(lái)自于欺詐客戶(hù)端的否認服務(wù)攻擊。
當一個(gè)服務(wù)器產(chǎn)生一個(gè)來(lái)自于服務(wù)器本身的節,用于傳送到一個(gè)已連接的客戶(hù)端(例如:在由服務(wù)器代表客戶(hù)端提供的數據存儲服務(wù)的上下文中),節必須既(1)不包括‘from’屬性或(2)包括‘from’屬性,其值是帳戶(hù)的裸JID(<node@domain>)或客戶(hù)的全JID(<node@domain/resource>)。服務(wù)器不準發(fā)送給客戶(hù)端一個(gè)不包括‘from’屬性的節,它必須設想節是從服務(wù)器到已連接客戶(hù)端。
在‘jabber:server‘命名空間中,一個(gè)節必須處理一個(gè)‘from’屬性;如果服務(wù)器收到不滿(mǎn)足此限制的節,它必須產(chǎn)生一個(gè)<improper-addressing/>流錯誤條件。更進(jìn)一步,包含在‘from’屬性中的JID的域標識符部分必須匹配發(fā)送服務(wù)器(或任何已認證相關(guān)域,如發(fā)送服務(wù)器的主機名或其它由發(fā)送服務(wù)器已認證域)的主機名,當在SASL協(xié)商或回叫協(xié)商通信中;如果一個(gè)服務(wù)器收到一個(gè)不滿(mǎn)足此約束的節,它必須產(chǎn)生一個(gè)<invalid-from/>流錯誤條件。這些條件都必須關(guān)閉流并終止潛在的TCP連接;這有助于阻止欺詐服務(wù)器的否認服務(wù)攻擊。
9.1.3 id
可選‘id’屬性可能由發(fā)送實(shí)體因內部跟蹤收發(fā)(特別是跟蹤固有在IQ節語(yǔ)義中的請求-響應交互)節而使用。對值‘id’屬性來(lái)說(shuō),它是可選的唯一全局的,在域內的或流中的。IQ節語(yǔ)義強加了其它約束;看IQ語(yǔ)義(9.2.3)。
9.1.4 type
類(lèi)型域屬性指定目的或消息上下文,出席或IQ節的詳細信息。‘type’屬性的特別允許值依賴(lài)節是否是一個(gè)消息,出席,或IQ;消息與出席節的值是特別用于即時(shí)消息與出席應用的,并因此定義義在[XMPP-IM],然而IQ節的值特指IQ節在一個(gè)結構化的請求-響應“會(huì )話(huà)”中的角色,并因此定義在以下IQ語(yǔ)義(9.2.3節)。對三種節僅有的一個(gè)通用‘type’值是“error”;看節錯誤(9.3節)。
9.1.5 xml:lang
此節應當處理一個(gè)‘xml:lang’屬性(定義在[XML]2.2節),如果節包含傾向于表示到一個(gè)人類(lèi)用戶(hù)(RFC2277[CHARSET]中有解釋?zhuān)?#8220;對人的國際化”)的XML字符數據。‘xml:lang’屬性值指定任意人類(lèi)可讀XML字符數據的缺省語(yǔ)言,可能被特定的子元素的‘xml:lang’屬性覆蓋。如果節沒(méi)有‘xml:lang’屬性,實(shí)現必須設想為流指定的缺省語(yǔ)言已在以下流屬性(4。4節)中定義。‘xml:lang’屬性的值必須是一個(gè)NMTOKEN并必須遵從定義在3066[LANGTAGS]中的格式。
9.2基本語(yǔ)義
9.2.1消息語(yǔ)義
<message/>節種類(lèi)可被看作“推”機制,一個(gè)實(shí)體推信息給其它實(shí)體,與EMAIL系統中發(fā)生的通信類(lèi)似。所有消息節應該擁有‘to’屬性,指定有意的消息接收者;根據接收到那樣的一個(gè)節,服務(wù)器應該路由或傳送它到有意的接收者(參考服務(wù)器處理用于相關(guān)XML節的通用路由與傳送規則XML節的規則(10節))。
9.2.2 出席語(yǔ)義
<presence/>元素可被看作基本廣播或“出版-訂閱”機制,多實(shí)體收到他們已訂閱(在這種情況下,網(wǎng)絡(luò )可利用信息)實(shí)體的信息??偟膩?lái)說(shuō),出版實(shí)體應該發(fā)送一個(gè)不帶‘to’屬性的出席節,在這種情況下,與此實(shí)體相連的服務(wù)器應該廣播或復用節給所有訂閱實(shí)體。然而,一個(gè)出版實(shí)體也可能發(fā)送一個(gè)帶有‘to’屬性的出席節,此種情況下,服務(wù)器應該路由或傳送節到有意的接收者。參考處理XML節(10節)的服務(wù)器規則,用于通用路由與相關(guān)XML節的傳送規則,并且用于即時(shí)消息與出席應用的出席-特定規則[XMPP-IM]。
9.2.3 IQ語(yǔ)義
信息/請求,或IQ,是一個(gè)請求-響應機制,與[HTTP]在某些方面相似。IQ語(yǔ)義讓一個(gè)實(shí)體向其它實(shí)體請求或接收其它實(shí)體的響應成為可能。請求與響應的數據內容由IQ無(wú)素的直接子元素的命名空間聲明定義,并且,交互由請求實(shí)體通過(guò)使用‘id’屬性來(lái)跟蹤。因此,IQ交互遵從結構化數據交換的一個(gè)通用模式,此交換例如得到/結果或設置/結果(雖然如果合適的話(huà),對一個(gè)請求的響應可能會(huì )以錯誤返回):
Requesting Responding
Entity Entity
---------- ----------
| |
| <iq type=‘get‘ id=‘1‘> |
| ------------------------> |
| |
| <iq type=‘result‘ id=‘1‘> |
| <------------------------ |
| |
| <iq type=‘set‘ id=‘2‘> |
| ------------------------> |
| |
| <iq type=‘error‘ id=‘2‘> |
| <------------------------ |
| |
為了加強這些語(yǔ)義,以下規則應用:
1) 對IQ節來(lái)說(shuō),‘id’屬性是REQUIRED。
2) 對IQ節來(lái)說(shuō)。‘type’屬性是需要的。值必須是以下之一:
*get——節是一個(gè)用于信息或需求的請求。
*set——節提供所需數據,設置新值,或替換現存值。
*result——節是成功得到或設置請求的響應。
*error——先前發(fā)送得到或設置的相關(guān)過(guò)程或傳送的錯誤(參考節錯誤(9.3節))。
3) 收到類(lèi)型為“get”或“set”的IQ請求的實(shí)體必須以類(lèi)型為“result”或“error”的IQ響應來(lái)響應(響應必須保留請求的‘id’屬性)。
4) 收到類(lèi)型為“result”或“error”的節不準靠發(fā)送一個(gè)進(jìn)一步的類(lèi)型為“result”或“error”的IQ響應節來(lái)響應;然而,如以上顯示,請求實(shí)體可能發(fā)送另一個(gè)請求(如:一個(gè)類(lèi)型為“set”的IQ,為了提供通過(guò)得到/結果對發(fā)現的所需的信息)。
5) 類(lèi)型為“get”或“set”的IQ節必須包含一個(gè)并僅有一個(gè)子元素,指定特別的請求或響應語(yǔ)義。
6) 一個(gè)類(lèi)型為“result”的IQ節必須包含0或一個(gè)子元素。
7) 類(lèi)型為“error”類(lèi)型的IQ節應當包含在相關(guān)“get”或“set”子元素中,并且,必須包含一個(gè)<error/>子元素;詳細信息,參考節錯誤(9.3節)。
9.3 節錯誤
節相關(guān)錯誤以類(lèi)似流錯誤(4.7節)的方式處理。然而,不像流錯誤,節錯誤不可是不可恢復的;因此,暗含相關(guān)源發(fā)送者行為的錯誤節能按順序糾正錯誤。
9.3.1 規則
以下規則應用于節相關(guān)錯誤:
1) 檢測相關(guān)節錯誤條件的接收或處理實(shí)體必須返回給發(fā)送實(shí)體一個(gè)同種節(消息,出席或IQ),它的‘type’屬性被設置成值“error”(那樣的節在此被稱(chēng)為“錯誤節”)。
2) 產(chǎn)生錯誤節的實(shí)體應當包含被送的源XML,為了發(fā)送者能夠檢測,并且,如果必要的話(huà),在試圖重送前糾正XML。
3) 一個(gè)錯誤節必須包含一個(gè)<error/>子元素。
4) 一個(gè)<error/>子元素不準被包括,如果‘type’屬性有不止一個(gè)“錯誤”值(或無(wú)‘類(lèi)型’屬性)。
5) 接收一個(gè)錯誤節的實(shí)體不準響應帶有進(jìn)一步錯誤節的節;這有助于阻止循環(huán)。
9.3.2 語(yǔ)法
節相關(guān)錯誤語(yǔ)法如下:
<stanza-kind to=‘sender‘ type=‘error‘>
[RECOMMENDED to include sender XML here]
<error type=‘error-type‘>
<defined-condition xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas‘/>
<text xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas‘
xml:lang=‘langcode‘>
OPTIONAL descriptive text
</text>
[OPTIONAL application-specific condition element]
</error>
</stanza-kind>
節種類(lèi)是消息、出席或iq之一。
<error/>元素的‘type’屬性值必須是以下之一:
*cancel——不重試(錯誤不可恢復)
*continue——進(jìn)行(僅是一個(gè)警告條件)
*modify——改變數據發(fā)送后重試
*auth——提供信任后重試
*wait——等待之后重試(錯誤是臨時(shí)的)
<error/>元素:
必須包含一個(gè)子元素,此子元素與以下指定的已定義的節錯誤條件一致;此元素必須被‘urn:ietf:params:xml:ns:xmpp-stanzas‘命名空間所認證。
可能包含<text/>子元素,此子元素包含XML字符數據,用于描繪更細節的錯誤;此元素必須被‘urn:ietf:params:xml:ns:xmpp-stanzas‘命名空間所認證,并且應該擁有一個(gè)‘xml:lang‘屬性。
可能包含一個(gè)子元素,用于特殊-應用錯誤條件;此元素必須由一個(gè)已定義-應用命名空間認證,并且,它的結構由此命名空間定義。
<text/>元素是可選的。如果包括在內,它應當僅用于提供描述性或診斷性信息,這些信息用于補充已定義條件或特殊-應用條件的意思。它不應當由應用程序性的描述。它不應當用作向用戶(hù)表達的錯誤信息,但可能顯示除與包含條件元素(或元素們)相關(guān)的錯誤消息。
最后,為維護向后兼容性,此方案(在[XMPP-IM]中指定的)允許可選的在<error/>元素中包含‘code’屬性。
9.3.3 已定義條件
以下條件被定義用于節錯誤。
<bad-request/>——發(fā)送者已發(fā)送畸形的或不能被處理的(例如,一個(gè)包含未識別‘type’屬性值的IQ節)XML;相關(guān)錯誤類(lèi)型應當是“modify”。
<conflict/>——訪(fǎng)問(wèn)不被授權,因為一個(gè)現存資源或會(huì )話(huà)以同樣名字或地址存在;相關(guān)錯誤類(lèi)型應當是“cancel”。
<feature-not-implemented/>——被請求特征未被接收者或服務(wù)器實(shí)現,并且因此不能被處理;相關(guān)錯誤類(lèi)型應當是“cancel”。
<forbidden/>——請求實(shí)體不擁有執行行為的所需許可;相關(guān)錯誤類(lèi)型應當是“auth”。
<gone/>——接收者或服務(wù)器不在以此地址聯(lián)系(錯誤節可能包含一個(gè)新地址在<gone/>元素的XML字符數據中);相關(guān)錯誤類(lèi)型應當是“modify”。
<internal-server-error/>——服務(wù)器不能處理節,因為錯誤配置或一個(gè)另外-未定義內部服務(wù)器錯誤;相關(guān)錯誤類(lèi)型應當是“wait”。
<item-not-found/>——JID地址或被請求項不能被發(fā)現;相關(guān)錯誤類(lèi)型應當是“cancel”。
<jid-malformed/>——已提供的發(fā)送實(shí)體或與一個(gè)XMLL地址(例:‘to’屬性值)通信或其它方面(例:資源標識符)與地址方案(3節)中定義的語(yǔ)法不符;相關(guān)錯誤類(lèi)型應當是“modify”。
<not-acceptable/>——接收者或服務(wù)器理解請求,但拒絕處理它,因為它不滿(mǎn)足由接收者或服務(wù)器(例:消息中相關(guān)可接受字的本地策略)所定義的標準;相關(guān)錯誤類(lèi)型應當是“modify”。
<not-allowed/>——接收者或服務(wù)器不允許任何實(shí)體執行動(dòng)作;相關(guān)錯誤類(lèi)型應當是“cancel”。
<not-authorized/>——發(fā)送者必須在被允許執行動(dòng)作前提供合適的信任,或已經(jīng)提供不合適的信任;相關(guān)錯誤類(lèi)型應當是“auth”。
<payment-required/>——請求實(shí)體未授權去訪(fǎng)問(wèn)被需求服務(wù),因為需要付費;相關(guān)錯誤類(lèi)型應當是“auth”。
<recipient-unavailable/>——有意的接收者臨時(shí)不可用;相關(guān)錯誤類(lèi)型應當是“wait”(注:一個(gè)應用不準返回此錯誤,如果這樣做將提供關(guān)于意向接收 者對未授權知道此類(lèi)信息的實(shí)體的網(wǎng)絡(luò )可利用性信息)。
<redirect/>——接收者或服務(wù)器為此信息重定向請求到其他實(shí)體,通常是臨時(shí)的(錯誤節應當包含可替換地址,必須是一個(gè)有效的JID,在<redirect/>元素的XML字符數據中);相關(guān)錯誤類(lèi)型應當是“modify”。
<registration-required/>——請求實(shí)體未被授權訪(fǎng)問(wèn)所請求服務(wù),因為需要注冊;相關(guān)錯誤類(lèi)型應當是“auth”。
<remote-server-not-found/>——一個(gè)指定作為意向接收者的部分或全部的JID的遠程服務(wù)器或服務(wù)不存在;相關(guān)錯誤類(lèi)型應當是“cancel”。
<remote-server-timeout/>——一個(gè)指定作為意向接收者(或被請求去執行一個(gè)請求)的部分或全部的JID的遠程服務(wù)器或服務(wù)不能在一個(gè)合理的時(shí)間內被聯(lián)系到;相關(guān)錯誤類(lèi)型應當是“wait”。
<resource-constraint/>——服務(wù)器或接收者缺少必要的系統資源去服務(wù)請求;相關(guān)錯誤類(lèi)型應當是“wait”。
<service-unavailable/>——服務(wù)器或接收者當前并不提供所請求的服務(wù);相關(guān)錯誤類(lèi)型應當是“cancel”。
<subscription-required/>——請求實(shí)體不被授權訪(fǎng)問(wèn)被請求服務(wù),因為需要訂閱;相關(guān)錯誤類(lèi)型應當是“auth”。
<undefined-condition/>——錯誤條件并不是此列表中由其它條件定義的那些之一;任何錯誤類(lèi)型可能與此條件相關(guān),并且,它應當僅用于與一個(gè)特殊-應用條件相連。
<unexpected-request/>——接收者或服務(wù)器理解請求,但此時(shí)(例:請求無(wú)序/請求不在狀態(tài))并不期望它;相關(guān)錯誤類(lèi)型應當是“wait”。
9.3.4 特殊-應用條件
像所知道的,一個(gè)應用可能靠包含一個(gè)錯誤元素中的合適的-命名空間的子元素來(lái)提供特殊-應用節錯誤信息。特殊-應用元素應當補充或進(jìn)一步認證一個(gè)已定義元素。因此,<error/>元素將包含兩個(gè)或三個(gè)子元素:
<iq type=‘error‘ id=‘some-id‘>
<error type=‘modify‘>
<bad-request xmlns=‘urn:ietf:params:xml:ns:xmpp-stanzas‘/>
<too-many-parameters xmlns=‘a(chǎn)pplication-ns‘/>
</error>
</iq>
10. 處理XML節的服務(wù)器規則
兼容服務(wù)器實(shí)現必須確保有序處理任兩實(shí)體間的XML節。
超出有序處理的需求,每個(gè)服務(wù)器實(shí)現將包含它自己的“傳送樹(shù)”用于處理它所接收的節。那樣的一個(gè)樹(shù)決定是否一個(gè)節需要被路由到其它域,內部處理,或傳送到與被連節點(diǎn)相關(guān)的資源。以下規則應用:
10.1 無(wú)‘to’地址
如果節擁有無(wú)‘to’屬性,服務(wù)器應當代表發(fā)送它的實(shí)體處理它。因為所有從其它服務(wù)器收到的節必須擁有一個(gè)‘to’屬性,此規則僅應用于從一個(gè)連到服務(wù)器的已注冊實(shí)體(如客戶(hù)端)收到的節。如果服務(wù)器收到一個(gè)無(wú)‘to’屬性的出席節,服務(wù)器應當廣播它到被訂閱到發(fā)送實(shí)體的出席實(shí)體,如果可利用的話(huà)(用于定義在[XMPP-IP]即時(shí)消息與表示應用的出席廣播的語(yǔ)義。)如果服務(wù)器接收一個(gè)類(lèi)型為“get”或“set”的沒(méi)有‘to’屬性的IQ節,并且它理解認證節內容的命名空間,它必須也能代表發(fā)送實(shí)體處理節或返回給發(fā)送實(shí)體(在“process”意思處被認證命名空間的語(yǔ)義決定)一個(gè)錯誤。
10.2 外部域
如果JID的域標識符部分的主機包含在‘to’屬性中并不匹配服務(wù)器本身的已配置主機名或子域中的已配置主機之一,服務(wù)器應當路由節到外部域(服從本地服務(wù)提供與相關(guān)內部域通信的安全策略)。有兩種可能情況:
一個(gè)服務(wù)器到服務(wù)器流已在兩域間存在:發(fā)送者的服務(wù)器為現存流的外部域路由節到已授權服務(wù)器。
兩域間存在無(wú)主機到主機流:發(fā)送者的服務(wù)器(1)解析外部域(定義在以下服務(wù)器到服務(wù)器通信(節14。4))的主機名,(2)在兩域間(定義在如下使用TLS(節5)并且使用SASL(節6))協(xié)商服務(wù)器到服務(wù)器的流,并(3)為通過(guò)新近-建立的流的外部域路由節到授權服務(wù)器。
如果路由到接收者的服務(wù)器不成功,發(fā)送者的服務(wù)器必須返回一個(gè)錯誤給發(fā)送者;如果接收者的服務(wù)器能被聯(lián)系但被接收者的服務(wù)器傳送到接收者是不成功的,接收者的服務(wù)器必須經(jīng)由發(fā)送者的服務(wù)器返回一個(gè)錯誤給發(fā)送者。
10.3 子域
如果包含在‘to’屬性中的JID域標識符部分的主機名匹配服務(wù)器本身已配置主機名之一的子域,服務(wù)器必須也處理節本身或路由節到一個(gè)特別的對那個(gè)子域(如果子域被配置)有責任的服務(wù),或返回一個(gè)錯誤給發(fā)送者(如果子域不被配置)。
10.4 僅有域或特別資源
如果包含在‘to’屬性中的JID域標識符部分的主機名匹配服務(wù)器本身的一個(gè)已配置主機名,并且包含在‘to’屬性中的JID是<domain>或<domain/resource>形式,服務(wù)器(或在內的一個(gè)已定義資源)必須合乎節種類(lèi)處理節或返回錯誤節給發(fā)送者。
10.5 同域中的節點(diǎn)
如果包含在‘to’屬性中的JID域標識符部分的主機名匹配服務(wù)器本身的一個(gè)已配置主機名,并且包含在‘to’屬性中的JID是<node@domain>或<node@domain/resource>形式,服務(wù)器應當傳送節到由包含在‘to’屬性中的JID表達的節的意向接收者。以下規則應用:
11. XMPP內的XML使用
11.1 約束
XMPP是流XML元素的一個(gè)簡(jiǎn)單與特殊的協(xié)議,用來(lái)近實(shí)時(shí)的交換結構化信息。由于XMPP不需要任意分析與完整XML文檔,這兒沒(méi)有XMPP需要支持[XML]全特征的需求。特別的,以下約束應用。
關(guān)于XML產(chǎn)生,一個(gè)XMPP實(shí)現不準注入以下任意一個(gè)XML流:
*評論(定義在[XML]節2。5)
*處理說(shuō)明(2。6節)
*內部或外部DTD子集(2。8節)
*除了預定義實(shí)體(4。6節)的內部或外部實(shí)體參考。
*包含映射到預定義實(shí)體(4。6節)保留字符的字符數據或屬性值;那樣的字符必須被避免
關(guān)于XML處理,如果一個(gè)XMPP實(shí)現接收到那樣的約束XML數據,它必須忽略此數據。
11.2 XML命名空間名與前綴
XML命名空間[XML-NAMES]被用在所有與XMPP-兼容的XML中,去創(chuàng )建數據擁有權的嚴格界限。命名空間的基本功能是分離結構的混合在一起的XML元素的不同詞匯。確保XMPP-兼容XML是命名空間-了解使任意允許的XML能夠與XMPP中的任意數據元素結構化的混合。XML命名空間名與前綴的規則定義在以下子部分。
11.2.1 流命名空間
流命名空間聲明在所有XML流頭中都是需要的。流命名空間名必須是‘http://etherx.jabber.org/streams‘。<stream/>元素與它的<features/>與<error/>子元素的元素名必須被所有實(shí)例中的流命名空間認定合格。一個(gè)實(shí)現應當為那些元素產(chǎn)生僅有的‘stream:‘前綴,并且因為歷史原因可能接受僅有的‘stream:‘前綴。
11.2.2 缺省命名空間
缺省命名空間聲明是需要的,并且用在所有XML流中,為了定義允許的根流元素的第一級子元素。此命名空間聲明必須與初始流與響應流相同,為了兩個(gè)流一致的被認證合格。缺省命名空間聲明應用于流與所有在由其它命名空間認證合格的流(除非由另一命名空間顯示認定合格,或由流命名空間或回叫命名空間前綴認證)中發(fā)送的節。
服務(wù)器實(shí)現必須支持以下兩個(gè)缺省命名空間(由于歷史原因,一些實(shí)現可能支持僅有的那些兩個(gè)缺省命名空間):
*jabber:client——缺省命名空間,當流用于客戶(hù)端與服務(wù)器通信時(shí)所聲明的。
*jabber:server——缺省命名空間,當流用于兩服務(wù)器間通信時(shí)聲明的。
客戶(hù)端實(shí)現必須支持‘jabber:client‘缺省命名空間,并且由于歷史原因可能只支持缺省命名空間。
實(shí)現不準為缺省命名空間中的元素產(chǎn)生命名空間前綴,如果缺省命名空間是‘jabber:client‘或‘jabber:server‘。一個(gè)實(shí)現不應當為元素產(chǎn)生命名空間前綴,元素由‘jabber:client‘與‘jabber:server‘之外的內容(與流相反)命名空間認證的。
注:‘jabber:client‘與‘jabber:server‘命名空間是接近同一的,但用在不同的上下文中(客戶(hù)端到服務(wù)順通信用‘jabber:client‘與服務(wù)器到服務(wù)器通信用‘jabber:server‘)。這兩個(gè)僅有的不同是‘to’與‘from’屬性在‘jabber:client‘中發(fā)送的節中是可選的,然而在‘jabber:server‘中發(fā)送的節是必須的。如果一個(gè)兼容實(shí)現接受一個(gè)由‘jabber:client‘或‘jabber:server‘命名空間認證合格的流,它必須支持所有三個(gè)核心節種類(lèi)的(消息,出席,與IQ)通用屬性(9。1節)與基本語(yǔ)義(9。2節)。
11.2.3 回叫命名空間
回叫命名空間聲明對于所有用在服務(wù)器回叫(8節)中的元素都是需要的?;亟忻臻g的名字必須是‘jabber:server:dialback‘。所有由這個(gè)命名空間認證合格的元素必須被加前綴。一個(gè)實(shí)現應當為那種元素僅產(chǎn)生‘db:‘前綴并可能接受僅有的‘db:‘前綴。
11.3 確認(驗證)
除了‘jabber:server‘命名空間中節的相關(guān)‘to’與‘from’地址,服務(wù)器不為轉發(fā)到客戶(hù)端或另一個(gè)服務(wù)器的XML元素負責;一個(gè)實(shí)現可能選擇提供僅有的認證數據元素,但這是可選的(雖然一個(gè)實(shí)現不準接受XML,那也不是好格式)??蛻?hù)端不應當依賴(lài)此能力去發(fā)送數據,這些數據與方案并不符,并且應當忽略一個(gè)來(lái)的XML流中的非構造元素或屬性。XML流與節的驗證是可選的,包含在此的方案僅用于描述目的。
11.4 包含文本聲明
實(shí)現應當在發(fā)送流頭之前發(fā)送文本聲明。應用必須遵循文本聲明包含在內的相關(guān)環(huán)境的[XML]中的規則。
11.5 字符編碼
實(shí)現必須支持UTF-8 (RFC 3629 [UTF-8])統一字符集(ISO/IEC 10646-1 [UCS2])字符傳輸,RFC 2277 [CHARSET]中查。實(shí)現不準試圖使用其它編碼。
聯(lián)系客服