`

Jabber核心协议(XMPP Core :RFC3920)

    博客分类:
  • XMPP
阅读更多

1、 /XML StanzaXML Stream
Stream :以<stream>开始,至</stream>结束,在整个生命周期中,可以包含任意数量的XML元素
Stanza:Stream中结构化的XML片断
整个流看起来大致如下:
|--------------------|
| <stream>           |
|--------------------|
| <presence>         |
|   <show/>          |
| </presence>        |
|--------------------|

| <message to='foo'> |
|   <body/>          |
| </message>         |
|--------------------|
| <iq to='bar'>      |
|   <query/>         |
| </iq>              |
|--------------------|
| ...                |
|--------------------|
| </stream>          |
|--------------------|
 
 
2、 Stream Attributes
to :用于发起方stream 中(initial stream),表明接收者,响应Stream不能包含to,如果有则被忽略;
from :用于响应Stream中(response stream),表明接收者,发起方Stream不能包含from,如果有则被忽略;
id :用于响应Stream中,唯一性标识,出于安全性考虑,建议随机生成;
xml:lang:缺省语言
version:版本号,通常为1.0
 
3、 Stream Error:
当遇到有stream级别的错误时,需要发送一个<error/>tag,具体语法如下:
<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>
 
defined-condition举例:<xml-not-well-formed/>、<not-authorized/>、<bad-format/>、<host-unknown/>等
 
4、 Transport Layer Security (TLS) protocol
当一个Stream被发起以后,需要通过TLS来保证连接的安全性,下面是一个从客户端到服务器的例子。
Step 1: Client initiates stream to server:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>
Step 2: Server responds by sending a stream tag to client:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_123'
    from='example.com'
    version='1.0'>
Step 3: Server sends the STARTTLS extension to client along with authentication mechanisms and any other stream features:
<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>
Step 4: Client sends the STARTTLS command to server:
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Step 5: Server informs client that it is allowed to proceed:
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Step 5 (alt): Server informs client that TLS negotiation has failed and closes both stream and TCP connection:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
</stream:stream>
Step 6: Client and server attempt to complete TLS negotiation over the existing TCP connection.
Step 7: If TLS negotiation is successful, client initiates a new stream to server:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>
Step 7 (alt): If TLS negotiation is unsuccessful, server closes TCP connection.
Step 8: Server responds by sending a stream header to client along with any available stream features:
<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>
Step 9: Client continues with SASL negotiation (Use of SASL).
 
5、Simple Authentication and Security Layer (SASL) protocol
在TLS之后是用户的安全认证,采用SASL协议,下面是一个从client到server的例子:
   Step 1: Client initiates stream to server:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'     version='1.0'>
Step 2: Server responds with a stream tag sent to client:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    id='c2s_234'
    from='example.com'
    version='1.0'>
Step 3: Server informs client of available authentication mechanisms:
<stream:features>
 <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>PLAIN</mechanism>
 </mechanisms>
</stream:features>
Step 4: Client selects an authentication mechanism:
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
      mechanism='DIGEST-MD5'/>
Step 5: Server sends a [BASE64] (Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” July 2003.) encoded challenge to client:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==
</challenge>
The decoded challenge is:
realm="somerealm",nonce="OA6MG9tEQGm2hh",\
qop="auth",charset=utf-8,algorithm=md5-sess
Step 5 (alt): Server returns error to client:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
 <incorrect-encoding/>
</failure>
</stream:stream>
Step 6: Client sends a [BASE64] (Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” July 2003.) encoded response to the challenge:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo
YXJzZXQ9dXRmLTgK
</response>
The decoded response is:
username="somenode",realm="somerealm",\
nonce="OA6MG9tEQGm2hh",cnonce="OA6MHXh6VqTrRk",\
nc=00000001,qop=auth,digest-uri="xmpp/example.com",\ response=d388dad90d4bbd760a152321f2143af7,charset=utf-8
Step 7: Server sends another [BASE64] (Josefsson, S., “The Base16, Base32, and Base64 Data Encodings,” July 2003.) encoded challenge to client:
<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZAo=
</challenge>
The decoded challenge is:
rspauth=ea40f60335c427b5527b84dbabcdfffd
Step 7 (alt): Server returns error to client:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
 <temporary-auth-failure/>
</failure>
</stream:stream>
Step 8: Client responds to the challenge:
<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
Step 9: Server informs client of successful authentication:
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
Step 9 (alt): Server informs client of failed authentication:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
 <temporary-auth-failure/>
</failure>
</stream:stream>
Step 10: Client initiates a new stream to server:
<stream:stream
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams'
    to='example.com'
    version='1.0'>
Step 11: Server responds by sending a stream header to client along with any additional features (or an empty features element):
<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、  Resource Binding
SASL之后便是Resource Binding,但这个只是client到server时需要,而server与server之间不需要。
    Server advertises resource binding feature to client:
<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>
If the client wishes to allow the server to generate the resource identifier on its behalf, it sends an IQ stanza of type "set" that contains an empty <bind/> element:
Client asks server to bind a resource:
<iq type='set' id='bind_1'>
 <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</iq>
A server that supports resource binding MUST be able to generate a resource identifier on behalf of a client. A resource identifier generated by the server MUST be unique for that <
node@domain>.
If the client wishes to specify the resource identifier, it sends an IQ stanza of type "set" that contains the desired resource identifier as the XML character data of a <resource/> element that is a child of the <bind/> element:
Client binds a resource:
<iq type='set' id='bind_2'>
 <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <resource>someresource</resource>
 </bind>
</iq>
Once the server has generated a resource identifier for the client or accepted the resource identifier provided by the client, it MUST return an IQ stanza of type "result" to the client, which MUST include a <jid/> child element that specifies the full JID for the connected resource as determined by the server:
Server informs client of successful resource binding:
<iq type='result' id='bind_2'>
 <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
    <jid>somenode@example.com/someresource</jid>
 </bind>
</iq>
A server SHOULD accept the resource identifier provided by the client, but MAY override it with a resource identifier that the server generates; in this case, the server SHOULD NOT return a stanza error (e.g., <forbidden/>) to the client but instead SHOULD communicate the generated resource identifier to the client in the IQ result as shown above.
When a client supplies a resource identifier, the following stanza error conditions are possible (see Stanza Errors (Stanza Errors)):
·         The provided resource identifier cannot be processed by the server in accordance with Resourceprep (Resourceprep).
·         The client is not allowed to bind a resource to the stream (e.g., because the node or user has reached a limit on the number of connected resources allowed).
·         The provided resource identifier is already in use but the server does not allow binding of multiple connected resources with the same identifier.
The protocol for these error conditions is shown below.
Resource identifier cannot be processed:
<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>
Client is not allowed to bind a resource:
<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>
Resource identifier is in use:
<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>
If, before completing the resource binding step, the client attempts to send an XML stanza other than an IQ stanza with a <bind/> child qualified by the 'urn:ietf:params:xml:ns:xmpp-bind' namespace, the server MUST NOT process the stanza and SHOULD return a <not-authorized/> stanza error to the client.
 
7、  XML Stanzas
'jabber:client'和'jabber:server'命名空间定义了三种stanza:<message/>、 <presence/>、<iq/>.
       详细定义需要学习RFC3921。
8、  实验
分别选择两个Jabber Server做连接测试:
第一个:jabber.org
telnet jabber.org 5222
<?xml version='1.0'?>
<stream:stream
       to='jabber.org'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>
收到如下内容:
<?xml version='1.0'?>
<stream:stream
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       id='94769953'
       from='jabber.org'
       version='1.0'
       xml:lang='en'>
      
       <stream:features>
              <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
              <compression xmlns='http://jabber.org/features/compress'>
                     <method>zlib</method>
              </compression>                  
              <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
                     <mechanism>DIGEST-MD5</mechanism>
                     <mechanism>PLAIN</mechanism>
              </mechanisms>
              <register xmlns='http://jabber.org/features/iq-register'/>
       </stream:features>
从返回的内容来看,基本上跟RFC3720所说一致,不过多了一个压缩?,接下来就没法进行了,看来还得研究一下压缩算法
 
第二个:talk.google.com,这个就是大名鼎鼎的Google Talk了,由于也是采用XMPP,因此也可能连接:
telnet talk.google.com 5222
<?xml version='1.0'?>
<stream:stream
       to='google.com'
       xmlns='jabber:client'
       xmlns:stream='http://etherx.jabber.org/streams'
       version='1.0'>
收到内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="google.com"
       id="8F2DEA3E08EDD09C"
       version="1.0"
       xmlns:stream="
http://etherx.jabber.org/streams"
       xmlns="jabber:client">
       <stream:features>
              <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
              <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
                     <mechanism>X-GOOGLE-TOKEN</mechanism>
              </mechanisms>
       </stream:features>
google talk倒是没采用压缩算法,不过居然是自己专用的SASL。
接下来发送:
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
收到:
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
TLS还是能够顺利进行的,接下来的就没法进行了。可以看出跟Google Talk通信是可行的,只不过需要熟悉Google Talk的扩展协议,目前暂时还没有收集这方面的资料。

 

分享到:
评论

相关推荐

    中文版 xmpp协议之 可扩展消息出席协议:核心 RFC3920

    XMPP协议最初是由Jabber开源社区在1999年开发的,后来在2002年被XMPP工作组改写并提交至IETF(Internet Engineering Task Force,互联网工程任务组),进而演变成RFC3920标准。 XMPP协议定义了核心的即时消息与出席...

    RFC3920 - Jabber XMPP中文版

    《深入解析RFC3920:Jabber XMPP的核心协议》 一、核心概念与架构 1. **概述**:RFC3920详细介绍了可扩展消息和出席信息协议(XMPP)的核心功能,该协议通过XML流实现在任意两个网络终端之间进行接近实时的结构化...

    xmpp 协议介绍(rfc3920)

    《XMPP:核心协议》(RFC3920)是一份由互联网工程任务组(IETF)发布的文档,该文档详细介绍了Extensible Messaging and Presence Protocol(可扩展消息与呈现协议,简称XMPP)的核心功能。XMPP是一种基于流式的XML...

    XMPP正式RFC标准3920

    ### XMPP正式RFC标准3920:可扩展的消息与出席信息协议 #### 概述 **XMPP正式RFC标准3920**是互联网工程任务组(IETF)发布的一项标准,它定义了可扩展消息与出席信息协议(XMPP)的核心功能,该协议允许在任意两...

    XMPP-RFC3920中文

    **XMPP协议概述** XMPP的设计目标是通过XML流实现实时信息交换,用于即时消息、出席状态更新以及请求-响应服务。它的主要特点在于其可扩展性,允许开发者构建各种应用程序以满足不同需求。 ### 2. **通用架构** ...

    RFC3920:核心协议.doc

    【RFC3920:核心协议】文档详细阐述了可扩展的消息和出席信息协议(XMPP)的核心功能,这是互联网标准跟踪协议的一部分,用于实时消息传递和出席信息的交换。XMPP利用XML流来实现在互联网上的即时通信,提供了一个...

    xmpp-RFC3920中文翻译版.doc

    RFC3920定义了XMPP的核心部分,即XMPP Core,它为即时消息和在线状态的应用提供了基础性的框架和支持。 #### 二、XMPP核心功能 **核心功能**:根据RFC3920文档,XMPP的核心功能包括XML流、TLS(Transport Layer ...

    XMPP协议之RFC6120

    RFC6120文档详细介绍了XMPP协议的核心技术细节,并且在文档的1.1节概述了XMPP的架构,包括全球地址、存在、持久连接和结构化数据等概念。在1.2节中回顾了XMPP的历史,1.3节总结了其功能概要,而1.4节定义了在文档中...

    jabber/xmpp技术研究与应用

    Jabber/XMPP(eXtensible Messaging and Presence Protocol)是一种基于XML的即时消息传递和在线状态服务协议。它最初由Jabber开发,后被IETF采纳为正式标准。该协议的核心优势在于其开放性、灵活性以及跨平台的特性...

    RFC3920中文翻译版.pdf

    RFC3920是XMPP协议的官方文档,描述了协议的详细技术标准和要求。其内容广泛,包括了从协议的基本架构、地址空间、到TLS(传输层安全协议)和SASL(简单认证与安全层协议)的使用,资源绑定,服务器回拨,以及XML的...

    xmpp协议(中文翻译版)

    在给定的描述中,提到了以下几份RFC文档,它们是XMPP协议核心规范的重要组成部分: 1. RFC3920:这是XMPP的核心协议之一,全称为“XMPP Core”。它定义了XMPP网络协议的基础架构,包括TCP连接、流管理、安全性和...

    RFC3920可扩展消息出席协议

    RFC3920定义的XMPP协议为即时通讯领域带来了革命性的变化,它不仅提供了一个强大且灵活的消息传递平台,还促进了跨平台、跨协议的即时消息与出席服务的整合。通过其开放性、可扩展性和标准性,XMPP成为了众多即时...

    xmpp rfc 3920

    RFC 3920定义了XMPP的核心特性,并被确立为互联网标准跟踪协议之一。该文档强调了XMPP的国际化考虑,确保不同语言和地区能够有效利用该协议。 #### 五、安全考量 由于XMPP设计用于实时通信,因此安全性尤为重要。...

    RFC3920(XMPP)中文翻译版

    ### RFC3920(XMPP)中文翻译版——核心知识点解析 #### 一、概述与背景 **RFC3920**定义了**可扩展的消息和出席信息协议(XMPP)**的核心功能,该协议利用XML流实现任意两个网络终端间的接近实时交换结构化信息。...

    RFC6120 - Jabber_XMPP中文版

    可扩展的消息和出席信息协议(XMPP)是一个XML... 本文定义了XMPP的核心协议方法: XML流的配置和解除, 通道加密, 验证, 错误处理, 以及消息通讯基础, 网络可用性 ("presence"), 和 请求-应答 交互. 本文取代了 RFC 3920

    xmpp-php:用于XMPP(Jabber)协议PHP客户端库

    XMPP(Jabber)协议PHP客户端库 这是一种低级套接字实现,由于缺少在线此类库,使PHP能够与XMPP进行通信(至少我可以找到具有不错文档的库)。 XMPP核心文档可以在找到。 安装要求和示例 项目要求在composer.json ...

    jabber协议分析及开发文档

    包含①《Instant Messaging in Java,The Jabber Protocols》、②《Developing Applications Using Jabber》、③RFC-3920、④RFC-3921。 ①英文文档,详细分析jabber协议。This book is dedicated to the Jabber ...

    RFC6120(中文版)Jabber_XMPP.rar

    可扩展的消息和出席信息协议(XMPP)是一个XML... 本文定义了XMPP的核心协议方法: XML流的配置和解除, 通道加密, 验证, 错误处理, 以及消息通讯基础, 网络可用性 ("presence"), 和 请求-应答 交互. 本文取代了 RFC 3920

    XMPP协议中文参考指南

    在 XMPP 协议中,XML 节的语法符合 'jabber:client' 和 'jabber:server' 名字空间的 XML 节的基本语义和通用属性已经在 RFC 3920 中定义了。消息语法符合 'jabber:client' 或 'jabber:server' 名字空间的消息节用于 ...

Global site tag (gtag.js) - Google Analytics