Document started on 20070329 by Jeff Connelly for a Google Summer of Code 2007 Application. Information in this document is entirely the result of original research; it is not endorsed by MySpace or NewsCorp.
Important: This document will no longer be maintained, in favor of the Pidgin Developer Wiki MySpaceIM page.
Connect to im.myspace.akadns.net port 1863 TCP.
If port 1863 is not accessible, the client will try to connect using ports 6660,6661,6662,6665,6668,6669,0080 and 0443 in succession. If successful, the port will be stored in HKCU\Software\MySpace\IM\LastConnectedPort and used for further connections.
Users are identified by several means:
Tokens are separated by backslashes, which alternate as name, value, name, value, etc. For example, a complete message would be:
This message has the following information:
Name Value ============= lc 1 nc AAAA... id 1 final (empty)
The end of a message is marked with a key named final and an empty value.
The following data types are present:
Integers These are just stored as ASCII Text Also ASCII Binary Base64 encoded Boolean Presence of the key indicates 'true', absense 'false' Dictionary Multiple key=value's, separated by \x1c (field usually named 'body') List Items separated by '|'
The client connects to the server (as described in the Hosts section), and the server immediately sends a "login challenge" message. The important part of this challenge message is the binary nonce field, named nc. The client computes its login response using this field.
First note, nc is 0x40 bytes and it is split into two parts, after being base64-decoded:
SHA-1 hash the following concatenated together:
Just to be clear, there are two hashes computed above.
Using the first 0x10 bytes of the hash value as an 128-bit RC4 key, encrypt the following concatenated together:
The network interface addresses are obtained using the Win32 GetIpAddrTable API call. They should be the actual interface IPs on the system, even if they are RFC1918 private addresses. The server most likely uses these addresses to determine if a connection can be directly initiated to the host, or if it must pass through some kind of NAT device.
After encrypting, base64 the encrypted message to obtain the value for response.
response = encrypt(key=hash(hash(pw) + nc2), data=nc1+username+IP_list)where hash=SHA-1, encrypt(key, data)=RC4. Fairly simple, but took some time to reverse-engineer.
The login procedure, as described above, is implemented in msimlogin (251 lines of C++), using similar Win32 CryptoAPI calls that MySpaceIM uses. msimlogin computes response for a specific test vector (username/password: testuser/testpw, as well as certain network interfaces) and verifies the result is correct. No network communication is performed.
Also implemented in Python myc.py—this program is higher-level, in that it uses the simpler PyCrypto library instead of Win32 API calls. This script accepts a username/password on the command line and connects to MySpaceIM's servers to get a login response. Base64 conversion is performed where needed. New tests to the protocol will likely be tested in this Python script first.
The login procedure will (hopefully) ultimately be implemented in a Gaim protocol plugin, using the appropriate libraries and the C programming language.
After computing response client then the login message, as follows:
Where %s and %d are placeholders. The %s in \response\%s\ will be replaced by the base64'd response as described in the previous section, for example. The following values are acceptable to cause the MySpaceIM servers to respond:
The server quickly (even before waiting for the client response, above) sends a 'persistr' message, with various information. The 'body' field contains key=value pairs, separated by the \034 characters (the "dictionary" type described earlier in this document). It contains various parameters for the client:
In response to the "login response message", the server will send another message. If the login failed, a message will say so. If it succeeded, various information will be sent. (TODO: describe these).
Followed by: (TODO)
TODO: describe the 3 additional Challenge,ChallengeData messages. Web challenge.
FROM SERVER - web challenge
\persistr\\cmd\257\dsn\17\uid\3656574\lid\26\rid\20015794\body\Challenge=2437569020 \034ChallengeData=CTtWmfBzuq4rxoe5GJhk0bfNp7tGQljzsIKaTBOARc21898xR26Y4qs9MBohcn+FlnD/ 1+T9KL/1Ftuo9vd3elbw==\034Challenge=2437569023\034ChallengeData=3PZg0J
on home.myspace.com, client does:
GET /Modules/IM/Pages/UrlRedirector.aspx?challenge=8408570-3656574-267577152&response=5CiUQCLEkz1ryhNZpv/IPxdmXS1tNnZaDk/kGx4cQxM&target=searchfriends&targetid=3656574 HTTP/1.1\r\n
on collect.myspace.com, client does:
GET /index.cfm?fuseaction=im.friendslist&setonlinenow=1&setrsi=1&MyToken=6451502b-0ba5-4805-91b3-b5925d8f1747 HTTP/1.1\r\n
If you login without a username/IM name, MySpaceIM will prompt you to select one, very cautiously warning you cannot change it. To check if a username is available, client sends (similar to 'buddy search' message):
The server replies with:
Both messages from server, sent upon connect for each user on buddy list. \bm\100\f\6221\msg\|s|1|ss|:-)|ls||ip|0|p|0\final\ \bm\100\f\15187323\msg\|s|0|ss|Offline\final\
User status message:
User information message:
These messages are simply:
Sent periodically to keep connection alive.
Commands related to your buddy list.
Accessed from "Add" button on official MySpaceIM client. Before a buddy can be added, the buddy must be found. The user enters a username or email address, and the client contacts the server to obtain the numeric user ID used internally throughout the protocol. Buddy search message from client:
Server responds with:
The client also updates the blocklist, removing from block list (b-) and adding to accept list (a+).
cmd=258 (group info)
\persistr\\cmd\258\dsn\2\uid\3656574\lid\16\rid\64\body\GroupName=MySpaceIM Rooms\034Position=2\034GroupFlag=196612\final\\persistr\\cmd\258\dsn\2\uid\3656574\lid\16\rid\65\body\GroupName=Recent Contacts\034Position=3\034GroupFlag=196610\f
Comes predefined with groups (ways to organize contacts):
Sent from client to server, to tell server to not relay messages from these users:
The client also sends a persist message and updates the block list when deleting a buddy. Example message sequence:
Instant messages are sent by specifying the user's numeric ID in the 't' field, and received with the sender's numeric ID in the 'f' field.
Messages are sent with a 'bm' of '1'. Outgoing messages have the to ('t') field set to the numeric user ID, incoming messages have 'f' (from) se.
Message text is formatted using "tags", not quite like HTML. Tags and attribute names are single letters to save space. Attributes are either quoted with ' or `. For unknown reasons, the client uses ' but the server translates it to `.
Tags end as /(number)(tag), for example /1b, /1c, /1f, /1p. I suspect the number could be the nesting level or how many tags to close (not investigated).
Example: <f f='Times' h='16'><c v='black'><b v='white'>hello</1b></1c></1f></1p>
"Zaps" are actions, sent with bm=121, with msg text of !!!ZAP_SEND!!!=RTE_BTN_ZAPS_n, where n is the zero-based index in the array. 0 is just a regular "zap", up to 9 which is "raspberry" (whatever that means...)
For bm=100, 'f' is set to the numeric user ID of the user the message is from. 'msg' is set to an array string such as |s|0|ss|Offline (user is offline).