Tuesday 22 May 2007

Adding SSO to JWChat

We're in the process of deploying a new Jabber server here, and have already got the server (jabberd2) and assorted clients (Gaim, Psi, AdiumX, Cocinella) supporting Kerberos based single signon. In my idle moments, though, I've been playing with JWChat - which doesn't support any of the WebSSO technologies, instead requiring a username and password. This limitation isn't really JWChat's fault - instead, it's a product of the way that it must be implemented. JWChat is a complete, Javascript based, Jabber client which runs in the browser - which talks XMPP encapsulated in HTTP (using either HTTP-Binding, or HTTP-Polling) via a proxy, back to your Jabber server. The fact that it's implemented in the browser means that it doesn't have access to anything useful, like a password store, let alone a Kerberos credentials cache. The fact that the proxy just passes XMPP packets blindly to the server, means that you can't use authentication to the proxy as a way of securely authenticating to the Jabber server.

So, here's a cunning plan. There's already a Man-In-The-Middle (the proxy). This is already slightly active at moments during the session. My plan is to make this proxy a little more active when connection establishment is being performed. In particular ...
*) Use the EXTERNAL SASL mechanism to indicate that the authentication is happening over an external channel.
*) The proxy runs at a URL which is optionally protected by some form of proxiable authentication (the one I'm interested in here is Kerberos, but other options are possible).
*) If the user has successfully authenticated to the proxy, then it looks out for the stream:features packet at the start of the XMPP handshake. It intercepts this packet, and adds EXTERNAL to the _start_ of the list of supported SASL mechanisms.
*) The client then picks which authentication mechanism to use. If it is a hacked version of JWChat, it will try EXTERNAL
*) The proxy looks out for an attempt at doing EXTERNAL. If there is one, it doesn't forward this packet to the server. Instead, it starts its own GSSAPI based authentication, using the current user's credentials. It talks directly to the XMPP server (without returning any packets to the client) until the GSSAPI handshake is complete. It then fakes success or failure to the client as coming from the EXTERNAL mechanism.

This should all work, with a few caveats. We can't establish security layers (unless the proxy becomes really clever). The proxy needs to know about a Kerberised authentication mechanism (in our case, probably NegotiateAuth), and about how to do the SASL GSSAPI mechanism. The proxy needs to decode, and encode, XMPP packets by itself.

I'm going to have a go at implementing this using Punjab as the proxy (as Python is slightly less unfamiliar than Java at the moment, and there is at least a free SPNEGO / NegotiateAuth plugin for Twisted available in the Apple CalDav source)

Sunday 13 May 2007

AFS & Kerberos Workshop

Sitting in Atlanta waiting for a delayed flight on my way back from the AFS & Kerberos Best Practices Workshop at SLAC.

The conference was a little lower-key this year, as accounting restrictions presented commercial sponsorship & the provision of food at meal breaks. Whilst this perhaps reduced the amount of mingling that took place, it didn't really reduce the quality of the talks - which were another strong mixture of case-studies and development reports. Another great effort from Derrick, Jeff, Russ,Tracy, Alf (and the sadly missing Moose).

The talks from the workshop are up on their web pages at http://www.pmw.org/afsbpw07/. Of particular interest to us are Kristen's talk on NDMP, Russ's talk on his pam modules (which I hope we'll be able to migrate to using before our next client platform release), Love's description of rxgk, Matt and Marcus's byte range locking, and Derrick's version of hostafsd.

There was also some talk of testing and build farms, which I hope I'll be able to find a way to help with.