Monday, August 07, 2006

Jabbering with Google Talk over XMPP

I am writing an XMPP client that can talk to Google and maybe implement some cool things on top of it. So this weekend I began exploring the specs and intend to maintain an account of how it is going. XMPP is a widely discussed/implemented topic and has many many clients - so it is no research topic. Why did I choose to do this? Just for fun to try something new (for me) out. I know I can get the XMPP library from Jive Software but thats no fun. Sometimes re-inventing the wheel has its own pleasures :-).

The XMPP specs are an open standard on which Jabber and Google Talk are based. There are a number of extensions which are under consideration and most of the cool things have already been thought of such as RPC over XMPP.

So far as a prototype, I have managed to get connected to talk.google.com, perform starttls and authenticate myself followed by resource binding and initiating a session. Now, my prototype code is hitting its limitations and I will have to spend some time fixing it to be able to do some serious talking with XMPP. I have also managed to get my account successfuly blocked for authenticating incorrectly as well - but got out of that mess. :-)

I was hoping to sniff out the conversation that the Google Talk client is having with the server using Ethereal as per this blog that describes X-GOOGLE-TOKEN, a Google mechanism for Single Sign-on. As per that blog, the Google Chat client does not do starttls but does an XMPP authentication over an un-secure socket using a Google generated token (the actual authentication with the Google token server is over https) so all the communication can be sniffed. However, my client seems to be doing a starttls and I can't sniff any details out after the proceed response. Too bad - appears that Google Talk has changed since the blog was written.

Here's the sequence of communication with the Google Talk server - (formatted for readability with text sent from me in this colour and the response in this colour and comments in this colour).



<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X0B367FC8A9597BA4" 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>

<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls" /> <--- Start TLS - basically the rest of the communication is over SSL
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

TLS Succeeded - we are good to go...

<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X1A565C1E8E3FD7CA" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>\
<mechanism>X-GOOGLE-TOKEN</mechanism>
</mechanisms>
</stream:features>

Now we get the PLAIN auth mechanism which is basically base64 encoded \u0000username\u0000password string which I have blacked out here.
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>XXXXXXXXXXXXXXXXXX</auth>
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/> <--- authenticated

<stream:stream
to='gmail.com'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
version='1.0'>
<?xml version="1.0" encoding="UTF-8"?>
<stream:stream from="gmail.com" id="X77D6827CD0B365BA" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<stream:features>
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>
</stream:features>

<iq type='set' id='bind_1'>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
</iq>
<iq id="bind_1" type="result">
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
<jid>XXXXXXXX@gmail.com/D922F673</jid>
</bind>
</iq>


<iq to='gmail.com' type='set' id='sess_1'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>
<iq from="gmail.com" type="result" id="sess_1"/>

Authenticated, Resource bound and Session created. Now, I need to send a message!

</stream:stream>



Next article on this, I hope to have successfully sent a message.

10 comments:

Anonymous said...

Hi there, I have the same problem. I tried to read off the conversation from the capture I make using ethereal. Unfortunately, all the contents after authentication are encrypted and I couldn't find a way to decrypt it yet. I'm still trying. If I found something, I will let you know here.

regards~

Sachin said...

Hey,

Sorry your comment took me so long to publish - I was on vacation with no email access.

Well, you should not be able to decrypt it because it is SSL - so not much hope there. I wonder if there is some switch by which google talk can be forced to use its X-GOOGLE-TOKEN mechanism instead of TLS.

Sachin

Anonymous said...

Is it possible to decrypt messages in GTalk

Divyarajsinh Jadeja said...

Can u suggest me nice APIs to use XMPP in C++.
I want to use it in VC++.
To communicate with G Talk.

Rahul Bhattacharjee said...

cool blog.Helps a lot for the new comers into this field.Soon I am planning to write a command line client for gtalk.

Anonymous said...

Sir,
this is way long since u last posted. :)
i am trying to write a gtalk app in VB..as u said..i would like to code from scratch...its more fun.
could u point me to some resources..
This s my first venture in coding Xmpp jabber, so any help would be appreciated :D

ruturajmd@gmail.com

thank you.

Sachin said...

I haven't done any VB work in ages so I can't help you with VB-XMPP resources.

I suggest you read the XMPP spec http://www.ietf.org/rfc/rfc3920.txt

I found that I wanted slightly more flexible XML APIs and I found this very useful - http://xmliter.sourceforge.net/

Create a google talk id for experimentation so you don't drive your friends nuts by logging in and out :-)

I followed this up with two other small blogs that complete a prototypical client - take a look.

Have fun!

Anonymous said...

hi sachin, this post was really helpful. I am trying to sniffer GTalk messages using Wireshark and I could not see any readable text beyond the &ltstarttls&gt and &ltproceed&gt tags. But in dystopics blog which you referred, I could see messages beyond that as well. Has Google Talk undergone any changes in this respect? I appreciate if you could share some info regarding this.

Sachin said...

Hi Deepan,

The blog I linked to demonstrates the usage of X-Google-Token - a Google proprietary authentication mechanism that does not go over https hence allows you to read the conversation. Once starttls happens, the subsequent conversation will be over https and I doubt that externally you'll be able to sniff that at all.

I suspect there is a way to force GoogleTalk to use X-Google-Token instead of TLS - see this post http://sachinhejip.blogspot.com/2007/07/another-reason-to-have-x-google-token.html but I am not sure what that is. Maybe posting on some GTalk forum might provide some answers.

Sachin

Anonymous said...

Hi!
I have the following problem:

I did everything until this:


After that I send this:



And I am getting no answere. Does anybody of you know why?