I started off implementing a new SASL mechanism, SCRAM-SHA-1, in Psi which will be used
if no external SASL library is available.
Using this mechanism users can login securely even over unencrypted connections and if they want Psi to remember their password, this can be done more securely if SCRAM-SHA-1 is available at the server.
More on this part here.
The second part of the project was implementing Stream Management, XEP-0198, in Psi. Luckily, Matthew Wild, one of Prosody's main developers, started to implement it around the same time so we could easily test each independent implementation against each other.
I've implemented the most important and interesting parts of XEP-0198: stanza acknowledgment and stream resumption. Together they make chatting, but basically everything in XMPP, more reliable.
Especially stream resumption is nice in case your connection is dropped. In this case you don't have to go through the whole roster retrieval and presence distribution steps again. The stream resumption part wasn't that easy to implement, because currently Psi destroys its complete XMPP stack state on disconnection with the server.
During the last couple of weeks I've added a new groupchat join dialog to Psi. This included reusable data models for browsing server room listings, bookmarks and history of joined rooms. Additionally the new dialog lets you choose more than one room to join. I've also modified the still existing old join dialog (It still exists because it also handles join logic.) to support bulk join. This means if you join multiple rooms on login, due to bookmarks, or via the new join dialog, the dialogs indicating join process are hidden as long as no error occurs.
It was quite interesting getting to know Psi's and Iris's codebase which are from quite varying design quality considering their parts
but most of the time it was quite understandable and Justin, Psi's and Iris's original and main developer, was always able to answer my
questions on the code and design.
Coding in the GSoC umbrella organisation XSF was quite fun and well organized. The weekly meetings helped to keep you on track and frequent reports from fellow student kept you up to date on their projects' progress.
All the developed code is available at my github account.
I finally got the new join dialog for Psi finished.
When the dialog opens it shows you the rooms available at your server, if there are any, your recently joined rooms and your bookmarked ones. At the top you simply enter the nickname which you want to use to join the rooms.
There's little special about this dialog and it works how you'd expect it to work, hopefully. If you want to give it a try yourself the code is available here.
Here another short update on my Google Summer of Code project.
I've designed a new dialog for Psi which should ease the process of joining a room. The new dialog's features include:
- all sources of existing rooms in a single dialog
- allow entering a JID of a room manually
- select multiple rooms from server room list, history and bookmarks and join them at once
Psi is a powerful and popular XMPP client which runs on nearly any platform. It recently got features like Jingle Audio which enables peer-to-peer audio calls.
These new features aside, Psi's user interface is lacking in various places, including, but not limited to, the multi-user chat area. This is kind of sad since the project's mission statement includes ease of use.
The second part of my Google Summer of Code project is to improve this area.
Psi's known to be used more by power IM users than by people who are new to IM, and as power user you like auto-join a couple of MUCs and also connect from multiple places to your account. However if you're already logged in and joined all those rooms, a lot MUC software will complain that you are already in the room, when a your second resource tries to auto-join those.
In Psi this situation can be described by a single picture/screenshot. :)
A possible solution to this problem is to handle auto-join of chatrooms on login completely differently compared to manual joins. A long requested feature for Psi is to have chatrooms show up in your contact list. This has already been implemented by the Psi+ project and it's working quite nicely.
For auto-join one couldn't show any dialogs at all and just let the items in the contact list indicate whether a join was successful or an error occurred.
The next MUC section that could need some improvement is manually joining a room. You have to go to different places depending if you already know where to join or not.
- You already know the conference you want to join.
- You have the room already bookmarked.
- You have no clue what conference to go in, still you want to chat with other people.
A possibile solution to this problem is providing a single dialog for the general task of 'Joining a MUC'. More on that is soon to follow.
Here comes another short update on my Google Summer of Code project.
Stanza acknowledgement is finally done, including representation in the GUI. You can see a short demonstration of the feature in the video below where I'm chatting with Matthew Wild, one of Prosody's main developers. He developed a module for Prosody that implements parts of Stream Management. This made my client side implementation much more easier to test.
The idea is simple: the status icon in the top left corner is replaced with a throbber animation, known to users from recent OSes and browsers, as long as there are messages that haven't been acked by the server.
Psi will at least request an ack after half a minute. However only if there's something to acknowledge for the server.
This week is mid-term evaluation of the Google Summer of Code projects. SCRAM support and stanza acknowledgement, which is the most important part of the Stream Management XEP, are both finished including GUI.
Here another short update.
Stanza acknowledgement from client to server is working now and chat dialogs get notified when a message sent by them has been acked by the server. The only thing left here is the visual representation in chat dialogs of unacked and acked messages.
After that is done I'll try to add support for session resumption and hopefully get it done till mid-term evaluation next week. Most of this stuff doesn't sound hard to implement however there is currently only one server implementation of XEP-0198 and that one only supports stanza acknowledgement, so it's a bit hard to test my client side implementation of it. XEP-0198 resulted out of long discussions in the XSF on how to improve reliability and the overall experience of chatting over XMPP. It's important that this extension is implemented so we can test in real life whether these changes help or not.
50% of my end semester exams are taken and the rest is following in the next week. After those I'll have plenty of time to start the second big part of this project, UI improvements in Psi.
Here the short but little late update on my GSoC project status.
Acking requests coming from the server is basically implemented in Iris. Psi as a client can tell Iris that the last received stanza has been handled and Iris will take care of the rest.
Next on the list: Sending own acking requests to the server so we know the stanzas Psi's send have successfully been handled by the server.
SCRAM is a new mechanism designed to let you sign in into your servers much more securely than with existing mechanisms. It involves applying various algorithms to your password to make it extremely difficult to hack.
The SCRAM-SHA-1 SASL mechanism was added to the XMPP spec, and replaces the legacy DIGEST-MD5 mechanism. Its various security features include hashed passwords being send over the internet, and hash passwords being stored on disk. Attackers which can read the network traffic or the server's password database are unable to do any harm.
I just finished a SCRAM-SHA-1 implementation for Psi as part of my GSoC project. There are test cases to write and wider testing to be done, but we now have a working implementation.
What does this mean for Psi users? Well, usually, when you don't want to enter your password each time you login, you tell Psi to save it. Most clients, if not all, store it in clear text form if you tell them to store it at all. This is fairly insecure, and anyone with access to the computer could get access to your password. It's a common security advice that you shouldn't use the same password for all your accounts on various services on the internet. However, human laziness is a powerful force. So, if you use the same password for various services, and someone malicious gains access to it, she/he can gain access into all the other accounts where you used that password.
Now SCRAM comes into play. If your server supports this, and your client supports this, you can have them store your password in a form not very usable by attackers. Thankfully Prosody got some new authentication backend APIs thanks to Jeff Mitchell. You can read more about that in Jeff's blog post. Effectively this means that if a malicious person gains read access to your network or the server, they can't do anything, and if they gain access to your computer, they can do nothing more than login into your jabber account.
What are the consequences of using a hash to login? It basically comes down to support. It requires support by both the client and the server. Only when both have support do you get the full security SCRAM offers. On client side, since you're clearing your plaintext password you have to login using SCRAM in the future. On the server side, you're storing the iteration count, salt and the and two keys instead of the plaintext password. This reduces your possible login methods to only PLAIN (this should only be done over TLS) and SCRAM-SHA-1.
This is currently only available in a development branch. It'll soon get merged into the main branch. To enable this in Psi, first make sure your server supports SCRAM. Then go to the Misc tab in your Account Properties dialog and check the checkbox labelled “Store password as salted hash...”.
Apply the changes. Reconnect.
Now when you visit your Account Properties dialog, you'll notice that the input box for your password is empty. YAY.
So what's next on the agenda for my Google Summer of Code project? Currently I'm a little behind but I'll get started on implementing stanza acknowledgement and session resumption of XEP-0198 the next couple of days to get back on the track.
So coding time of Google Summer of Code 2010 just began and I wanted to put out some introductory note about what I'm planning to archive this summer.
The project consists of mainly four parts:
- implementing the new SCRAM-SHA-1 SASL authentication mechanism
This should be a rather easy part. Adding SCRAM-SHA-1 to Iris, Psi's core XMPP C++ library based on the Qt framework. Additionally I'll try to introduce the ability to store the password in hashed form, if the user wants to store it at all. However this demands you're using a XMPP server supporting the SCRAM SASL mechanism and it's using a constant salt and iteration count.
- implementing XEP-0198 for a more reliable client-to-server connection
XEP-0198 has been developed in the XMPP community because reliability is still a problem when communication over the internet, even when using TCP. This protocol extension provides features like stanza acknowledgment, session resumption and throttling. Using this XEP clients can tell the user that she/he can be sure that the message reached the server or if there has been a problem. No more strange wondering about messages getting lost.
- implementing XEP-0184; this way you can let your chat partner know you've read a message
The guys from the Psi+ project already wrote a patch for this as I found out a couple of days ago. I'll evaluate the patch, merge it and make it works in a decent way. You don't want to spam people with message receipt requests.
- redesigning the multi-user conference join dialog
Currently you have your bookmarked rooms in a drop-down menu, the recent joined MUC rooms in the join dialog and public rooms available at your server are accessible via the service discovery dialog. I'll try to unify those three use cases in a single MUC dialog which should easy to process of joining MUCs.