XMPP and Chat Server – Step by Step

i spend time to read through the XMPP core protocol. @http://xmpp.org/rfcs/rfc3920.html.

Things need to know about XMPP.

1. Client and server communicate through port 5222 via a TCP connection. 2. XMPP informations are contained on XML streams. A XMPP session is opened by <stream> tag and ended by </stream> tag.  All other parts are located between them. 3. For security purpose, the open stream is followed by moderate Transpor Layer Security (TLS)  negotiation and compulsory Simple Authentication and Security Layer (SASL) negotiation. 4. A new stream will be opened immediately after the SASL negotiation, and it will be more securit and safe.

How XMPP works step by step

Step 1: Open stream

Client: Clients send a open stream packet to server to request a new session. <stream:stream       to=’example.com’       xmlns=’jabber:client’       xmlns:stream=’http://etherx.jabber.org/streams’       version=’1.0′> where “example.com” is domain name of XMPP server connected to.

Server: Server sends back a XML stream starts with <stream:freatures>, includes requirements of either TLS  or SASL negotiation, or both.

<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>   <mechanism>EXTERNAL</mechanism>  </mechanisms> </stream:features>

Step 2: Encryption and Authorization.

2.1 If server needs TLS negotiation.

Client: Clients send a STARTTLS to server. <starttls xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/> Server: Server sends back a message shows the TLS is allowed: <proceed xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/> or failed: <failure xmlns=’urn:ietf:params:xml:ns:xmpp-tls’/> </stream:stream> In case of failure, the server closed the TCP connect.

Client: If TLS is processed, then clients request a new session: <stream:stream    xmlns=’jabber:client’    xmlns:stream=’http://etherx.jabber.org/streams’    to=’example.com’    version=’1.0′>

Server: Server responses a XML stream indicating the needs of SASL negotiation. <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>

2.2 SASL negotiation

Client needs to choose an authentication method available from server to carry out SASL negotiation. In case above, “DIGEST-MD5“, “PLAIN” and “EXTERNAL” are options.

The “PLAIN” authorization method is the simplest among them. It works as following.

Client: Client send a stream with selected authorization method with base64 encoded user name and password. The user name and password are allocated in format of “UserNamePassword”.

For example, i would like to log on as “mbed@ceit.org”, whose password is “mirror”. And, the string to be send to encoder is “mbedmirror”, and the encoded string is “AG1iZWQAbWlycm9y”.

Then, the client sends the following stream to server. <auth xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’ mechanism=’PLAIN’>AG1iZWQAbWlycm9y</auth>

Server: If the server accept the authorization, it sends back a stream with “success” tag. <success xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/> or: Server: If the password does not match the user name, or there is an error on encoding, the server will sends a failure stream. <failure xmlns=’urn:ietf:params:xml:ns:xmpp-sasl’/>

Details of “DIGEST-MD5” authorization can be found at http://www.ietf.org/rfc/rfc2831.txt.

Round 3 Resource binding (Optional)

Client: Client asks server to bind a resource: <iq type=’set’ id=’bind_1′> <bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’/> </iq>

or: Client: Client binds a resource: <iq type=’set’ id=’bind_2′>

<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>

<resource>someresource</resource>

</bind>

</iq>

Server: Server sends back another <iq> stanza, if the “type” tag is “result”, that means the binding is successful, otherwise, it is failed. <iq type=’result’ id=’bind_2′>

<bind xmlns=’urn:ietf:params:xml:ns:xmpp-bind’>

<jid>somenode@example.com/someresource</jid>

</bind>

</iq>

Step 4: Request a new session

Immediately after SASL negotiation or optional resource binding, clients must establish a session to start instant messaging.

Client: Client request session with server: <iq to=’example.com’     type=’set’     id=’sess_1′>   <session xmlns=’urn:ietf:params:xml:ns:xmpp-session’/> </iq>

Server: Server sends back a iq stanza showing whether session has been created successful or not.

The successful message will be like: <iq from=’example.com’     type=’result’     id=’sess_1’/>

If the server failed to create a session, it will reply a message like below or other type of error messages. <iq from=’example.com’ type=’error’ id=’sess_1′>    <session xmlns=’urn:ietf:params:xml:ns:xmpp-session’/>    <error type=’auth’>      <forbidden          xmlns=’urn:ietf:params:xml:ns:xmpp-stanzas’/>    </error>  </iq>

Step 5: client and server exchange XMPP stanzas

If all steps above are successful, then client can send XMPP stanzas to server and receive XML streams. Client can send <iq> stanzas to request roster or other information from server, and use <presence> stanzas to change its presence status. Instance message and other payload can be send via <message> stanzas.

Step 6: close stream

Finally, if clients want to finish the talk and close the XMPP session, it needs to send a close stream to server. <presence type=’unavailable’/> </stream:stream>

Then, server will change client’s presence to “Offline” and close TCP connections with clients.

Add a Comment

Your email address will not be published. Required fields are marked *