閱讀187 返回首頁    go 技術社區[雲棲]


xmpp即時通訊二

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/>--流命名空間名不隻是https://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='https://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='https://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='https://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='https://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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步2:服務器以發送給客戶端一個流標記作為響應:
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='https://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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步7(代替 ):如果TLS協商不成功,服務器關閉TCP連接。
步8:服務器靠發送帶有任何可利用流特征的流頭給客戶端作為響應。
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='https://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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步2:Server2發送一個流標記給Server1作為響應:
   <stream:stream
       xmlns='jabber:server'
       xmlns:stream='https://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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步7(替代):如果TLS協商不成功,Server2關閉TCP連接。
步8:Server2靠發送一個帶有任何可利用流特征的流頭給Server1:
   <stream:stream
       xmlns='jabber:server'
       xmlns:stream='https://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)

最後更新:2017-04-03 12:54:49

  上一篇:go [LeetCode]*137.Single Number II
  下一篇:go android 之ndk開發