Extensible Messaging and Presence Protocol (XMPP): Core

摘要:node

        此文檔定義了可擴展消息出席協議(XMPP)的核心特性:協議使用XML元素在任意兩個網絡端點間近實時的交換結構化信息。當XMPP爲交換XML數據提供通常化,可擴展的框架時,它主要用於創建知足RFC2779的即時消息與出席應用的需求。安全

1 介紹服務器

1.1 概要網絡

        XMPP是一個開放的可擴展標記語言[XML]協議,用於近實時的消息、出席與請求-響應服務。基本語法語義最初是由Jabber開源社區在1999年開發的。2002年,XMPP工做組受權開發一個Jabber協議的改寫本,將適用於IETF的即時消息(IM)與出席技術。
        做爲XMPP工做組的成果,此文檔定義了XMPP 1.0的核心內容;提供即時消息與出席功能的擴展需求定義在RFC2779[IM-REQS]中,由XMPP:即時消息與出席[XMPP-IM]指定。session

1.2 術語架構

        文檔中的大寫關鍵字:"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",  "MAY", "OPTIONAL"在BCP14, 在RFC 2119 [TERMS]中描述。併發

2 通常架構app

2.1 概述框架

        雖然XMPP並未與任何特定網絡架構結合,但到目前爲止,它大體上已經由一個客戶-服務器的架構實現了。其中,客戶端利用XMPP訪問基於[TCP]鏈接的一個服務器,而且,服務器間也經過TCP鏈接進行彼此間的通訊。
          XMPP 
Client------------Server------------Server               
           TCP               TCP
        下圖爲此架構的高層視圖(「-」表示使用XMPP通訊,「=」表示使用任何其它協議通訊)
   C1----S1---S2---C3
         |
   C2----+--G1===FN1===FC1
符號表示以下:
1) C1,C2,C3 = XMPP客戶端
2) S1,S2 = XMPP服務器
3) G1 = 網關:在XMPP與外部協議(非XMPP)的消息網絡間轉換。
4) FN1 = 外部消息網絡
5) C1 = 外部消息網絡的客戶端dom

2.2 服務器

        服務器做爲XMPP通訊擔當智能抽象層。它的主要責任是:
1) 管理鏈接其它實體的會話,以XML流格式(第4節)在已受權的客戶端、服務器以及其它實體間來回傳送。
2) 經過XML流在實體間路由具備合適地址的XML節(第9節)。
        大多數與XMPP兼容的服務器設想有能力存儲客戶端的數據(例:基於XMPP即時消息與出席應用的用戶的聯繫列表);在這種狀況下,XML數據由服務器自身表明客戶端直接處理,並不路由到其它實體。

2.3 客戶端

        大多數客戶端經過[TCP]鏈接直接連到服務器,而且使用XMPP,充分利用由服務器及任何相關服務所提供的功能。多種資源(例如:設備或位置)可能表明每一個被受權客戶端同時連到服務器上。每一個資源均由定義在地址方案(第3節)下的XMPP地址的資源標識符來區別(例如:<node@domain/home> vs. <node@domain/work>)。客戶端與服務器的推薦鏈接端口爲5222,已由IANA註冊(參考端口編號(15.9節))。

2.4 網關

        網關是服務器端的一種特殊服務,它的主要功能是將XMPP翻譯成外部消息系統所使用的協議(非XMPP),也可將數據翻譯回XMPP。例如EMAIL網關(參考[SMTP]),Internet Relay Chat(參考[IRC]),SIMPLE(參考[SIIMPLE],Session Initiation Protocol for Instant Messaging and Presence Leveraging Extensions),短消息服務(SMS),遺留即時消息服務,諸如AIM,ICQ,MSN Messenger,Yahoo! Instant Messenger。網關與服務器間的通訊,網關與外部消息系統間的通訊,均未在此文檔中定義。

2.5 網絡

        因爲每一個服務器由網絡地址指定,而且因爲服務器與服務器間的通訊是客戶與服務器協議的直接擴展,實際上,系統由互相通訊的服務器網絡組成。舉個例子,<juliet@example.com>能與<romeo@example.net>交換消息、出席,以及其它信息。這是使用網絡尋址標準的消息協議(例如[SMTP])所熟悉的模式。任意兩服務器間的通訊是可選的。若是可通訊,此類通訊就應當發生在綁定到[TCP]鏈接的XML流上。服務器間鏈接的推薦端口爲5269,由IANA註冊(參考端口編號(15.9節))

3 尋址方案

3.1 概述

        實體可被看做是使用XMPP進行通訊的任意網絡端點(例如:一個網絡上的ID)。任意此類實體均以與RFC2396[URI]一致的格式來惟一設定地址。因爲歷史緣由,XMPP實體的地址稱做Jabber標識符或JID。一個有效JID包含一套有序元素:域標識符,結點標識符,資源標識符。
        JID的語法定義以下,使用增廣巴斯科範式[ABNF](Augmented Backus-Naur Form)。(Ipv4地址與Ipv6地址規則定義在[Ipv6]的附錄B;符合結點規則的容許字符序列由Nodeprep profile of [STRINGPREP]定義,編入本文檔的附錄A;符合資源規則的容許字符序列由Resourceprep profile of [STRINGPREP]定義,編入本文檔的附錄B;子域規則參考國際化域標識的概念,在[IDNA]中有述)。

      jid             = [ node "@" ] domain [ "/" resource ]
      domain          = fqdn / address-literal
      fqdn            = (sub-domain 1*("." sub-domain))
      sub-domain      = (internationalized domain label)
      address-literal = IPv4address / IPv6address

        全部JID均基於前述規則。此結構最普通的用法就是用戶以<user@host/resource>形式標識一個即時消息用戶、用戶鏈接的服務器、用戶鏈接的資源(例如:特別的客戶端)。
        然而,結點類型可能不只是客戶端,舉個例子,一個提供多用戶聊天服務的特別聊天室,能夠以<room@service>(「room」是聊天室名,「service」是多用戶聊天服務的主機名)做爲地址。而且,此聊天室的特別擁有者可能以<room@service/nick>(「nick」是此擁有者的房間暱稱)做地址,許多其它JID類型均有可能(例如:<domain/resource>多是一個服務器端腳本或服務)。
        JID(結點標識符,域標識符,資源標識符)的每一個可容許部分長度不許超過1023字節,結果,最大總長度(包括‘@’,‘/’分隔符)爲3071字節。

3.2 域標識符

        域標識符是基本標識符,且是JID中僅有的一個必須的元素(僅有域標識符的JID是有效的)。它一般表示網絡網關與「主要的」服務器,具備爲其它實體間的鏈接進行XML路由與數據管理的能力。然而,由域標識符做爲參考的實體並不老是服務器,它多是一項以服務器子域爲地址的服務,提供多於服務器(例:多用戶聊天服務,用戶目錄,或外部消息系統的一個網關)的功能。
        每一個服務器或服務的域標識符將經過網絡進行通訊,它多是IP地址,並應當是徹底合法的域名(參考[DNS])。域標識符必須是一個「國際化的域名」,定義在[IDNA],Nameprep [NAMEPREP] profile of stringprep [STRINGPREP]能夠無錯應用。比較兩個域標識符以前,服務器必須(客戶端是應該)首先對標籤(定義在[IDNA])應用Nameprep profile,以補足每一個標識符。

3.3 節點標識符

        結點標識符是一個可選的輔助標識符,放在域標識符以前,後以‘@’字符分隔。它一般表示實體請求與使用由服務器或網關(例如:一個客戶端)提供的網絡訪問,雖然它也能表示其它種類的實體(例如:有多用戶聊天服務功能的聊天室)。由結點標識符表示的實體,在特定域上下文中,在XMPP即時消息與出席應用中被加以地址,此類地址稱做「bare JID」,形式爲<node@domain>
        結點標識符必須像the Nodeprep profile of [STRINGPREP]這樣格式化,能夠無錯應用。比較兩個結點標識符以前,服務器必須(客戶端應該)首先對每一個標識符應用Nameprep profile。

3.4 資源標識符

        資源標識符是一個可選的第三位標識符,位於域標識符以後,後跟‘/’做爲分隔符。資源標識符能夠修改<node@domain>也能夠只是<domain>地址。它一般表示一個特別的會話、鏈接(例如:一個設備或位置),或屬於帶有節點標識符的對象(例如:在多用戶聊天室的一個參與者)。當提供必要的信息來完成資源綁定(第7節)時,資源標識符對服務器與其它客戶端均不透明,而且由客戶端實現來定義,之後,它做爲一個「已鏈接資源」參考。實體可能同時維護多鏈接,每一個已鏈接的資源均由資源標識符來進行區別。
        資源標識符必須按Resourceprep profile of [STRINGPREP]格式化,才能無錯應用。比較兩個資源標識符前,服務器必須(客戶端應該)首先爲每一個標識符應用Resourceprep profile。

3.5 決定地址

        SASL協商後(第6節),若是正確,資源綁定(第7節),流接收實體必須決定初始實體的JID。
        若是SASL協商(第6節)期間未指定受權身份,對服務器服務器間的通訊,初始實體的JID應當被受權身份,派生於認證身份,在SASL(Simple Authentication and Security Layer簡單受權與安全層)說明[SASL]中定義。
        若是SASL協商(第6節)期間未指定受權身份,對客戶端服務器的通訊,「bare JID」(<node@domain>)應該被受權身份,被派生於受權認證,定義在[SASL]。在資源綁按期間(第7節)「full JID」(<node@domain/resource>)的資源標識符部分應當是客戶端與服務器間協商的資源標識符。
        接收實體必須確保結果JID(包括結點標識符,域標識符,資源標識符,分隔符)聽從此節中前面所定義的規則與格式;爲知足此限制,接收實體可能須要替代由接收實體所決定的規範的JID初始實體所發送的JID。

 

4 XML流

4.1概述
      使presence-aware實體間可以相互迅速的、異步交換相關的小負載的結構化信息有兩種基本元素:XML流與XML節。術語定義以下:

      XML流定義:XML流是一個容器,用於網絡上任意兩實體間交換XML元素。XML流的開始是以一個起始的XML<stream>標記(有合適的屬性與命名空間聲明)表示,XML流的結尾以一個結束的XML</stream>標記表示。在流的生命週期中,初始化它的實體可以經過流發送極多的XML元素,元素與XML節(定義在此,<message/>, <presence/>, 或 <iq/>元素由缺省命名空間驗證)都用於協商流(例:協商使用TLS(第5節)或使用SASL(第6節))。「初始流」是從初始實體(一般是一個客戶端或服務器)到接收實體(一般是一個服務器)的協商,並被看做與從初始實體到接收實體的會話一致。初始流能從初始實體到接收實體單向通訊;爲了可以從接收實體到初始實體的信息交換,接收實體必須在反方向協商一個流(「響應流」)。

      XML節定義:XML節是一個不連續的結構化信息語義單元,經過XML流從一個實體發送到另外一個實體。XML節以根</stream>的直接子層存在,若是它匹配產品[43]內容[XML],則能夠很好的平衡。

      任何XML節的開始都由深度爲1的XML流(例如:<presence>)的開始標記元素來清楚的表示,XML節的結尾由相應的深度爲1的關閉標記來清楚的表示。爲傳送想要的信息,一個XML節可能包含必要的子元素(帶有屬性,元素,XML字符數據)。在此定義的僅有的XML節是<message/>,<presence/>,<iq/>元素,由流的缺省命名空間驗證,在XML節(第9節)中描述;爲傳輸層安全(TLS:Transport Layer Security)協商,SASL協商,或服務器回叫(第8節)而發送的XML元素,並不會看成XML節來考慮。

      考慮一個客戶端與服務器的會話例子。爲了鏈接到服務器,客戶端必須初始化一個XML流:發送一個起始的<stream>標記給服務,可選先於一個指定XML版本的文本聲明與字符編碼支持(參考文本聲明的內容(11.4);也可參考字符編碼(11.5))。服從本地策略與所提供的服務,服務器接下來應該回復另外一個XML流給客戶端,再次可選先於一個文本聲明。一但客戶端完成了SASL協商(第6節),客戶端能夠經過流發送極多的XML節給網絡上的任意容器。當客戶端想關閉流時,它簡單發送一個關閉</stream>標記給服務器(也能夠由服務器來關閉流),從這之後,客戶端與服務器都應終止潛在的鏈接(一般是一個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>        |
   |--------------------|

4.2 綁定到TCP
        雖然將一個XML流結合到一個[TCP]鏈接上不是必須的(例如:兩個實體能經過其它諸如[HTTP]投票選舉機制而彼此互連),此說明也只定義了XMPP到TCP的綁定。在客戶端到服務器端通訊的上下文中,服務器必須容許客戶端爲了從客戶端到服務器與服務器到客戶端的XML節發送共享的一個單TCP鏈接。在服務器到服務器的通訊上下文中,服務器必須使用一條TCP鏈接用於從服務器到其對等服務器的XML節傳送,另外一條TCP鏈接(由對等初始化)用於對其等服務器到服務器的XML節傳送,總共有兩條TCP鏈接。

4.3 流安全
        當在XMPP1.0中協商XML流時,TLS應當按TLS應用(第5節)所定義的來使用,SASL必須按SASL(第6節)所定義的來使用。「初始流」(例如:從初始實體到接收實體的流)與「響應流」(例如:從接收實體到初始實體的流)必須被分別保護,即便雙向安全可能已經過相互的認證機制所創建。實體不該當在流被認證以前,嘗試經過流發送XML節(第9節),但若是這樣作了,那麼,其它實體不許接受此類節,並應當返回一個<non-authorized/>流錯誤,而後終止兩端的XML流與潛在的TCP鏈接;注意,這隻適用於XML節(例如:<message/>, <presence/>, <iq/>元素,由缺省命名空間檢查)並不適用於流協商(例如:用於協商使用TLS(第5節)或使用SASL(第6節))的XML元素。

4.4 流屬性
      流元素屬性以下:
      1) to—‘ to’屬性應當僅用於從初始實體到接收實體的XML流頭中,而且必須被設成一個接收實體服務的主機名。‘to’屬性不該當設在接收實體迴應初始實體的XML流頭中;然而,若是‘to’屬性包括在內,它應當被初始實體默默忽略。
      2) from—‘ from’屬性應當僅用於從接收實體到初始實體的XML流頭中,而且必須被設成一個接收實體服務的主機名,此接收實體正受權訪問初始實體。‘from’屬性不該在初始實體發送到接收實體的流頭中;然而,若是‘from’屬性包括在內,它應當被接收實體忽略。
      3) id—‘ id’屬性應當僅用於從接收實體到初始實體的XML流頭中。此屬性是惟一一個由接收實體建立的,做爲初始實體流與接收實體間會話的密鑰,而且,在接收應用(一般是一個服務器)中是惟一的。注意:流ID多是嚴格安全的,而且所以必須是即不能預測也不能重複的(參考[RANDOM]推薦關於隨機安全觀點)。‘id’屬性不該在初始實體到接收實體的XML流頭中;然而,若是‘id’屬性包含在內,應被接收實體忽略。
      4) xml:lang—‘ xml:lang’屬性(定義在[XML]的12.2)應當包含在初始實體的初始流頭中,用於指定缺省語言,此語言能夠是任何經過流發送的人類可讀的XML字符數據。若是屬性包含在內,接收實體應當記住此值並作爲初始流與響應流的缺省值;若是此屬性不包含在內,接收實體應當爲兩個流使用一個可配置的缺省值,它必須爲響應流在頭中通訊。對全部經過初始化流發送的節,若是初始實體不包含‘xml:lang’屬性,接收實體應當應用缺省值;若是初始實體包含‘xml:lang’屬性,接收實體不許修改或刪除它(參考xml:lang(9.1.5))。‘xml:lang’屬性值必須是一個NMTOKEN(定義在[XML](2.3)),而且必須與定義在RFC3006[LANGTAGS]中的格式一致。
      5) version—版本屬性出現設到至少是「1.0」信號值,支持定義在說明書中的相關流協議(包括流特徵)。有關代與屬性處理的具體規則定義以下:
可總結以下:

            |  initiating to receiving  |  receiving to initiating
    ---------+---------------------------+-----------------------
    to       |  hostname of receiver     |  silently ignored
    from     |  silently ignored         |  hostname of receiver
    id       |  silently ignored         |  session key
    xml:lang |  default language         |  default language
    version  |  signals XMPP 1.0 support |  signals XMPP 1.0 support

4.4.1版本支持
      XMPP版本在此指定爲「1.0」,特別的,這封裝了流相關協議(TLS應用(5),SASL應用(6),流錯誤(4.7)),還有三個已定義的XML節類型(<message/>, <presence/>, and <iq/>)的語義。XMPP版本的編號方案是「<major>.<minor>」。Major與minor數字必須做爲分離的整數對待,而且每一個數字可能並不按單數字增長。所以"XMPP 2.4"是一個比"XMPP 2.13"低的版本,依次低於"XMPP 12.3"。前導零(例如:"XMPP 6.01")必須被接收者忽略並不許發送。
      Major版本號應當增長,只要流與節格式或是所需行爲已很大程度上改變,以致於老版本若是對它不理解的並採起在舊版說明中指定的動做時,只簡單忽略元素與屬性時沒法與新版本實體互操做,就要增長主版本號。次版本號指新能力,而且必須被有一個更小次版本號的實體所忽略,但被有更大次版本號的實體做信息目的用。舉例:次版本號可能指處理消息,出席,或IQ節新近定義的‘type’屬性值;有更大次版本號的實體將簡單注意它的通訊者不理解此‘type’屬性值,並所以而不發送它。
      如下規則由實現應用於產生與處理在流頭中的‘版本’屬性:
      1) 初始實體必須在初始流頭中將版本屬性值設到它所支持的最高版本號(例如:若是它所支持的最高版本號定義在此說明中,必須設值爲「1.0」)
      2) 接收實體必須在響應流頭中設置版本屬性值或者是初始實體提供的值,或者是接收實體所支持的最高版本號,不管哪個更低。接收實體必須對主、次版本號作數字比較,而不是"<major>.<minor>"字符串匹配。
      3) 若是包含在響應流頭中的版本號至少一個主版本號低於包含在初始流頭中的版本號,而且新版本實體不能像上述那樣與舊版本互操做,初始實體應當產生一個<unsupported-version/>流錯誤,並終止XML流與潛在的TCP鏈接。
      4) 若是每一個實體都收到一個帶有「無版本號」屬性的流頭,實體必須考慮由其它實體支持版本將是「0.0」並不該當在發送響應流時包括‘version’屬性。

4.5 命名空間聲明
      流元素必須擁有流命名空間聲明和一個缺省的命名空間聲明(命名空間聲明定義在XML命名空間說明文檔[XML-NAMES]中)。對有關流命名空間與缺省命名空間的更細節的信息,看命名空間名稱與前綴(11.2)。

4.6 流特徵
      若是初始化實體包含版本屬性,並在初始流頭中,其值至少設爲「1.0」,那麼接收實體必須發送一個<features/>子元素(由流命名空間前綴做前綴)給初始實體,以宣佈任何可被協商的(或另外須要被廣告的能力)流級別的特徵。當前,這僅用於廣告在此定義的TLS應用(5),SASL應用(6)和資源綁定(7),而且,會話按照[XMPP-IM]中所定義的來創建;然而,流特徵的功能性可被用於廣告其它未來可協商的特徵。若是實體不理解或不支持某些特徵,那麼它應當默默的忽略。若是一個或多個安全特徵(例如:TLS與SASL)須要在非安全特徵(例如:資源綁定)被提供以前成功被協商,非安全相關特徵不該當在相關安全特徵被協商以前包含在流特徵中被廣告。

4.7 流錯誤
      根流元素可能包含一個<error/>子元素,此元素由流命名空間前綴來加前綴。若是錯誤子元素感受到一個流級別錯誤發生,它必須由一個兼容實體(一般是一個服務器而不是一個客戶端)來發送。

4.7.1 規則
      如下規則應用於流級別錯誤:
      1) 設想全部流級別錯誤均是不可恢復的;所以,若是一個錯誤在流級別層發生,那麼檢測錯誤的實體必須發送一個流錯誤給其它實體,發送一個關閉</stream>標記,並終止潛在的TCP鏈接。
      2) 若是在流被創建期間發生錯誤,接收實體必須一直髮送起始<stream>標記,將<error/>元素做爲流元素的子元素,發送關閉</stream>標記,並終止潛在的TCP鏈接。此種狀況下,若是初始實體在‘to’屬性(或根本沒提供‘to’屬性)中提供了一個未知主機,服務器應當在流頭的‘from’屬性中提供服務器的受權主機名,並在終止前發送。

4.7.2 語法
      流錯誤語法以下:
   <stream:error>
     <defined-condition xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
     <text xmlns='urn:ietf:params:xml:ns:xmpp-streams'
           xml:lang='langcode'>
       OPTIONAL descriptive text
     </text>
     [OPTIONAL application-specific condition element]
   </stream:error>

      <error/>元素:
      1) 必須包含一個子元素,此子元素與如下定義的已定義的節錯誤條件之一相一致;此元素必須被'urn:ietf:params:xml:ns:xmpp-streams'命名空間認爲是合格的。
      2) 可能包含一個<text/>子元素,此子元素包含了更詳細描述錯誤的XML字符數據;此元素必須被'urn:ietf:params:xml:ns:xmpp-streams'命名空間認爲是合格的,而且,應當擁有一個'xml:lang'屬性來指明XML字符數據的天然語言。
      3) 可能包含一個用於說明特殊應用錯誤條件的子元素;此元素必須由一個已定義應用命名空間來認證,而且,它的結構由那個命名空間來定義。

      <text/>元素是可選的。若是包含了此元素,它應當僅用於提供描述性或診斷性的信息,來補充一個已定義的條件或特殊應用條件的意思;它不該當由一個應用以程序化的形式敘述。它不該看成爲錯誤消息展現給一個用戶,但可能另外顯示與包含條件元素(或元素們)相關的錯誤消息。

4.7.3 已定義條件
      如下定義了流級別錯誤條件:
      1)<bad-format/>--已經發送XML的實體不能被處理;此錯誤可能用於代替更特殊的XML相關錯誤,例如:<bad-namespace-prefix/>, <invalid-xml/>,
 <restricted-xml/>, <unsupported-encoding/>, <xml-not-well-formed/>,雖然更特殊的錯誤是首選。
      2)<bad-namespace-prefix/>--實體已經發送了一個不被支持的名空間前綴,或在一個須要那樣一個前綴的元素中發送了沒有命名空間的前綴(參考XML命名空間名與前綴(11.2))。
      3)<conflict/>--服務器正爲實體關閉活動流,由於一個已經被初始化的新流與現存流衝突。
      4)<connection-timeout/>--一段時間內(可根據本地服務策略配置)實體並不經過流產生任何通訊。
      5)<host-gone/>--由初始實體在流頭中提供的‘to’屬性值對應於一個主機名,而此主機名已再也不被一個服務器看成主機了。
      6)<host-unknown/>--由初始實體在流頭中提供的‘to’屬性值於服務器所擁有的主機名不一致。
      7)<improper-addressing/>--一個在兩個服務器間發送的節,缺乏‘to’或‘from’屬性(或此屬性無值)
      8)<internal-server-error/>--服務器經歷了錯誤配置或其它未定義內部錯誤使其沒法提供服務。
      9)<invalid-from/>--在‘from’地址中提供的JID或主機名與已受權的JID或有效域協商不匹配,此有效域協商爲經過SASL或回叫服務器間的協商,或經過受權與資源綁定的客戶端與服務器間的協商。
      10)<invalid-id/>--流ID或回叫ID是無效的或與之前提供的ID不匹配。
      11)<invalid-namespace/>--流命名空間名不僅是http://etherx.jabber.org/streams,或回叫命名空間名不僅是"jabber:server:dialback"(參考XML命名空間名與前綴(11.2))
      12)<invalid-xml/>--實體經過流向執行驗證的服務器發送了無效的XML(參考驗證(11.3))。
      13)<not-authorized/>--實體試圖在流被認證前發送數據,或不受權執行一個相關流協商的活動;接收實體在發送流錯誤前不許處理違規節。
      14)<policy-violation/>--實體違反了某些本地策略;服務器可能選擇在<text/>元素或特殊-應用條件元素中指定策略。
      15)<remote-connection-failed/>服務器不能適當的鏈接到遠程實體,須要認證或受權。
      16)<resource-constraint/>服務器缺乏提供服務給流的必要的系統資源。
      17)<restricted-xml/>實體試圖發送受限的XML特徵,例如評註、處理介紹,DTD,實體參考,或保留字符(參考(11.1))。
      18)<see-other-host/>服務器將不提供服務給初始實體,但正重定向傳輸給另外一個主機;服務器應當指定替換的主機名或IP地址(必須是有效域標識符),做爲<see-other-host/>元素的XML字符數據。
      19)<system-shutdown/>服務器被關閉,而且全部的活動流被關閉。
      20)<undefined-condition/> 錯誤條件是由此列表中的其它已定義條件中的一個;此錯誤條件應當僅用在與特殊-應用條件相結合。
      21)<unsupported-encoding/>初始實體已在不被服務器支持的編碼中爲流編碼(11.5)
      22)<unsupported-stanza-type/>初始實體已發送了一個不被服務器支持的第一級子流。
      23)<unsupported-version/>由初始實體在流頭提供的版本屬性值指定了一個不被服務器支持的XMPP版本;服務器可能在<text/>元素中指定它支持的版本。
      24)<xml-not-well-formed/>初始實體已經發送了不標準的XML,標準的XML由[XML]定義。

4.7.4 特殊應用條件
      注意,一個應用可能經過在錯誤元素中包含一個合適的命名空間子元素來提供特殊應用流錯誤信息。特殊應用元素應當補充或進一步驗證一個已定義元素。所以,<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>

4.8簡化的流例子
      此部分包含兩個簡化的客戶端與服務器(「C」行是從客戶端發送到服務器,而「S」行是由服務器發送到客戶端)間基於流會話的例子;這些例子解釋進一步的概念。

   A basic "session":

   C: <?xml version='1.0'?>
      <stream:stream
          to='example.com'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   ...  encryption, authentication, and resource binding ...
   C:   <message from='juliet@example.com'
                 to='romeo@example.net'
                 xml:lang='en'>
   C:     <body>Art thou not Romeo, and a Montague?</body>
   C:   </message>
   S:   <message from='romeo@example.net'
                 to='juliet@example.com'
                 xml:lang='en'>
   S:     <body>Neither, fair saint, if either thee dislike.</body>
   S:   </message>
   C: </stream:stream>
   S: </stream:stream>

   A "session" gone bad:

   C: <?xml version='1.0'?>
      <stream:stream
          to='example.com'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   ...  encryption, authentication, and resource binding ...
   C: <message xml:lang='en'>
        <body>Bad XML, no closing body tag!
      </message>
   S: <stream:error>
       <xml-not-well-formed
           xmlns='urn:ietf:params:xml:ns:xmpp-streams'/>
      </stream:error>
   S: </stream:stream>

5 使用TLS

5.1 概述
      XMPP包含一個方法,用於保護流不被篡改和偷聽。此信道加密方法利用傳輸層安全(TLS)協議[TLS],連同「STARTTLS」擴展,在爲描述在RFC 2595[USINGTLS]中的IMAP[IMAP],POP3[POP3],ACAP[ACAP]等類似協議擴展模型。用於STARTTLS擴展的命名空間名是'urn:ietf:params:xml:ns:xmpp-tls'。

      一個給定域的管理者可能須要使用TLS來進行客戶端到服務器的通訊,服務器到服務器的通訊,或兩者兼有。客戶端應使用TLS去保護流,在企圖完成SASL協商以前,並且,服務器出於保護服務器到服務器的通訊的考慮,應在兩個域間使用TLS。

      應用如下規則:
      1) 聽從此說明的初始實體必須包含版本屬性,並在初始流頭中將其值設爲「1.0」。
      2) 若是兩服務器間的TLS協商發生,直到服務器宣稱的域名系統(DNS)主機名被決定(參考服務器到服務器的通訊(14.4))後,才能處理通訊。
      3) 當與此說明一致的接收實體收到一個包含版本屬性設爲至少「1.0」的初始化流時,發送一個流頭做響應(包含版本標記)後,必須包含一個<starttls/>元素(由'urn:ietf:params:xml:ns:xmpp-tls'命名空間認證)並帶有它所支持的其它流特徵的列表。[服務器以<starttls/>響應]
      4) 若是初始實體選擇使用TLS,TLS協商必須在SASL協商處理以前完成;這種協商順序是必要的,用於幫助保護SASL協商期間發送認證信息,並在TLS協商以前這段時間,使基於使用認證的SASL EXTERNAL機制成爲可能。
      5) 在TLS協商期間,實體不許在根流元素中發送任何空白字符(匹配[XML]內容,產品[3])做爲元素間(任何在TLS例子中的空白字符都只是爲了便於閱讀)的分隔符;這種限制有助於確保合適的安全層字節精度。
      6) 接收實體必須考慮TLS協商在發送<proceed/>元素的關閉「>」字符以後當即開始。初始實體必須考慮TLS協商在收到來自於接收實體的<proceed/>元素的關閉「>」字符以後當即開始。
      7) 初始實體必須驗證由接收實體表示的證書;參考證書驗證(14.2)相關證書驗證步驟。
      8) 證書必須根據初始實體(例如:一個用戶)提供的主機名來檢查,而不是經過域名系統解析的主機名;例如:若是用戶指定一個"example.com"的主機名,而DNS SRV[SRV]查找並返回"im.example.com",證書必須做爲"example.com"被檢查。若是對任何此種XMPP實體(例如,客戶端或服務器)的一個JID在一個證書中被表示,它必須做爲一個UTF8String來表示,UTF8String在位於subjiectAltName中的一個otherName實體中,使用[ASN.1]對象標識符"id-on-xmppAddr",在本文檔5.1.1中說明。
      9) 若是TLS協商成功,接收實體必須拋棄TLS生效以前,來自初始實體的任何非安全格式的知識。
      10) 若是TLS協商成功,初始實體必須拋棄TLS生效以前,來自接收實體的任何非安全格式知識。
      11) 若是TLS協商成功,接收實體不許提供STARTTLS擴展給當流從新開如時被提供的帶有其餘流特徵的初始實體。
      12) 若是TLS協商成功,初始實體必須繼續SASL協商。
      13) 若是TLS協商結果失敗,接收實體必須終止XML流與潛在的TCP鏈接。
      14) 參考強制實施技術(14.7)相關的必須被支持的機制。

5.1.1 ASN.1用於XMPP地址的對象標識符
      上述[ASN.1]對象標識符"id-on-xmppAddr"定義以下:
   id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
           dod(6) internet(1) security(5) mechanisms(5) pkix(7) }

   id-on  OBJECT IDENTIFIER ::= { id-pkix 8 }  -- other name forms

   id-on-xmppAddr  OBJECT IDENTIFIER ::= { id-on 5 }

   XmppAddr ::= UTF8String
        對象標識符可能也以點分制顯示,格式爲"1.3.6.1.5.5.7.8.5"

5.2 敘述
      當初始實體使用TLS保護一個帶有接收實體的流時,步驟以下:
      1) 初始實體打開一個TCP鏈接,靠發送開放XML流頭給接收實體,此流頭包含版本屬性,並設其值至少爲「1.0」,來初始化流。
      2) 接收實體以打開一個TCP鏈接併發送一個XML流頭給初始實體做爲響應,此流頭包含值至少爲「1.0」版本屬性。
      3) 接收實體靠包含帶有其它支持流特徵(若是TLS須要與接收實體交互,它應當靠包含一個<required/>元素做爲<starttls/>的子元素來標記此事實)的列表來爲初始實體提供STARTTLS擴展。
      4) 初始實體發起STARTTLS命令(例:由 'urn:ietf:params:xml:ns:xmpp-tls' 命名空間確認的<starttls/>元素)去指導但願開始TLS協商去保護流的接收實體。
      5) 接收實體必須以由命名空間'urn:ietf:params:xml:ns:xmpp-tls'認證了的<proceed/>元素或<failure/>元素響應。若是有失敗狀況發生,接收實體必須終止雙方的XML流與潛在的TCP鏈接。若是接着向下進行,實體必須嘗試經過TCP鏈接完成TLS協商,並不許發送任何進一步的XML數據,直到TLS協商完成。
      6) 初始實體與接收實體嘗試依據[TLS]完成TLS協商。
      7) 若是TLS協商不成功,接收實體必須終止TCP鏈接。若是TLS協商成功,初始實體必須靠發送一個開始XML流頭給接收實體(它並不須要先發送一個關閉</stream>標記,由於接收實體與初始實體必須考慮到原始流根據成功的TLS協商而被關閉),以初始一個新流。
      8) 根據從初始實體接收的新流頭,接收實體必須靠發送一個新XML流頭給有可利用特徵(不包括STARTTLS特徵)的初始實體來響應。

5.3客戶端到服務器的例子
      下面例子顯示了一個客戶端保護使用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協商(6)

5.4 服務器到服務器的例子
      如下例子顯示兩服務器保護使用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通知Server1TLS協商失敗並關閉流:
   <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協商(6)

6.使用SASL
6.1 概述
      XMPP包含一個認證流的方法,此方法依靠一個簡單認證與安全層(SASL)協議[SASL]的XMPP-specific profile。SASL提供一個通常化方法,用於給基於鏈接的協議加認證支持,而且,XMPP使用一個通常化XML命名空間profile,用於SASL,聽從[SASL]的profiling需求。

      如下規則應用:
      1) 若是兩個服務器間發生SASL協商,直到由服務器宣稱的域名系統(DNS)主機名被解析了(參考服務器到服務器通訊(14.4)),通訊纔可處理。
      2) 若是實始實體可以進行SASL協商,,它必須在初始流頭中包含值至少爲「1.0」的版本屬性。
      3) 若是接收實體可以進行SASL協商,它必須在一個<mechanisms/>元素中廣告一個或多個認證機制,此元素靠'urn:ietf:params:xml:ns:xmpp-sasl'命名空間響應從初始實體(若是開放流標記包含所設值至少爲「1.0」的版本屬性)接收的開放流標記認證。
      4) 在SASL協商期間,實體不許在根流元素中發送任何空白字符(匹配[XML]內容,產品[3])做爲元素間(任何在SASL例子中的空白字符都只是爲了便於閱讀)的分隔符;這種限制有助於確保合適的安全層字節精度。
      5) 任何包含在XML元素中的XML字符數據,在SASL協商期間使用,必須使用base64編碼,編碼在RFC3548第三節有定義。
      6) 若是所提供的一個「簡單用戶名」可以被選定SASL機制(例:由DIGEST-MD5與CRAM-MD5機制所支持,但不靠EXTERNAL與GSSAPI機制所支持)所支持,在認證期間,初始實體應看成爲簡單用戶名提供它的發送域(IP地址或包含在域標識符中的全認證域名)在服務器對服務器的通訊狀況下,或是它的已註冊賬戶名(包含在XMPP結點標識符中的用戶或結點名)在客戶到服務器的通訊狀況下。
      7) 若是初始實體但願表明其它實體與支持受權身份傳輸的被選SASL機制來行動,初始實體在SASL協商期間必須提供一個受權身份。若是初始實體不但願表明另外一個實體行動,它不許提供一個受權身份。正如[SASL]中指定的,初始實體不許提供一個受權身份,除非一個受權身份不一樣於缺省受權身份,此缺省受權身份派生於描述在[SASL]中的認證身份。若是提供了,受權身份值對服務器來講必須是<domain>值形式(例:只有一個域標識符),對客戶端來講,必須是<node@domain>值形式(例:結點標識符與域標識符)。
      8) 靠涉及到安全層協商的SASL協商的成功,接收實體必須拋棄來自自己沒有得到SASL協商的初始實體的任何知識。
      9) 靠涉及到安全層協商的SASL協商的成功,初始實體必須拋棄來自自己沒有得到SASL協商的接收實體的任何知識。
      10) 參考必須被支持的相關機制的強制實施技術(14.7)。

6.2敘述
      當初始實體使用SASL認證接收實體時,步驟以下:
      1) 初始實體請求SASL認證,經過在開放XML流頭中包含版本屬性,並將其發送給接收實體,屬性值設爲「1.0」。
      2) 發送一個XML流頭做爲迴應後,接收實體廣告一個可利用的SASL認證機制列表;列表中每一項都是一個<mechanism/>元素,做爲<mechanism/>容器元素的子元素,由'urn:ietf:params:xml:ns:xmpp-sasl'命名空間認證,在流命名空間中,依次是<features/>元素的子元素。若是使用TLS(5)須要在一個特別認證機制可能使用之間創建,接收實體不許提供在TLS協商以前的可利用SASL認證機制列表中的機制。若是初始實體在TLS協商以前出示了有效證書,接收實體應當在SASL協商(參考[SASL])之間,提供SASL EXTERNAL機制給初始實體,雖然EXTERNAL機制可能在其它環境下被提供了。
      3) 初始實體選擇一個機制,靠發送一個已被'urn:ietf:params:xml:ns:xmpp-sasl'命名空間認定爲合格的<auth/>元素給接收實體,併爲‘mechanism’屬性包含一個合適的值。若是此機制須要XML字符數據,此元素可能包含XML字符數據(在SASL術語中,「初始響應」);若是初始實體須要發送一個0長度的初始響應,它必須按一個單等號符號(「=」)傳輸此響應,意味着響應出現,但不包含數據。
      4) 若是須要,接收實體靠發送一個<chanllenge/>元素來挑戰實始實體,此元素由給初始實體的'urn:ietf:params:xml:ns:xmpp-sasl'命名空間來限定;此元素可能包含XML字符數據(必須根據由初始實體選擇的SASL機制的定義一致的來計算)。
      5) 初始實體響應此挑戰,靠發送由'urn:ietf:params:xml:ns:xmpp-sasl'命名空間限定的<response/>元素給接收實體;此元素可能包含XML字符數據(必須根據由初始實體選擇的SASL機制的定義一致的來計算)。
      6) 若是須要,接收實體發送更多的挑戰,初始實體發送更多的響應。

      Challenge/response序列對繼續,直到如下三種事情之一發生:
      1) 初始實體終止握手,靠發送一個由'urn:ietf:params:xml:ns:xmpp-sasl'命名空間限定的<abort/>元素給接收實體。根據接收一個<abort/>元素,接收實體應當容許一個可配置的但合理的重試號(至少2),以後,必須終止TCP鏈接;這使初始實體(例:一個終端用戶客戶端)可以忍受已提供的不正確的信任(例:一個錯誤類型的password)而不用被迫重連。
      2) 接收實體報告握手失敗,靠發送一個由'urn:ietf:params:xml:ns:xmpp-sasl'命名空間限定的<failure/>元素給初始實體(失敗的特殊緣由應當以<failure/>元素的子元素進行通訊,<failure/>元素定義在SASL錯誤中(6.4))。若是錯誤狀況發生,接收實體應當容許一個可配置的,但合理的重試號(至少2),以後,它必須終止TCP鏈接;這使初始實體(例:一個終端用戶客戶端)可以忍受已提供的不正確的信任(例:一個錯誤類型的password)而不用被迫重連。
      3) 接收實體報告握手成功,靠發送一個由'urn:ietf:params:xml:ns:xmpp-sasl'命名空間限定的<success/>元素給初始實體;此元素可能包含XML字符數據(在SASL術語中,「additional data with success」),若是須要靠選定的SASL機制。根據接收的<success/>元素,初始實體必須靠發送一個開放的XML流頭去初始化一個新流給接收實體(它沒必要事先發送一個關閉</stream>標記,由於接收實體與初始實體必須考慮源流根據發送或接收<success/>元素而將被關閉)。根據從初始實體接收的新流頭,接收實體必須發送一個新XML流頭給初始實體做爲響應,並帶有任何可利用的特徵(但並不包含STARTTLS與SASL特徵)或一個空<features/>元素(重要表示沒有其它特徵可利用);任何那種其它在此未定義的特徵必須由XMPP的相關擴展來定義。

6.3 SASL定義
      [SASL]的profiling需求要求協議定義提供如下信息:
      服務名:「xmpp」
      初始序列:初始實體提供一個開放XML流頭後,而且接收實體按此響應後,接收實體提供一個可接收的認證方法列表。初始實體從列表中選擇一個方法並做爲‘machanism’屬性值發送給接收實體,此屬性被<auth/>元素擁有,隨意的包括一個初始響應以免環路。
      交換序列:挑戰與響應經過由接收實體到初始實體<challenge/>元素的交換與由初始實體到接收實體的<response/>元素的交換而執行。接收實體靠發送一個<failure/>元素報告錯誤,發送一個<success/>元素報告成功;初始實體靠發送<abort/>元素終止交換。根據成功協商,兩端都認爲源XML流將被關而且新流頭由兩端實體發送。
      安全層協商:安全層在爲接收實體發送<success/>元素的關閉「>」字符後當即有效,安全層在爲初始實體發送<success/>元素的關閉「>」字符後當即有效。層順序爲:首先是[TCP],而後是[TLS],而後是[SASL],而後是XMPP。
      使用受權身份:受權身份能夠被XMPP用於指示客戶端非缺省<node@domain>或服務器發送<domain>。

6.4 SASL錯誤
      如下是SASL相關錯誤條件的定義:(略)
1)<aborted/>--
2)<incorrect-encoding/>--
3)<invalid-authzid/>--
4)<invalid-mechanism/>--
5)<mechanism-too-weak/>--
6)<not-authorized/>--
7)<temporary-auth-failure/>--

6.5 客戶端到服務器的例子
      如下例子顯示了使用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'>  cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
   </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   LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNoYXJzZXQ9dXRmLTgK
   </response>
步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:服務器經過發送流頭來響應客戶端,伴隨有任意另外的特徵(或空特徵元素):
   <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>

6.6服務器到服務器的例子
      如下例子顯示服務器與服務器使用SASL認證的數據流,正常狀況下,是在TLS協商以後(注:如下可替換步驟是由失敗狀況提供的;他們不是詳盡的也不是必要的由數據發送而觸發)。

步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_234'
       version='1.0'>
步3:Server2通知Server1可利用的認證機制:
   <stream:features>
     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
       <mechanism>DIGEST-MD5</mechanism>
       <mechanism>KERBEROS_V4</mechanism>
     </mechanisms>
   </stream:features>
步4:Server1選擇一個認證機制:
   <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
         mechanism='DIGEST-MD5'/>
步5:Server2發送一個[BASE64]編碼挑戰給Server1:
   <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(替換):Server2返回錯誤給Server1
   <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
     <incorrect-encoding/>
   </failure>
   </stream:stream>
步6:Server1發送[BASE64]編碼響應挑戰:
   <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
   dXNlcm5hbWU9ImV4YW1wbGUub3JnIixyZWFsbT0ic29tZXJlYWxtIixub25j
   ZT0iT0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5j
PTAwMDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5vcmciLHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNoYXJzZXQ9dXRmLTgK
   </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:Server2發送另外一個[BASE64]編碼挑戰給Server1:
   <challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
   cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
   </challenge>
解碼挑戰是:
   rspauth=ea40f60335c427b5527b84dbabcdfffd
步7(替換):Server2返回錯誤給Server1:
   <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
     <invalid-authzid/>
   </failure>
   </stream:stream>
步8:Server1響應挑戰:
   <response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步8(替換):Server1終止協商:
   <abort xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9:Server2通知Server1成功認證:
   <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
步9(替換):Server2通知Server1認證失敗:
   <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
     <aborted/>
   </failure>
   </stream:stream>
步10:Server1初始化一個新流給Server2:
   <stream:stream
       xmlns='jabber:server'
       xmlns:stream='http://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步11:Server2經過發送一個流頭響應Server1,並伴隨着其它特徵(或空特徵元素):
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       from='example.com'
       id='s2s_345'
       version='1.0'>
   <stream:features/>

 

7.資源綁定
        接收實體SASL協商(6)以後,初始實體可能想要或是須要綁定一個特殊資源至那個流。普通的,這僅用於客戶端:爲了聽從在此指定的尋址格式(3)與節傳送規則(10),必須有一個資源標識符聯合客戶端的<node@domain>(便可以由服務器產生也能夠由客戶應用提供);這確保基於流使用的地址是「全JID」形式<node@domain/resource>。

        根據在SASL協商中接收的一個成功指示,客戶端必須發送一個新流頭給服務器,服務器必須用可利用流特徵列表中的內容來響應。特別的,若是服務器須要客戶端在SASL成功協商後,將資源綁定到流上,它必須包括一個由在流特徵列表中的'urn:ietf:params:xml:ns:xmpp-bind'命名空間限定的空<bind/>元素。成功SASL協商後(不是前),它經過發送響應流的頭表示給客戶端:

服務器廣告資源綁定特徵給客戶端:
   <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>

        根據這樣的通知,資源綁定是須要的,客戶端必須靠送給服務器一個包含由'urn:ietf:params:xml:ns:xmpp-bind' 命名空間限定的,類型「set」(參考IQ語義(9.2.3))的IQ節,將資源綁定到流上。

        若是客戶端但願容許服務器表明本身產生資源標識符,它發送一個類型「set」的IQ節,包含一個空<bind/>元素:

        客戶端請求服務器綁定資源:
   <iq type='set' id='bind_1'>
     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
   </iq>

        支持資源綁定的服務器必須能表明一個客戶端產生一個資源標識符。由服務器產生的資源標識符必須對<node@domain>是惟一的。若是客戶端但願指定資源標識符,它發送一個類型爲「set」的IQ節,包含所需資源的標識符,做爲<bind/>元素子元素<resource/>的XML字符數據。

        客戶端綁定一個資源:
   <iq type='set' id='bind_2'>
     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
       <resource>someresource</resource>
     </bind>
   </iq>

        一旦服務器爲客戶端產生了一個資源標識符或是接受了由客戶端提供的資源標識符,它必須返回一個類型爲「result」的IQ節給客戶端,必須包含一個<jid>子元素,來爲服務器決定的已鏈接資源指定全JID:

        服務器通知客戶端成功資源綁定:
   <iq type='result' id='bind_2'>
     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
       <jid>somenode@example.com/someresource</jid>
     </bind>
   </iq>

        服務器應當接受由客戶端提供的資源標識符,但可能用一個服務器產生的資源標識符覆蓋它;在這種狀況,服務器不該當返回一個節錯誤(例:<forbidden/>)給客戶端,取而代之,應當以以上顯示的IQ結果,傳達產生的資源標識符給客戶端。

         當客戶端提供一個資源標識符,如下節錯誤條件是可能的(參考節錯誤(9.3)):
1) 提供的資源標識符不能被與Resourceprep(附錄B)一致的服務器處理。
2) 客戶端不容許綁定資源到流上(例:由於結點或用戶已經達到了在被容許的鏈接的資源的數目)。
3) 已提供資源標識符已經使用,但服務器並不容許用一樣的標識符綁定多鏈接資源。

        用於這些錯誤條件的協議顯示以下。

        資源標識符不能被處理:
   <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>

        資源標識符在使用:
     <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>

        若是,完成資源綁定步驟以前,客戶端嘗試發送一個XML節,而不僅是一個帶有由'urn:ietf:params:xml:ns:xmpp-bind'命名空間限定的<bind/>子元素的IQ節,服務器不許處理此節,而且,應當返回一個<not-authorized/>節錯誤給客戶端。

8.服務器回叫

8.1概述
        Jabber協議來自於XMPP適用的,包含一個「服務器回叫」方法,用以保護免受域哄騙,所以,使哄騙XML節更困難。服務器回叫並非一個安全機制,而且僅致使服務器身份弱驗證(參考服務器到服務器的通訊(14.4)相關方法的安全特性)。域須要健壯的安全性,應當使用TLS與SASL;參考服務器到服務器通訊(4.4)細節。若是SASL用於服務器到服務器的認證,回叫不該當使用,由於它是沒必要要的。包含回叫文檔主要是出於與現存實現與部署向後兼容的緣由。

        服務器回叫方法因域名系統(DNS)存在而成爲可能,因爲一個服務器可以(正常的)對一個給定域發現受權服務器。由於回叫依靠DNS,域內通訊不許處理,直到由服務器宣稱的域名系統(DNS)的主機名被解析(參考服務器到服務器的通訊(14.4))。

        服務器回叫是單向的,致使一個方向上一個流身份的(弱)驗證。由於服務器回叫不是一個認證機制,經過回叫是不可能進行雙向認證的。所以,服務器回叫必須在每一個方向上完成,爲了使在兩個域間進行雙向通訊成爲可能。

        產生與驗證密鑰的方法用於服務器回叫,必須考慮被用的主機名,由接收服務器產生的流ID,和由受權服務器的網絡祕密知道。流ID在服務器回叫中是嚴格安全的,而且所以必須是即不可預測也不可重複的(參考[RANDOM]推薦資料相關用於安全觀點的隨機性。)

        任何在回叫協商期間發生的錯誤必須考慮一個流錯誤,致使終止流與潛在的TCP鏈接。協議描述中說明的可能的錯誤條件以下。

        如下術語應用:
1) 源服務器——試圖在兩個域間創建鏈接的服務器。
2) 接收服務器——嘗試認證源服務器是否按它聲明的那樣去表達。
3) 受權服務器——回答由源服務器宣稱的DNS主機名;對基本環境來講是源服務器,但在源服務器網絡中能夠是一個分離的機器。

8.2事件順序
        如下是回叫事件順序的簡單總結:
1) 源服務器創建到接收服務器的鏈接。
2) 源服務器經過鏈接,給接收服務器發送‘key’值。
3) 接收服務器創建到認證服務器的鏈接。
4) 接收服務器向受權服務器發送相同的‘key’值。
5) 受權服務器回答密鑰值是否有效。
6) 接收服務器通知源服務器受權是否經過。

        咱們能夠將事件順序如下圖表示:
   Originating               Receiving
     Server                    Server
   -----------               ---------
       |                         |
       |   establish connection  |
       | ----------------------> |
       |                         |
       |   send stream header    |
       | ----------------------> |
       |                         |
       |   send stream header    |
       | <---------------------- |
       |                         |                   Authoritative
       |   send dialback key     |                       Server
       | ----------------------> |                   -------------
       |                         |                         |
                                 |   establish connection  |
                                 | ----------------------> |
                                 |                         |
                                 |   send stream header    |
                                 | ----------------------> |
                                 |                         |
                                 |   send stream header    |
                                 | <---------------------- |
                                 |                         |
                                 |   send verify request   |
                                 | ----------------------> |
                                 |                         |
                                 |   send verify response  |
                                 | <---------------------- |
                                 |
       |  report dialback result |
       | <---------------------- |
       |                         |

8.3協議
        服務器間具體協議交互以下:
1) 源服務器創建TCP鏈接到接收服務器。
2) 源服務器發送流頭給接收服務器:
   <stream:stream
       xmlns:stream='http://etherx.jabber.org/streams'
       xmlns='jabber:server'
       xmlns:db='jabber:server:dialback'>
      注:‘to’與‘from’屬性在根流元素中是可選的。包含xmlns:db命名空間聲明,名字顯示向接收實體指示源服務器支持回叫。若是命名空間名不正確,那麼,接收服務器必須產生一個<invalid-namespace/>流錯誤條件並終止XML流與TCP鏈接。
3) 接收服務器應當發送一個流頭返回給源服務器,包含一個用於交互的惟一的ID:
   <stream:stream
       xmlns:stream='http://etherx.jabber.org/streams'
       xmlns='jabber:server'
       xmlns:db='jabber:server:dialback'
       id='457F9224A0...'>
      注:‘to’與‘from’屬性在根流元素中是可選的。若是命名空間名不正確,那麼源服務器必須產生一個<invalid-namespace/>流錯誤條件,並終止XML流與TCP鏈接。並且,接收服務器應當迴應,但可能根據適當的安全策略默默終止XML流與TCP鏈接。然而,若是接收服務器想要處理,它必須發送一個流頭返回給源服務器。
4) 源服務器發送一個回叫密鑰給接收服務器:
   <db:result
       to='Receiving Server'
       from='Originating Server'>
     98AF014EDC0...
   </db:result>
      注:此密鑰並不被接收服務器所檢查,由於接收服務器並不保存相關源服務器間會話信息。由源服務器產生的密鑰必須部分基於接收服務器在先前步驟提供的ID值,並部分基於源服務器與受權服務器的保密共享。若是‘to’地址值並不與接收服務器所識別的主機名匹配,那麼,接收服務器必須產生一個<host-unknown/>流錯誤條件並終止XML流與潛在的TCP鏈接。若是‘from’地址值與帶有接收服務器已經創建的鏈接的域匹配,那麼,接收服務器可能選擇爲新鏈接產生一個<not-authorized/>流錯誤條件,而後終止XML流與潛在的與新請求相關的TCP鏈接。
5) 接收服務器創建一個TCP鏈接支持由源服務器宣稱的域,做爲它鏈接到受權服務器的結果。(注意:做爲優化,一個實現可能重用一個現存的鏈接。)
6) 接收服務器發送給受權服務器一個流頭:
   <stream:stream
       xmlns:stream='http://etherx.jabber.org/streams'
       xmlns='jabber:server'
       xmlns:db='jabber:server:dialback'>
注:在根流元素中,‘to’與‘from’屬性是可選的。若是命名空間名不正確,則受權服務器必須產生一個<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鏈接。若是流錯誤發生在接收服務器與受權服務器間,則接收服務器必須產生一個<remote-connection-failed/>流錯誤條件並終止它與發起服務器間的兩個XML流與潛在的TCP鏈接。
8) 接收服務器發給受權服務器要求認證密鑰的請求:
   <db:verify
       from='Receiving Server'
       to='Originating Server'
       id='457F9224A0...'>
     98AF014EDC0...
   </db:verify>
      注:通過這兒的是來自接收服務器的流頭的主機名、源標識符,到步驟3中的發起服務器,源服務器發送給接收服務器的密鑰在步驟4。根據這些信息,還有受權服務器網絡中的共享密鑰信息,密鑰被驗證。任何驗證方法可能用於產生密鑰。若是‘to’地址值與受權服務器識別的主機名不匹配,那麼,受權服務器必須產生一個<host-unknown/>流錯誤條件並終止兩個XML與潛在的TCP鏈接。若是‘from’地址值與源服務器打開TCP鏈接時(或任意相關有效域,例如接收服務器的主機名或其它有效域一個有效子域)所表示的主機名不匹配,則受權服務器必須產生一個<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與步驟3中的接收服務器不匹配,那麼接收服務器必須產生一個<invalid-id/>流錯誤條件並終止兩個XML流與潛在的TCP鏈接。若是‘to’地址值與接收服務器所識別的主機名不匹配,則接收服務器必須產生一個<host-unknown/>流錯誤條件並終止兩個XML流與潛在的TXP鏈接。若是‘from’地址值與源服務器打開TCP鏈接時(或任意相關有效域,例如接收服務器的主機名或其它有效域一個有效子域)所表示的主機名不匹配,則接收服務器必須產生一個<invalid-from/>流錯誤條件並終止兩個XML流與潛在的TCP鏈接。返回認證信息給接收服務器以後,受權服務器應當終止他們之間的流。
10) 接收服務器通知源服務器結果:
   <db:result
       from='Receiving Server'
       to='Originating Server'
type='valid'/>
      注:在這裏,鏈接可經過一個type='valid'或報告爲無效來被認證。若是鏈接無效,則接收服務器必須終止兩個XML流與潛在的TCP鏈接。若是鏈接被認證,數據可被源服務器發送並被接收服務器讀取;在此這前,全部發送給接收服務器的XML節應該默默被扔掉。

      前述結果是接收服務器已經認證了源服務器的身份,爲了節經過「初始流」(如,從源服務器到接收服務器的流)的XML能被源服務器發送與接收服務器能接收,爲了驗證使用「響應流」(如,從接收服務器到源服務器)實體的身份,回叫必須以相反方向完成。

      成功回叫協調後,接收服務器應當接收來自經過現存已認證鏈接的源服務器的子序列<db:result/>包(例如,認證需求發送到子域或其它由接收服務器服務主機名);這使在一個方向上的原來的已認證鏈接的"piggybacking"成爲可能。

      即便回叫協調成功,服務器必須認證從其它服務器接收的XML節,包括‘from’屬性與‘to’屬性;若是一個節並不知足此限制,接收節的服務器必須產生一個<improper-addressing/>流錯誤條件並終止兩個XML流與潛在的TCP鏈接。進一步講,服務器必須認證從其它服務器,包括流的一個已驗證域的‘from’屬性;若是節並不知足此限制,收到節的服務器必須產生一個<invalid-from/>流錯誤條件並終止兩個XML流與潛在的TCP鏈接。這兩個檢查有助於阻止關聯到特別節的哄騙。

9.XML節
      TLS協商(5節)後,若是須要SASL協商(6節)與資源綁定(7節),XML節可經過流來發送。定義了三種XML節用於'jabber:client'與'jabber:server'命名空間:<message/>, <presence/>, and <iq/>。另外,這種節有五個通用屬性。這些通用屬性,像三種節的基本語義同樣,都定義在此;與即時消息與表示應用相關的XML節的更詳細信息在[XMPP-IM]中提供。

9.1通用屬性
      如下五個屬性對message, presence與IQ均通用:

9.1.1 to
      ‘to’屬性指定接收節的JID。
      在‘jabber:client’命名空間中,節應當處理‘to’屬性,雖然,由服務器處理的從客戶端到服務器端的節不該該擁有‘to’屬性。
      在'jabber:server'命名空間中,節必須擁有‘to’屬性;若是服務器收到一個不知足此限制的節,它必須產生一個<improper-addressing/>流錯誤條件並終止兩個XML流與錯誤服務器的潛在鏈接。
      若是‘to’屬性無效或不能鏈接,發現此事實的(一般是發送的或接收的服務器)實體必須返回一個合適的錯誤給發送者,設置錯誤節的‘from’屬性爲錯誤服務器提供的‘to’屬性值。

9.1.2 from
      ‘from’屬性指明發送者的IID。
      當服務器收到一個在由'jabber:client'命名空間認證的已受權流的上下文中的XML節,它必須作如下事件之一:
1) 驗證客戶端提供的‘from’屬性值就是用於聯合實體的已鏈接資源的值。
2) 加一個‘from’地址值給節,此節的值是裸JID(<node@domain>)或全JID(<node@domain/resource>),這些JID由服務器決定用於產生節的已聯接資源(看地址決定(3.5節))。

        若是一個客戶端試圖發送‘from’屬性並不匹配實體的已聯接資源的XML節,服務器應該返回一個<invalid-from/>流錯誤給客戶端。若是一個客戶端試圖經過一個流來發送一個還未受權的XML節,服務器應當返回一個<not-authorized/>流錯誤給客戶端。若是產生了,這些條件都必須關閉流並終止潛在的TCP鏈接;這有助於阻止來自於欺詐客戶端的否定服務攻擊。
        當一個服務器產生一個來自於服務器自己的節,用於傳送到一個已鏈接的客戶端(例如:在由服務器表明客戶端提供的數據存儲服務的上下文中),節必須既(1)不包括‘from’屬性或(2)包括‘from’屬性,其值是賬戶的裸JID(<node@domain>)或客戶的全JID(<node@domain/resource>)。服務器不許發送給客戶端一個不包括‘from’屬性的節,它必須設想節是從服務器到已鏈接客戶端。
        在'jabber:server'命名空間中,一個節必須處理一個‘from’屬性;若是服務器收到不知足此限制的節,它必須產生一個<improper-addressing/>流錯誤條件。更進一步,包含在‘from’屬性中的JID的域標識符部分必須匹配發送服務器(或任何已認證相關域,如發送服務器的主機名或其它由發送服務器已認證域)的主機名,當在SASL協商或回叫協商通訊中;若是一個服務器收到一個不知足此約束的節,它必須產生一個<invalid-from/>流錯誤條件。這些條件都必須關閉流並終止潛在的TCP鏈接;這有助於阻止欺詐服務器的否定服務攻擊。

9.1.3 id
      可選‘id’屬性可能由發送實體因內部跟蹤收發(特別是跟蹤固有在IQ節語義中的請求-響應交互)節而使用。對值‘id’屬性來講,它是可選的惟一全局的,在域內的或流中的。IQ節語義強加了其它約束;看IQ語義(9.2.3)。

9.1.4 type
      類型域屬性指定目的或消息上下文,出席或IQ節的詳細信息。‘type’屬性的特別容許值依賴節是不是一個消息,出席,或IQ;消息與出席節的值是特別用於即時消息與出席應用的,並所以定義義在[XMPP-IM],然而IQ節的值特指IQ節在一個結構化的請求-響應「會話」中的角色,並所以定義在如下IQ語義(9.2.3節)。對三種節僅有的一個通用‘type’值是「error」;看節錯誤(9.3節)。

9.1.5 xml:lang
      此節應當處理一個‘xml:lang’屬性(定義在[XML]2.2節),若是節包含傾向於表示到一我的類用戶(RFC2277[CHARSET]中有解釋,「對人的國際化」)的XML字符數據。‘xml:lang’屬性值指定任意人類可讀XML字符數據的缺省語言,可能被特定的子元素的‘xml:lang’屬性覆蓋。若是節沒有‘xml:lang’屬性,實現必須設想爲流指定的缺省語言已在如下流屬性(4。4節)中定義。‘xml:lang’屬性的值必須是一個NMTOKEN並必須聽從定義在3066[LANGTAGS]中的格式。

9.2基本語義
9.2.1消息語義
      <message/>節種類可被看做「推」機制,一個實體推信息給其它實體,與EMAIL系統中發生的通訊相似。全部消息節應該擁有‘to’屬性,指定有意的消息接收者;根據接收到那樣的一個節,服務器應該路由或傳送它到有意的接收者(參考服務器處理用於相關XML節的通用路由與傳送規則XML節的規則(10節))。

9.2.2 出席語義
      <presence/>元素可被看做基本廣播或「出版-訂閱」機制,多實體收到他們已訂閱(在這種狀況下,網絡可利用信息)實體的信息。總的來講,出版實體應該發送一個不帶‘to’屬性的出席節,在這種狀況下,與此實體相連的服務器應該廣播或複用節給全部訂閱實體。然而,一個出版實體也可能發送一個帶有‘to’屬性的出席節,此種狀況下,服務器應該路由或傳送節到有意的接收者。參考處理XML節(10節)的服務器規則,用於通用路由與相關XML節的傳送規則,而且用於即時消息與出席應用的出席-特定規則[XMPP-IM]。

9.2.3 IQ語義
      信息/請求,或IQ,是一個請求-響應機制,與[HTTP]在某些方面類似。IQ語義讓一個實體向其它實體請求或接收其它實體的響應成爲可能。請求與響應的數據內容由IQ無素的直接子元素的命名空間聲明定義,而且,交互由請求實體經過使用‘id’屬性來跟蹤。所以,IQ交互聽從結構化數據交換的一個通用模式,此交換例如獲得/結果或設置/結果(雖然若是合適的話,對一個請求的響應可能會以錯誤返回):

   Requesting                 Responding
     Entity                     Entity
   ----------                 ----------
       |                           |
       | <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’屬性是須要的。值必須是如下之一:
*get——節是一個用於信息或需求的請求。
*set——節提供所需數據,設置新值,或替換現存值。
*result——節是成功獲得或設置請求的響應。
*error——先前發送獲得或設置的相關過程或傳送的錯誤(參考節錯誤(9.3節))。
3) 收到類型爲「get」或「set」的IQ請求的實體必須以類型爲「result」或「error」的IQ響應來響應(響應必須保留請求的‘id’屬性)。
4) 收到類型爲「result」或「error」的節不許靠發送一個進一步的類型爲「result」或「error」的IQ響應節來響應;然而,如以上顯示,請求實體可能發送另外一個請求(如:一個類型爲「set」的IQ,爲了提供經過獲得/結果對發現的所需的信息)。
5) 類型爲「get」或「set」的IQ節必須包含一個並僅有一個子元素,指定特別的請求或響應語義。
6) 一個類型爲「result」的IQ節必須包含0或一個子元素。
7) 類型爲「error」類型的IQ節應當包含在相關「get」或「set」子元素中,而且,必須包含一個<error/>子元素;詳細信息,參考節錯誤(9.3節)。

9.3 節錯誤
      節相關錯誤以相似流錯誤(4.7節)的方式處理。然而,不像流錯誤,節錯誤不但是不可恢復的;所以,暗含相關源發送者行爲的錯誤節能按順序糾正錯誤。

9.3.1 規則
      如下規則應用於節相關錯誤:
1) 檢測相關節錯誤條件的接收或處理實體必須返回給發送實體一個同種節(消息,出席或IQ),它的‘type’屬性被設置成值「error」(那樣的節在此被稱爲「錯誤節」)。
2) 產生錯誤節的實體應當包含被送的源XML,爲了發送者可以檢測,而且,若是必要的話,在試圖重送前糾正XML。
3) 一個錯誤節必須包含一個<error/>子元素。
4) 一個<error/>子元素不許被包括,若是‘type’屬性有不止一個「錯誤」值(或無‘類型’屬性)。
5) 接收一個錯誤節的實體不許響應帶有進一步錯誤節的節;這有助於阻止循環。

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

      節種類是消息、出席或iq之一。
<error/>元素的‘type’屬性值必須是如下之一:
*cancel——不重試(錯誤不可恢復)
*continue——進行(僅是一個警告條件)
*modify——改變數據發送後重試
*auth——提供信任後重試
*wait——等待以後重試(錯誤是臨時的)

      <error/>元素:
      必須包含一個子元素,此子元素與如下指定的已定義的節錯誤條件一致;此元素必須被'urn:ietf:params:xml:ns:xmpp-stanzas'命名空間所認證。
      可能包含<text/>子元素,此子元素包含XML字符數據,用於描繪更細節的錯誤;此元素必須被'urn:ietf:params:xml:ns:xmpp-stanzas'命名空間所認證,而且應該擁有一個'xml:lang'屬性。
      可能包含一個子元素,用於特殊-應用錯誤條件;此元素必須由一個已定義-應用命名空間認證,而且,它的結構由此命名空間定義。

      <text/>元素是可選的。若是包括在內,它應當僅用於提供描述性或診斷性信息,這些信息用於補充已定義條件或特殊-應用條件的意思。它不該當由應用程序性的描述。它不該當用做向用戶表達的錯誤信息,但可能顯示除與包含條件元素(或元素們)相關的錯誤消息。

      最後,爲維護向後兼容性,此方案(在[XMPP-IM]中指定的)容許可選的在<error/>元素中包含‘code’屬性。

9.3.3 已定義條件
      如下條件被定義用於節錯誤。

<bad-request/>——發送者已發送畸形的或不能被處理的(例如,一個包含未識別‘type’屬性值的IQ節)XML;相關錯誤類型應當是「modify」。

<conflict/>——訪問不被受權,由於一個現存資源或會話以一樣名字或地址存在;相關錯誤類型應當是「cancel」。

<feature-not-implemented/>——被請求特徵未被接收者或服務器實現,而且所以不能被處理;相關錯誤類型應當是「cancel」。

<forbidden/>——請求實體不擁有執行行爲的所需許可;相關錯誤類型應當是「auth」。

<gone/>——接收者或服務器不在以此地址聯繫(錯誤節可能包含一個新地址在<gone/>元素的XML字符數據中);相關錯誤類型應當是「modify」。

<internal-server-error/>——服務器不能處理節,由於錯誤配置或一個另外-未定義內部服務器錯誤;相關錯誤類型應當是「wait」。

<item-not-found/>——JID地址或被請求項不能被發現;相關錯誤類型應當是「cancel」。

<jid-malformed/>——已提供的發送實體或與一個XMLL地址(例:‘to’屬性值)通訊或其它方面(例:資源標識符)與地址方案(3節)中定義的語法不符;相關錯誤類型應當是「modify」。

<not-acceptable/>——接收者或服務器理解請求,但拒絕處理它,由於它不知足由接收者或服務器(例:消息中相關可接受字的本地策略)所定義的標準;相關錯誤類型應當是「modify」。

<not-allowed/>——接收者或服務器不容許任何實體執行動做;相關錯誤類型應當是「cancel」。

<not-authorized/>——發送者必須在被容許執行動做前提供合適的信任,或已經提供不合適的信任;相關錯誤類型應當是「auth」。

<payment-required/>——請求實體未受權去訪問被需求服務,由於須要付費;相關錯誤類型應當是「auth」。

<recipient-unavailable/>——有意的接收者臨時不可用;相關錯誤類型應當是「wait」(注:一個應用不許返回此錯誤,若是這樣作將提供關於意向接收 者對未受權知道此類信息的實體的網絡可利用性信息)。

<redirect/>——接收者或服務器爲此信息重定向請求到其餘實體,一般是臨時的(錯誤節應當包含可替換地址,必須是一個有效的JID,在<redirect/>元素的XML字符數據中);相關錯誤類型應當是「modify」。

<registration-required/>——請求實體未被受權訪問所請求服務,由於須要註冊;相關錯誤類型應當是「auth」。

<remote-server-not-found/>——一個指定做爲意向接收者的部分或所有的JID的遠程服務器或服務不存在;相關錯誤類型應當是「cancel」。

<remote-server-timeout/>——一個指定做爲意向接收者(或被請求去執行一個請求)的部分或所有的JID的遠程服務器或服務不能在一個合理的時間內被聯繫到;相關錯誤類型應當是「wait」。

<resource-constraint/>——服務器或接收者缺乏必要的系統資源去服務請求;相關錯誤類型應當是「wait」。

<service-unavailable/>——服務器或接收者當前並不提供所請求的服務;相關錯誤類型應當是「cancel」。

<subscription-required/>——請求實體不被受權訪問被請求服務,由於須要訂閱;相關錯誤類型應當是「auth」。

<undefined-condition/>——錯誤條件並非此列表中由其它條件定義的那些之一;任何錯誤類型可能與此條件相關,而且,它應當僅用於與一個特殊-應用條件相連。

<unexpected-request/>——接收者或服務器理解請求,但此時(例:請求無序/請求不在狀態)並不指望它;相關錯誤類型應當是「wait」。

9.3.4 特殊-應用條件
      像所知道的,一個應用可能靠包含一個錯誤元素中的合適的-命名空間的子元素來提供特殊-應用節錯誤信息。特殊-應用元素應當補充或進一步認證一個已定義元素。所以,<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>

10. 處理XML節的服務器規則
      兼容服務器實現必須確保有序處理任兩實體間的XML節。
超出有序處理的需求,每一個服務器實現將包含它本身的「傳送樹」用於處理它所接收的節。那樣的一個樹決定是否一個節須要被路由到其它域,內部處理,或傳送到與被連節點相關的資源。如下規則應用:

10.1 無‘to’地址
      若是節擁有無‘to’屬性,服務器應當表明發送它的實體處理它。由於全部從其它服務器收到的節必須擁有一個‘to’屬性,此規則僅應用於從一個連到服務器的已註冊實體(如客戶端)收到的節。若是服務器收到一個無‘to’屬性的出席節,服務器應當廣播它到被訂閱到發送實體的出席實體,若是可利用的話(用於定義在[XMPP-IP]即時消息與表示應用的出席廣播的語義。)若是服務器接收一個類型爲「get」或「set」的沒有‘to’屬性的IQ節,而且它理解認證節內容的命名空間,它必須也能表明發送實體處理節或返回給發送實體(在「process」意思處被認證命名空間的語義決定)一個錯誤。

10.2 外部域
      若是JID的域標識符部分的主機包含在‘to’屬性中並不匹配服務器自己的已配置主機名或子域中的已配置主機之一,服務器應當路由節到外部域(服從本地服務提供與相關內部域通訊的安全策略)。有兩種可能狀況:

      一個服務器到服務器流已在兩域間存在:發送者的服務器爲現存流的外部域路由節到已受權服務器。

      兩域間存在無主機到主機流:發送者的服務器(1)解析外部域(定義在如下服務器到服務器通訊(節14。4))的主機名,(2)在兩域間(定義在以下使用TLS(節5)而且使用SASL(節6))協商服務器到服務器的流,並(3)爲經過新近-創建的流的外部域路由節到受權服務器。

      若是路由到接收者的服務器不成功,發送者的服務器必須返回一個錯誤給發送者;若是接收者的服務器能被聯繫但被接收者的服務器傳送到接收者是不成功的,接收者的服務器必須經由發送者的服務器返回一個錯誤給發送者。

10.3 子域
      若是包含在‘to’屬性中的JID域標識符部分的主機名匹配服務器自己已配置主機名之一的子域,服務器必須也處理節自己或路由節到一個特別的對那個子域(若是子域被配置)有責任的服務,或返回一個錯誤給發送者(若是子域不被配置)。

10.4 僅有域或特別資源
      若是包含在‘to’屬性中的JID域標識符部分的主機名匹配服務器自己的一個已配置主機名,而且包含在‘to’屬性中的JID是<domain>或<domain/resource>形式,服務器(或在內的一個已定義資源)必須合乎節種類處理節或返回錯誤節給發送者。

10.5 同域中的節點
      若是包含在‘to’屬性中的JID域標識符部分的主機名匹配服務器自己的一個已配置主機名,而且包含在‘to’屬性中的JID是<node@domain>或<node@domain/resource>形式,服務器應當傳送節到由包含在‘to’屬性中的JID表達的節的意向接收者。如下規則應用:

1) 若是JID包含一個資源標識符(例:是<node@domain/resource>形式)而且,這兒存在一個已鏈接資源匹配全JID,接收者的服務器應當傳送的節到確切匹配此資源標識符流或會話。
2) 若是JID包含一個資源標識符而且這兒存在匹配全JID的無鏈接資源,接收者的服務器應當返回一個<service-unavailable/>節錯誤給發送者。
3) 若是JID是<node@domain>形式,而且這兒存在爲此結點的至少一個已鏈接資源,接收者的服務器應當傳送節到鏈接資源的至少一個,根據應用-特殊規則(一套傳送規則,用於定義在[XMPP-IM]即時消息與出席應用)。

11. XMPP內的XML使用

11.1 約束
      XMPP是流XML元素的一個簡單與特殊的協議,用來近實時的交換結構化信息。因爲XMPP不須要任意分析與完整XML文檔,這兒沒有XMPP須要支持[XML]全特徵的需求。特別的,如下約束應用。

      關於XML產生,一個XMPP實現不許注入如下任意一個XML流:
*評論(定義在[XML]節2。5)
*處理說明(2。6節)
*內部或外部DTD子集(2。8節)
*除了預約義實體(4。6節)的內部或外部實體參考。
*包含映射到預約義實體(4。6節)保留字符的字符數據或屬性值;那樣的字符必須被避免

      關於XML處理,若是一個XMPP實現接收到那樣的約束XML數據,它必須忽略此數據。

11.2 XML命名空間名與前綴
      XML命名空間[XML-NAMES]被用在全部與XMPP-兼容的XML中,去建立數據擁有權的嚴格界限。命名空間的基本功能是分離結構的混合在一塊兒的XML元素的不一樣詞彙。確保XMPP-兼容XML是命名空間-瞭解使任意容許的XML可以與XMPP中的任意數據元素結構化的混合。XML命名空間名與前綴的規則定義在如下子部分。

11.2.1 流命名空間
      流命名空間聲明在全部XML流頭中都是須要的。流命名空間名必須是'http://etherx.jabber.org/streams'。<stream/>元素與它的<features/>與<error/>子元素的元素名必須被全部實例中的流命名空間認定合格。一個實現應當爲那些元素產生僅有的'stream:'前綴,而且由於歷史緣由可能接受僅有的'stream:'前綴。

11.2.2 缺省命名空間
      缺省命名空間聲明是須要的,而且用在全部XML流中,爲了定義容許的根流元素的第一級子元素。此命名空間聲明必須與初始流與響應流相同,爲了兩個流一致的被認證合格。缺省命名空間聲明應用於流與全部在由其它命名空間認證合格的流(除非由另外一命名空間顯示認定合格,或由流命名空間或回叫命名空間前綴認證)中發送的節。

      服務器實現必須支持如下兩個缺省命名空間(因爲歷史緣由,一些實現可能支持僅有的那些兩個缺省命名空間):
*jabber:client——缺省命名空間,當流用於客戶端與服務器通訊時所聲明的。
*jabber:server——缺省命名空間,當流用於兩服務器間通訊時聲明的。

      客戶端實現必須支持'jabber:client'缺省命名空間,而且因爲歷史緣由可能只支持缺省命名空間。

      實現不許爲缺省命名空間中的元素產生命名空間前綴,若是缺省命名空間是'jabber:client'或'jabber:server'。一個實現不該當爲元素產生命名空間前綴,元素由'jabber:client'與'jabber:server'以外的內容(與流相反)命名空間認證的。

      注:'jabber:client'與'jabber:server'命名空間是接近同一的,但用在不一樣的上下文中(客戶端到服務順通訊用'jabber:client'與服務器到服務器通訊用'jabber:server')。這兩個僅有的不一樣是‘to’與‘from’屬性在'jabber:client'中發送的節中是可選的,然而在'jabber:server'中發送的節是必須的。若是一個兼容實現接受一個由'jabber:client'或'jabber:server'命名空間認證合格的流,它必須支持全部三個核心節種類的(消息,出席,與IQ)通用屬性(9。1節)與基本語義(9。2節)。

11.2.3 回叫命名空間
      回叫命名空間聲明對於全部用在服務器回叫(8節)中的元素都是須要的。回叫命名空間的名字必須是'jabber:server:dialback'。全部由這個命名空間認證合格的元素必須被加前綴。一個實現應當爲那種元素僅產生'db:'前綴並可能接受僅有的'db:'前綴。

11.3 確認(驗證)
      除了'jabber:server'命名空間中節的相關‘to’與‘from’地址,服務器不爲轉發到客戶端或另外一個服務器的XML元素負責;一個實現可能選擇提供僅有的認證數據元素,但這是可選的(雖然一個實現不許接受XML,那也不是好格式)。客戶端不該當依賴此能力去發送數據,這些數據與方案並不符,而且應當忽略一個來的XML流中的非構造元素或屬性。XML流與節的驗證是可選的,包含在此的方案僅用於描述目的。

11.4 包含文本聲明
      實現應當在發送流頭以前發送文本聲明。應用必須遵循文本聲明包含在內的相關環境的[XML]中的規則。

11.5 字符編碼      實現必須支持UTF-8 (RFC 3629 [UTF-8])統一字符集(ISO/IEC 10646-1 [UCS2])字符傳輸,RFC 2277 [CHARSET]中查。實現不許試圖使用其它編碼。

相關文章
相關標籤/搜索