閱讀805 返回首頁    go 阿裏雲 go 技術社區[雲棲]


xmpp即時通訊三

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='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_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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步11:服務器通過發送流頭來響應客戶端,伴隨有任意另外的特征(或空特征元素):
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='https://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='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_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='https://etherx.jabber.org/streams'
       to='example.com'
       version='1.0'>
步11:Server2通過發送一個流頭響應Server1,並伴隨著其它特征(或空特征元素):
   <stream:stream
       xmlns='jabber:client'
       xmlns:stream='https://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='https://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='https://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='https://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='https://etherx.jabber.org/streams'
       xmlns='jabber:server'
       xmlns:db='jabber:server:dialback'>
注:在根流元素中,‘to’與‘from’屬性是可選的。如果命名空間名不正確,則授權服務器必須產生一個<invalid-namespace/>流錯誤條件並終止兩個XML流與潛在的TCP連接。
7) 授權服務器發送給接收服務器一個流頭:
   <stream:stream
       xmlns:stream='https://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連接。這兩個檢查有助於阻止關聯到特別節的哄騙。

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

  上一篇:go C#之簡單工廠模式與多態性
  下一篇:go 在 Windows 下為 PHP 5.4 安裝 PEAR、PHPUnit 及 phpDoc2