XMPP協議( RFC 3920 )

1.簡介

XMPP是一個開放式的XML協議,設計用於準實時消息和出席信息以及請求-響應服務。其基本的語法和語義最初主要是由Jabber開放 源代碼社區於1999年開發的。2002年,XMPP工作組被授權接手開發和改編Jabber協議以適應IETF的即時消息和出席信息技術。作爲XMPP 工作組的成果,本文定義了 XMPP 1.0 的核心功能;在 RFC 2779 [IMP-REQS] 中指定的提供即時消息和出席信息功能的擴展,定義在 XMPP-IM 協議 [the Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence] 中。

 

2.通用的架構

概述

儘管XMPP沒有指定任何特定的網絡結構,但它通常是採用客戶-服務器 架構進行實現,其中客戶端通過TCP方式使用XMPP訪問服務器,服務器之間也採用TCP方式進行通信。
以下是這一架構的抽象的示意圖 (這裏 "-" 表示使用 XMPP 通訊, "=" 表示可使用任何協議通訊)。

 

  C1----S1---S2---C3
        |
  C2----+--G1===FN1===FC1

 

符號的含義如下:
  • C1, C2, C3 = XMPP 客戶端
  • S1, S2 = XMPP 服務器
  • G1 = 一個XMPP和外部(非XMPP)消息網絡之間進行“翻譯”的網關
  • FN1 = 一個外部消息網絡
  • FC1 = 外部消息網絡上的一個客戶端

服務器

服務器充當XMPP通信的一個智能抽象層,它主要負責:
  • 對受驗證的客戶端,服務器以及其他實體之間以XML流形式的連接和會話進行管理。
  • 在這些實體間使用XML流對合理編址的XML節(第九章)進行路由
大部分 XMPP 兼容的服務器也負責存儲客戶端使用的數據 (比如基於XMPP協議的及時消息應用中的聯繫人名單); 在這種情況下, XML 數據直接服務器來處理,而不需要轉發到其他實體。

客戶端

大部分客戶端通過 TCP 連接直接連到服務器,並通過XMPP獲得由服務器以及聯合服務器所提供的全部功能。多個不同資源(比如不同的設備和地點)的客戶端可以 同時登陸並且併發的連接到一個服務器,每個不同資源的客戶端通過XMPP地址的資源標識符來區分(比如<node@domain/ home> 和 <node@domain/work>),參見地址空間(第三章)。建議 的客戶端和服務器連接的端口是 5222 ,這個端口已經在 IANA(在第十五章第九節查閱端口號碼) 註冊了。

網關

網關是一個特殊用途的服務器端的服務,主要功能是把 XMPP 翻譯成外部(非XMPP)消息系統,並把返回的消息翻譯成 XMPP 。例如到 email(參見 [SMTP] ),IRC(參見 [IRC] ),SIMPLE(參見 [SIMPLE] ),SMS 的網關;還有和別的消息服務的網關,比如AIM,ICQ,MSN Messenger,Yahoo! Instant Messenger。網關和服務器之間的通信,網關和外部消息系統的通信,不在本文描述範圍之內。

網絡

因爲每個服務器都是由一個網絡地址來標識的並且服務器之間的通信是 客戶-服務器 協議的直接擴展,實際上整個系統是由很多互通的服務器構成的。例如,<[email protected]> 可以和 <[email protected]> 交換消息,出席信息和其他信息。這種模式常見於那些需要使網絡地址標準化的協議(比如 SMTP )。任意兩個服務器之間的通信是可選(OPTIONAL)的。如果被激活,那麼這種通信應該(SHOULD)通過 XML 流綁定到 TCP 連接上進行。建議的(RECOMMENDED)服務器之間的連接端口爲 5269 ,這個端口號已經在 IANA (在第十五章第九節查閱端口號碼)註冊了。

3.地址空間

概覽

一個實體可以是任何一個被認爲是一個網絡端點的東西(例如網絡上的一個 ID ),而且它是通過XMPP進行通信的。
一個 XMPP 實體的地址被稱爲 Jabber Identifier 或 JID,包括一組排列好的元素:域名(domain identifier),節點名(node identifier),和資源名(resource identifier)。
JID的語法定義,使用 [ABNF] 中的 Augmented Backus-Naur 格式。(IPv4 地址和 IPv6地址規則在 附錄B 中的 [IPv6] 中定義;確定節點規則的合法字符順序由 附錄A 的 [STRINGPREP] 的 Nodeprep 部分來定義;確定資源規則的合法字符順序由 附錄B 的 [STRINGPREP] 的Resourceprep 部分來定義;子域名規則參考 [IDNA] 中關於國際域名標籤的描述。)。
jid = [ node "@" ] domain [ "/" resource ]
domain = fqdn / address-literal
fqdn = (sub-domain 1*("." sub-domain))
sub-domain = (internationalized domain label)
address-literal = IPv4address / IPv6address
所有 JID 都是基於上述的結構。類似 <user@host/resource> 這種結構,最常用來標識一個即時消息用戶,這個用戶所連接的服務器,以及這個用戶用於連接的資源(比如特定類型的客戶端軟件)。不過,節點類型不是客戶端 也是有可能的,比如一個用來提供多用戶聊天服務的特定的聊天室,地址可以是 <room@service> (這裏 “room“ 是聊天室的名字而 ”service“ 是多用戶聊天服務的主機名),而加入了這個聊天室的某個特定的用戶的地址則是 <room@service/nick> (這裏 ”nick“ 是用戶在聊天室的暱稱)。許多其他的 JID 類型都是可能的(例如 <domain/resource> 可能是一個服務器端的腳本或服務)。
一個 JID 的每個合法部分(節點名,域名,資源名)的長度不能(MUST NOT)超過 1023 字節。也就是整體長度(包括 '@' 和 '/' )不能超過 3071 字節。

域名

域名是一個主要的ID並且是 JID 中唯一必需(REQUIRED)的元素(一個純粹的域名也是一個合法的 JID)。它通常代表網絡的網關或者“主”服務器,其他實體通過連接它來實現 XML 轉發和數據管理功能。然而,由一個域名標識引用的實體,並非總是一個服務器,它也可能是一個服務器的子域地址,提供額外的功能(比如多用戶聊天服務,用戶 目錄,或一個到外部消息系統的網關)。
每個服務器或者服務的域名,可以(MAY)是一個 IP 地址,但應該(SHOULD)是一個完全合法的域名(參見 [DNS]).一個域名ID必須(MUST)是 [IANA] 裏定義的“國際化域名”,並且按 [STRINGPREP]中的 [NAMEPREP] profile進行成功的字符轉換。在比較兩個域名ID之前,服務器必須(MUST),客戶端應該(SHOULD)首先按照Nameprep profile(定義在[IANA]中) 來轉換每個域名的字符。

節點名

節點名是一個可選(OPTIONAL)的第二 ID,放在域名之前並用符號"@"分開.它通常表示一個向服務器或網關請求和使用網絡服務的實體(比如一個客戶端),當然它也能夠表示其他的實體(比如在 多用戶聊天系統中的一個房間). 節點名所代表的實體,它的地址依賴於一個特定的域名;在 XMPP 的即時消息和出席信息應用系統中,這個地址是“純 JID” <node@domain> 中的一部分。
一個節點名必須按 [STRINGPREP] 中的 Nodeprep profile 進行成功的字符轉換。在比較兩個節點ID之前,服務器必須(MUST),客戶端應該(SHOULD)首先按 Nodeprep profile 轉換每個ID的字符。

資源名

資源名是一個可選的第三 ID,它放在域名的後面並由符號"/"分開。資源名可以跟在 <node@domain>後面也可以跟在 <domain> 後面。它通常表示一個特定的會話,連接(比如設備或者所在位置),或者一個附屬於某個節點ID實體相關實體的對象(比如多用戶聊天室中的一個參加者)。對 於服務器和和其他客戶端來說,資源名是不透明的。當它提供必需的信息以完成資源綁定(參見第七章)的時候,通常是由客戶端來實現的(儘管可以由客戶端向服 務器請求完成),然後顯示爲“已連接的資源”。一個實體可以(MAY)併發維護多個已連接的資源。每個已連接的資源由不同的資源ID來區分。
一個資源名必須(MUST)按 [STRINGPREP] 中的 Resourceprep profile 進行成功的格式化。在比較兩個資源ID之前,服務器必須(MUST),客戶端應該(SHOULD)首先按 Resourceprep profile 轉換每個ID的字符。

地址的確認

在 SASL (見第六章)握手之後(如果必要的話,也在資源綁定(見第七章)之後),正在接收流信息的實體必須(MUST)確認初始實體的 ID 。
對於服務器間的通信,在 SASL 握手時,如果沒有指明授權的ID,這個初始的實體應該(SHOULD)是經過認證實體(參見 簡單認證和安全層協議 [SASL] 中的定義)授權的ID(見第六章)。
對於客戶端和服務器的通信,在 SASL 握手時,如果沒有指明授權的ID,“純 JID” (<node@domain>)應該(SHOULD)是經過認證實體(參見 [SASL] 中的定義)授權的ID,“全 JID” (<node@domain/resource>)的資源ID部分應該(SHOULD)是由客戶端和服務器在資源綁定的時候商定的(參見第七 章)。
接收的實體必須(MUST)確保結果JID(包括節點名,域名,資源名以及分隔符)與本章前面部分描述的規則和格式相一致;爲了滿足這些約束條件,接收實體可能(MAY)需要把初始實體的發送方 JID 替換成接收實體認可的規範 JID。

4.XML流

概覽

兩個基本概念,XML流和XML節,使得在出席信息已知的實體之間,異步交換低負載的結構化信息成爲可能。這兩個術語定義如下:
XML流的定義:一個XML流是一個容器,包含了兩個實體之間通過網絡交換的XML元素。一個XML流是由一個XML打開標籤 <stream> (包含適當的屬性和名字空間聲明)開始的,流的結尾則是一個XML關閉L標籤 </stream> 。
在流的整個生命週期,初始化它的實體可以通過流發送大量的XML元素,用於流的握手(例如 TLS 握手(第五章) 或 SASL 握手(第六章))或XML節(在這裏指符合缺省名字空間的元素,包括<message/>,<presence/>, 或 <iq/> 元素)。“初始的流”由初始化實體(通常是一個客戶端或服務器)和接收實體(通常是一個服務器)握手,從接收實體來看,它就是那個初始實體的"會話".初 始化流允許從初始化實體到接收實體的單向通信;爲了使接收實體能夠和初始實體交換信息,接收實體必須發起一個反向的握手(應答流).
XML節的定義: 一個XML節是一個實體通過 XML 流向另一個實體發送的結構化信息中的一個離散的語義單位。 一個XML節直接存在於根元素<stream/>的下一級,這樣可以說是很好的匹配 了[XML](譯者注:在標準參考一節)的第43條.任何XML節都是從一個XML流的下一級的某個打開標籤(如 <presence>)開始,到相應的關閉標籤(如 </presence>)。一個XML節可以(MAY)包含子元素(相關的屬性,元素, 和 XML 字符數據等) 以表達完整的信息.在這裏定義的XML節僅限於<message/>, <presence/>, 和 <iq/> 元素,具體描述間見 XML Stanzas(第九章);爲TLS握手(第五章)、SASL握手(第六章)、服務器回撥(第八章)的需要而發送的XML元素,不被認爲是一個XML節。
設想一個客戶端和服務器會話的例子。爲了連接一個服務器,一個客戶端必須(MUST)發送一個打開標籤<stream>給服 務器,初始化一個XML流, 也可選擇(OPTIONAL)在這之前發送一段文本聲明XML版本和支持的字符集(參見文本聲明的內容(第十一章第四節); 也可看字符編碼(第十一章第五節))。視本地化策略和提供的服務而定,服務器應該(SHOULD)回覆一個XML流給客戶端,同樣的,也可選擇在這之前發 送一段文本聲明。一旦客戶端完成了SASL握手(第六章),客戶端可以(MAY)通過流發送不限量的XML節給網絡中的任何接收者。當客戶端想關閉這個 流,它只需要簡單的發送一個關閉標籤</stream>給服務器(或者作爲另一個選擇,可能由服務器關閉這個流)。然後,客戶端和服務器都應 該(SHOULD)徹底地終止這個連接(通常是一個TCP連接)。
那些習慣認爲XML是一個以文本爲中心風格的人可能希望看看一個與服務器連接的客戶端會話,包含兩個 打開-關閉 XML文檔:一個是從客戶端到服務器,一個是從服務器到客戶端。下圖中,根元素<stream/> 可以被認爲是每個“文檔”的文檔實體,這兩個“文檔”通過累積那些在XML上傳輸的XML節來搭建的。無論如何,下圖只是方便理解;實際上XMPP並不處 理文檔而是處理XML流和XML節。
基本上,一個XML流相當於一個會話期間所有XML節的一個信封。我們可以簡單的把它描述成下圖:
  |--------------------|
  | <stream>           
  |--------------------|
  | <presence>         
  |   <show/>          
  | </presence>        
  |--------------------|
  | <message to='foo'> 
  |   <body/>          
  | </message>         
  |--------------------|
  | <iq to='bar'>      
  |   <query/>         
  | </iq>              
  |--------------------|
  | ...                
  |--------------------|
  | </stream>          
  |--------------------|

綁定到TCP

雖然有很多非必需的連接使用XML流來綁定[TCP]連接(兩個實體可以通過別的機制來互聯,比如通過[HTPP]連接輪詢),本規範只 定義了 XMPP 到 TCP 的綁定。在客戶和服務器通信的過程中,服務器必須(MUST)允許客戶端共享一個TCP連接來傳輸XML節,包括從客戶端傳到服務器和從服務器傳到客戶 端。在服務器之間的通信過程中,服務器必須(MUST)用一個 TCP連接 向對方發送 XML節,另一個 TCP連接(由對方初始化)接收對方的XML節,一共兩個 TCP連接。

流的安全

在XMPP 1.0中,當XML流開始握手時,TLS(安全傳輸層協議 )應該(SHOULD)按 第五章:TLS的使用 中的規定來使用,SASL必須(MUST)按 第六章:SASL的使用 中的規定來使用。儘管可能(MAY)存在某種共有的機制能夠保證雙向安全,但是“初始化流”(比如從初始化實體發給接收實體的流)和“應答流”(比如從接 收實體發給初始化實體的流)還是必須(MUST)安全的分開。在流被驗證之間,實體不應該(SHOULD NOT) 嘗試通過流發送XML節(第九章);就算它這樣做了,對方的實體也不能(MUST NOT)接受這些XML節,並且應該(SHOULD)返回一個 <not-authorized/> 的流錯誤信息並且終止當前TCP連接上雙方的XML流;注意,這僅僅是針對XML節(包含在缺省命名空間中的 <message/>, <presence/>, 和 <iq/> 元素),而不是指那些用於 TLS握手(第五章)、SASL握手(第六章)握手的流。

stream 屬性

stream 元素的屬性如下:
  • to -- 'to' 屬性應(SHOULD)僅出現在初始化實體發給接收實體的 XML 流的頭當中,並且它的值必須(MUST)是接收實體所在的主機名。 在接收實體發送給初始化實體的 XML 流的頭中不應該(SHOULD NOT)出現 'to' 屬性。若 'to' 屬性出現在應答流中,則初始化實體應(SHOULD)忽略它。
  • from -- 'from' 屬性應(SHOULD)僅出現在接收實體發給初始化實體的 XML 流的頭當中,並且它的值必須(MUST)是爲當前初始化實體授權的接收實體所在的主機名。 注意,不應該(SHOULD NOT)有 'from'屬性出現在初始實體發送給接收實體的 XML流的頭中;無論如何,如果'from'屬性出現在初始化流中,接收實體應該(SHOULD)忽略它。
  • id -- 'id'屬性應該(SHOULD)僅用於接收實體發送給初始化實體 XML流的頭。這個屬性是一個由接收實體創建的具有唯一性的ID,一個初始實體和接收實體之間的會話ID,並且它在接收方的應用程序中(通常是一個服務 器)必須(MUST)是唯一的。 注意,這個流 ID 必須是足夠安全的,所以它必須是不可預知的和不可重複的(參見[RANDOM] 瞭解如何獲得隨機性以保證安全性)。不應該(SHOULD NOT)有 'id'屬性出現在初始實體發送給接收實體的 XML流的頭中;無論如何,如果'id'屬性出現在初始化流中,接收實體應該(SHOULD)忽略它。
  • xml:lang -- 'xml:lang'屬性(定義在[XML]中的第二章第十二節)應該(SHOULD)包含在初始化實體發給接收實體的 XML流的頭中,以指定在流中傳輸的可讀XML字符所使用的缺省語言。如果這個屬性出現了,接收實體應該(SHOULD)記住它的值,作爲初始化流和應答 流的缺省屬性;如果這個屬性沒有出現,接收實體應該(SHOULD)用一個可配置的缺省值用於雙方的流,這個屬性值必須(MUST)在應答流的頭中傳達。 對於所有初始化流中傳輸的節,如果初始實體沒有提供'xml:lang'屬性,接收實體應該(SHOULD)應用缺省值;如果初始實體提供了 'xml:lang'屬性,接收實體不能(MUST NOT)修改或刪除它(參見第九章第一節第五小節 xml:lang)。'xml:lang'屬性的值必須(MUST)是一個 NMTOKEN (定義在[XML]的第二章第三節) 並且必須(MUST)遵守 RFC 3066 [LANGTAGS] 規定的格式。
  • version -- version屬性(最少需要"1.0")爲本規範中和流相關的協議提供了支持。關於這個屬性的生成和處理的詳細規則將在下文中定義。
我們現在可以總結如下:
  初始化方發給接收方 接收方發給初始化方
to 接收方的主機名 忽略
from 忽略 接收方的主機名
id 忽略 會話鍵值
xml:lang 缺省語言 缺省語言
version 支持XMPP 1.0 支持XMPP 1.0

版本支持

在這裏XMPP的版本是"1.0";準確地說,這裏囊括了和流相關的所有協議(TLS的使用 (第五章),SASL的使用(第六章), 和流錯誤(第四章第七節)),以及三個定義好的XML節類型(<message/>,<presence/>,和 <iq/>)。XMPP版本號的編號順序是“<主版本號>.<副版本號>”。主版本和副版本號必須(MUST)是獨 立的整數並且每個號碼可以(MAY)單獨以阿拉伯數字增長。 這樣,"XMPP 2.4"的版本將比"XMPP 2.13"更低。號碼前面 的“0”(比如XMPP 6.01)必須(MUST)被接收方忽略並且不能(MUST NOT)被髮送出去.
如果流和節的格式或者必需的處理方式有了顯著的改變,以至於老版本的實體如果只是簡單的忽略它不理解的節和屬性並且繼續像老版本一樣的處 理方式,會使得老版本的實體不能夠和新版本的實體交互,只有在這時候主版本號才應該(SHOULD)增加。副版本號顯示新的性能,它必須(MUST)被副 版本號更低的實體忽略,但被高(副)版本號的實體用於瞭解信息。 例如,一個副版本號顯示處理某種新定義的"type"屬性的值(用於 message,presence或IQ節)的能力;副版本號高的實體將會瞭解到與之通信的對方不能夠理解這個"type"屬性的值,所以將不會發送它。
以下規則是用於'版本'屬性在實現流的頭信息時如何生成和處理:
  1. 初始化實體必須(MUST)在初始化流的頭信息中把'版本'的值設置成它所支持的最高版本 。(比如,如果最高版本支持就是本規範,那麼它必須(MUST)設置成"1.0").
  2. 接收實體必須(MUST)在應答流的頭信息中把'版本'的值設置成初始化實體所提供的版本或它所支持的最高版本,取其中版本號較低的那一個 。接收實體必須(MUST)把主版本號和副版本號作爲數字來比較,而不是對"主版本號.副版本號"這個字符串進行比較.
  3. 如果在應答流的頭信息的版本號中至少有一個主版本號低於初始化流的頭信息的版本號,並且如前所述,新版本的實體不能夠和舊版本實體交互,初始化實體應該 (SHUOULD)生成一個<unsupported-version/>的流錯誤信息並終止XML流和它的TCP連接。
  4. 如果一個實體收到一個頭信息中沒有'version'屬性的流,這個實體必須(MUST)把對方實體的'version'當成'0.0'並且在它發送的應答流的頭中也不應該(SHOULD NOT)包含'version'屬性.

名字空間聲明

流的元素必須(MUST)同時滿足一個流名字空間聲明和一個缺省名字空間聲明("名字空間聲明"定義在 XML 名字空間定義 [XML-NAMES]中).關於流名字空間和缺省名字空間的詳細信息,參考 名字空間的名字和前綴(第十一章第二節).

流的特性

如果初始化的實體在初始化流的頭信息中設置'version'屬性的信息爲"1.0",接收實體必須(MUST)向初始化實體發送一個 <features/> 子元素以聲明任何可供協商的流一級的特性(或者其他需要聲明的能力).目前,這僅用於聲明本文中定義的 TLS的使用(第五章),SASL的使用(第六章)和資源綁定(第七章),以及 XMPP-IM 中定義的會話的建立;無論如何,流特性這一功能將來可以用於聲明任何可協商的特性.如果一個實體不理解或支持安全特性,它應該(SHOULD)忽略它.如 果要在一個非安全相關的特性(比如資源綁定)被提議之前,完成一個或多個安全特性(比如TLS和SASL)的協商,這個非安全相關的特性不應該 (SHOULD NOT)在相應的安全特性協商完畢之前被聲明.

流錯誤

流的根元素可以(MAY)包含一個 <error/> 子元素,由流的名字空間前綴作爲它的前綴。這個"錯誤"子元素必須(MUST)由感知到發生了流級別錯誤的實體發送(通常是一個服務器而不是一個客戶端)。

規則

以下規則適用於流級別的錯誤:
  • 它假定所有流級別的錯誤都是不可恢復的;所以,如果一個錯誤發生在流級別,發現這個錯誤的實體必須(MUST)發送一個流錯誤信息給另一個實體,發送一個關閉標籤 </stream>,並終止這個流所在的TCP連接。
  • 如果這個錯誤發生在流剛開始設置的時候,接收實體必須(MUST)仍然發送一個開放標籤 <stream> ,並在流元素中包含一個<error/>的子元素,然後發送一個關閉標籤 </stream>,最後終止相應的TCP連接。在這種情況下,如果初始化實體在 'to' 屬性中提供了一個未知的主機名,服務器應該(SHOULD)在終止之前,先在流的頭信息的 'from' 屬性中提供一個服務器認證的主機名.

語法

流錯誤的語法如下:
   <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/>元素:
  • 必須(MUST)包含一個子元素以描述一個下文定義的節錯誤條件;這個子元素必須(MUST)符合'urn:ietf:params:xml:ns:xmpp-streams'名字空間.
  • 可以(MAY)包含一個 <text/> 子元素,用XML字符數據描述錯誤的細節;這個元素必須(MUST)符合'urn:ietf:params:xml:ns:xmpp-streams'名 字空間並且應該(SHOULD)擁有一個'xml:lang'屬性表明XML字符數據的自然語言。
  • 可以(MAY)包含一個子元素用於描述一個明確的應用程序錯誤條件;這個元素必須(MUST)符合一個應用程序定義的名字空間,並且它的結構是由那個名字空間定義的。
<text/> 元素是可選的(OPTIONAL)。如果有這個元素,它應該(SHOULD)僅用於提供描述或調試信息以補充一個已定義的條件或應用程序定義的條件。它不 應該(SHOULD NOT)被一個應用程序當成一個可編程的信息。它不應該(SHOULD NOT)被用於向用戶表達錯誤信息,但是可以(MAY)作爲和條件元素相關的錯誤信息之外的附加說明。

已定義的條件

以下流級別的錯誤條件是已定義的:
  • <bad-format/> -- 實體已經發送XML但是不能被處理;這個錯誤可以(可以)被更多特定的XML相關的錯誤替換,比如 <bad-namespace-prefix/>, <invalid-xml/>, <restricted-xml/>, <unsupported-encoding/>, 以及 <xml-not-well-formed/>,儘管更多特定的錯誤是首選的。
  • <bad-namespace-prefix/> -- 實體發送的名字空間前綴不被支持,或者在一個需要某種前綴的元素中沒有發送一個名字空間前綴(參見 XML Namespace Names and Prefixes (第十一章第二節)).
  • <conflict/> -- 服務器正在關閉爲這個實體激活的流,因爲一個和已經存在的流有衝突的新的流已經被初始化。
  • <connection-timeout/> -- 實體已經很長時間沒有通過這個流發生任何通信流量(可由一個本地服務策略來配置).
  • <host-gone/> -- 初始化實體在流的頭信息中提供的'to'屬性的值所指定的主機已經不再由這臺服務器提供
  • <host-unknown/> -- 由初始化實體在流的頭信息中提供的 'to' 屬性的值和由服務器提供的主機名不一致.
  • <improper-addressing/> -- 一個在兩臺服務器之間傳送的節缺少 'to' 或 'from' 屬性(或者這個屬性沒有值).
  • <internal-server-error/> -- 服務器配置錯誤或者其他未定義的內部錯誤,使得服務器無法提供流服務.
  • <invalid-from/> -- 在'from'屬性中提供的 JID 或 主機名地址,和認證的 JID不匹配 或服務器之間無法通過SASL(或回撥)協商出合法的域名,或客戶端和服務器之間無法通過它進行認證和資源綁定。
  • <invalid-id/> -- 流 ID 或回撥 ID 是非法的或和以前提供的 ID 不一致.
  • <invalid-namespace/> -- 流名字空間和 "http://etherx.jabber.org/streams " 不相同或回撥名字空間和 "jabber:server:dialback" 不相同.(參考 XML Namespace Names and Prefixes (第十一章第二節)).
  • <invalid-xml/> -- 實體通過流發送了一個非法的XML給執行驗證的服務器 (參考 Validation (第十一章第三節)).
  • <not-authorized/> -- 實體試圖在流被驗證之前發送數據或不被許可執行一個和流協商有關的動作,接收實體在發送錯誤信息之前不允許(MUST NOT)處理厭惡的節。
  • <policy-violation/> -- 實體違反了某些本地服務策略;服務器可以(MAY)選擇在 <text/> 元素或應用程序定義的錯誤條件(元素)中詳細說明策略。
  • <remote-connection-failed/> -- 服務器無法正確連接到用於驗證或授權的遠程實體。
  • <resource-constraint/> -- 服務器缺乏必要的系統資源爲流服務。
  • <restricted-xml/> -- 實體試圖發送受限的XML特性,比如一個註釋,處理指示,DTD,實體參考,或保留的字符(參考 Restrictions (第十一章第一節)).
  • <see-other-host/> -- 服務器將不提供服務給初始化實體但是把它重定向到另一臺主機;服務器應該(SHOULD)在<see-other-host/>元素的XML 字符數據中指明替代服務器名或IP地址(它必須(必須)是合法的域名標識)。
  • <system-shutdown/> -- 服務器正在關機並且所有激活的流正在被關閉。
  • <undefined-condition/> -- 錯誤條件不在本文已定義的錯誤條件列表之中;這個錯誤條件應該(SHOULD)僅用於"應用程序定義條件"元素.
  • <unsupported-encoding/> -- 初始化實體以一個服務器不不支持的編碼方式編碼了一個流(參照Character Encoding (第十一章第五節)).
  • <unsupported-stanza-type/> -- 初始化實體發送了一個流的一級子元素但是服務器不支持.
  • <unsupported-version/> -- 由初始化實體在流的頭信息中指定的'version'屬性的值所指定的版本不被服務器支持;服務器可以(MAY)在<text/>元素中指定一個它支持的版本號.
  • <xml-not-well-formed/> -- 初始化實體發送了一個不規範的XML(參考[XML]).

應用程序定義條件

大家知道,應用程序可以(MAY)在error元素中包含一個適當名字空間的子元素來提供一個應用程序定義流錯誤信息."應用程序定義"元素應該(SHOULD)補充或甚至限定一個已定義的元素.所以 <error/> 元素將包含兩個或三個子元素:
   <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























='application-ns'























/>
























   </stream:error>
















































   </stream:stream>
















































簡化的流示例

這裏包含兩個簡化的例子,描述了基於流的客戶端在服務器上的“會話”(這裏"C"表示從客戶端發給服務器,"S"表示從服務器發給客戶端);這些例子只是用於舉例說明原理.
一個基本的 "會話":
   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























='[email protected]'























 to























='[email protected]'























 xml:lang























='en'























>
























 
   C:     























<body>















































Art thou not Romeo, and a Montague?























</body>
















































 
   C:   























</message>
















































 
   S:   























<message























 from























='[email protected]'























 to























='[email protected]'























 xml:lang























='en'























>
























 
   S:     























<body>















































Neither, fair saint, if either thee dislike.























</body>
















































 
   S:   























</message>
















































 
   C: 























</stream:stream>
















































 
   S: 























</stream:stream>
















































 

一個不成功的 "會話" :
   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>
















































TLS 的使用

概覽

XMPP包含的一個保證流安全的方法來防止篡改和偷聽.這個傳輸層安全協議[TLS]的頻道加密方法, 模擬了類似的其他"STARTTLS"(見RFC 2595 [USINGTLS])的擴展,如 IMAP [IMAP], POP3 [POP3], and ACAP [ACAP]."STARTTLS"的擴展名字空間是'urn:ietf:params:xml:ns:xmpp-tls'.
一個給定域的管理員可以(MAY)要求客戶端和服務器通信以及服務器之間通信時使用TLS,或者兩者都要求。客戶端應該(SHOULD) 在嘗試完成 SASL (第六章)握手之前使用 TLS,服務器應該(SHOULD)在兩個域之間使用 TLS 以保證服務器間通信的安全。
以下是使用規則:
  1. 一個遵守本協議的初始化實體必須(MUST)在初始化流的頭信息中包含一個'version'屬性並把值設爲“1.0”。
  2. 如果TLS握手發生在兩個服務器之間,除非服務器聲稱的DNS主機名已經被解析(見第十四章第四節 Server-to-Server Communications),通信不能(MUST NOT)繼續進行。
  3. 當一個遵守本協議的接收實體接收了一個初始化流(它的頭信息中包含一個'version'屬性並且值設爲“1.0”),在發送應答流的的頭信息(其中包含 版本標記)之後,它必須發送(MUST)<starttls/>元素(名字空間爲 'urn:ietf:params:xml:ns:xmpp-tls')以及其他它支持的流特性 。
  4. 如果初始化實體選擇使用TLS,TLS握手必須在SASL握手之前完成;這個順序用於幫助保護SASL握手時發送的認證信息的安全,同時可以在必要的時候在TLS握手之前爲SASL外部機制提供證書。
  5. TLS握手期間,一個實體不能(MUST NOT)在流的根元素中發送任何空格符號作爲元素的分隔符(在下面的TLS示例中的任何空格符都僅僅是爲了便於閱讀);這個禁令用來幫助確保安全層字節精度。
  6. 接收實體必須(MUST)在發送<proceed/> 元素的關閉符號">" 之後立刻開始TLS協商。初始化實體必須(MUST)在從接收實體接收到<proceed/> 元素的關閉符號">" 之後立刻開始TLS協商。
  7. 初始化實體必須(MUST)驗證接收實體出示的證書;關於證書驗證流程參見Certificate Validation ( 第十四章第二節)。
  8. 證書必須(MUST)檢查初始化實體(比如一個用戶)提供的主機名;而不是通過DNS系統解析出來的主機名;例如,如果用戶指定一個主機 名"example.com"而一個DNS SRV [SRV]查詢返回"im.example.com",證書必須(MUST)檢查"example.com".如果任何種類的XMPP實體(例如客戶端或 服務器)的JID出現在一個證書裏,它必須(MUST)表現爲一個別名實體裏面的UTF8字符串,存在於subjectAltName之中。如何使用 [ASN.1] 對象標識符 "id-on-xmppAddr" 定義在本文的第五章第一節第一小節。
  9. 如果 TLS 握手成功了,接收實體必須(MUST) 丟棄TLS 生效之前從初始化實體得到的任何不可靠的信息.
  10. 如果 TLS 握手成功了,初始化實體必須(MUST) 丟棄TLS 生效之前從接收實體得到的任何不可靠的信息.
  11. 如果 TLS 握手成功了,接收實體不能(MUST NOT)在流重新開始的時候通過提供其他的流特性來向初始化實體提供 STARTTLS 擴展.
  12. 如果 TLS 握手成功了,初始化實體必須(MUST)繼續進行SASL握手。
  13. 如果 TLS 握手失敗了,接收實體必須(MUST)終止XML流和相應的TCP連接。
  14. 關於必須(MUST)支持的機制,參照 Mandatory-to-Implement Technologies (第十四章第七節) 。

用於 XMPP 地址的 ASN.1 對象標識符

上文提到的[ASN.1] 對象標識符 "id-on-xmppAddr"定義如下:
id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
dod(6) internet(1) security(5) mechanisms(5) pkix(7) }
id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms
id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 }
XmppAddr ::= UTF8String
對象標識符也可以(MAY)使用點分隔的格式,如 "1.3.6.1.5.5.7.8.5".

敘述

當一個初始化實體用TLS保護一個和接收實體之間的流,其步驟如下:
  1. 初始化實體打開一個TCP連接,發送一個打開的XML流頭信息(其'version'屬性設置爲"1.0")給接收實體以初始化一個流。
  2. 接收實體打開一個TCP連接,發送一個XML流頭信息(其'version'屬性設置爲"1.0")給初始化實體作爲應答。
  3. 接收實體向初始化實體提議STARTTLS範圍(包括其他支持的流特性),如果TLS對於和接收實體交互是必需的,它應該(SHOULD)在<starttls/>元素中包含子元素<required/>.
  4. 初始化實體發出STARTTLS命令(例如, 一個符合'urn:ietf:params:xml:ns:xmpp-tls'名字空間的 <starttls/> 元素) 以通知接收實體它希望開始一個TLS握手來保護流。
  5. 接收實體必須(MUST)以'urn:ietf:params:xml:ns:xmpp-tls'名字空間中的<proceed/>元素 或<failure/>元素應答。如果失敗,接收實體必須(MUST)終止XML流和相應的TCP連接。如果繼續進行,接收實體必須 (MUST)嘗試通過TCP連接完成TLS握手並且在TLS握手完成之前不能(MUST NOT)發送任何其他XML數據。
  6. 初始化實體和接收實體嘗試完成TLS握手。(要符合[TLS]規範)
  7. 如果 TLS 握手不成功, 接收實體必須(MUST)終止 TCP 連接. 如果 TLS 握手成功, 初始化實體必須(MUST)發送給接收實體一個打開的XML流頭信息來初始化一個新的流(先發送一個關閉標籤</stream>是不必要的, 因爲接收實體和初始化實體必須(MUST)確保原來的流在TLS握手成功之後被關閉) 。
  8. 在從初始化實體收到新的流頭信息之後,接收實體必須(MUST)發送一個新的XML流頭信息給初始化實體作爲應答,其中應包含可用的特性但不包含STATRTTLS特性。

客戶端-服務器 示例

以下例子展示一個客戶端使用STARTTLS保護數據流 (注意: 以下步驟舉例說明協議中的失敗案例;在這個例子中它們並不詳盡並且也不是必須被數據傳輸觸發的).
步驟 1: 客戶端初始化流給服務器:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 2: 服務器發送一個流標籤給客戶端作爲應答:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 id























='c2s_123'























 from























='example.com'























 version























='1.0'























>























步驟 3: 服務器發送 STARTTLS 範圍給客戶端(包括驗證機制和任何其他流特性):
   <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: 客戶端發送 STARTTLS 命令給服務器:
   <starttls























 xmlns























='urn:ietf:params:xml:ns:xmpp-tls'























/>























步驟 5: 服務器通知客戶端可以繼續進行:
   <proceed























 xmlns























='urn:ietf:params:xml:ns:xmpp-tls'























/>























步驟 5 (或者): 服務器通知客戶端 TLS 握手失敗並關閉流和TCP連接:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-tls'























/>
























   </stream:stream>















































步驟 6: 客戶端和服務器嘗試通過已有的TCP連接完成 TLS 握手.
步驟 7: 如果 TLS 握手成功, 客戶端初始化一個新的流給服務器:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 7 (或者): 如果 TLS 握手不成功, 服務器關閉 TCP 連接.
步驟 8: 服務器發送一個流頭信息應答客戶端,其中包括任何可用的流特性:
   <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: 客戶端繼續 SASL 握手 (第六章).

服務器-服務器示例

以下例子展示兩個服務器之間使用STARTTLS保護數據流 (注意: 以下步驟舉例說明協議中的失敗案例;在這個例子中它們並不詳盡並且也不是必須被數據傳輸觸發的).
步驟 1: Server1 初始化流給 Server2:
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 2: Server2 發送一個流標籤給 Server1 作爲應答:
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 from























='example.com'























 id























='s2s_123'























 version























='1.0'























>























步驟 3: Server2 發送 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 發送 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 通知 Server1 TLS握手失敗並關閉流:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-tls'























/>
























   </stream:stream>















































步驟 6: Server1 和 Server2 嘗試通過 TCP 完成 TLS 握手.
步驟 7: 如果 TLS 握手成功, Server1 初始化一個新的流給 Server2:
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 7 (或者): 如果 TLS 握手不成功, Server2 關閉 TCP 連接.
步驟 8: Server2 發送一個包含任何可用流特性的流頭信息給 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 握手(第六章).

SASL 的使用

概覽

XMPP 有一個驗證流的方法,即XMPP特定的SASL(簡單驗證和安全層)[SASL]。SASL提供了一個通用的方法爲基於連接的協議增加驗證支持,而XMPP使用了一個普通的XML名字空間來滿足SASL的需要。
以下規則應用於:
  1. 如果SASL協商發生在兩臺服務器之間,除非服務器宣稱的DNS主機名得到解析,否則不能(MUST NOT)進行通信。(參見 服務器間的通信(第十四章第四節)).
  2. 如果初始化實體有能力使用 SASL 協商, 它必須(MUST)在初始化流的頭信息中包含一個值爲"1.0"的屬性'version'。
  3. 如果接收實體有能力使用 SASL 協商, 它必須(MUST)在應答從初始化實體收到的打開流標籤時(如果打開的流標籤包含一個值爲"1.0"的'version'屬性),通過 'urn:ietf:params:xml:ns:xmpp-sasl'名字空間中的<mechanisms/>元素聲明一個或多個驗證機 制.
  4. 當 SASL 協商時, 一個實體不能(MUST NOT)在流的根元素中發送任何空格符號(匹配 production [3] content of [XML])作爲元素之間的分隔符(在以下的SASL例子中任何空格符號的出現僅僅是爲了增加可讀性); 這條禁令幫助確保安全層字節的精確度。
  5. 當SASL握手時,在XML元素中使用的任何 XML 字符數據必須被編碼成 base64, 編碼遵循 RFC 3548 第三章的規定。
  6. 如果一個 簡單名字"simple username" 規範被選定的SASL機制所支持,(比如, 這被 DIGEST-MD5 和 CRAM-MD5 機制支持但不被 EXTERNAL 和 GSSAPI 機制支持), 驗證的時候初始化實體應該(SHOULD)在服務器間通信時提供 簡單名字 自身的發送域(IP地址或包含在一個域標識符中的域名全稱),在客戶端與服務器之間通信時提供註冊用戶名(包含在一個XMPP節點標識符中的用戶或節點 名)。
  7. 如果初始化實體希望以另一個實體的身份出現並且SASL機制支持授權ID的傳輸,初始化實體在SASL握手時必須(MUST)提供一個授權ID。如果初始 化實體不希望以另一個實體的身份出現,初始化實體在SASL握手時不能(MUST NOT)提供一個授權ID。在 [SASL] 的定義中,除非授權ID不同於從驗證ID(詳見[SASL])中得到的缺省的授權ID,初始化實體不能(MUST NOT)提供授權ID。如果提供了,這個授權ID的值必須(MUST)是<domain>的格式(對於服務器來說) 或<node@domain>的格式(對於客戶端來說).
  8. 在成功進行包括安全層的SASL握手之後,接收實體必須(MUST)丟棄任何從初始化實體得到的而不是從SASL協商本身獲得的信息。
  9. 在成功進行包括安全層的SASL握手之後,初始化實體必須(MUST)丟棄任何從接收實體得到的而不是從SASL協商本身獲得的信息。
  10. 參看 強制執行的技術 (第十四章第七節) ,瞭解關於必須(MUST)支持的機制.

敘述

一個初始化實體使用SASL和接收實體做驗證的步驟如下:
  1. 初始化實體請求SASL驗證,它發送一個打開的XML流頭信息給接收實體,其'version'屬性的值爲"1.0".
  2. 在發送一個XML流頭回復之後,接收實體聲明一個可用的SASL驗證機制清單;每個機制作爲一個<mechanism/>元素,作爲子元素包 含在<mechanisms/>容器元素(其名字空間爲'urn:ietf:params:xml:ns:xmpp-sasl')中, 而<mechanisms/>則包含在流名字空間中的<features/>元素中。如果在使用任何驗證機制之前需要使用 TLS(見第五章),接收實體不能(MUST NOT)在TLS握手之前提供可用的SASL驗證機制清單。如果初始化實體在優先的TLS協商過程中呈現了一個合法的證書,接收實體應該(SHOULD) 在SASL握手中提出一個SASL外部機制給初始化實體,儘管這個外部機制可以(MAY)在其它環境下提供。
  3. 初始化實體發送一個符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間的<auth/>元素(其中包含了適 當的'mechanism'屬性值)給接收實體,以選擇一個機制。如果這個機制支持或需要,這個元素可以(MAY)包含XML字符數據(在SASL術語 中,即“初始化應答”);如果初始化實體需要發送一個零字節的初始化應答,它必須(MUST)傳輸一個單獨的等號作爲應答,這表示應答有效但不包含數據。
  4. 如果必要,接收實體向初始化實體發送一個符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間 的<challenge/>元素來發出挑戰;這個元素可以(MAY)包含XML字符數據(必須按照初始化實體選擇的SASL機制進行一致性運 算)。
  5. 初始化實體向接收實體發送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間的<response/>元素作爲應答;這個元素可以(MAY)包含XML字符數據(必須按照初始化實體選擇的SASL機制進行一致性運算)。
  6. 如果必要,接收實體發送更多的挑戰給初始化實體,初始化實體發送更多的迴應。
這一系列的 挑戰/應答 組,持續進行直到發生以下三件事中的一件爲止:
  1. 初始化實體向接收實體發送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間的<abort/>元素以中止 握手。在接收到<abort/>元素之後,接收實體應該(SHOULD)允許一個可配置的但是合理的重試次數(至少2次),然後它必須 (MUST)終止TCP連接;這使得初始化實體(如一個最終用戶客戶端)能夠容忍可能不正確的credentials(如密碼輸入錯誤)而不用強制重新連 接。
  2. 接收實體向初始化實體發送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間的<failure/>元素以 報告握手失敗(詳細的失敗原因應該在<failure/>的一個適當的子元素中溝通,在第六章第四節中的SASL Errors中定義)。如果失敗的情況發生了,接收實體應該(SHOULD)允許一個可配置的但是合理的重試次數(至少2次), 然後它必須(MUST)終止TCP連接;這使得初始化實體(如一個最終用戶客戶端)能夠容忍可能不正確的credentials(如密碼輸入錯誤)而不用 強制重新連接。
  3. 接收實體向初始化實體發送符合'urn:ietf:params:xml:ns:xmpp-sasl'名字空間的<success/>元素以 報告握手成功;如果所選擇的SASL機制要求,這個元素可以(MAY)包含XML字符數據(見SASL術語,“成功的額外數據”)。接收 到<success/> 元素之後,初始化實體必須(MUST)發送一個打開的XML流頭信息給接收實體以發起一個新的的流(不需要先發送一個 </stream>標籤,因爲在發送和接收到<success/>元素之後,接收實體和初始化實體必須確認原來的流被關閉了)。 從初始化實體接收到新的流頭信息之後,接收實體必須(MUST)發送一個新的流頭信息給初始化實體作爲迴應,附上任何可用的特性(但不包括 STARTTLS 和 SASL 特性)或一個空的 <features/> 元素(這表示沒有更多的特性可用);任何沒有在本文定義的附加特性必須(MUST)在XMPP的相關擴展中定義。

SASL 定義

[SASL]的必要條件要求通過協議定義來提供以下信息:
service name(服務名): "xmpp"
initiation sequence(開始序列): 當初始化實體提供一個打開的XML流頭信息並且接收實體善意回應之後,接收實體提供一個可接受的驗證方法清單。初始化實體從這個清單中選擇一個方法,把它 作爲 <auth/> 元素的 'mechanism' 屬性的值發送給接收實體,也可以選擇發送一個初始化應答以避免循環。
exchange sequence(交換序列): 挑戰和迴應的交換,從接收實體發送給初始化實體的 <challenge/> 元素和從初始化實體發送給接收實體的 <response/> 元素信息。接收實體通過發送 <failure/>元素報告失敗,發送<success/>元素報告成功;初始化實體通過發送<abort/> 元素中止交換。成功的協商之後,兩邊都認爲原來的XML流已經關閉並且都開始發送新的流頭信息。
security layer negotiation(安全層協商): 安全層在接收實體發送 <success/> 元素的關閉字符">"之後立刻生效,在初始化實體發送 <success/> 元素的關閉字符">"之後也立刻生效。層的順序是 [TCP],[TLS],然後是 [SASL],然後是 [XMPP]。
use of the authorization identity(授權ID的使用): 授權ID可在xmpp中用於表示一個客戶端的非缺省的<node@domain>,或一個服務器的<domain> 。

SASL 錯誤

SASL相關的錯誤條件定義如下:
  • <aborted/> -- 接收實體認可由初始化實體發送的<abort/>元素;在迴應一個<abort/>元素時發送。
  • <incorrect-encoding/> -- 由初始化實體提供的數據無法處理,因爲[BASE64]編碼不正確(例如,因爲編碼不符合[BASE64]的第三章); 在迴應一個包含初始化響應數據的<response/> 元素或<auth/>元素時發送.
  • <invalid-authzid/> -- 由初始化實體提供的授權id是非法的,因爲它的格式不正確或初始化實體無權給那個ID授權;在迴應一個包含初始化響應數據的<response/> 元素或<auth/>元素時發送。
  • <invalid-mechanism/> -- 初始化實體不能提供一個機制活、或請求一個不被接受實體支持的機制;在迴應一個<auth/>元素時發送。
  • <mechanism-too-weak/> -- 初始化實體請求的機制比服務器策略對它的要求弱;在迴應一個包含初始化響應數據的<response/> 元素或<auth/>元素時發送。
  • <not-authorized/> -- 驗證失敗,因爲初始化實體沒有提供合法的credentials(這包括但不限於未知用戶名等情形);在迴應一個包含初始化響應數據 的<response/> 元素或<auth/>元素時發送。
  • <temporary-auth-failure/> -- 驗證失敗,因爲接收實體出現了臨時的錯誤;在迴應一個<response/> 元素或<auth/>元素時發送。

客戶端-服務器 示例

以下例子展示了一個客戶端和一個服務器使用SASL作驗證的數據流,通常是在成功的TLS握手之後(注意:以下顯示的替代步驟僅用於舉例說明協議的失敗情形;它們不夠詳盡也不需要由例子中的數據傳送來觸發)。
步驟 1: 客戶端初始化流給服務器:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 2: 服務器向客戶端發送流標籤作爲應答:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 id























='c2s_234'























 from























='example.com'























 version























='1.0'























>























步驟 3: 服務器通知客戶端可用的驗證機制:
   <stream:features>
















































     <mechanisms























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























       <mechanism>















































DIGEST-MD5























</mechanism>
















































       <mechanism>















































PLAIN























</mechanism>
















































     </mechanisms>
















































   </stream:features>















































步驟 4: 客戶端選擇一個驗證機制:
   <auth























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























 mechanism























='DIGEST-MD5'























/>























步驟 5: 服務器發送一個 [BASE64] 編碼的挑戰給客戶端:
   <challenge























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi
   LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
   























</challenge>















































解碼後的挑戰信息是:
   realm="somerealm",nonce="OA6MG9tEQGm2hh",/
   qop="auth",charset=utf-8,algorithm=md5-sess























步驟 5 (替代): 服務器返回一個錯誤給客戶端:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <incorrect-encoding























/>
























   </failure>
















































   </stream:stream>















































步驟 6: 客戶端發送一個[BASE64]編碼的迴應這個挑戰:
   <response























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i
   T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw
   MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i
   LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
   YXJzZXQ9dXRmLTgK
   























</response>















































解碼後的迴應信息是:
   username="somenode",realm="somerealm",/
   nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",/
   nc=00000001,qop=auth,digest-uri="xmpp/example.com",/
   response=d388dad90d4bbd760a152321f2143af7,charset=utf-8























步驟 7: 服務器發送另一個[BASE64]編碼的挑戰給客戶端:
   <challenge























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
   























</challenge>















































解碼後的挑戰信息是:
   rspauth=ea40f60335c427b5527b84dbabcdfffd























步驟 7 (或者): 服務器返回一個錯誤給客戶端:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <temporary-auth-failure























/>
























   </failure>
















































   </stream:stream>















































步驟 8: 客戶端應答這個挑戰:
   <response























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























/>























步驟 9: 服務器通知客戶端驗證成功:
   <success























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























/>























步驟 9 (或者): 服務器通知客戶端驗證失敗:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <temporary-auth-failure























/>
























   </failure>
















































   </stream:stream>















































步驟 10: 客戶端發起一個新的流給服務器:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 11: 服務器發送一個流頭信息迴應客戶端,並附上任何可用的特性(或空的features元素):
   <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>
















































服務器-服務器 示例

以下例子展示了一個服務器和另一個服務器使用SASL作驗證的數據流,通常是在成功的TLS握手之後(注意:以下顯示的替代步驟僅用於舉例說明協議的失敗情形;它們不夠詳盡也不需要由例子中的數據傳送來觸發)。
步驟 1: 服務器1 發起一個流給 服務器2 :
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 2: 服務器2 迴應一個流標籤給 服務器1:
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 from























='example.com'























 id























='s2s_234'























 version























='1.0'























>























步驟 3: 服務器2 通知 服務器1 可用的驗證機制:
   <stream:features>
















































     <mechanisms























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























       <mechanism>















































DIGEST-MD5























</mechanism>
















































       <mechanism>















































KERBEROS_V4























</mechanism>
















































     </mechanisms>
















































   </stream:features>















































步驟 4: 服務器1 選擇一個驗證機制:
   <auth























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























 mechanism























='DIGEST-MD5'























/>























步驟 5: 服務器2 發送一個[BASE64]編碼的挑戰給 服務器1:
   <challenge























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9
   ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz
   























</challenge>















































解碼後的挑戰信息是:
   realm="somerealm",nonce="OA6MG9tEQGm2hh",/
   qop="auth",charset=utf-8,algorithm=md5-sess























步驟 5 (替代): 服務器2 返回一個錯誤給 服務器1:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <incorrect-encoding























/>
























   </failure>
















































   </stream:stream>















































步驟 6: 服務器1 發送一個[BASE64]編碼的迴應這個挑戰:
   <response























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
   ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
   PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5v
   cmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3
   LGNoYXJzZXQ9dXRmLTgK
   























</response>















































解碼後的應答信息是:
   username="example.org",realm="somerealm",/
   nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",/
   nc=00000001,qop=auth,digest-uri="xmpp/example.org",/
   response=d388dad90d4bbd760a152321f2143af7,charset=utf-8























步驟 7: 服務器2 發送另外一個[BASE64]編碼的挑戰給 服務器1:
   <challenge























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























   cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
   























</challenge>















































解碼後的挑戰信息是:
   rspauth=ea40f60335c427b5527b84dbabcdfffd























步驟 7 (或者): 服務器2 返回一個錯誤給 服務器1:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <invalid-authzid























/>
























   </failure>
















































   </stream:stream>















































步驟 8: 服務器1 迴應挑戰:
   <response























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























/>























步驟 8 (或者): 服務器1 中止協商:
   <abort























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























/>























步驟 9: 服務器2 通知 服務器1 驗證成功:
   <success























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























/>























步驟 9 (或者): 服務器2 通知 服務器1 驗證失敗:
   <failure























 xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'























>
























     <aborted























/>
























   </failure>
















































   </stream:stream>















































步驟 10: 服務器1 重新發起一個新的流給 服務器2:
   <stream:stream























 xmlns























='jabber:server'























 xmlns:stream























='http://etherx.jabber.org/streams'























 to























='example.com'























 version























='1.0'























>























步驟 11: 服務器2 發送一個流頭信息應答 服務器1 ,並附上任何可用的特性(或一個空的features元素).:
   <stream:stream























 xmlns























='jabber:client'























 xmlns:stream























='http://etherx.jabber.org/streams'























 from























='example.com'























 id























='s2s_345'























 version























='1.0'























>
























   <stream:features























/>
























資源綁定

在和接收實體完成 SASL 協商(第六章)之後,初始化實體可能(MAY)想要或者需要綁定一個特定的資源到流上.通常這僅適用於客戶端: 爲了滿足本文定義的尋址格式(第三章)和節傳輸規則(第十章),客戶端<node@domain>必須(MUST)擁有一個相關的資源 ID(由服務器生成或由客戶端程序提供);以確保在流上使用的地址是一個“全JID”(<node@domain/resource>)。
接收到一個成功的SASL握手之後,客戶端必須(MUST)發送一個新的流頭信息給服務器,服務器必須(MUST)返回一個包含可用的流 特性列表的頭信息。特別是,在成功的SASL握手之後如果服務器需要客戶端綁定一個資源,它必須(MUST)在握手成功之後(而不是之前)發送給客戶端的 應答流特性中包含一個空的符合'urn:ietf:params:xml:ns:xmpp-bind'名字空間的<bind/>元素。:
服務器向客戶端聲明資源綁定特性:
   <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'























/>
























   </stream:features>















































收到要求資源綁定的通知後,客戶端必須(MUST)通過發送一個符合'urn:ietf:params:xml:ns:xmpp-bind'名字空間的“set”類型的IQ節(參見 IQ 語義 (第九章第二節第三小節))給服務器來綁定一個資源到流中。
如果客戶端端希望允許服務器給自己生成一個資源ID,它可以發送一個包含空的<bind/>元素的“set”類型的IQ節。:
客戶端請求服務器綁定資源:
   <iq























 type























='set'























 id























='bind_1'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























/>
























   </iq>















































一個支持資源綁定的服務器必須(MUST)自動生成一個資源ID給客戶端。一個由服務器生成的資源ID對於那個<node@domain>必須(MUST)是唯一的。
如果客戶端希望指定資源ID,它發送一個包含期望資源ID的“set”類型的 IQ節,把資源ID作爲<bind/>元素下的<resource/>子元素的XML字符數據:
客戶端綁定一個資源:
   <iq























 type























='set'























 id























='bind_2'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























>
























       <resource>















































someresource























</resource>
















































     </bind>
















































   </iq>















































一旦服務器爲客戶端生成了一個資源ID或接受了客戶端自己提供的資源ID,它必須(MUST)返回一個“result”類型的 IQ 節給客戶端,這個節必須包含一個指明全JID的<jid/>子元素表示服務器決定連接的資源:
服務器通知客戶端資源綁定成功:
   <iq























 type























='result'























 id























='bind_2'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























>
























       <jid>















































[email protected]/someresource























</jid>
















































     </bind>
















































   </iq>















































一個服務器應該(SHOULD)接受客戶端提供的資源ID,但是可以(MAY)用服務器生成的資源ID覆蓋它;在這種情況下,服務器不應 該(SHOULD NOT)返回一個錯誤信息一個(如<forbidden/>)給客戶端,而應該(SHOULD)在上文所述的 IQ result 中返回生成的資源ID。
當一個客戶端自行提供資源ID時,可能發生以下的節錯誤(參見 Stanza Errors (第九章第三節)):
- 提供的資源ID服務器無法處理,因爲不符合資源字符規範Resourceprep(附錄B)。
- 客戶端不被允許綁定一個資源(如節點或用戶已經達到允許連接的資源數限制)。
- 提供的資源ID已經被使用但是服務器不允許以同一個資源ID綁定多個連接。
協議對這些錯誤條件規定如下.
資源ID不能處理:
   <iq























 type























='error'























 id























='bind_2'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























>
























       <resource>















































someresource























</resource>
















































     </bind>
















































     <error























 type























='modify'























>
























       <bad-request























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























/>
























     </error>
















































   </iq>















































客戶端不允許綁定一個資源:
   <iq























 type























='error'























 id























='bind_2'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























>
























       <resource>















































someresource























</resource>
















































     </bind>
















































     <error























 type























='cancel'























>
























       <not-allowed























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























/>
























     </error>
















































   </iq>















































資源ID已經在使用:
   <iq























 type























='error'























 id























='bind_2'























>
























     <bind























 xmlns























='urn:ietf:params:xml:ns:xmpp-bind'























>
























       <resource>















































someresource























</resource>
















































     </bind>
















































     <error























 type























='cancel'























>
























       <conflict























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























/>
























     </error>
















































   </iq>















































如果,在完成資源綁定步驟之前,客戶端試圖以符合'urn:ietf:params:xml:ns:xmpp-bind'名字空間 的<bind/>子元素髮送一個非IQ類型的XML節,服務器不能(MUST NOT)處理這個節,而應該(SHOULD)返回一個<not-authorized/>節錯誤信息給客戶端.

服務器回撥

概覽

Jabber協議接受的來自XMPP的包括“服務器回撥”方法,用於防治域名欺騙,使得欺騙XML節更爲困難。服務器回撥不是一個安全機 制,並且它的服務器身份認證結果很弱(參見服務器之間的通信(第十四章第四節)中關於這個方法的安全特性)。需要健壯的安全性的域名應該(SHOULD) 使用TLS或SASL;細節參見服務器間的通信(第十四章第四節)。如果SASL用於服務器間通信,回撥就不需要用了(SHOULD NOT)。本文描述回撥的好處在於向後兼容現存的實現和部署。
服務器回撥方法由現存的DNS系統的存在而成爲可能,因爲一個服務器(通常)可以查詢給定域的授權服務器。由於服務器回撥依賴於DNS,除非服務器宣稱的DNS主機得到解析,域之間的通信無法進行(參見服務器間的通信(第十四章第四節))。
服務器回撥是單向性的,可在單一方向上對一個流進行(微弱的)身份驗證.因爲服務器回撥不是一個驗證機制,通過回撥獲得相互的認證是不可能的.因此,爲了使得服務器之間的雙向通信,服務器回撥必須(MUST)在每個方向上完成。
在服務器回撥中生成和檢驗密鑰的方法必須(MUST)考慮計算被使用的主機名,由接收服務器生成的流ID,和只有授權服務器網絡才知道的 祕密。在服務器回撥中流ID是安全性的關鍵所以必須(MUST)是不可預知的和不可重複的(見[RANDOM]中關於使用隨機數獲得安全性的建議).
任何回撥協商過程中發生的錯誤必須(MUST)被當成一個流錯誤,並導致流以及相關的TCP連接的終止.可能發生的錯誤情況協議中描述如下.
以下術語適用:
  • 發起服務器 -- 嘗試在兩個域之間建立連接的那個服務器.
  • 接收服務器 -- 嘗試驗證發起服務期聲稱的域名的那臺服務器.
  • 授權(權威?Authoritative) 服務器 -- 回答發起服務器聲稱的DNS主機名的服務器;基本上這應該是那臺發起服務器,但是它也可能是一個在發起服務器網絡中獨立的服務器。

事件順序

以下是回撥中的事件順序的簡介:
  1. 發起服務器和接收服務器建立一個連接。
  2. 發起服務器通過到連接發送一個 'key' 值給接收服務期。
  3. 接收服務器建立一個連接到授權服務器。
  4. 接收服務器發送一個相同的 'key' 值給授權服務器。
  5. 授權服務器回答這個key是否合法。
  6. 接收服務器通知發起服務器是否被驗證通過。
我們用用以下圖形展示這個事件流程(見附件s2s.png):

{image:img=s2s}

   發起服務器               接收服務器
  -----------               ---------
      |                         |
      |   建立連接              |
      | ----------------------> |
      |                         |
      |   發stream頭            |
      | ----------------------> |
      |                         |
      |   發stream頭            |
      | <---------------------- |
      |                         |                   
      |   發回撥key             |                     授權服務器
      | ----------------------> |                   -------------
      |                         |                         |
                                |   建立連接              |
                                | ----------------------> |
                                |                         |
                                |   發stream頭            |
                                | ----------------------> |
                                |                         |
                                |   發stream頭            |
                                | <---------------------- |
                                |                         |
                                |   發驗證請求            |
                                | ----------------------> |
                                |                         |
                                |   發驗證響應            |
                                | <---------------------- |
                                |
      |  報告回撥結果           |
      | <---------------------- |
      |                         |

協議

服務器之間互動的細節協議如下:
1. 發起服務器和接受服務器建立TCP連接.
2. 發起服務器發送流頭信息給接收服務器:
   <stream:stream























 xmlns:stream























='http://etherx.jabber.org/streams'























 xmlns























='jabber:server'























 xmlns:db























='jabber:server:dialback'























>























注意: 'to'和'from'屬性在流的根元素是可選的(OPTIONAL). 其中包含的xmlns:db名字空間向接收服務器聲明瞭發起服務器支持回撥. 如果名字空間不正確,接收實體必須(MUST)生成一個<invalid-namespace/>流錯誤條件並且終止XML流和相應的TCP 連接.
3. 接收服務器應該(SHOULD)回送一個流頭信息給發起服務器,爲這次交互生成一個唯一性的ID :
   <stream:stream























 xmlns:stream























='http://etherx.jabber.org/streams'























 xmlns























='jabber:server'























 xmlns:db























='jabber:server:dialback'























 id























='457F9224A0...'























>























注意: 'to'和'from'屬性在流的根元素是可選的(OPTIONAL). 如果名字空間不正確,發起服務器必須生成一個<invalid-namespace/>流錯誤條件並且終止XML流和相應的TCP連接.也要 注意,在這裏接收服務器應該(SHOULD)應答但是可以(MAY)出於安全策略考慮只是悄悄地終止XML流和TCP連接;無論如何,如果接收服務器希望 繼續,它必須(MUST)回送一個流頭信息給發起服務器.
4. 發起服務器發送一個回撥密鑰給接收服務器:
   <db:result























 to























='Receiving Server'























 from























='Originating Server'























>
























     98AF014EDC0...
   























</db:result>















































注意: 這個密鑰不由接收服務器檢查,因爲接收服務器在會話之間(between sessions)不保存發起服務器的信息. 這個由發起服務器生成的密鑰必須(MUST)是基於接收服務器在上一步驟中提供的ID值,以及發起服務器與授權服務器共享的安全機制生成的。 如果 'to' 地址的值和接收服務器知道的主機名不匹配,接收服務器必須(MUST)生成一個<host-unknown/>流錯誤條件並且終止XML流和 相應的TCP連接. 如果 'from' 地址和接收服務器已經建立的連接的域名相吻合,接收服務器必須(MUST)維護這個已經存在的連接,直到證明這個新的連接是合法的爲止;另外,接收實體可 以(MAY)選擇生成一個<not-authorized/> 流錯誤條件給這個新的連接並且終止和新連接申請相關的XML流及相應的TCP連接.
5. 接收服務器向發起服務器聲明的那個域建立一個 TCP 連接,作爲結果它連接到授權服務器. (注意: 爲了優化性能, 在這裏一個實現可以(MAY)重用現有的連接.)
6. 接收服務器發送一個流頭信息給授權服務器:
   <stream:stream























 xmlns:stream























='http://etherx.jabber.org/streams'























 xmlns























='jabber:server'























 xmlns:db























='jabber:server:dialback'























>























注意: 'to'和'from'屬性在流的根元素是可選的(OPTIONAL). 如果名字空間不正確,授權服務器必須生成一個<invalid-namespace/>流錯誤條件並且終止XML流和相應的TCP連接.
7. 授權服務器發送流頭信息給接收服務器:
   <stream:stream























 xmlns:stream























='http://etherx.jabber.org/streams'























 xmlns























='jabber:server'























 xmlns:db























='jabber:server:dialback'























 id























='1251A342B...'























>























注意: 如果名字空間不正確,接收服務器必須生成一個<invalid-namespace/>流錯誤條件並且終止它和授權服務器之間的XML流和相應的TCP連接. 如果一個流錯誤發生在接收服務器和 授權服務器 之間,接收服務器必須(MUST)生成一個 <remote-connection-failed/> 流錯誤條件並且終止它和 發起服務器 之間的XML流和相應的TCP連接.
8. 接收服務器發送一個密鑰檢查請求給授權服務器:
   <db:verify























 from























='Receiving Server'























 to























='Originating Server'























 id























='457F9224A0...'























>
























     98AF014EDC0...
   























</db:verify>















































注意: 現在這裏已經有了主機名,第三步中接收服務器發送給發起服務器的ID,第四步中發起服務器發送給接收服務器的密鑰. 基於這些信息, 加上授權服務器網絡共享的安全信息, 這個密鑰被證實了.任何可用於驗證的辦法都可以(MAY)用於生成密鑰. 如果 'to' 地址的值和授權服務器知道的主機名不匹配,授權服務器必須(MUST)生成一個<host-unknown/>流錯誤條件並且終止XML流和 相應的TCP連接. 打開這個連接時,如果 'from' 地址和接收服務器聲明的主機名(或任何合法的域,如驗證過的接收服務器的子域名或寄宿在接收服務器上的其他經過驗證的域)不符,授權服務器必須 (MUST)生成一個<invalid-from/>流錯誤條件並且終止XML流和相應的TCP連接.
9. 授權服務器檢查密鑰是否合法:
   <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 和第三步中接收服務器提供的不符,接收服務器必須(MUST)生成一個<invalid-id/>流錯誤條件並且終止XML流和相應的TCP 連接. 如果 'to' 地址的值和接收服務器知道的主機名不匹配,接收服務器必須(MUST)生成一個<host-unknown/>流錯誤條件並且終止XML流和 相應的TCP連接. 打開這個連接時,如果 'from' 地址和發起服務器聲明的主機名(或任何合法的域,如驗證過的發起服務器的子域名或寄宿在發起服務器上的其他經過驗證的域)不符,接收服務器必須 (MUST)生成一個<invalid-from/>流錯誤條件並且終止XML流和相應的TCP連接. 在返回驗證信息給接收服務器之後,授權服務器應該(SHOULD)終止它們之間的流.
10. 接收服務器通知發起服務器結果:
   <db:result























 from























='Receiving Server'























to























='Originating Server'























 type























='valid'























/>























注意: 在這一個點上, 連接已經由 type='valid' 確認驗證是通過了,還是沒通過. 如果連接是非法的,接收服務器必須(MUST)終止XML流和相應的TCP連接. 如果連接是合法的, 數據可以從發起服務器發送由接收服務器讀取;在此之前,所有發送給接收服務器的XML節應該(SHOULD)被丟棄.
進一步的結果是,接收服務器已經驗證了發起服務器的ID,所以通過初始化流("initial stream",例如從發起服務器到接收服務器的流)發起服務器可以發送,接收服務器可以接受XML節. 爲了使用應答流("response stream",例如從接收服務器到發起服務器的流)驗證實體ID,回撥必須(MUST)在相對的兩個方向上都完成.
在成功的回撥協商之後, 接收服務器應該(SHOULD)接受接下來發起服務器通過當前的合法連接發送的 <db:result/> 包 (例如, 發送給子域或其他寄宿在接收服務器上的主機名的驗證請求); 這在單一方向上激活了原始合法連接的 "piggybacking" .
即使回撥協商成功了, 服務器仍然必須(MUST)檢查從其他服務器接收的所有XML節的'from'和'to'屬性; 如果一個節不符合這些限定, 收到這些節的服務器必須(MUST)生成一個<improper-addressing/> 流錯誤條件並終止XML流和相應的TCP連接. 而且, 一個服務器也必須(MUST)檢查從其他的有合法域名的服務器的流中收到的節的'from'屬性; 如果一個節不符合這一限定, 接收節的服務器必須(MUST)生成一個 <invalid-from/> 流錯誤條件並終止XML流和相應的TCP連接. 所有這些檢查都用來幫助防止特定的節僞造行爲.

XML節

在 TLS 協商(第五章) (如果想要), SASL 協商(第六章), 和資源綁定(第七章)(如果需要)之後, XML節就可以通過流發送了. 在'jabber:client'和'jabber:server'名字空間中定義了三種XML節: <message/>, <presence/>, 和 <iq/>. 另外, 這三種節有五種通用的屬性. 這些通用屬性, 加上三種節的術語,在這裏定義; 更多關於和即時消息及出席信息應用相關的XML節語法詳細信息在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準/RFC3921]中提供.

通用屬性

以下五種屬性通用於 message, presence, 和 IQ 節:

to

'to' 屬性表示節的預期接收者的JID.
在'jabber:client'名字空間中, 一個節應該(SHOULD)處理一個'to'屬性, 儘管由服務器處理的從客戶端發給服務器的節(如, 發送給服務器用於廣播給其他實體的出席信息) 應該不(SHOULD NOT)處理'to'屬性.
在'jabber:server'名字空間中, 一個節必須(MUST)處理一個'to'屬性; 如果一個服務器收到一個不符合此限定的節, 它必須(MUST)生成一個<improper-addressing/>流錯誤條件並終止和這個非法服務器的XML流和相應的TCP連接.
如果'to'屬性的值非法或無法聯絡, 發現這個事實的實體(通常是發送者或接收者的服務器)必須(MUST)返回一個適當的錯誤給發送者, 錯誤節的'from'屬性設置成非法節的提供的'to'屬性的值.

from

'from' 屬性表示發送者的 JID .
當一個服務器接收了一個符合'jabber:client'名字空間的合法流的XML節, 它必須(MUST)做以下步驟中的一步:
  1. 驗證客戶端提供的'from'屬性值就是那個相關實體連接的資源
  2. 爲生成這個節的已連接的資源增加一個'from'地址(由服務器決定是純JID或全JID)(參見 地址的決定 Determination of Addresses (第三章第五節))
  3. 如果一個客戶端試圖發送一個XML節,而它的'from'屬性和這個實體已連接的資源不符, 服務器應該(SHOULD)返回一個<invalid-from/>流錯誤條件給客戶端. 如果一個客戶端試圖通過一個尚未驗證的流發送一個XML節, 服務器應該(SHOULD)返回一個<not-authorized/>流錯誤條件給客戶端. 如果生成了, 所有這些條件必須(MUST)導致流的關閉和相應的TCP連接的終止; 這有助於防止不誠實的客戶的拒絕服務攻擊.
當一個服務器從服務器自身生成一個節用於一個已連接的客戶端的信息發佈(例如, 在服務器爲客戶端提供數據存儲服務的情況下), 這個節必須(MUST) (1) 不包含 'from' 屬性 或 (2) 包含一個'from'屬性,它的值是這個賬號的純 JID (<node@domain>) 或 客戶端的全 JID (<node@domain/resource>). 如果節不是由服務器自身生成的,那麼一個服務器不能(MUST NOT)發送不帶'from'屬性的節. 當一個客戶端接收到一個不包含'from'屬性的節, 它必須(MUST)認爲這個節是從客戶端連接的服務器發來的.
在'jabber:server'名字空間, 一個節必須(MUST)處理一個'from'屬性; 如果一個服務器接收到一個不符合此限定的節, 它必須(MUST)生成一個<improper-addressing/>流錯誤條件. 而且, 'from'屬性的 JID值的域名ID部分必須(MUST)和以SASL協商連接或以回撥協商連接的發送服務器的主機名(或任何合法的域,如發送服務器主機名的合法子域,或 其他寄宿在發送服務器上的合法域)吻合; 如果一個服務器接收到的節不符合此限定, 它必須(MUST)生成一個<invalid-from/>流錯誤條件. 所有這些條件都必須(MUST)導致流的關閉和相應的TCP連接的終止; 這有助於防止不誠實的客戶端發起的拒絕服務攻擊.

id

可選的'id' 屬性可以(MAY)用於爲節的內部跟蹤發送實體,從IQ節 語義來講,就是通過發送和接收這些節來跟蹤“請求-應答”型的交互行爲。這個可選的(OPTIONAL)'id'屬性值在一個域或一個流中是全局唯一的。 IQ節語義學中對此有附加限定;見IQ Semantics (第九章第二節第三小節)。

type

'type' 屬性指明消息、出席信息或IQ節的意圖或上下文的詳細信息。'type'屬性所允許的值依據節的類型是消息、出席信息還是IQ而有很大不同; 用於消息和出席信息節的值定義在即時消息和出席信息應用中,所以在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準/RFC3921]中定 義,反之用於IQ節的值定義了在一個 請求-應答 的“會話”中IQ節的角色,所以定義在IQ語義學中(第九章第二節第三小節)。 所有三種節的通用'type'值是"error";見Stanza Errors (第九章第三節)。

xml:lang

如果一個節包含用於顯示給人human user看的XML字符數據(在RFC 2277 中 有所解釋[CHARSET],"internationalization is for humans"),這個節應該(SHOULD)處理一個'xml:lang'屬性(定義在第二章第十二節[XML])。 'xml:lang'屬性的值指明任何一個人類可讀的XML字符數據的缺省語言, 它可以(MAY)被特定的子元素的'xml:lang'值重載。 如果一個節不處理一個'xml:lang'屬性,一個實現必須(MUST)認爲缺省的語言就是流屬性中定義的語言(第四章第四節). 'xml:lang'屬性值必須(MUST)是一個 NMTOKEN 並且必須(MUST)遵守 RFC 3066 [LANGTAGS]中定義的格式.

基本語義學

消息語義學

<message/>節類型可以被看作是一個"push"機制用於一個實體推送信息給另一個實體,類似發生在email系統 中的通信. 所有消息節應該(SHOULD)處理一個表明預定的消息接收者的'to'屬性;接收了這樣一個節之後,一個服務器應該(SHOULD)路由或遞送它給預定 的接收者(見 Server Rules for Handling XML Stanzas (第十章)的XML節相關的通用路由和遞送規則).

出席信息語義學

<presence/> 元素可以被看作一個基本的廣播或“出版-訂閱”機制,用於多個實體接收某個已訂閱的實體的信息(在這裏,是網絡可用性信息). 通常,一個發行實體應該(SHOULD)不帶'to'屬性發送一個出席信息,這時這個實體所連接的服務器應該(SHOULD)廣播或複用 (multiplex)那個節給所有訂閱的實體.無論如何,一個發行實體也可以(MAY)帶'to'屬性發送一個出席信息節,這時服務器應該 (SHOULD)路由或遞送這個節給預定的接收者.見 Server Rules for Handling XML Stanzas (第十章)的XML節相關的通用路由和遞送規則,以及[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準/RFC3921]中即時消息和出席信 息應用中出席信息的特定規則.

IQ語義學

信息/查詢(Info/Query),或曰IQ,是一個 請求-迴應 機制,某些情況下類似[HTTP].IQ語義學使一個實體能夠向另一個實體做出請求並做出應答. 請求和應答所包含的數據定義在IQ元素的一個直接的子元素的名字空間聲明中, 並且由請求實體用'id'屬性來跟蹤這一交互行爲. 因而,IQ交互伴隨着一個結構化的數據交換的通用模式例如 get/result 或 set/result (儘管有時候會以一個錯誤信息應答某個請求):
以下是IQ的流程圖,參見附件iq.png

{image:img=iq}

   請求實體                   響應實體
  ----------                 ----------
      |                           |
      | <iq type='get' id='1'>    |
      | ------------------------> |
      |                           |
      | <iq type='result' id='1'> |
      | <------------------------ |
      |                           |
      | <iq type='set' id='2'>    |
      | ------------------------> |
      |                           |
      | <iq type='error' id='2'>  |
      | <------------------------ |
      |                           |
爲了強制執行這些語義學,要應用以下規則:
1. 對於IQ節來說'id'屬性是必需的(REQUIRED).
2. 對於IQ節來說'type'屬性是必需的(REQUIRED). 它的值必須(MUST)是以下之一:
  • get -- 這個節是一個對信息或需求的請求.
  • set -- 這個節提供需要的數據, 設置新的值, 或取代現有的值.
  • result -- 這個節是一個對一個成功的 get 或 set 請求的應答.
  • error -- 發生了一個錯誤,關於處理或遞送上次發送的 get 或 set的(參見 節錯誤 Stanza Errors(第九章第三節)).
3. 一個接收到"get" 或 "set" 類型的IQ請求的實體必須(MUST)回覆一個"result"或"error"類型的IQ應答(這個應答必須(MUST)保留相關請求的'id'屬性).
4. 一個接收到"result"或"error"類型的IQ節的實體不能(MUST NOT)再發送更多的"result"或"error"類型的IQ應答; 無論如何, 如上所述, 請求實體可以(MAY)發送另一個請求(如, 一個"set"類型的IQ,通過get/result對提供查詢(discovery)所需的信息).
5. 一個"get" 或 "set" 類型的IQ節必須(MUST)包含並只包含一個子元素指明特定請求或應答的語義.
6. 一個"result"類型的IQ節必須(MUST)包含零或一個子元素.
7. 一個"error"類型的IQ節應該(SHOULD)包含和"get"或"set"相關聯的那個子元素並且必須(MUST)包含一個<error/>子元素;詳細信息,見Stanza Errors (第九章第三節).

節錯誤

節相關的錯誤的處理方式類似流錯誤(第四章第七節). 無論如何, 不像流錯誤, 節錯誤是可恢復的;所以錯誤節包含了暗示原來的發送者可以採取什麼行動來補救這個錯誤.

規則

以下規則適用於節相關的錯誤:
  • 接收或處理實體察覺到一個節相關的錯誤條件時應該(MUST)返回給發送實體一個同類型的節(消息,出席信息,或IQ),這個節的'type'屬性值則設置爲"error"(這裏這樣的節稱之爲"error stanza").
  • 生成一個錯誤節的實體應該(SHOULD)包含原來發送的XML,這樣發送者可以檢查它,並且如果必要,在嘗試重新發送之前糾正它.
  • 一個錯誤節必須(MUST)包含一個<error/>子元素.
  • 如果'type'屬性值不是"error"(或沒有"type"屬性),節不能(MUST NOT)包含一個<error/>子元素.
  • 接收到一個錯誤節的實體不能(MUST NOT)應答這個節更多的錯誤節; 這有助於防止死循環.

語法

節相關錯誤的語法如下:
   <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>















































stanza-kind 是 message, presence, 或 iq 中的一個.
<error/> 元素的'type'屬性值必須(MUST)是以下之一:
  • cancel -- 不重試(這個錯誤是不可恢復的)
  • continue -- 繼續進行(這個條件只是一個警告)
  • modify -- 改變數據之後重試
  • auth -- 提供證書之後重試
  • wait -- 等待之後重試(錯誤是暫時的)
<error/>元素:
  • 必須(MUST)包含一個子元素,符合以下定義的節錯誤條件之一;這個元素(MUST)符合'urn:ietf:params:xml:ns:xmpp-stanzas'名字空間.
  • 可以(MAY)包含一個<text/>子元素容納XML字符數據用來描述錯誤的更多細節;這個元素必須(MUST)符合 'urn:ietf:params:xml:ns:xmpp-stanzas'名字空間並且應該(SHOULD)處理'xml:lang'屬性.
  • 可以(MAY)包含一個應用程序定義的錯誤條件子元素;這個元素必須(MUST)符合一個應用程序定義的名字空間,並且它的結構由這個名字空間定義.
<text/>元素是可選的(OPTIONAL).如果包含它,它應該(SHOULD)僅用於提供描述或診斷信息以補充一個 已定義的條件或應用程序定義的條件. 它不應(SHOULD NOT)被應用程序認爲是一個程序性的. 它不應(SHOULD NOT)被用作向一個使用者展示的錯誤信息,但是可以(MAY)展示除條件元素(或元素們)相關的錯誤信息之外的信息.
最後,爲了維護向後兼容性, 這個schema (定義在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準/RFC3921])允許可選的在<error/>元素中包含一個("code")屬性.

已定義的條件

以下條件定義用於節錯誤.
  • <bad-request/> -- 發送者發送的XML是不規範的或不能被處理(例如 一個IQ節包含了一個未被承認的'type'屬性值); 相關的錯誤類型應該(SHOULD)是"modify".
  • <conflict/> -- 不同意訪問,因爲相同的名字或地址已存在一個資源或會話;相關的錯誤類型應該( SHOULD)是"cancel".
  • <feature-not-implemented/> -- 請求的特性未被接收者或服務器實現所以不能處理;相關的錯誤類型應該(SHOULD)是"cancel".
  • <forbidden/> -- 請求實體沒有必需的許可來執行這一動作;相關的錯誤類型應該(SHOULD)是"auth".
  • <gone/> -- 接收者或服務器無法再以這個地址進行聯繫(錯誤節可以(MAY)在<gone/>元素的XML字符數據中包含一個新的地址);相關的錯誤類型應該(SHOULD)是"modify".
  • <internal-server-error/> -- 服務器不能處理節,因爲錯誤的配置或其他未定義的內部服務器錯誤;相關的錯誤類型應該(SHOULD)是"wait".
  • <item-not-found/> -- JID地址或申請的條目無法找到;相關的錯誤類型應該(SHOULD)是"cancel".
  • <jid-malformed/> -- 發送的實體提供的XMPP地址或與之通信的某個XMPP地址(如一個'to'屬性值)或這個XMPP地址中的一部分(如一個資源ID)不符合尋址方案的語 法(第三章);相關的錯誤類型應該(SHOULD)是"modify".
  • <not-acceptable/> -- 接收者或服務器理解這個請求但是拒絕處理,因爲它不符合某些接收者或服務器定義的標準(例如,一個關於消息中可接收的單詞的本地策略);相關錯誤類型應該(SHOULD)是"modify".
  • <not-allowed/> -- 接收者或服務器不允許任何實體執行這個動作;相關錯誤類型應該(SHOULD)是"cancel".
  • <not-authorized/> -- 在被允許執行某個動作之前發送者必須提供適當的證書,或已提供了不正確的證書;相關錯誤類型應該(SHOULD)是"auth".
  • <payment-required/> -- 請求實體未被授權訪問請求的服務,因爲需要付費;相關錯誤類型應該(SHOULD)是"auth".
  • <recipient-unavailable/> -- 預定的接收者暫時不可用;相關錯誤類型應該(SHOULD)是"wait"(注意: 如果這樣做會導致泄露預定接收者的網絡可用性給一個未被授權瞭解此信息的實體,應用程序不應該(MUST NOT)返回這個錯誤).
  • <redirect/> -- 接收者或服務器重定向這個請求信息到另一個實體,通常是暫時的(這個錯誤節應該 (SHOULD)在<redirect/>元素的XML字符數據中包含一個預備的地址,它必須(MUST)是一個合法的JID); 相關的錯誤類型應該(SHOULD)是"modify".
  • <registration-required/> -- 請求實體未被授權訪問請求的服務,因爲需要註冊;相關錯誤類型應該(SHOULD)是"auth".
  • <remote-server-not-found/> -- 在預定的接收者的全部或部分JID中的一個遠程服務器或服務不存在;相關錯誤類型應該(SHOULD)是"cancel".
  • <remote-server-timeout/> -- 在預定的接收者(或需要完成的一個申請)的全部或部分JID中的一個遠程服務器或服務無法在合理的時間內聯繫到;相關錯誤類型應該(SHOULD)是"wait".
  • <resource-constraint/> -- 服務器或接收者缺乏足夠的系統資源來服務請求;相關錯誤類型應該(SHOULD)是"wait".
  • <service-unavailable/> -- 服務器或接收者目前無法提供被請求的服務;相關錯誤類型應該(SHOULD)是"cancel".
  • <subscription-required/> -- 請求實體未被授權訪問能請求的服務,因爲需要訂閱;相關錯誤類型應該(SHOULD)是"auth".
  • <undefined-condition/> -- 錯誤條件不是本列表中定於的其他條件之一;任何錯誤類型可能和這個條件有關,並且它應該(SHOULD)僅用於關聯一個應用程序定義的條件.
  • <unexpected-request/> -- 接收者或服務器理解這個請求但是不希望是在這個時間(比如,請求的順序顛倒);相關錯誤類型應該(SHOULD)是"wait".

應用程序定義條件

大家知道,一個應用程序可以(MAY)通過在錯誤元素裏包含一個適當名字空間的字元素來提供應用程序定義的節錯誤信息. 應用程序定義的元素應該(SHOULD)補充或進一步限定一個已定義的元素. 因而,<error/>元素將包含兩個或三個子元素:
   <iq























 type























='error'























 id























='some-id'























>
























     <error























 type























='modify'























>
























       <bad-request























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























/>
























       <too-many-parameters























 xmlns























='application-ns'























/>
























     </error>
















































   </iq>
















































   <message























 type























='error'























 id























='another-id'























>
























     <error























 type























='modify'























>
























       <undefined-condition























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























/>
























       <text























 xml:lang























='en'























 xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'























>
























         Some special application diagnostic information...
       























</text>
















































       <special-application-condition























 xmlns























='application-ns'























/>
























     </error>
















































   </message>
















































服務器處理XML節的規則

兼容的服務器實現必須(MUST)確保兩個實體之間的XML節按次序處理.
在按次序處理的需求之外, 每個服務器實現將包含它自己的遞送樹"delivery tree"以處理它接收到的節.這個樹決定一個節是否需要路由到其他域, 在內部處理, 還是遞送到和一個已連接的節點相關的資源. 以下規則適用:

沒有'to'地址

如果這個節沒有'to'屬性, 服務器應該(SHOULD)爲發送它的實體處理這個節. 因爲所有從其他服務器收到的節必須(MUST)擁有'to'屬性, 這個規則僅適用於從一個連接到這臺服務器的已註冊實體(如一個客戶端)收到的節.如果這個服務器收到一個沒有'to'屬性的出席信息節, 服務器應該(SHOULD)向那些訂閱了這個發送實體的出席信息的所有實體廣播它, 如果可能的話(即時消息和出席信息應用程序中出席信息廣播的語義定義在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準 /RFC3921]). 如果服務器接收到一個類型爲"get" 或 "set" 的沒有'to'屬性的節並且它理解這個節的名字空間下的內容, 它必須(MUST)爲這個發送實體處理節(在這裏"process"的含義是由相關的名字空間的語義所決定的)或返回一個錯誤給發送實體.

外部域

如果'to'屬性中的JID的域ID部分的主機名和服務器自身或其子域配置的主機名不匹配, 服務器應該(SHOULD)路由這個節到外部域(取決於本地服務規定或安全策略關於域間通信的規定).有兩種可能的情況:
- 一個服務器之間的流已經存在於兩個域之間: 發送者的服務器通過這個已存在的流爲這個外部域路由這個節到授權服務器
- 兩個域之間不存在服務器間的流: 發送者服務器 (1) 解析這個外部域的主機名(定義在服務器間的通信Server-to-Server Communications (第十四章第四節)), (2) 在兩個域之間進行服務器到服務器的流協商(定義在 Use of TLS (第五章) 和 Use of SASL (第六章)), 然後 (3) 通過這個新建的流爲外部域路由這個節到授權服務器
如果路由到接收者的服務器不成功, 發送者的服務器必須(MUST)返回一個錯誤給發送者; 如果接收者的服務器聯繫上了但是從接收者的服務器遞送到接收者不成功, 接收者服務器必須(MUST)通過發送者的服務器返回一個錯誤給發送者.

子域

如果'to'屬性中的JID的域ID部分的主機名和服務器自身配置的主機名的一個子域名匹配,服務器必須(MUST)自己處理這個節或路由這個節到專門負責這個子域的特定服務(如果子域被配置了),或者返回一個錯誤給發送者(如果子域沒有配置).

純粹的域或特定的資源

如果'to'屬性中的JID的域ID部分的主機名和服務器自身配置的主機名本身匹配,並且'to'屬性中的JID類型 是<domain> 或 <domain/resource>, 服務器(或其中定於的資源)必須(MUST)根據節的類型適當的處理這個節或返回一個錯誤節給發送者.

同一域中的節點

如果'to'屬性中的JID的域ID部分的主機名和服務器自身配置的主機名本身匹配,並且'to'屬性中的JID類型 是<node@domain> 或 <node@domain/resource>, 服務器應該(SHOULD)遞送這個節到節的'to'屬性中的JID所指明的預定的接收者. 以下規則適用:
  1. 如果這個JID包含一個資源ID(例如, 格式是<node@domain/resource>)並且存在一個連接的資源符合這個全JID, 接收者服務器應該(SHOULD)遞送這個節給正確符合這個資源ID的流或會話.
  2. 如果這個JID包含一個資源ID(例如, 格式是<node@domain/resource>)並且不存在一個連接的資源符合這個全JID, 接收者服務器應該(SHOULD)返回一個<service-unavailable/> 節錯誤給發送者.
  3. 如果這個JID的格式是<node@domain>並且存在至少一個此節點的連接資源, 接收服務器應該( SHOULD)遞送這個節給至少其中一個已連接的資源, 依據應用程序定義的規則(一系列即時消息和出席信息應用程序的遞送規則定義在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準 /RFC3921]).

XMPP中的XML用法

限制

XMPP是一個簡單的流式XML元素的專用協議用於接近實時地交換結構化信息. 因爲XMPP不需要任意的解析和所有的XML文檔, 所以XMPP不需要支持[XML]的所有功能. 特殊的, 適用以下限制.
關於XML生成, 一個XMPP實現不能(MUST NOT)在XML流中注入以下任何東西:
  • 註釋 (第二章第五節[XML])
  • 處理指示(第二章第六節 同上)
  • 內部或外部的 DTD 子集 (第二章第八節 同上)
  • 內部或外部的實體參考 (第四章第二節 同上) 除了預定實體以外(第四章第六節 同上)
  • 字符數據或屬性值包含和預定實體列表中吻合的未逃逸的unescaped字符(第四章第六節 同上); 這些字符必須(MUST)逃逸
關於XML處理, 如果一個XMPP實現接收到這些受限的XML數據,它必須(MUST)忽略這些數據.

XML 名字空間的名字和前綴

XML名字空間[XML-NAMES]爲所有XMPP兼容的XML建立數據所有權的嚴格界限. 這個名字空間的基本功能是把結構上混合在一起的XML元素區分出不同的詞彙. 確保XMPP兼容的XML有名字空間的感知能力使得任何允許的XML可以被結構化的混合到任何XMPP數據元素中. XML名字空間的名字和前綴的規則在下一小節中.

流名字空間

在所有的XML流頭中必須聲明一個流名字空間. 流名字空間必須(MUST)是 'http://etherx.jabber.org/streams' . 元素名<stream/>和它的<features/>和<error/>子元素必須(MUST)在所有實例中符合 這個流名字空間前綴. 一個實現應該(SHOULD)只爲這些元素生成'stream:'前綴, 並且由於歷史原因可以(MAY)只接受'stream:'前綴.

缺省名字空間

在所有的XML流中必須聲明一個缺省的流名字空間用於定義允許的流根元素的一級子元素. 這個名字空間聲明對於初始化流和應答流必須(MUST)是相同的使得雙方的流都是合格一致的. 缺省的名字空間聲明適用於流和所有在流中發送的節(除非由流名字空間或回撥名字空間的前綴顯式的符合另一個名字空間).
一個服務器實現必須(MUST)支持以下兩個缺省名字空間(由於歷史原因, 一些實現可能(MAY)只支持這兩個缺省名字空間):
  • jabber:client -- 當流用於客戶端和服務器的通信時聲明這個缺省名字空間
  • jabber:server -- 當流用於兩個服務器間的通信時聲明這個缺省名字空間
一個客戶端實現必須(MUST)支持'jabber:client'缺省名字空間,並且由於歷史原因可以(MAY)只支持這個缺省名字空間.
如果缺省名字空間是'jabber:client'或'jabber:server',一個實施不能(MUST NOT)在這個名字空間下爲元素生成名字空間前綴. 一個實現不應該(SHOULD NOT)按照元素的內容(可能和流相反)生成不同於'jabber:client'和'jabber:server'名字空間前綴.
注意: 'jabber:client' 和 'jabber:server' 名字空間接近於相同但是用於不同的上下文(客戶端服務器通信用'jabber:client' 而服務器間通信用'jabber:server'). 這兩者之間僅有的不同在於在'jabber:client'中被髮送的節中'to'和'from'屬性是可選的(OPTIONAL),而在 'jabber:server'中被髮送的節中它們是必需的(REQUIRED). 如果兼容的實施接受一個符合'jabber:client'或'jabber:server'名字空間的流, 它必須(MUST)支持通用屬性(第九章第一節)和三個核心節類型(message, presence, 和IQ)的基本語義(第九章第二節).

回撥名字空間

所有用於服務器回撥的(第八章)元素都必須聲明一個回撥名字空間. 回撥名字空間的名字必須(MUST)是'jabber:server:dialback'. 所有符合此名字空間的元素必須(MUST)有前綴. 一個實現應該(SHOULD)只爲這些元素生成'db:'前綴並且只可以(MAY)接受'db:'前綴.

確認

除了注意'jabber:server'名字空間中關於節中'to'和'from'地址的規定,一個服務器不需要爲轉發到客戶端或其他服 務器負責檢查XML元素;一個實現可以(MAY)選擇僅提供有效數據元素但這是可選的(OPTIONAL)(儘管一個實現不能(MUST NOT)接受不規範的XML). 客戶端不應該(SHOULD NOT)濫用發送不符合schema的數據的能力, 並且應該(SHOULD)忽略接收到的XML流中任何和schema不一致的元素或屬性值. XML流和節的有效性確認是可選的(OPTIONAL),並且在這裏提到的schemas僅用於描述的用途.

文本聲明的包含

實現應該(SHOULD)在發送一個流頭信息之前發送一個文本聲明. 應用程序必須(MUST)遵守[XML]中關於環境(那裏對文本聲明做了規定)的規則.

字符編碼

實現必須(MUST)支持通用字符集Universal Character Set (ISO/IEC 10646-1 [UCS2])字符到UTF-8(RFC 3629 [UTF-8])的轉換, 必須符合 RFC 2277 [CHARSET]. 實現不能(MUST NOT)試圖使用任何其他的編碼.

核心的兼容性要求

本章總結了可擴展的消息和出席信息協議中的某些方面,爲了實施的兼容性,它們必須(MUST)被服務器和客戶端支持,當然協議的其他方面 也應該(SHOULD)被支持. 爲了兼容的目的, 我們在覈心協議(它必須(MUST)被任何服務器或客戶端支持, 無論是什麼特定的應用)和即時消息協議(僅僅是在覈心協議之上的即時消息和出席信息應用必須(MUST)支持它)之間劃了一個級別. 在本章中定義了所有服務器和客戶端的兼容性要求; 即時消息服務器和客戶端的兼容性要求在[XMPP-IM|XMPP文檔列表/XMPP正式RFC標準/RFC3921]的相關章節中定義.

服務器

除了所有已定義的關於安全, XML使用, 和國際化的要求之外, 一個服務器還必須(MUST)支持以下核心協議以保證兼容性:
  • 在地址中應用[STRINGPREP] 的 [NAMEPREP], Nodeprep (附錄 A),和 Resourceprep (附錄 B) profiles (包括確保域ID是[IDNA]中定義的國際化域名)
  • XML流(第四章), 包括Use of TLS(第五章), Use of SASL(第六章), 和Resource Binding (第七章)
  • 三個在stanza semantics(第九章第二節)中已定義的節類型(即,<message/>, <presence/>, 和<iq/>)的基本語義
  • 生成錯誤的語法及相關的流, TLS, SASL, 和 XML節的語義
另外, 一個服務器可以(MAY)支持以下核心協議:
  • 服務器回撥 (第八章)

客戶端

一個客戶端必須(MUST)支持以下核心協議以滿足兼容性:
  • XML流(第四章), 包括Use of TLS(第五章), Use of SASL(第六章), 和Resource Binding (第七章)
  • 三個在stanza semantics(第九章第二節)中已定義的節類型(即,<message/>, <presence/>, 和<iq/>)的基本語義
  • 處理(並且, 如果可能, 生成) 錯誤的語法及相關的流, TLS, SASL, 和 XML節的語義
另外, 一個客戶端應該(SHOULD)支持以下核心協議:
  • 地址的生成應用[STRINGPREP] 的 [NAMEPREP], Nodeprep (附錄 A),和 Resourceprep (附錄 B) profiles

國際化事項

XML流在Character Encoding(第十一章第五節)中定義爲必須(MUST)被編碼成UTF-8. 在Stream Attributes(第四章第四節)中特別定義了, 一個XML流應該(SHOULD)包含一個'xml:lang'屬性,它被認爲是通過這個用於人類用戶解讀的流發送的任何XML字符數據的缺省語言. 在 xml:lang (第九章第一節第五小節)特別定義了, 如果一個XML節是用來給人類用戶解讀,這個節應該(SHOULD)包含一個'xml:lang'屬性. 服務器在爲連接的實體路由或遞送節的時候應該(SHOULD)應用缺省的'xml:lang'屬性, 並且不能(MUST NOT)修改或刪除它從其他實體收到的節的'xml:lang'屬性.

安全性事項

高安全性

爲了XMPP通信的目的(客戶端-服務器 和 服務器-服務器), "高安全性"條款談的是相互驗證和完整性檢查安全性技術的使用; 特別是, 當使用基於證書的驗證來提供高安全性, 應該( SHOULD)建立一個帶外的信任鏈,儘管一個共享簽名證書可能允許以前不知道的證書在帶內建立信任關係. 參見以下第十四章第二節關於證書確認程序.
實施必須(MUST)支持高安全性. 服務提供者應該(SHOULD)基於本地安全策略使用高安全性.

證書確認

當一個XMPP點和另一個XMPP點安全的地通信, 它必須(MUST)確認對方終端的證書.有三種可能的情況:
情形 #1: 點包含一個終端實體證書,以根證書的證書鏈中一環出現(見[X509]中的第六章第一節).
情形 #2: 點的證書由一個對方不知道的證書授權.
情形 #3: 點的證書由自己簽名.
在情形#1, 確認方必須(MUST)做以下兩條之一:
  1. 根據[X509]的規則確認對方證書.然後證書應該(SHOULD)被對方接下來在[HTTP-TLS]中描述的規則反向確認預期的身份。但如 果"xmpp"是subjectAltName擴展類型,則必須(MUST)使用證書中的顯示的身份。如果這兩項檢查之一失敗,用戶導向的客戶端必須 (MUST)通知用戶(客戶端可以(MAY)給用戶機會繼續連接)或以一個壞證書的錯誤終止連接。自動客戶端應該(SHOULD)終止連接(以一個壞證書 錯誤)並在適當的日誌中記錄這個錯誤。自動客戶端可以(MAY)提供一個配置設置成禁止檢查,但同時必須(MUST)提供一個激活檢查的配置。
  2. 點應該(SHOULD)出示證書給一個用戶用於批准,包括完整的證書鏈.點必須(MUST)緩存這個證書(或一些其他不會忘記的表達方式比如一個哈希值).在將來的連接中,點必須(MUST)展示相同的證書並且如果改變了證書必須(MUST)通知用戶.
在情形#2 和情形#3, 實現應該(SHOULD)執行上述第二條.

客戶端-服務器通信

一個兼容的客戶端實現必須(MUST)支持TLS和SASL用於連接到服務器.
用於加密XML流的TLS協議(在 Use of TLS(第五章)定義)提供可信的機制幫助確保機密性和實體之間數據交換的完整性.
用於驗證XML流的SASL協議(在 Use of SASL(第六章)定義)提供可靠的機制用於確認一個連接到服務器的客戶端確實是它自己所聲明的那個客戶端.
服務器宣稱的DNS主機名被解析之前,客戶端-服務器通信不能(MUST NOT)繼續進行。應該首先嚐試解析[SRV]記錄,其服務名爲"xmpp-client",協議名爲"tcp",整個資源記錄類似"_xmpp- client._tcp.example.com."(使用字符"xmpp-client"表示服務ID是經過IANA註冊).如果SRV查找失敗,退而 求其次,將查找一個正規的IPv4/IPv6地址記錄來決定IP地址,使用"xmpp-client"端口5222,這個端口是在IANA註冊了的。
客戶端的IP地址和訪問方法不能(MUST NOT)被服務器公開, 也不能被被任何原始服務器之外的服務器索取。這幫助保護客戶端的服務器避免受到直接攻擊(譯者注:似乎應該是客戶避免受到直接攻擊,但原文如此)或被第三方知道它的身份。

服務器-服務器通信

一個兼容的服務器實現必須(MUST)支持TLS和SASL,用於域間的通信.因爲歷史原因,一個兼容的實施也應該(SHOULD)支持服務器回撥(第八章).
因爲服務提供者是一個策略問題,對於任何給定域和其他域的通信中,它是可選的(OPTIONAL),服務器之間的通信可以(MAY)被任何特定部署的管理員禁止。如果一個特殊的域允許域間的通信,它應該(SHOULD)允許高安全性。
管理員可能想在服務器間使用SASL來通信,以確保雙方的驗證和保密性(比如在機構的私有網絡).兼容實施應該(SHOULD)爲這個目的支持SASL.
服務器宣稱的DNS主機名被解析之前,服務器-服務器通信不能(MUST NOT)繼續進行。應該首先嚐試解析[SRV]記錄,其服務名爲"xmpp-server",協議名爲"tcp",整個資源記錄類似"_xmpp- server._tcp.example.com."(使用字符"xmpp-server"表示服務ID是經過IANA註冊的,注意要用"xmpp- server"取代以前用的"jabber",因爲以前的用法不符合[SRV]標準;希望保持向後兼容的實現可以繼續查找或應答"jabber"服務 ID).如果SRV查找失敗,退而求其次,將查找一個正規的IPv4/IPv6地址記錄來決定IP地址,使用"xmpp-server"端口5269,這 個端口是在IANA註冊了的。
服務器回撥防止域欺騙,從而使得僞造XML節更爲困難.它和SASL和TLS不一樣,它不是一個用於驗證、安全或加密服務器之間的流的機 制, 所以只是服務器身份的微弱確認而已。而且除非它使用了DNSSec [DNSSEC]否則它 容易受到DNS中毒攻擊,即使DNS信息是正確的,如果攻擊者劫持了遠程域,回撥也不能防止它的攻擊.需要健壯的安全性的域應該(SHOULD)使用 TLS和SASL.如果服務器間的驗證使用了SASL,回撥就不應該(SHOULD NOT)使用了,因爲它是多餘的.

層的次序

協議中的層的次序必須(MUST)如下堆積:
  1. TCP
  2. TLS
  3. SASL
  4. XMPP
這個次序的原理是,[TCP]是基於連接的層,被所有使用,所以處於最上層, [TLS]經常是由操作系統層提供,[SASL]經常由應用程序層提供, XMPP則是應用程序本身.

缺乏綁定到TLS的SASL通道

SASL構架不提供一個機制來綁定SASL驗證到一個提供機密性和完整性保護的安全層。這一通道綁定"channel binding"的缺乏阻礙了SASL確認低層安全性所綁定的源和目標終端和SASL所驗證的結果是否一致。如果終端不一致, 低層安全性不能被信任用來保護SASL驗證的實體之間的數據傳輸。在這種情況下,一個SASL安全層進行握手的時候應該有效的忽略低層安全性的存在。

強制實現的技術

最低要求, 所有實現必須(MUST)支持以下機制:
對於驗證: SASL [DIGEST-MD5] 機制
對於機密性: TLS (使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 密碼)
對於兩者: TLS 加 SASL EXTERNAL(使用 TLS_RSA_WITH_3DES_EDE_CBC_SHA 密碼支持客戶端證書)

防火牆

使用XMPP通信通常是通過[TCP]連接到5222端口(客戶端-服務器)或5269端口(服務器-服務器), 正如在IANA註冊的那樣(見 IANA Considerations (第十五章)). 使用這些廣爲人知的端口允許管理員很容易的通過一般的防火牆來激活或禁止XMPP活動.

在SASL中使用base64

客戶端和服務器都必須(MUST)確認在SASL協商中收到的任何[BASE64]數據. 一個實現必須(MUST)拒絕(不是忽略)任何非顯式允許base64字母的字符串; 這有助於預防建立隱蔽通道泄漏信息的行爲。一個實現不能(MUST NOT)在非法輸入處中斷,如果那個('=')被包含在一些和最後的數據字符(如, "=AAA" or "BBBB=CCC")不同的東西里面,必須(MUST)拒絕接下來的任何包含('=')的base64字符;這有助於防止對這個實現的緩存溢出攻擊和其 他攻擊。Base 64編碼從外表看隱藏了容易辨認的信息,例如密碼,但是不提供任何算法機密性。Base 64編碼必須(MUST)按照RFC 3548 [BASE64]第三章的定義執行。

Stringprep Profiles

爲了處理域ID,XMPP使用了[STRINGPREP]中的[NAMEPREP] profile; 和Nameprep有關的安全性考慮, 參考[NAMEPREP]中的相關章節.
另外, XMPP 定義了兩個[STRINGPREP]的 profiles: 用於node identifiers的Nodeprep(附錄 A)和用於resource identifiers的Resourceprep(附錄 B).
Unicode 和 ISO/IEC 10646 集有許多字符看起來相似. 在許多時候, 安全協議的使用者可能看起來吻合,比如當比較信任的第三方的名字的時候. 因爲沒有很多上下文的時候不可能映射看起來相似的字符,比如知道所用的字符集, stringprep不匹配相似字符串,也不因爲一些字符串象看起來象別的字符串而禁止它們.
一個節點ID可能被作爲一個實體的XMPP地址的一部分. 一個通常的用途是作爲一個即時消息用戶的用戶名;另一個用途是作爲一個多用途聊天室的名字; 很多其他種類的實體可能使用節點ID作爲他們的地址的一部分。 這些服務的安全性可能會受到國際化節點ID的不同表達的威脅;例如, 一個用戶鍵入一個單獨的國際化的節點ID可能訪問了另一個用戶的帳號信息, 或一個用戶可能獲得訪問一個受限的聊天室或服務的訪問權限.
一個資源ID可能被作爲一個實體的XMPP地址的一部分。一個通常的用戶是即時消息用戶所連接的資源(激活的會話)的名字; 另一個是作爲多用戶聊天室的某用戶的暱稱; 許多其他種類的實體可能使用資源ID作爲他們地址的一部分.這些服務的安全性可能會受到國際化資源ID的不同表達的威脅;例如, 一個用戶可能嘗試以同一個名字初始化多個會話,或一個用戶可能發送一個消息給多用戶聊天室的一個人但實際上發給了另外一個人.

IANA 事項

用於TLS數據的XML名字空間名

XMPP中用於TLS相關數據的 URN 子名字空間定義如下. (這個名字空間的名字遵守The IETF XML Registry [XML-REG]定義的格式.)
URI: urn:ietf:params:xml:ns:xmpp-tls
Specification: RFC 3920
Description: This is the XML namespace name for TLS-related data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920 .
Registrant Contact: IETF, XMPP Working Group, <[email protected]>

用於SASL數據的XML名字空間名

XMPP中用於SASL相關數據的 URN 子名字空間定義如下. (這個名字空間的名字遵守The IETF XML Registry [XML-REG]定義的格式.)
URI: urn:ietf:params:xml:ns:xmpp-sasl
Specification: RFC 3920
Description: This is the XML namespace name for SASL-related data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920 .
Registrant Contact: IETF, XMPP Working Group, <[email protected]>

用於流錯誤的XML名字空間名

XMPP中用於流相關錯誤的 URN 子名字空間定義如下. (這個名字空間的名字遵守The IETF XML Registry [XML-REG]定義的格式.)
URI: urn:ietf:params:xml:ns:xmpp-streams
Specification: RFC 3920
Description: This is the XML namespace name for stream-related error data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920 .
Registrant Contact: IETF, XMPP Working Group, <[email protected]>

用於資源綁定的XML名字空間名

XMPP中用於資源綁定的 URN 子名字空間定義如下. (這個名字空間的名字遵守The IETF XML Registry [XML-REG]定義的格式.)
URI: urn:ietf:params:xml:ns:xmpp-bind
Specification: RFC 3920
Description: This is the XML namespace name for resource binding in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920 .
Registrant Contact: IETF, XMPP Working Group, <[email protected]>

用於節錯誤的XML名字空間名

XMPP中用於節相關錯誤數據的 URN 子名字空間定義如下. (這個名字空間的名字遵守The IETF XML Registry [XML-REG]定義的格式.)
URI: urn:ietf:params:xml:ns:xmpp-stanzas
Specification: RFC 3920
Description: This is the XML namespace name for stanza-related error data in the Extensible Messaging and Presence Protocol (XMPP) as defined by RFC 3920 .
Registrant Contact: IETF, XMPP Working Group, <[email protected]>

Nodeprep Profile of Stringprep

The Nodeprep profile of stringprep是在Nodeprep(附錄 A)定義的. IANA已經在stringprep profile registry中註冊了 Nodeprep.
Name of this profile:
Nodeprep
RFC in which the profile is defined:
RFC 3920
Indicator whether or not this is the newest version of the profile:
This is the first version of Nodeprep

Resourceprep Profile of Stringprep

The Resourceprep profile of stringprep是在Resourceprep(附錄 B)定義的. IANA已經在stringprep profile registry中註冊了Resourceprep.
Name of this profile:
Resourceprep
RFC in which the profile is defined:
RFC 3920
Indicator whether or not this is the newest version of the profile:
This is the first version of Resourceprep

GSSAPI 服務名

IANA已經註冊了 "xmpp" 作爲一個 GSSAPI [GSS-API] 服務名, 在SASL Definition (第六章第三節)定義了.

端口號

IANA已經註冊了"xmpp-client" 和 "xmpp-server" 作爲[TCP]端口號5222和5269的關鍵字.
這些端口應該(SHOULD)用於客戶端-服務器 和 服務器-服務器通信,但它們的使用是可選的(OPTIONAL).

參考

標準化參考

[ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234 , November 1997.
[BASE64] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 3548 , July 2003.
[CHARSET] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277 , January 1998.
[DIGEST-MD5] Leach, P. and C. Newman, "Using Digest Authentication as a SASL Mechanism", RFC 2831 , May 2000.
[DNS] Mockapetris, P., "Domain names - implementation and specification", STD 13, RFC 1035 , November 1987.
[GSS-API] Linn, J., "Generic Security Service Application Program Interface Version 2, Update 1", RFC 2743 , January 2000.
[HTTP-TLS] Rescorla, E., "HTTP Over TLS", RFC 2818 , May 2000.
[IDNA] Faltstrom, P., Hoffman, P., and A. Costello, "Internationalizing Domain Names in Applications (IDNA)", RFC 3490 , March 2003.
[IPv6] Hinden, R. and S. Deering, "Internet Protocol Version 6 (IPv6) Addressing Architecture", RFC 3513 , April 2003.
[LANGTAGS] Alvestrand, H., "Tags for the Identification of Languages", BCP 47, RFC 3066 , January 2001.
[NAMEPREP] Hoffman, P. and M. Blanchet, "Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)", RFC 3491 , March 2003.
[RANDOM] Eastlake 3rd, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750 , December 1994.
[SASL] Myers, J., "Simple Authentication and Security Layer (SASL)", RFC 2222 , October 1997.
[SRV] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR for specifying the location of services (DNS SRV)", RFC 2782 , February 2000.
[STRINGPREP] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454 , December 2002.
[TCP] Postel, J., "Transmission Control Protocol", STD 7, RFC 793 , September 1981.
[TERMS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119 , March 1997.
[TLS] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", RFC 2246 , January 1999.
[UCS2] International Organization for Standardization, "Information Technology - Universal Multiple-octet coded Character Set (UCS) - Amendment 2: UCS Transformation Format 8 (UTF-8)", ISO Standard 10646-1 Addendum 2, October 1996.
[UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629 , November 2003.
[X509] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3280 , April 2002.
[XML] Bray, T., Paoli, J., Sperberg-McQueen, C., and E. Maler, "Extensible Markup Language (XML) 1.0 (2nd ed)", W3C REC-xml, October 2000, <http://www.w3.org/TR/REC-xml >.
[XML-NAMES] Bray, T., Hollander, D., and A. Layman, "Namespaces in XML", W3C REC-xml-names, January 1999, <http://www.w3.org/TR/REC-xml-names >.

信息參考

[ACAP] Newman, C. and J. Myers, "ACAP -- Application Configuration Access Protocol", RFC 2244 , November 1997.
[ASN.1] CCITT, "Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1)", 1988.

 

[DNSSEC] Eastlake 3rd, D., "Domain Name System Security Extensions", RFC 2535 , March 1999.
[HTTP] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616 , June 1999.
[IMAP] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501 , March 2003.
[IMP-REQS] Day, M., Aggarwal, S., Mohr, G., and J. Vincent, "Instant Messaging // Presence Protocol Requirements", RFC 2779 , February 2000.
[IRC] Oikarinen, J. and D. Reed, "Internet Relay Chat Protocol", RFC 1459 , May 1993.
[JEP-0029] Kaes, C., "Definition of Jabber Identifiers (JIDs)", JSF JEP 0029, October 2003.
[JEP-0078] Saint-Andre, P., "Non-SASL Authentication", JSF JEP 0078, July 2004.

[JEP-0086] Norris, R. and P. Saint-Andre, "Error Condition Mappings", JSF JEP 0086, February 2004.

[JSF] Jabber Software Foundation, "Jabber Software Foundation", <http://www.jabber.org/ >.
[POP3] Myers, J. and M. Rose, "Post Office Protocol - Version 3", STD 53, RFC 1939 , May 1996.
[SIMPLE] SIMPLE Working Group, "SIMPLE WG", <http://www.ietf.org/html.charters/simple-charter.html >.
[SMTP] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821 , April 2001.
[URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396 , August 1998.
[USINGTLS] Newman, C., "Using TLS with IMAP, POP3 and ACAP", RFC 2595 , June 1999.
[XML-REG] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688 , January 2004.
RFC3921 Saint-Andre, P., Ed., "Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence", RFC 3921 , October 2004.

 

附錄 A. Nodeprep

A.1. 介紹

這個附錄定義了 "Nodeprep" profile of [STRINGPREP]. 它定義了處理規則讓用戶能夠在XMPP中輸入國際化節點標識符並儘可能正確的獲取正確的字符內容. (一個XMPP節點標識符是XMPP地址的可選部分,它在域名標識符和那個'@'分隔符之前;它經常但不是專門用來關聯一個即時消息用戶名)這些處理規則 僅僅適用於XMPP節點標識符但不適用於任意文本或任何XMPP的其他方面.
這個腳本定義了以下這些, 正如 [STRINGPREP]要求的:
  • 腳本預期的適用性: XMPP的國際化節點標識符
  • 用於stringprep的輸入輸出字符集: Unicode 3.2, 定義在本附錄的第二章
  • 使用的映射: 定義在第三章
  • Unicode正規化使用: 定義在第四章
  • 禁止輸出的字符串: 定義在第五章
  • 雙字節字符處理: 定義在第六章

A.2. 字符集

本腳本使用Unicode 3.2的未分配編碼列表,指向 Table A.1, 也定義在 [STRINGPREP]的附錄 A 中.

A.3. 映射

本腳本指定使用[STRINGPREP]的以下表:
Table B.1
Table B.2

A.4. 正規化

本腳本指定 Unicode正規化使用 form KC, 定義在 [STRINGPREP]中.

A.5. 禁止輸出

本腳本指定使用以下的[STRINGPREP]表禁止輸出.
Table C.1.1
Table C.1.2
Table C.2.1
Table C.2.2
Table C.3
Table C.4
Table C.5
Table C.6
Table C.7
Table C.8
Table C.9
另外, 以下Unicode字符也被禁止:
#x22 (")
#x26 (&)
#x27 (')
#x2F (/)
#x3A (:)
#x3C (<)
#x3E (>)
#x40 (@)

A.6. 雙字節

本腳本指定按照[STRINGPREP]第六章檢查雙字節.

附錄 B. Resourceprep

B.1. 介紹

這個附錄定義了 "Resourceprep" profile of [STRINGPREP]. 它定義了處理規則讓用戶能夠在XMPP中輸入國際化資源標識符並儘可能正確的獲取正確的字符內容. (一個XMPP資源標識符是XMPP地址的可選部分,它在域名標識符和'/'分隔符之後;它經常但不是專門用來關聯一個即時消息會話名)這些處理規則僅僅 適用於XMPP資源標識符但不適用於任意文本或任何XMPP的其他方面.
這個腳本定義了以下這些, 正如 [STRINGPREP]要求的:
  • 腳本預期的適用性: XMPP的國際化節點標識符
  • 用於stringprep的輸入輸出字符集: Unicode 3.2, 定義在本附錄的第二章
  • 使用的映射: 定義在第三章
  • Unicode正規化使用: 定義在第四章
  • 禁止輸出的字符串: 定義在第五章
  • 雙字節字符處理: 定義在第六章

B.2. 字符集

本腳本使用Unicode 3.2的未分配編碼列表,指向 Table A.1, 也定義在 [STRINGPREP]的附錄

B.3. 映射

本腳本指定使用[STRINGPREP]的以下表:
Table B.1

B.4. 正規化

本腳本指定使用 Unicode normalization form KC, 定義在 [STRINGPREP]中.

B.5. 禁止輸出

本腳本指定使用以下的[STRINGPREP]表禁止輸出.
Table C.1.2
Table C.2.1
Table C.2.2
Table C.3
Table C.4
Table C.5
Table C.6
Table C.7
Table C.8
Table C.9

B.6. 雙字節

本腳本指定按照[STRINGPREP]第六章檢查雙字節.

附錄 C. XML 規劃

以下 XML schemas 是描述性的, 不是標準的. 'jabber:client' 和 'jabber:server' 名字空間的標準定義, 參照 RFC3921 .

C.1. Streams namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='http://etherx.jabber.org/streams'
























       xmlns























='http://etherx.jabber.org/streams'
























       elementFormDefault























='unqualified'























>
























 
     <xs:element























 name























='stream'























>
























       <xs:complexType>
















































         <xs:sequence























 xmlns:client























='jabber:client'
























                      xmlns:server























='jabber:server'
























                      xmlns:db























='jabber:server:dialback'























>
























           <xs:element























 ref























='features'























 minOccurs























='0'























 maxOccurs























='1'























/>
























           <xs:any























 namespace























='urn:ietf:params:xml:ns:xmpp-tls'
























                   minOccurs























='0'
























                   maxOccurs























='unbounded'























/>
























           <xs:any























 namespace























='urn:ietf:params:xml:ns:xmpp-sasl'
























                   minOccurs























='0'
























                   maxOccurs























='unbounded'























/>
























           <xs:choice























 minOccurs























='0'























 maxOccurs























='1'























>
























             <xs:choice























 minOccurs























='0'























 maxOccurs























='unbounded'























>
























               <xs:element























 ref























='client:message'























/>
























               <xs:element























 ref























='client:presence'























/>
























               <xs:element























 ref























='client:iq'























/>
























             </xs:choice>
















































             <xs:choice























 minOccurs























='0'























 maxOccurs























='unbounded'























>
























               <xs:element























 ref























='server:message'























/>
























               <xs:element























 ref























='server:presence'























/>
























               <xs:element























 ref























='server:iq'























/>
























               <xs:element























 ref























='db:result'























/>
























               <xs:element























 ref























='db:verify'























/>
























             </xs:choice>
















































           </xs:choice>
















































           <xs:element























 ref























='error'























 minOccurs























='0'























 maxOccurs























='1'























/>
























         </xs:sequence>
















































         <xs:attribute























 name























='from'























 type























='xs:string'























 use























='optional'























/>
























         <xs:attribute























 name























='id'























 type























='xs:NMTOKEN'























 use























='optional'























/>
























         <xs:attribute























 name























='to'























 type























='xs:string'























 use























='optional'























/>
























         <xs:attribute























 name























='version'























 type























='xs:decimal'























 use























='optional'























/>
























         <xs:attribute























 ref























='xml:lang'























 use























='optional'























/>
























       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='features'























>
























       <xs:complexType>
















































         <xs:all























 xmlns:tls























='urn:ietf:params:xml:ns:xmpp-tls'
























                 xmlns:sasl























='urn:ietf:params:xml:ns:xmpp-sasl'
























                 xmlns:bind























='urn:ietf:params:xml:ns:xmpp-bind'
























                 xmlns:sess























='urn:ietf:params:xml:ns:xmpp-session'























>
























           <xs:element























 ref























='tls:starttls'























 minOccurs























='0'























/>
























           <xs:element























 ref























='sasl:mechanisms'























 minOccurs























='0'























/>
























           <xs:element























 ref























='bind:bind'























 minOccurs























='0'























/>
























           <xs:elemnt























 ref























='sess:session'























 minOccurs























='0'























/>
























         </xs:all>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='error'























>
























       <xs:complexType>
















































         <xs:sequence























  xmlns:err























='urn:ietf:params:xml:ns:xmpp-streams'























>
























           <xs:group























   ref























='err:streamErrorGroup'























/>
























           <xs:element























 ref























='err:text'
























                       minOccurs























='0'
























                       maxOccurs























='1'























/>
























         </xs:sequence>
















































       </xs:complexType>
















































     </xs:element>
















































 
   </xs:schema>
















































C.2. Stream error namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='urn:ietf:params:xml:ns:xmpp-streams'
























       xmlns























='urn:ietf:params:xml:ns:xmpp-streams'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='bad-format'























 type























='empty'























/>
























     <xs:element























 name























='bad-namespace-prefix'























 type























='empty'























/>
























     <xs:element























 name























='conflict'























 type























='empty'























/>
























     <xs:element























 name























='connection-timeout'























 type























='empty'























/>
























     <xs:element























 name























='host-gone'























 type























='empty'























/>
























     <xs:element























 name























='host-unknown'























 type























='empty'























/>
























     <xs:element























 name























='improper-addressing'























 type























='empty'























/>
























     <xs:element























 name























='internal-server-error'























 type























='empty'























/>
























     <xs:element























 name























='invalid-from'























 type























='empty'























/>
























     <xs:element























 name























='invalid-id'























 type























='empty'























/>
























     <xs:element























 name























='invalid-namespace'























 type























='empty'























/>
























     <xs:element























 name























='invalid-xml'























 type























='empty'























/>
























     <xs:element























 name























='not-authorized'























 type























='empty'























/>
























     <xs:element























 name























='policy-violation'























 type























='empty'























/>
























     <xs:element























 name























='remote-connection-failed'























 type























='empty'























/>
























     <xs:element























 name























='resource-constraint'























 type























='empty'























/>
























     <xs:element























 name























='restricted-xml'























 type























='empty'























/>
























     <xs:element























 name























='see-other-host'























 type























='xs:string'























/>
























     <xs:element























 name























='system-shutdown'























 type























='empty'























/>
























     <xs:element























 name























='undefined-condition'























 type























='empty'























/>
























     <xs:element























 name























='unsupported-encoding'























 type























='empty'























/>
























     <xs:element























 name























='unsupported-stanza-type'























 type























='empty'























/>
























     <xs:element























 name























='unsupported-version'























 type























='empty'























/>
























     <xs:element























 name























='xml-not-well-formed'























 type























='empty'























/>
























 
     <xs:group























 name























='streamErrorGroup'























>
























       <xs:choice>
















































         <xs:element























 ref























='bad-format'























/>
























         <xs:element























 ref























='bad-namespace-prefix'























/>
























         <xs:element























 ref























='conflict'























/>
























         <xs:element























 ref























='connection-timeout'























/>
























         <xs:element























 ref























='host-gone'























/>
























         <xs:element























 ref























='host-unknown'























/>
























         <xs:element























 ref























='improper-addressing'























/>
























         <xs:element























 ref























='internal-server-error'























/>
























         <xs:element























 ref























='invalid-from'























/>
























         <xs:element























 ref























='invalid-id'























/>
























         <xs:element























 ref























='invalid-namespace'























/>
























         <xs:element























 ref























='invalid-xml'























/>
























         <xs:element























 ref























='not-authorized'























/>
























         <xs:element























 ref























='policy-violation'























/>
























         <xs:element























 ref























='remote-connection-failed'























/>
























         <xs:element























 ref























='resource-constraint'























/>
























         <xs:element























 ref























='restricted-xml'























/>
























         <xs:element























 ref























='see-other-host'























/>
























         <xs:element























 ref























='system-shutdown'























/>
























         <xs:element























 ref























='undefined-condition'























/>
























         <xs:element























 ref























='unsupported-encoding'























/>
























         <xs:element























 ref























='unsupported-stanza-type'























/>
























         <xs:element























 ref























='unsupported-version'























/>
























         <xs:element























 ref























='xml-not-well-formed'























/>
























       </xs:choice>
















































     </xs:group>
















































 
     <xs:element























 name























='text'























>
























       <xs:complexType>
















































         <xs:simpleContent>
















































           <xs:extension























 base























='xs:string'























>
























             <xs:attribute























 ref























='xml:lang'























 use























='optional'























/>
























           </xs:extension>
















































         </xs:simpleContent>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:simpleType























 name























='empty'























>
























       <xs:restriction























 base























='xs:string'























>
























         <xs:enumeration























 value























=''























/>
























       </xs:restriction>
















































     </xs:simpleType>
















































 
   </xs:schema>
















































C.3. TLS namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='urn:ietf:params:xml:ns:xmpp-tls'
























       xmlns























='urn:ietf:params:xml:ns:xmpp-tls'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='starttls'























>
























       <xs:complexType>
















































         <xs:sequence>
















































           <xs:element
























               name























='required'
























               minOccurs























='0'
























               maxOccurs























='1'
























               type























='empty'























/>
























         </xs:sequence>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='proceed'























 type























='empty'























/>
























     <xs:element























 name























='failure'























 type























='empty'























/>
























 
     <xs:simpleType























 name























='empty'























>
























       <xs:restriction























 base























='xs:string'























>
























         <xs:enumeration























 value























=''























/>
























       </xs:restriction>
















































     </xs:simpleType>
















































 
   </xs:schema>
















































C.4. SASL namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='urn:ietf:params:xml:ns:xmpp-sasl'
























       xmlns























='urn:ietf:params:xml:ns:xmpp-sasl'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='mechanisms'























>
























       <xs:complexType>
















































         <xs:sequence>
















































           <xs:element























 name























='mechanism'
























                       maxOccurs























='unbounded'
























                       type























='xs:string'























/>
























         </xs:sequence>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='auth'























>
























       <xs:complexType>
















































         <xs:simpleContent>
















































           <xs:extension























 base























='empty'























>
























             <xs:attribute























 name























='mechanism'
























                           type























='xs:string'
























                           use























='optional'























/>
























           </xs:extension>
















































         </xs:simpleContent>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='challenge'























 type























='xs:string'























/>
























     <xs:element























 name























='response'























 type























='xs:string'























/>
























     <xs:element























 name























='abort'























 type























='empty'























/>
























     <xs:element























 name























='success'























 type























='empty'























/>
























 
     <xs:element























 name























='failure'























>
























       <xs:complexType>
















































         <xs:choice























 minOccurs























='0'























>
























           <xs:element























 name























='aborted'























 type























='empty'























/>
























           <xs:element























 name























='incorrect-encoding'























 type























='empty'























/>
























           <xs:element























 name























='invalid-authzid'























 type























='empty'























/>
























           <xs:element























 name























='invalid-mechanism'























 type























='empty'























/>
























           <xs:element























 name























='mechanism-too-weak'























 type























='empty'























/>
























           <xs:element























 name























='not-authorized'























 type























='empty'























/>
























           <xs:element























 name























='temporary-auth-failure'























 type























='empty'























/>
























         </xs:choice>
















































       </xs:complexType>
















































     </xs:element>
















































     <xs:simpleType























 name























='empty'























>
























       <xs:restriction























 base























='xs:string'























>
























         <xs:enumeration























 value























=''























/>
























       </xs:restriction>
















































     </xs:simpleType>
















































 
   </xs:schema>
















































C.5. Resource binding namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='urn:ietf:params:xml:ns:xmpp-bind'
























       xmlns























='urn:ietf:params:xml:ns:xmpp-bind'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='bind'























>
























       <xs:complexType>
















































         <xs:choice























 minOccurs























='0'























 maxOccurs























='1'























>
























           <xs:element























 name























='resource'























 type























='xs:string'























/>
























           <xs:element























 name























='jid'























 type























='xs:string'























/>
























         </xs:choice>
















































       </xs:complexType>
















































     </xs:element>
















































 
   </xs:schema>
















































C.6. Dialback namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='jabber:server:dialback'
























       xmlns























='jabber:server:dialback'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='result'























>
























       <xs:complexType>
















































         <xs:simpleContent>
















































           <xs:extension























 base























='xs:token'























>
























             <xs:attribute























 name























='from'























 type























='xs:string'























 use























='required'























/>
























             <xs:attribute























 name























='to'























 type























='xs:string'























 use























='required'























/>
























             <xs:attribute























 name























='type'























 use























='optional'























>
























               <xs:simpleType>
















































                 <xs:restriction























 base























='xs:NCName'























>
























                   <xs:enumeration























 value























='invalid'























/>
























                   <xs:enumeration























 value























='valid'























/>
























                 </xs:restriction>
















































               </xs:simpleType>
















































             </xs:attribute>
















































           </xs:extension>
















































         </xs:simpleContent>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:element























 name























='verify'























>
























       <xs:complexType>
















































         <xs:simpleContent>
















































           <xs:extension























 base























='xs:token'























>
























             <xs:attribute























 name























='from'























 type























='xs:string'























 use























='required'























/>
























             <xs:attribute























 name























='id'























 type























='xs:NMTOKEN'























 use























='required'























/>
























             <xs:attribute























 name























='to'























 type























='xs:string'























 use























='required'























/>
























             <xs:attribute























 name























='type'























 use























='optional'























>
























               <xs:simpleType>
















































                 <xs:restriction























 base























='xs:NCName'























>
























                   <xs:enumeration























 value























='invalid'























/>
























                   <xs:enumeration























 value























='valid'























/>
























                 </xs:restriction>
















































               </xs:simpleType>
















































             </xs:attribute>
















































           </xs:extension>
















































         </xs:simpleContent>
















































       </xs:complexType>
















































     </xs:element>
















































 
   </xs:schema>
















































C.7. Stanza error namespace

   <?xml























 version























='1.0'























 encoding























='UTF-8'























?>
























 
   <xs:schema
























       xmlns:xs























='http://www.w3.org/2001/XMLSchema'
























       targetNamespace























='urn:ietf:params:xml:ns:xmpp-stanzas'
























       xmlns























='urn:ietf:params:xml:ns:xmpp-stanzas'
























       elementFormDefault























='qualified'























>
























 
     <xs:element























 name























='bad-request'























 type























='empty'























/>
























     <xs:element























 name























='conflict'























 type























='empty'























/>
























     <xs:element























 name























='feature-not-implemented'























 type























='empty'























/>
























     <xs:element























 name























='forbidden'























 type























='empty'























/>
























     <xs:element























 name























='gone'























 type























='xs:string'























/>
























     <xs:element























 name























='internal-server-error'























 type























='empty'























/>
























     <xs:element























 name























='item-not-found'























 type























='empty'























/>
























     <xs:element























 name























='jid-malformed'























 type























='empty'























/>
























     <xs:element























 name























='not-acceptable'























 type























='empty'























/>
























     <xs:element























 name























='not-allowed'























 type























='empty'























/>
























     <xs:element























 name























='payment-required'























 type























='empty'























/>
























     <xs:element























 name























='recipient-unavailable'























 type























='empty'























/>
























     <xs:element























 name























='redirect'























 type























='xs:string'























/>
























     <xs:element























 name























='registration-required'























 type























='empty'























/>
























     <xs:element























 name























='remote-server-not-found'























 type























='empty'























/>
























     <xs:element























 name























='remote-server-timeout'























 type























='empty'























/>
























     <xs:element























 name























='resource-constraint'























 type























='empty'























/>
























     <xs:element























 name























='service-unavailable'























 type























='empty'























/>
























     <xs:element























 name























='subscription-required'























 type























='empty'























/>
























     <xs:element























 name























='undefined-condition'























 type























='empty'























/>
























     <xs:element























 name























='unexpected-request'























 type























='empty'























/>
























 
     <xs:group























 name























='stanzaErrorGroup'























>
























       <xs:choice>
















































         <xs:element























 ref























='bad-request'























/>
























         <xs:element























 ref























='conflict'























/>
























         <xs:element























 ref























='feature-not-implemented'























/>
























         <xs:element























 ref























='forbidden'























/>
























         <xs:element























 ref























='gone'























/>
























         <xs:element























 ref























='internal-server-error'























/>
























         <xs:element























 ref























='item-not-found'























/>
























         <xs:element























 ref























='jid-malformed'























/>
























         <xs:element























 ref























='not-acceptable'























/>
























         <xs:element























 ref























='not-allowed'























/>
























         <xs:element























 ref























='payment-required'























/>
























         <xs:element























 ref























='recipient-unavailable'























/>
























         <xs:element























 ref























='redirect'























/>
























         <xs:element























 ref























='registration-required'























/>
























         <xs:element























 ref























='remote-server-not-found'























/>
























         <xs:element























 ref























='remote-server-timeout'























/>
























         <xs:element























 ref























='resource-constraint'























/>
























         <xs:element























 ref























='service-unavailable'























/>
























         <xs:element























 ref























='subscription-required'























/>
























         <xs:element























 ref























='undefined-condition'























/>
























         <xs:element























 ref























='unexpected-request'























/>
























       </xs:choice>
















































     </xs:group>
















































 
     <xs:element























 name























='text'























>
























       <xs:complexType>
















































         <xs:simpleContent>
















































           <xs:extension























 base























='xs:string'























>
























             <xs:attribute























 ref























='xml:lang'























 use























='optional'























/>
























           </xs:extension>
















































         </xs:simpleContent>
















































       </xs:complexType>
















































     </xs:element>
















































 
     <xs:simpleType























 name























='empty'























>
























       <xs:restriction























 base























='xs:string'























>
























         <xs:enumeration























 value























=''























/>
























       </xs:restriction>
















































     </xs:simpleType>
















































 
   </xs:schema>
















































附錄 D. 核心Jabber協議和XMPP的不同

本章是非標準的.
譯者注:附錄D對於新接觸XMPP的人沒有什麼意義,就不翻譯了,免得浪費時間。因爲現在RFC公佈已經很久了,以前的Jabber實現很多都進化到XMPP了。
XMPP has been adapted from the protocols originally developed in the Jabber open-source community, which can be thought of as "XMPP 0.9". Because there exists a large installed base of Jabber implementations and deployments, it may be helpful to specify the key differences between the relevant Jabber protocols and XMPP in order to expedite and encourage upgrades of those implementations and deployments to XMPP. This section summarizes the core differences, while the corresponding section of RFC3921 summarizes the differences that relate specifically to instant messaging and presence applications.

D.1. Channel Encryption

It was common practice in the Jabber community to use SSL for channel encryption on ports other than 5222 and 5269 (the convention is to use ports 5223 and 5270). XMPP uses TLS over the IANA-registered ports for channel encryption, as defined under Use of TLS (Section 5) herein.

D.2. Authentication

The client-server authentication protocol developed in the Jabber community used a basic IQ interaction qualified by the 'jabber:iq:auth' namespace (documentation of this protocol is contained in [JEP-0078], published by the Jabber Software Foundation [JSF]). XMPP uses SASL for authentication, as defined under Use of SASL (Section 6) herein.
The Jabber community did not develop an authentication protocol for server-to-server communications, only the Server Dialback (Section 8) protocol to prevent server poofing. XMPP supersedes Server Dialback with a true server-to-server authentication protocol, as defined under Use of SASL (Section 6) herein.

D.3. Resource Binding

Resource binding in the Jabber community was handled via the 'jabber:iq:auth' namespace (which was also used for client authentication with a server). XMPP defines a dedicated namespace for resource binding as well as the ability for a server to generate a resource identifier on behalf of a client, as defined under Resource Binding (Section 7).

D.4. JID Processing

JID processing was somewhat loosely defined by the Jabber community (documentation of forbidden characters and case handling is contained in [JEP-0029], published by the Jabber Software Foundation [JSF]). XMPP specifies the use of [NAMEPREP] for domain identifiers and supplements Nameprep with two additional [STRINGPREP] profiles for JID processing: Nodeprep (Appendix A) for node identifiers and Resourceprep (Appendix B) for resource identifiers.

D.5. Error Handling

Stream-related errors were handled in the Jabber community via XML character data text in a <stream:error/> element. In XMPP, stream-related errors are handled via an extensible mechanism defined under Stream Errors (Section 4.7) herein. Stanza-related errors were handled in the Jabber community via HTTP-style error codes. In XMPP, stanza-related errors are handled via an extensible mechanism defined under Stanza Errors (Section 9.3) herein. (Documentation of a mapping between Jabber and XMPP error handling mechanisms is contained in [JEP-0086], published by the Jabber Software Foundation [JSF].)

D.6. Internationalization

Although use of UTF-8 has always been standard practice within the Jabber community, the community did not define mechanisms for specifying the language of human-readable text provided in XML character data. XMPP specifies the use of the 'xml:lang' attribute in such contexts, as defined under Stream Attributes (Section 4.4) and xml:lang (Section 9.1.5) herein.

D.7. Stream Version Attribute

The Jabber community did not include a 'version' attribute in stream headers. XMPP specifies inclusion of that attribute as a way to signal support for the stream features (authentication, encryption, etc.) defined under Version Support (Section 4.4.1) herein.

貢獻者

XMPP的大部分核心方面是由1999年開始的Jabber開源社區開發的. 這個社區是由 Jeremie Miller建立的, 他於1999年1月發佈了最初版的jabber server源代碼. 主要的基礎協議的早期貢獻者還包括 Ryan Eatmon, Peter Millard, Thomas Muldowney,和 Dave Smith. XMPP工作組的工作主要集中在安全性和國際化方面; 在這些領域, 使用 TLS 和 SASL 的協議最初是由 Rob Norris貢獻的, stringprep profiles 最初是由 Joe Hildebrand貢獻的. The error code syntax 是由Lisa Dusseault建議的.

致謝

感謝許多在貢獻者名單之外的人們. 儘管很難提供一個完整的名單, 以下個人對於定義協議或評論標準提供了很多幫助:
Thomas Charron, Richard Dobson, Sam Hartman, Schuyler Heath, Jonathan Hogg, Cullen Jennings, Craig Kaes, Jacek Konieczny, Alexey Melnikov, Keith Minkler, Julian Missig, Pete Resnick, Marshall Rose, Alexey Shchepin, Jean-Louis Seguineau, Iain Shigeoka, Greg Troxel, and David Waite.
也感謝 XMPP工作組的成員和 IETF 社區在本文的成文過程中一直提供的評論和反饋。

 

作者地址

Peter Saint-Andre (editor)
Jabber Software Foundation
EMail: [email protected]

完整的版權聲明

Copyright (C) The Internet Society (2004).
This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/S HE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the IETF's procedures with respect to rights in IETF Documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr . The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at [email protected].
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章