Snow Leopard Server includes an iChat server which supports the use of plug-in transports enabling users to connect to other instant messaging networks, like MSN, thereby enabling iChat users to speak to contacts on the MSN network as well as have multiple machines logged into the same MSN account at the same time. Here’s how to set it up…
History
When Apple first released their own instant messaging client, they partnered with America Online and implemented the AOL Instant Messenger protocol. As I’m an American, this was fortuitous to me, as this was the service that myself and most of my friends used. After moving to Australia, many of my local friends preferred Microsoft’s MSN Messenger, a different, incompatible network. Not only was Microsoft’s Mac software atrocious, I’ve never really been a fan of having their trash on my computer, so I avoided its use.
Many friends started using a multi-protocol IM client named Adium, an open source project. Unfortunately, while I love the ethics behind open source software, and much of my business relies upon it, I’ve still yet to see a half decent open source user interface, and Adium was no exception.
Leading up to the release of OS X 10.4, Tiger, many hoped Apple would add compatibility with more IM networks into iChat. When Tiger was released in 2005, Apple did indeed include a new protocol, but not MSN, Yahoo, or any other commercial service, but rather XMPP, more commonly known as Jabber, an open standard, the same protocol Google chose when implementing GoogleTalk.
Shortly after Tiger’s release, an excellent blog article by Melvin Rivera at allforces.com shot around the interwebs showing people how through iChat, they could use Jabber as a conduit or a proxy to connect to users on MSN and other IM networks. The article showed people how to setup an account at a public Jabber server that supported these other networks. This was a great trick, but I wasn’t fond of the idea of my conversations going through yet another stranger’s server.
Alongside the release of Jabber support in iChat in Tiger, Apple included a Jabber-based iChat Server in OS X Server 10.4. Myself, and a few other enterprising folks over at Apple’s discussion boards, figured out a way to install PyMSNt, a python based transport, enabling the connecting of Jabber to MSN on our own OS X servers, thus removing the need to run our iChat clients through unknown servers. Each iteration of OS X Server required us to slightly tweak the installation. Here’s how to install and configure PyMSNt on Snow Leopard Server.
Before We Start
Naturally, you need to have Snow Leopard server installed, the iChat server running, and your copy of iChat already able to connect to it.
You will also need to have the Developer Tools installed on the server, which is available from the Snow Leopard Server Install DVD or from developer.apple.com.
Lastly, you should also be relatively comfortable using Terminal. For the entire tutorial, you will need to run all commands as root, so you will either need to remember to prefix each line with sudo, or escalate yourself to root using:
sudo su
Prerequisites
There are a couple required prerequisites in the form of Python modules. Unfortunately, Snow Leopard has made things quite a bit more challenging due to the inclusion of Python 2.5 and 2.6 and the transition from 32 bit to 64 bit.
I’ve had issues getting PyMSNt to run with the default version of 2.6. Due to what I assume is Apple’s own dependencies on 2.6 (calendar/wiki server), I’m not comfortable switching the system default to 2.5.
The first module required is pyOpenSSL. pyOpenSSL happens to be built in to Apple’s version of Python 2.6, but we have to compile and install it for 2.5. You can get the latest pyOpenSSL 0.9 here:
http://sourceforge.net/projects/pyopenssl/files/pyopenssl/0.9/pyOpenSSL-0.9.tar.gz/download
Now, the installation directions say to use the standard pair of commands: python setup.py build and then python setup.py install. Unfortunately, running just python will default to Python 2.6, and compile and install it as a 2.6 module, which is not what we want. So, modify those commands to be:
python2.5 setup.py build
python2.5 setup.py install
Now, if you want avatar support beyond PNG, you need to install Python Image Library. That’s particularly hairy and not required, so feel free to either skip this or come back to it later.
Python Image Library or PIL has two optional dependencies, libjpeg and freetype. You need libjpeg to view non-PNG MSN avatars.
Many instructions on the internet will direct you to jpegsrcv6b. I could not get that to work. Instead, I did succeed with jpegsrc7:
http://www.ijg.org/files/jpegsrc.v7.tar.gz
But here’s the problem. Python 2.5 runs in 32 bit mode. The compilers try to compile libjpeg in 64 bit mode. If you’ve been following info about the way Snow Leopard works, 32 bit processes won’t load 64 big libraries/plugins and vice versa. SO, you have to compile libjpeg for 32-bit. To do that, I used:
CC="gcc -arch i386" ./configure --enable-shared --enable-static
make
make install
If you’re feeling particularly thorough, Freetype-2.3.9 should install normally without a hitch.
You can now install PIL, making sure to specify python2.5 as necessary:
python2.5 setup.py build_ext -i
After running that, TEST it with:
python2.5 selftest.py
This MUST pass. If it doesn’t something is wrong.
Finally:
python2.5 setup.py install
Configuration
Next, you need to prepare iChat server for PyMSNt. Edit /etc/jabberd/router-users.xml
You will notice an existing block like this:
<users>
<user>
<name>jabberd</name>
<secret>asdf!ghjk#</secret>
</user>
</users>
You need to add another user for your MSN transport. Let’s assume your primary Jabber ID is example.com. You should add a block for a user named msn.example.com. This does not need to resolve via DNS. So when done, it should look like this:
<users>
<user>
<name>jabberd</name>
<secret>asdf!ghjk#</secret>
</user>
<user>
<name>msn.example.com</name>
<secret>asdf!ghjk#</secret>
</user>
</users>
I found that in the past, I was able to use a different secret for the MSN handshake, but I had issues with that this time, so make the msn.example.com secret match the existing one for jabberd. Also, note this secret down as you’ll need it shortly.
As mentioned, the PyMSNt project has changed hands, but there are no files at the new home, so this tutorial expects you to download 0.11.3 (latest at the time of writing) from:
http://delx.net.au/projects/pymsnt/tarballs/pymsnt-0.11.3.tar.gz
Decompress this archive and for the sake of this tutorial, store it at /var/jabber/modules/pymsnt . You can store it anywhere else you want, but you’ll need to adjust the commands and files below accordingly.
Once you have placed it there, make sure it is owned by the jabber user/group with:
chown -R jabber:jabber /var/jabber/modules/pymsnt
Let’s change to that directory for the next few commands:
cd /var/jabber/modules/pymsnt/
You need to copy the sample config file and edit it:
cp -p config-example.xml config.xml
(the -p makes sure the resulting file is the same permissions, i.e. still owned by user jabber)
nano config.xml
(use any appropriate text editor you want. Personally, I like nano)
OK, so:
- You need to set the Jabber ID (
<jid>) to the name you defined in the router-users.xml file, e.g. msn.example.com - Set the
<host>to your primary hostname (this must resolve!) - Comment out
<background/>, making that line look like this:<!-- <background/> -->; - Make
<secret>match the<secret>you specified in router-users.xml
Save your changes and exit. That should do it for the config file for now.
Also, thanks to help from Tim Harris and the Py Transport Users Group , you need to make the following changes to src/legacy/msn/msn.py:
Change this line (113 in my file):
MSN_PROTOCOL_VERSION = "MSNP11 CVR0"
to
MSN_PROTOCOL_VERSION = "MSNP11"
And change this line (2553 in my file):
DATA = 0x20
to
DATA = 0x1000020
Next, we want to configure launchd to launch PyMSNt. Initially, under previous versions of OS X Server, I set this up to launch onDemand only if the iChat server was running. I accomplished this by using a launchd key called QueueDirectories, which only launches the job if files appear in a directory. I set it to watch the /var/run/jabber directory as iChat server placed pid files in there at launch. Unfortunately, it seems that in 10.6, it doesn’t clean these files up at quit, but I believe this is due to a change in Python’s Twisted removal of the removePID function (something that affects PyMSNt as well), and I expect Apple to fix it in the future. So, this plist will work now, and also in the future once Apple fix this.
Also, you’ll notice that you must invoke PyMSNt using python2.5, not python.
Place these contents in /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>net.cjb.delx.pymsnt</string>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python2.5</string>
<string>./PyMSNt.py</string>
</array>
<key>QueueDirectories</key>
<array>
<string>/var/run/jabberd</string>
</array>
<key>UserName</key>
<string>_jabber</string>
<key>WorkingDirectory</key>
<string>/var/jabberd/modules/pymsnt</string>
<key>StandardOutPath</key>
<string>/var/log/pymsnt.log</string>
<key>StandardErrorPath</key>
<string>/var/log/pymsnt.log</string>
</dict>
</plist>
You can leave out the StandardOutPath and StandardErrorPath directives if you don’t care about logging, but they’re helpful at least for getting this up and running. However, the log file needs to be owned by Jabber, so create it and change the owner if you’re going to keep those directives in:
touch /var/log/pymsnt.log
chown jabber /var/log/pymsnt.log
Last, but not least, load the launchd plist with:
launchctl load -w /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
At this point, the installation is complete. However, you still need to register for the MSN service and unfortunately, this ability is not built into iChat. The only application for OS X that I’m aware of that can do this is PSI. You will need version 0.13 or greater to connect to Snow Leopard’s Jabber server. When configuring, in Account Properties under Connection:
- You have to manually specify host/port, specifying 5223 as port.
- Set “Encrypt connection:” to “Legacy SSL”
- Set “Allow plaintext authentication:” to “Over encrypted connection”

Registration
After changing those settings, you should now be able to login with PSI and register for the MSN transport. Head back over to the allforces.com article and perform Step 4. Once you have done this, if you have an existing buddy list, you should get bombarded with authorisations which you can happily ignore and quit PSI and open iChat and see your MSN contacts in your buddy list!
Buddy List Format
As mentioned in Step 5 at allforces.com, for iChat to associate your buddies with your contacts in your Address Book, you need to store or add them as Jabber buddies and observe the format required. For example, if your buddy is john@hotmail.com, and your MSN transport is at msn.example.com, you need to add a Jabber buddy in the format of john%hotmail.com@msn.example.com. Once the contact is in your buddy list, it’s much easier to Get Info, and attach them to the proper Address Book contact, which will enable iChat to create the handle in the proper format for Address Book.
What’s Supported and What’s Not?
Pretty much just straight text chat, avatars and file transfers are supported. Many of the extra emoticons from MSN won’t come through, but rather you’ll just see their text equivalents (::mad::).
Yahoo contacts are not supported. However, note that there is a similar Jabber transport for Yahoo, which is beyond the scope of this article.
No audio or video of any kind is supported.
What’s Improved?
Since Jabber supports multiple logins from multiple devices, and its the Jabber server keeping you logged into MSN, you can now be logged into MSN from multiple devices, which is something neither Adium, nor MSN Messenger itself can do!
Known Issues
Yahoo Upsell
Every time you sign on to Jabber, and thus onto MSN automatically, Microsoft will send you an instant message recommending that you upgrade to a more recent version of MSN Messenger so that you can communicate with Yahoo contacts (which does not work via this method):
New! Send messages to your friends on Yahoo! Messenger - install the latest version of Windows Live(TM) Messenger.
You can ignore this, delete this, or embrace it. My workaround was to add the name of the MSN transport (the source of the IM) as a buddy, e.g. msn.example.com, and then attach the built-in AppleScript action, “Auto Decline.applescript” when receiving a Text Invitation from them. This makes iChat immediately close the message. Unfortunately, it has the side effect of hiding the occasional relevant message from the transport, such as the fact that you might have been disconnected.
iCal Server Clash
This is only relevant if you are running Snow Leopard’s iCal Server on the same server. The default port for unencrypted iCal Server communications is port 8008. It seems that when launched, it creates two additional listeners on the next 2 higher adjacent ports, being 8009 and 8010 in the default configuration. Unfortunately, naughty Apple has trounced on Jabber’s reserved port usage of 8010 for file transfers. Bad Apple! Worse, there is little documentation about what iCal Server uses 8010 for. Initially, I tried shifting the unencrypted iCal Server port to something else. As I only use the encrypted port for client communication, I didn’t really care. However, most annoyingly, the wiki server calendar client looks for the iCal Server at 8008 over localhost, and I don’t know how to change that.
What can you do?
Believe it or now, if you launch PyMSNt first, and iCal Server afterwards, iCal Server adjusts itself accordingly, and everything is dandy. Unfortunately, that’s not how the startup sequence typically goes, so you’ll find the need to do this shuffle after restart.
launchctl unload /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
serveradmin stop calendar
launchctl load /Library/LaunchDaemons/net.cjb.delx.pymsnt.plist
serveradmin start calendar
I believe there are dependencies one can put in launchd plist files, but I haven’t experimented with that yet.
What else can you do?
You can make PyMSNt listen for file transfers at a different port. In config.xml, the directive to change is <ftJabberPort>8010</ftJabberPort> and pick a different number. I’ve tried changing this to something quite different, like 18010 and then doing port mapping on my router to map the public 8010 to 18010 since the iCal Server doesn’t need public access to 8010, only via localhost. I haven’t been able to test this thoroughly yet. Also, this is of no use to someone not using port mapping. It would be great if I could bind PyMSNt to NOT use localhost to avoid the conflict, but that’s beyond my knowledge.