collective.converse
integrates converse.js and the
Prosody XMPP server into Plone.
Before running buildout, you'll need to install various libraries needed by Prosody:
- lua5.1: The Lua 5.1 interpreter - liblua5.1: Lua 5.1 library - libssl 0.9.8 or later: OpenSSL - libidn11: GNU libidn library, version 1.1 - libevent
These can be installed on Debian/Ubuntu with apt-get:
sudo apt-get install lua5.1 liblua5.1-dev libidn11-dev libssl-dev luarocks libevent-dev
On Mac, if you use brew:
brew install libidn libevent openssl lua51
Note
It could happen that lua51 installs into /usr/local/Cellar/lua@5.1. If so, then symlink it to /usr/local/Cellar/lua51.
and if you use MacPorts:
sudo port install libidn libevent openssl lua51* luarocks*
Note
luarocks and lua51 need to be fixed on macports (luarocks to use lua5.1 instead of the latest, and lua5.1 to use default lua CFLAGS instead of overriding them).
To integrate collective.converse
into your own project, you'll want to
include prosody.cfg
from this repo in your bulidout config.:
[buildout] extends = /path/to/prosody.cfg
Then you'll need to create a secrets.cfg
file, with the following format:
[prosody.cfg.lua] # TODO: don't use these values, they're for demonstration purposes only, # generate your own OR YOU WILL BE HACKED! otp_seed = XVGR73KMZH2M4XMY token_secret = JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7 [instance] zope-conf-additional += <product-config collective.converse> instance_name Plone xmpp_domain example.org auto_subscribe 1 bosh_url http://example.org:5280/http-bind otp_seed XVGR73KMZH2M4XMY token_secret JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7 debug 0 </product-config>
Don't use the secrets values in the example above, generate your own. Read the section User Authentication below to see how to do that.
The zope-conf-additional
additional section above lets you configure your
XMPP settings via buildout. In the very least you'll need to provide the
otp_seed
and token_secret
values because they can't be configured from
within Plone itself (for security reasons).
However the other values can be configured at the ${plone}/@@xmpp-settings
URL once you've installed collective.converse.
To find out what the configuration settings are for, go read their descriptions
at ${plone}/@@xmpp-settings
.
Be aware that the values in secrets.cfg
will override any manually
configured settings whenever you restart Plone. If you want to avoid that, then
don't put those value in secrets.cfg
.
Once you've configured secrets.cfg, you can run buildout.
Plone generates HMAC tokens which contain time-based one-time-pin (TOTP) tokens and are hashed with SHA256.
Converse.js, the JavaScript XMPP client receives this token and then passes it on to Prosody which verifies the tokens authenticity, i.e. it checks whether the token was really generated by Plone.
For this to work, Plone and Prosody need to share a common secret key and a secret OTP seed.
We use a Prosody modules mod_sasl_hmac_md to register a custom SASL authentication mechanism (called "SASL-HMAC") and mod_auth_hmac_md to create an authentication provider that accepts signed TOTP tokens.
The tokens are in HMAC-SHA256 format and are generated by Plone when a client wants to sign in to Prosody (the XMPP server).
A private key needs to be generated that will be shared between Plone and Prosody. This key is used in the HMAC token construction in Plone and by mod_auth_hmac.lua in Prosody to verify the HMAC token.
Your key needs to be 32 bytes (the HMAC specification recommends that the key length is at least as long as the output of the hash function used, in our case sha256 which outputs 32 byte strings).
You can generate the key as follows:
>>> import pyotp >>> pyotp.random_base32(length=32) u'JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7'
The key then needs to be added to secrets.cfg.
prosody_token_secret = JYXEX4IQOEYFYQ2S3MC5P4ZT4SDHYEA7
Each token contains a TOTP (time-based one-time-pin) which restricts that token's validity to a specific time window which is usually a few minutes starting from token creation.
For the TOTP we also need a shared secret key between Plone and Prosody. This can be generated with [pyotp](https://pypi.python.org/pypi/pyotp).
>>> import pyotp >>> pyotp.random_base32() u'XVGR73KMZH2M4XMY'
The key then needs to be added to secrets.cfg.
prosody_otp_seed = XVGR73KMZH2M4XMY