Programming XMPP Clients

From XMPP WIKI
Revision as of 11:38, 29 March 2012 by MattJ (talk | contribs) (Add warning to auth section about legacy auth)
Jump to navigation Jump to search

Basic Notes

You must know there is:

  1. <iq/> - for command exchanges
  2. <message/> - to transfer messages ;)
  3. <presence/> - to exchange presence information

You can send these items only within a XML stream. Usually these items should also contain:

  1. to - where the item should be delivered (example: to='user2@server2.com' or to='service3.server4.org')
  2. id - as identification for this item (important for iq)
  3. type - in example get, set, result, error as the basic types in a iq

Sounds complicate? Nah, it is not ;) You will know when the time comes...

In case an item does not contain a to the item will be delivered to user's own Jabber server!

Connecting to a server

Usually a Jabber server listens on port 5222 (TCP). As soon as you have connected and established a XML stream the server expects authentification as a user (#The log-in-process (aka authentication with a server or service)). Depending on server settings an option to create a new account is offered, too (#Creating a new account).

For a normal TCP socket the stream is established like this (RFC 3920 Section 4.8.):

  • 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>

Secure connections

  • Note, there are two layers of security to consider:
  1. Client <-> Server (encryption of the TCP connection; TLS and SASL should be used)
  2. Client <-> Client (data exchange between clients, in example an instant message; this should be done with GnuPG)

Creating a new account

Currently there is no official standard about how to create or delete an account. Anyway the existing servers still support the old way.

To create an account the client must not be authenticated.

  1. Request the required information.
  2. Register.
  • Example for registering a new account:
   C: <iq type='get' id='reg1'>
          <query xmlns='jabber:iq:register'/>
      </iq>
   S: <iq type='result' id='reg1'>
          <query xmlns='jabber:iq:register'>
              <username/>
              <password/>
          </query>
      </iq>
   C: <iq type='set' id='reg2'>
          <query xmlns='jabber:iq:register'>
              <username>hax0r</username>
              <password>god</password>
          </query>
      </iq>

The Server might respond with success...

   S: <iq type='result' id='reg2'>
          <query xmlns='jabber:iq:register'/>
      </iq>

or with an error:

   S: <iq type='error' id='reg2'>
          <query xmlns='jabber:iq:register'>
              <username>edrin</username><password>pwd</password>
          </query>
          <error code='409'>
              Username Not Available
          </error>
      </iq>
  • To delete an account the client must be authenticated - of course - and send:
 Sorry, I don't remember right now

The log-in-process (aka authentication with a server or service)

NOTE: This section is out of date! XMPP uses SASL for authentication, as described in RFC 6120. The stanzas described here are a legacy protocol that is discontinued in many servers today.

More details are described in XEP-0078: Non-SASL Authentication.

Under some circumstances you might want to provide the password as a digest; see XEP-0078: Non-SASL Authentication for more details about this.

For authentication with Jabber servers and services the jabber:iq:auth namespace must be used:

  1. Client requests required fields from server.
  2. Client authentication.
  • Example:
   C: <iq type='get' to='shakespeare.lit' id='auth1'>
          <query xmlns='jabber:iq:auth'>
             <username>bill</username>
          </query>
      </iq>

   S: <iq type='result' id='auth1'>
          <query xmlns='jabber:iq:auth'>
              <username/>
              <password/>
              <digest/>
              <resource/>
          </query>
      </iq>

   C: <iq type='set' id='auth2'>
          <query xmlns='jabber:iq:auth'>
              <username>bill</username>
              <password>Calli0pe</password>
              <resource>office</resource>
          </query>
      </iq>

On success server will respond with:

   S: <iq type='result' id='auth2'/>

Server Informs Client of Failed Authentication (Incorrect Credentials):

   S: <iq type='error' id='auth2'>
          <error code='401' type='auth'>
              <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
          </error>
      </iq>

Server Informs Client of Failed Authentication (Resource Conflict):

   S: <iq type='error' id='auth2'>
          <error code='409' type='cancel'>
              <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
          </error>
      </iq>

Server Informs Client of Failed Authentication (Required Information Not Provided).

   S: <iq type='error' id='auth2'>
          <error code='406' type='modify'>
              <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
          </error>
      </iq>

Sending a message

The information provided here conforms to RFC 3921 Section 4.

First lets take a look at the most complex situation.

  • A message with all message features in use:
   C: <message
          to='romeo@example.net'
          from='juliet@example.com/balcony'
          type='chat'
          xml:lang='en'>
          <subject>I implore you!</subject>
          <subject xml:lang='cz'>Úpěnlivě prosim!</subject>
          <body>Wherefore art thou, Romeo?</body>
          <body xml:lang='cz'>PročeŽ jsi ty, Romeo?</body>
          <thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
      </message>

Ok, here is the explaination;

  1. to - specifies the receiver - of course it should be required.
  2. from - the server routing your message should fill this for you; just leave away.
  3. type - specifies how romeo's client should handle the messag.
    1. normal or left away - a small message window should pop up.
    2. chat - a chat window should pop up.
    3. headline - message should be handled as a news feed - no response is expected.
    4. groupchat - for multi-user chat environment; see the according section in this guide.
    5. error - well, an error message; for details regarding stanza error syntax, refer to RFC 3920.
  4. xml:lang - the default language of text in this message; this is not supported by any client I know of yet.
  5. subject - useful especially for type 'normal' and type 'headline'; not supported in combination with type 'chat' in most clients.
  6. body - yes, this is the message text ;)
  7. thread - a very optional thing, clients could have several message/chat sessions at the same time; usually this is not really required, many clients are even ignoring this thing but they should not of course!
  • And here a very basic message:
   C: <message to='juliet@example.com'>
          <subject>I love you!</subject>
          <body>Meet at six? ;) Romeo</body>
      </message>