Installing a Wave Federation Prototype Server on Gentoo

The instructions on Google's Wave Protocol wiki can be easily applied to Gentoo Linux. It's actually pretty easy to set up your own wave server. This is just a minimalist working implementation of the server, it doesn't have all the features of the server at wave.google.com. In particular, you can't connect to it using a web browser as a client. So it's interesting to see how the protocol works, but it doesn't help much if you're trying to figure out how to make the best use of a Google Wave account.

I didn't need to deviate much from the instructions on the Google site. The only Gentoo-specific change was to set Openfire to use the 1.6 Java SDK. The wave protocol server will be an extension to an XMPP server, so we'll start by installing Openfire:

$ sudo emerge -av net-im/openfire

Copy the sample configuration file and make the copy is owned by the jabber user:
# cp /opt/openfire/conf/openfire.xml.sample /opt/openfire/conf/openfire.xml
$ sudo chown jabber:jabber opt/openfire/conf/openfire.xml

I left the ports (9090 and 9091) and language configuration as they were. Then, update the Gentoo wrapper config file so it uses the 1.6 SDK:

$ sudo vim /etc/conf.d/openfire
$ tail -n 2 /etc/conf.d/openfire
# GENTOO_VM=sun-jdk-1.5
GENTOO_VM=sun-jdk-1.6

Use a browser to connect to Openfire at http://localhost:9090/ and make the initial configurations. I tend not to like wizards, but the Openfire config wizard here is straightforward and pretty slick.

  1. Server Settings:
    • Domain: desktop.nick # I used my hostname here
    • Admin Console Port: 9090
    • Secure Admin Console Port: 9091
  2. Database Settings:
    • Select Embedded database. HSQLDB should enough for testing.
  3. Profile Settings:
    • Default
  4. Administrator Account:
    • Admin Email Address: test@desktop.nick # I used a real email address here but it shouldn't matter.
    • New Password: ******
    • Confirm Password: ******

Once this is done, restart Openfire:
# /etc/init.d/openfire restart

Then log back into http://localhost:9090/ using username 'admin' and the password we used on the last step. It seems that the wizard's interface is counterintuitive because the username one would expect to use the email address we gave, but that's not the case. Okay, so maybe the wizard is not so slick.

In the web interface, navigate to Server -> Server Settings -> External Components.

  • Service Enabled: select Enabled
    • Port: 5275 # This is the default
    • Default shared secret: sharedsecret # This will be in plaintext
  • Allowed to Connect: select Whitelist
    • Subdomain: wave
    • Shared secret: sharedsecret # Same as above

Navigate to Server -> Server Settings -> Security Settings.

  • Client Connection Security: leave Optional
  • Server Connection Security: select Custom
    • Server Dialback: Available
    • TLS Method: Optional
    • Accept self-signed certificates: checked

Strangely, whenever I reload that page it always comes up with the Client connection as Custom and the Server connection as Optional, the reverse of what I want. The wave server seems to actually work, so I suspect that the configuration changes I'm making are sticking and the way the change appears is a UI bug. I left other settings alone as this is not a public facing server. Openfire is now configured.

The next thing is to install the wave protocol extension. Obviously, there's nothing in the Gentoo portage tree yet, so we'll grab the sources from Google. I put them in the /opt directory to keep them separate from software manage by portage. They're making the sources available via mercurial, so the first thing I needed to do was emerge that.

$ sudo emerge -av dev-util/mercurial
...
$ sudo mkdir /opt/wave
$ sudo chown nick:nick /opt/wave
$ cd /opt/wave
$ hg clone https://wave-protocol.googlecode.com/hg/ wave-protocol # this pulls down a 15 meg directory structure
$ cd wave-protocol
$ ant

During the build process I got some warnings like this warning: unmappable character for encoding ASCII, but in the end it came out alright: BUILD SUCCESSFUL

The next step is to generate self-signed SSL certificates. This can be done from inside the /opt/wave/wave-protocol directory. I used my desktop name as the common name. Everything else could be left empty, but I put stuff in to make it feel more complete:


$ openssl genrsa 1024 | openssl pkcs8 -topk8 -nocrypt -out desktop.nick.key
$ openssl req -new -x509 -nodes -sha1 -days 365 -key desktop.nick.key -out desktop.nick.crt
Country Name (2 letter code) [AU]:NA
State or Province Name (full name) [Some-State]:OR
Locality Name (eg, city) []:Portland
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Dangerous Systems, Ltd
Organizational Unit Name (eg, section) []:Troublemakers
Common Name (eg, YOUR name) []:desktop.nick
Email Address []:test@desktop.nick

Test the certificate and key pairs to make sure the moduluses match:
$ openssl x509 -modulus -in desktop.nick.crt -noout
$ openssl rsa -in desktop.nick.key -modulus -noout

Copy the example config file and make changes as seem necessary.
$ cp run-config.sh.example run-config.sh

I only changed a few settings:
WAVE_SERVER_DOMAIN_NAME=desktop.nick
WAVE_SERVER_HOSTNAME=desktop.nick
XMPP_SERVER_SECRET=sharedsecret
XMPP_SERVER_PING=desktop.nick

Now, we can start the server. This command won't daemonize so we'll need to continue in another window:
$ ./run-server.sh

If everything went okay, the wave protocol prototype server is now running. We can now test it using the included client. The interface is nothing like the Ajax-heavy browser version. As I understand it, the point is that you can use this as a starting point to writing your own client. The included client acts a little bit like an IRC client. I'll connect in two terminal clients:

Here's the first terminal window
$ /opt/wave/wave-protocol/run-client-console.sh thingone
thingone@desktop.nick> /help
Commands:
connect user@domain server port connect to server:port as user@domain
open entry open a wave given an inbox entry
new create a new wave
add user@domain add a user to a wave
remove user@domain remove a user from a wave
read set all waves as read
undo [user@domain] undo last line by a user, defaulting to current user
scroll lines set the number of lines to scroll by with { and }
view mode change view mode for the open wavelet (normal, xml)
log dump the log to the screen
dumplog file dump the log to a file
clearlog clear the log
quit quit the clien
Scrolling:
{ scroll up open wave
} scroll down open wave
thingone@desktop.nick> /new
thingone@desktop.nick> /open 0
thingone@desktop.nick> /add thingtwo@desktop.nick

Now I'll connect from another terminal:

$ /opt/wave/wave-protocol/run-client-console.sh thingtwo
thingtwo@desktop.nick> /open 0
thingtwo@desktop.nick> hi everybody

In thingone's terminal window we see the message appear:
Blip: b+7_UAHW
hi everybody

Obviously, not quite the online collaboration replacement for email+IM+wiki quite yet. But as a proof of concept, we can see that it works.