UP | HOME

XMPP

XMPP is almost 20 years old now, and I've been using it (on a private server for the past few years, and additionally a local instance working over Tor for the past month) while looking for ways to get distributed messaging. New protocols and technologies are fun, and I don't quite like XML, but XMPP has good documentation, works, can be used in either federated or distributed fashion (as most of the other federated systems, coupled with Tor or a similar network), and has plenty of software – so now I'm thinking that it may be sufficient, at least for messaging.

Its specifications (see RFC 6120, RFC 6121, RFC 7622, and extensions) are well-written and apparently thought through, a small core with optional extensions is a nice approach, there is usable software, there are users, and even XML is not that bad (perhaps even quite suitable for a protocol like that, especially while not being abused).

Though the situation with software could have been better.

1 Message handling acknowledgements

Message delivery is pretty unreliable with some of the major clients and servers, since acknowledgements are not always supported – making it worse than email and approximately as IRC, with respect to reliability of delivery. I'd think XEP-0198 should be among the first extensions to implement, and usually assumed that it's there (without bothering to check, since didn't care much about XMPP, and assumed that it'll be dealt with anyway, because the protocol and the software are popular), but among the three XMPP implementations which I use:

  • libpurple (Pidgin, bitlbee, etc) didn't have it (though had a ticket open for 7 years). Submitted a PR a few days ago.
  • Prosody only has a community module.
  • jabberd2 implements a very dated version of it (about 10 years old; it didn't even have a "draft" status back then). Reported now, and switched to Prosody completely, since there were other issues with jabberd2 which Prosody doesn't have.

2 Client certificates

Certificate-based client authentication is not an essential feature, but I wanted to get rid of passwords as I did with email, so investigated that too.

Prosody has a a bunch of useful modules for authentication, including dovecot SASL and client certificate-based authentication (via SASL EXTERNAL authentication mechanism), but client support is rather bad:

  • libpurple doesn't do it, it's not clear whether it'd be welcome there, and apparently it won't be quick or easy to add (not just technically, but because of a relatively slow/unresponsive process1).
  • bitlbee's own XMPP implementation seems to have even more limited SASL support, and also has issues similar to those of libpurple, caused by its API (which bitlbee reuses for its implementation as well): XMPP streams aren't getting closed properly there either, potentially leading to message loss in conditions where it shouldn't happen.
  • weechat's jabber.py uses an old and abandoned Python library, which implements a now-obsolete RFC even for the core; there are just PLAIN and DIGEST-MD5 authentication mechanisms (SCRAM is required to be available for authentication by the current specification).
  • mcabber's loudmouth library also doesn't seem to support client certificates (or XEP-0198).
  • Emacs's jabber.el uses sasl.el, but that doesn't include EXTERNAL. Also no XEP-0198 (though I'm checking that and stream closing just occasionally, probably none of the others had it either). And it looks abandoned, too.
  • Conversations, an Android client in Java which I've checked out of curiosity, does support both client certificates and XEP-0198, and many other things.
  • ChatSecure's XMPPFramework doesn't seem to support it, but supports XEP-0198. And it's also for mobile devices anyway.
  • Profanity uses libstrophe, and both look nice at a glance, but no SASL EXTERNAL mechanism in libstrophe, and XEP-0198 implementation got stuck between libstrophe and Profanity for more than 2 years now.
  • Psi is a C++ monster, it may or may not be there; quick search reveals very few traces of SASL. Apparently XEP-0198 at least was there at some point.
  • Vacuum-IM is a smaller C++ monster, with SASLFeatureFactory and such; seems to only support ANONYMOUS, PLAIN, and DIGEST-MD5 (roughly as with weechat), so not even quite a valid XMPP implementation. No XEP-0198 in sight.
  • pontarius-xmpp is a Haskell client library, but checked it at once: there are just PLAIN, DIGEST-MD5, and SCRAM-SHA-1. No XEP-0198, and apparently it's tricky to add there.

Apparently it's very uncommon.

3 Fixing the software

While patching libpurple's jabber plugin, some minor libpurple-specific issues surfaced (related to both this XEP and XMPP in general), as it often happens with generic interfaces: they rarely fit well. That's one of the reasons why it's more fun to work on new implementations than to improve existing software: the latter is harder, takes more time for the same features (both implementation and organisational chores), and even then the features barely (if at all) fit into existing APIs.2 But in order to get somewhere, there has to be incremental improvement (which may be long and boring sometimes), and it looks like there's not enough of it.

On the other hand, some features are impossible to cram into libpurple without changing the APIs, and even libpurple, while being reused by multiple clients and for multiple protocols, implements XMPP from scratch instead of reusing a library; though there seems to be just libstrophe out of actually reusable (from any common language via C FFI) ones, but it only implements bare XMPP, ships with its own cryptographic functions, looks abandoned (last commit was about 4 years ago), and apparently it didn't work so well for Profanity. So here's that situation once again, in which there's many implementations already, but it feels like the right thing to do may be just to start over, and add one more – because none are perfect.

Worse than that: implementing a good library wouldn't be sufficient, because complete and proper UI can't be achieved with libpurple (at least its current version, following its conventions; and then there's even more restrictive bitlbee). So a good XMPP client implementation would involve dealing with UIs (likely multiple ones: I'd like an Emacs UI, many prefer GUIs, TUIs/CLIs are handy sometimes) and everything related; doing all that properly would be a large project. Such a project would be easier to start working on if there was certainty that the slight user-visible improvements would worth it.

A compromise may be to try to get at least important and basic things to work first, to get as far as practical with existing software, and only proceed to new implementations and experimentation then.

If one was to start over, apparently the proper way (leading to reusable and portable code, relying on mature and complete libraries which wouldn't introduce unnecessary limitations) would also be a boring one, along the lines of:

Slightly related: Software extensibility.

Footnotes:

1

Not to blame the maintainers, of course, who seem to continuously spend a lot of time on it, and it doesn't seem to be among the slowest or least responsive ones. But still, it's hard to start working on such a feature right away, and to be sure that time and effort won't be wasted.

2

It's similar with protocols, too, what's probably a part of the reason why there's so many of them (without even counting closed ones). And formats, and all kinds of things; sometimes it even seems to be easier (and again, more fun) to write a program than to learn how to use an existing one. Or to try a new one, at least, even if it's less advanced.