Wednesday, August 6, 2008

Quick summary of last week

Last week, I refactored TLS code in Gajim to match the new architecture. Debugging XMPP over TLS on ports 5223 and 5222 was not difficult thanks to well-designed wrappers for Python's standard library SSL and PyOpenSSL (by dkirov, I believe). Now I'm focusing on securing HTTP connections, which can be non-persistent and more prone to errors. It is crucial to handle various TCP and SSL errors effectively.

Dealing with persistent connections is challenging because Connection Manager implementations can vary. The other end could be an HTTP server, a proxy, or a port forwarding HTTP server. This requires a robust implementation of HTTP connections and separating HTTP from XMPP stream.

I also fixed a bug discovered by Asterix - authentication to ejabberd hangs when it doesn't immediately follow the init response. You can find more information here. I believe this is an issue with ejabberd, as the traffic scenario aligns with the XEP and it works fine with Openfire. For now, I have disabled sending empty bodies until an authentication module is added. This may result in an inactivity timeout if the delay is too long. I will test with Tigase and Punjab once I install them.

 

Monday, July 28, 2008

Another progress report

I improved the handling of HTTP connections in my implementation. It now supports non-persistent connections to ejabberd and keep-alive and pipelining connections to Openfire (using Safa's dev build). I also implemented acknowledgments checking and key-sequencing. Additionally, I made some modifications to the proxy group stored in the Gajim config file. The configuration dialog for BOSH proxy has slightly changed to allow an optional set of HTTP proxy before the Connection Manager.

Next, I will focus on securing BOSH TCP connections. Currently, Gajim attempts to establish an SSL connection first and falls back to plain text when SSL negotiation or handshake fails. When connecting to the Connection Manager via BOSH, there shouldn't be an issue as long as the client goes directly to CM. The protocol used (XMPP or HTTP) over SSL doesn't matter in this case, although there is no negotiation within BOSH. However, when a proxy is used, I observed that Firefox sends an HTTP request with the CONNECT method to the proxy, which opens a tunnel to the remote machine. The SSL handshake then occurs on the opened channel. I will adopt the same approach because there seems to be no other way to tunnel HTTPS over a proxy.

With the tunnel established using CONNECT, it would be more reasonable to send XMPP directly instead of using BOSH over HTTP. However, CONNECT is usually limited to certain port numbers. Nonetheless, I believe it should be possible to achieve the same with BOSH as well (Gajim already supports XMPP via HTTP proxy using the CONNECT method).

Sunday, July 13, 2008

Midterm update

I made changes to the Gajim XMPP code to support HTTP connections. Now, my branch is compatible with BOSH Connection Managers in ejabberd 2.0.1 and Openfire 3.5.2. You can find it in Gajim SVN:

svn co svn://svn.gajim.org/gajim/branches/bosh_support@9924

To connect using HTTP bindings, create a proxy of type "BOSH" in the Proxy Managing dialog (Accounts -> Connection tab -> Manage next to Proxy combobox). Then, enter the Connection Manager URI and port in the respective text fields.

Please note that there are some bugs, and I haven't tested it with a proxy yet. My next tasks include addressing protocol issues, adding TLS support, and fixing networking code before merging it back to the main codebase.

I also observed two issues with Openfire: it doesn't respond to the stream-restart body tag after SASL authentication, and it doesn't classify iq stanzas (children of the body tag) with an XML namespace. This caused the XML parser in Gajim to consider the iq stanzas as part of the http://jabber.org/protocols/httpbind namespace because it's the parent body's xmlns.

Sunday, June 15, 2008

Third week of GSoC

In the past two weeks, I realized that the design I proposed in my previous post was flawed. The socket wrapper in xmpppy doesn't allow for multiple wrappers per client, and it has unnecessary functionalities for the TCP connection object. Therefore, I am currently refactoring the NonBlockingTcp and NonBlockingClient classes in xmpppy. My next step will be implementing a BOSHTransport that can be plugged into the client just like the socket wrapper. Please note that this is still subject to change, so I will provide a class diagram next week.

In the meantime, I have created a unit testing template for NonBlockingClient. I have also set up openfire, punjab, and araneo on my virtual server for testing purposes, and jwchat on localhost for traffic analysis.

You may have noticed my posts appearing multiple times on planet jabber. This is because whenever I edit a post, Blogger updates the <updated> tag in the feed, and the planet reader sorts entries based on the update time instead of the original publication time. Unfortunately, I haven't found a way to ignore entry updates in the planet reader or exclude the update time from the Blogger feed. I am considering moving to Wordpress, as it allows for importing the blog from Blogger, or finding a way to manipulate the feed on my own. Until then, I won't be able to maintain information in my posts or fix any typos.

For a comprehensive list of XMPP software that supports BOSH, you can now visit the jabber.org wiki. I noticed a few more tigase projects on the list that I wasn't aware of, which is pretty cool.

Sunday, June 1, 2008

BOSH in XMPP software

I researched existing HTTP Binding implementations for testing my code with different servers and Connection Managers. BOSH, described in XEP-0124 and XEP-0206, provides mechanisms for reliable XML stream transfer over HTTP. XEP-0124 covers general syntax and error handling, while XEP-0206 addresses session negotiation, error processing, and SASL authentication for XMPP.

In the BOSH architecture, there are clients, servers, and Connection Managers. Clients communicate with the Connection Manager (CM) through HTTP POST requests/responses defined in the mentioned XEPs. The CM, acting as an XMPP client or using the component protocol, communicates with the XMPP server. The CM can be a standalone HTTP server or a built-in feature/extension of an XMPP server. To connect to an XMPP server via BOSH CM, you need the CM URL and port number in addition to the XMPP server address and port. If using built-in Connection Managers, the IP addresses of the XMPP server and CM will be the same, differing only in port numbers.

Here's an overview of XMPP software with BOSH support:


Servers
Servers with built-in Connection Manager.

Standalone Connection Managers
Act as a proxy between client and XMMP server.
Clients
Libraries
  • gloox (C++) - BOSH support done by MattJ during GSoC 2007. BOSH Connection classes are included in svn trunk and 1.0-beta2 (download page).
  • xmpp4r (Ruby)
  • xmpp4js (JavaScript)
  • JSJaC (JavaScript)
  • emite (Google Web Toolkit, Java) - XMPP library and client GUI for gwt, connecting through BOSH Connection Manager.

While I haven't tested all the listed software, I'll continue updating this overview during the summer as I progress with testing. For further reading, refer to MattJ's blog post.

Saturday, May 31, 2008

First steps

I'm providing a summary of my progress in the first six days of GSoC coding. Throughout the coding period, I plan to publish a blog post every weekend to document my journey.

My project focuses on expanding the functionality of the Gajim jabber client. To begin, I delved into understanding the existing code responsible for XMPP communication. Gajim utilizes a modified version of the xmpppy library, which includes non-blocking transports with callbacks and message queues to notify connected objects at regular intervals. The Gajim architecture involves three relevant layers: the Connection class, acting as the interface between the UI and xmpppy (one instance per jabber account); the Client class, responsible for establishing the connection to the XMPP server and handling authentication; and the transport classes that format data for different protocols (SSL, TLS, TCP, HTTP proxy, SOCKS5 proxy). The transports themselves are not aware of XMPP stanzas.

In the case of BOSH (Bidirectional-streams Over Synchronous HTTP) messages, XMPP messages are wrapped within a body tag containing BOSH-related attributes. These messages are sent to an HTTP server or proxy known as the Connection Manager, instead of directly to the XMPP server. The communication scheme differs slightly to allow for server-initiated requests in HTTP (refer to XEP-0124). Based on this understanding, I determined the starting point for my coding efforts. Considering the variation in stream initiation between XMPP over BOSH and plain XMPP, I decided to create a BOSHClient class derived from NBCommonClient. In the existing code, the Connection object holds an instance of NonBlockingClient, also derived from NBCommonClient, as shown in the class diagram.



The plan is to utilize the BOSHClient instead of NonBlockingClient for accounts connecting to the BOSH Connection Manager. Currently, I have successfully built and sent the initial request, received and parsed the response, albeit with limited error checking. My next steps involve integrating the Gajim module for SASL authentication and subsequently sending the first message via BOSH.

Monday, April 21, 2008

I'm accepted for GSoC 08

At about 10:30 PM Finnish time yesterday, I learned that my Google Summer of Code proposal "BOSH support in Gajim" was accepted by the XMPP Standards Foundation. I'll be working on BOSH, a way to tunnel XMPP via HTTP. This is something I found missing in Gajim during my previous job, where only HTTP/S outgoing application traffic was allowed.

The following morning, I was overwhelmed by over 200 new messages from the gsoc-student mailing list. Interestingly, I'm not the only one tackling BOSH this year. Safa Sofuoğlu is also working to improve BOSH support in Openfire, a server implementation I plan to test against.

It's unusual to have my entire summer planned out in mid-April, especially with remnants of snow still visible. Attached is a typical late April snapshot of Finland's nature from Koli National Park.