Generic Jabber (XMPP) with webOS

Tuesday, December 20. 2011

Generic Jabber (XMPP) with webOS

WebOS (The operating system of the Palm Pre and Palm Pixi phones) has a built-in messaging application but unfortunately it only supports Google Talk and AIM out of the box. It's a shame that Palm has not enabled more protocols and especially generic XMPP support. The used library (libpurple) supports everything so it's only missing in the GUI.

Google Talk uses XMPP so in theory it should work with any other XMPP server but unfortunately Palm has put this nasty code in the LibpurpleAdapter (which is used as a connector between the GUI and the low-level libpurple):

if (strcmp(prplProtocolId, "prpl-jabber") == 0
    && g_str_has_suffix(transportFriendlyUserName, "@gmail.com") == FALSE
    && g_str_has_suffix(transportFriendlyUserName, "@googlemail.com") == FALSE)
{
    // Special case for gmail... don't try to connect to mydomain.com if the
    // username is me@mydomain.com. They might not have
    // setup the SRV record. Always connect to gmail. 
    purple_account_set_string(account, "connect_server", "talk.google.com");
}

This code means: If the protocol is Jabber (XMPP) and the entered username does NOT end with @gmail.com or @googlemail.com then the XMPP server is hardcoded to talk.google.com. So if you enter a username like johndoe@jabber.org then the Messaging app does not connect to jabber.org but instead it connects to talk.google.com because of the above code. So we must get rid of this code somehow.

With some knowledge about assembler you might be able to toggle some logic in the binary so the above if statement always evaluates to false but there is a much easier solution. You just need to replace the string "connect_server" with some invalid string. I use "nonnect_server". The result is that the line simply sets some unused property and therefore simply does nothing.

Since WebOS 2 the LibpurpleAdapter program is renamed to imlibpurpletransport. In the following step-by-step instructions I will mention both variants for WebOS 1 and WebOS 2.

Access your phone

To be able to modify the LibpurpleAdapter file you need access to your phone. You have multiple options here:

  • Use the Terminal app which is available via Preware.
  • Use SSH.
  • Switch the phone into Developer Mode and then use novaterm from the Palm SDK.

If you are a hacker then you probably already have SSH installed. If you are not a hacker then I recommend installing Preware and then installing the Terminal app from within Preware.

The next steps require that you have successfully opened some terminal so you can enter commands.

Remount the root filesystem as read/write
To be able to modify files you have to remount the root filesystem with read/write support:
# mount -o remount,rw /
Patch the LibpurpleAdapter
Go to the /usr/bin directory:
# cd /usr/bin
Rename the original LibpurpleAdapter file:
# mv LibpurpleAdapter LibpurpleAdapter.orig           (For WebOS 1)
# mv imlibpurpletransport imlibpurpletransport.orig   (For WebOS 2)
Create the new patched LibpurpleAdapter file:
# cat LibpurpleAdapter.orig | sed s/connect_server/nonnect_server/ > LibpurpleAdapter           (For WebOS 1)
# cat imlibpurpletransport.orig | sed s/connect_server/nonnect_server/ > imlibpurpletransport   (For WebOS 2)
Make the new LibpurpleAdapter executable:
# chmod +x LibpurpleAdapter       (For WebOS 1)
# chmod +x imlibpurpletransport   (For WebOS 2)
Installing CA certificates

For some reason Palm has stripped all but one CA certificate file from the /usr/share/purple/ca-certs/ directory. I think the one and only CA cert in there is used by Google Talk and AIM so only this one is needed. But if you want to use other XMPP servers then you most likely need more CA-certificates. I have collected all certs which are normally included in libpurple into a ZIP file. Execute these commands to install them on your phone:

# cd /usr/share/purple/ca-certs
# wget http://www.ailis.de/~k/permdata/20100824/ca-certs.zip
# unzip ca-certs.zip
# rm ca-certs.zip

If you are using an XMPP server which is using a self-signed certificate then you need to install your own CA-certificate. Simply copy the PEM file into the /usr/share/purple/ca-certs/ directory.

Remount the root filesystem as read-only

This step is optional but recommended. You have finished all needed modifications so you no longer need write access to the root filesystem. So remount it as read-only with this command:

# mount -o remount,ro /
Restart LibpurpleAdapter

To enforce a reload of an already loaded LibpurpleAdapter you can restart your phone or you can simply kill the process:

# killall LibpurpleAdapter       (For WebOS 1)
# killall imlibpurpletransport   (For WebOS 2)
Setting up a dummy Google account (WebOS 2 only)

(Thanks to Micah N Gorrell for this info) Unfortunately Palm has changed the Google Talk IM module so it also tries to connect to other Google Services. So on account creation some other part of WebOS tries to login to the Google server. This is only done once on account creation and every time you change your password. No idea how to get rid of this. You have to create a temporary Google Account with your Jabber ID as E-Mail address. After successful account creation this Google account is no longer needed as long as you don't have to change the password of your Jabber account.

Finished

Now start the Messaging app, add a new "Google Talk" account and enter the username (For example johndoe@jabber.org) and password and it should work. On WebOS 2 the phone also asks if this account should also be used for contacts, mail and calendar. Make sure you deactivate all this Google-only stuff.

Alternatives

As an alternative to hacking the Google Talk client you can install the WebOS Internals Messaging Plugins. They never worked for me but maybe you have more luck.

Posted in WebOS | Comments (4)
jutso at 2010-10-21 15:15
Worked out very well here (WebOs 1.45).

Thank you!
Micah N Gorrell at 2011-02-27 02:55
Thank you very much for this post. Being able to use jabber natively on webOS is awesome. (Hopefully it'll be supported before too long...)

I ran into some certificate issues while setting this up. I have an OpenFire server that is using a self signed certificate. I finally managed to get it working by setting up pidgin on my desktop, and copying a certificate from ~/.purple/certificates/x509/tls_peers/jabber.mydomain.net

I then put that file in /usr/share/purple/certificates/x509/tls_peers/ on my phone, and was able to connect.

Also, if you are trying this and running into trouble, you can run /usr/bin/LibpurpleAdapter in a terminal. It is very verbose, and will likely print much more useful error messages than you will get in the UI.

I used this method to figure out that my server's certificate was for xmpp.mydomain.net and not jabber.mydomain.net like I thought it was. I changed my user to user@xmpp.mydomain.net and then it connected!

Thanks again
Micah N Gorrell at 2011-03-05 21:18
I recently upgraded to webOS 2.1 (using the instructions here: http://www.webos-internals.org/wiki/WebOS_2_Upgrade - thanks webosinternals!) The upgrade went very smooth, and I love webOS 2.1. But I wasn't able to use jabber...

After a bit of experimentation I managed to get it to work. It is a bit more complicated, but well worth it. When you add a google talk account, it now expects that account to be used for multiple google services. This made things a bit tricky, and it means that you need a google account to set it up.

1) Go to your google account settings page, and add an alternate email address that matches your jabber account name. Google will send a verification email. Once you have verified the email address you'll be able to login to your google account with that email address.

2) Apply the binary modification (as described in this article), but... the file name has changed. LibpurpleAdapter is now imlibpurpletransport. Aside from changing the filename the instructions should work.

3) Add any certificates you need. This should work exactly as it did in webOS 1.x. See my previous comment if you are having trouble.

4) Kill any running instances of imlibpurpletransport.

5) Change the password on your jabber account to match the password on your google account. I wish this could be avoided, but this was the only way I was able to make it work.

6) Add your account in the phone's messaging app. It will login to google, and show you a list of services that you can enable. Turn them all of except for messaging. (In theory you can turn some of them on, but I haven't tried that.)

7) Enjoy! You should have a working jabber account! If you run into trouble you can kill all running instances of imlibpurpletransport, and start it by hand in novaterm. It will print a lot of debug. If you read it carefully you should find a clue about why it is failing.
Klaus Reimer at 2011-12-20 19:13
@Micah: Thanks for the info. I have updated the article with WebOS 2 instructions.

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.