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