imfreedom/knowledgebase

8516cb8c3403
The build agents don't have convey 0.15 yet..
# MySpaceIM
> **NOTE:** The MySpace IM network has been shut down.
## Introduction
This document is a reverse-engineered protocol specification for
[MySpaceIM](http://www.myspace.com/im). The first version of this document was
created for build 673, but as of 2007-06-02 it refers to build 697 or newer.
This page is a known to be incomplete. It was originally started started by
User:jeff, residing at http://developer.pidgin.im/wiki/MsimProtocolSpec . An
older HTML version of this document is available.
Some text in italics refers to
[msimprpl](http://developer.pidgin.im/MySpaceIM), the MySpaceIM protocol plugin
for libpurple.
Contributions to this document are welcome!
## Servers
*msim_login*
Connect to im.myspace.akadns.net, which will point you to one of several MSIM
servers (currently 204.16.33.139-195).
69 - 74 connection attempts are allowed (usually 69) until the server will
block you out for a period of time.
All connections are made using TCP. The default port is 1863, but the client
will try to connect using ports 6660,6661,6662,6665,6668,6669,0080 and 0443 in
succession if 1863 fails. If successful, the port will be stored (the Win32
client uses `HKCU\Software\MySpace\IM\LastConnectedPort` in the registry) and
tried first for future connections.
## User Identifications
Users are identified by several means:
* User ID (uid) - unique number; used extensively by protocol. User's web page
at http://myspace.com/user_ID.
* Email address - used to sign in, and locate buddies.
* Username/IM Name - "Your unique name that can't be changed", shown on buddy
lists, and for user's web page at http://myspace.com/username.
* Display Name - shown on your web page, can be changed and non-unique.
* First Name and Last Name - "private and used for search only".
## Message Structure
*MsimMessage*
Tokens are separated by backslashes, which alternate as name, value, name,
value, etc. For example, this message:
```
\k1\v1\k2\v2\xxx\yyy\final\
```
contains the following information:
Key | Value
--- | -----
k1 | v1
k2 | v2
xxx | yyy
The end of a message is marked with \final\. Note that this marker is not a
key/value pair.
Special characters are escaped with '/':
Character | Escaped As
--------- | ----------
/ | /1
\ | /2
*msim_escape*, *msim_unescape*
The following data types can be defined:
Type | Description
---- |------------
Integers | These are just stored as ASCII, decimal
Text | ASCII
Binary | Base64 encoded
Boolean | Presence of the key indicates 'true', absense 'false'
Dictionary | Multiple key=value's, separated by \x1c
What I call here *dictionaries* (also known as associative arrays, hashes) are
often present in a field named body. Keys inside a dictionary use CamelCase and
boolean values are represented as a string, True or False, instead of the
absence of presence of a key.
Escape codes in dictionaries:
Character | Escaped As
--------- | ----------
' or ` | '
# | #
" | "
Escape codes in '|' delimited lists:
Character | Escaped As
--------- | ----------
/ | /1
\ | /2
## Login Sequence
*msim_login*, *msim_process*, *msim_login_challenge*
Upon connection, server immediately sends a "login challenge" message to the client:
Key | Type | Description
--- | ---- | -----------
lc | integer | 1
nc | binary | 0x40-byte nonce
id | integer | 1
Client sends login challenge response:
Key | Type | Description
--- | ---- | -----------
login2 | integer | 196610
username | text | Email address to login using
response | binary | Challenge response, derived using algorithm described below
clientver | integer | 673, corresponds to 1.0.673.0 in "About" dialog (679, etc.)
reconn | integer | 0
status | integer | 100
id | integer | 1
Server replies with:
Key | Type | Description
--- | ---- | -----------
lc | integer | 2
sesskey | integer | Session key
proof | Same as userid? Sometimes differs.
userid | Numeric userid
profileid | Same as userid?
uniquenick | Username
id | integer | 1
The session key is sent by the client in almost every future message.
Errors:
Code | Message | Type
---- | ------- | ----
259 | The supplied email address is invalid. | Fatal
260 | The password provided is incorrect. | Fatal
Code 260 is no longer used if trying to login with an invalid email address,
circa client build 404. Instead, invalid email and invalid passwords both
return code 260. See
[MySpaceIM Info Disclosure: Silently Fixed](http://www.planb-security.net/2006/09/myspaceim-info-disclosure-silently.html)
### Challenge/Response Login Algorithm
*msim_login_challenge*
response is computed from:
* First 0x20 bytes of nc field -- nc1
* Last 0x20 bytes of nc field -- nc2
* User's password, in UTF-16 little endian (only the first 10 characters, in
lower case)
* User's ASCII email address
Compute SHA1(SHA1(password) + nc2). This will result in 0x14 bytes. Using the
first 0x10 bytes (128 bits) as an RC4 key, encrypt the following concenated
together:
* nc1
* User's ASCII email address
* Four zero bytes: 00 00 00 00
* 1 byte = number of network interfaces on this machine
* IPv4 address of interface used to connect to server in network order.
Example: \x7f \x00 \x00 \x01 (for 127.0.0.1)
* IPv4 addresses of host's network interfaces in network order. Example: \x0a
\x00 \x00 \x40 (for 10.0.0.64), \xc0 \xa8 \x58 \x01 (for 192.168.88.1), and
so on.
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.
High-level summary:
```
response = RC4encrypt(key=hash(hash(pw) + nc2), data=nc1+username+IP_list)
```
## Buddy Messages
*msim_send_bm*
Messages from client or server:
Key | Type | Description
--- | ---- | -----------
bm | integer | Message type.
sesskey | integer | Session key.
t | integer | Userid to send message to (outgoing messages only).
f | integer | Userid message came from (incoming messages only).
date | integer | For offline messages, timestamp of when message was sent, Unix time
cv | integer | Client version build number.
msg | text | Text of message.
Known message types for bm:
Value | Notes | msg
----- | ----- | ---
1 | Instant message | See markup below.
100 | Status message | List, see below.
121 | Action Message | Zap or typing notification.
122 | Media Message | Key/value pairs joined by ampersands, see below.
124 | Profile Message | Contains age, song, gender, display name, headline, etc.
126 | Status Mood Message | Contains Status mood information
Servers appear to pass all buddy messages between clients, even if the type
('bm' field) is unrecognized. The
[Miranda IM plugin](http://forums.miranda-im.org/showthread.php?p=122912) uses
bm code 200 to "send miranda + plugin version information as is done with many
other protocols".
### Instant Messages
*msim_incoming_im*, *msim_send_im*
Message text is formatted using "tags", similar to HTML, and (aside from the
escaped forward slashes) is valid XML. Tags and attribute names are single
letters to save space. Attributes are either quoted with ' or backquote. For
unknown reasons, the client uses ' but the server translates it to the
backquote.
Tags end as in HTML: `<tag>...</tag>` (appears in protocol dumps as `< /1tag>`,
because `/` is encoded as `/1`).
Example:
```
<f f='Times' h='16'><c v='black'><b v='white'>hello</1b></1c></1f></1p>
```
Known tags:
* `<p>` = paragraph
* `<a>` = anchor (link)
* h = href
* This tag is self-closed, for example: `<a h='http://google.com' />`
displays http://google.com. It doesn't seem to be possible to change the
text of the link.
* `<f>` = font tag
* f = font face (Arial, Arial Black, Comic Sans MS, Courier New, Tahoma,
Times, Verdana, or another)
* h = font height, in pixels. For displays set to 96 DPI:
* 4pt = 5 (sizes must be between 4 and 72 points)
* 5pt = 7
* 6pt = 8
* 7pt = 9
* 8pt = 11
* 9pt = 12
* 10pt = 13
* 11pt = 15
* 12pt = 16
* 13pt = 17
* 14pt = 19
* 15pt = 20
* 16pt = 21
* 17pt = 23
* 18pt = 24
* 72pt = 96
* Note: 1 pt = 1/72 inch, and 1 inch = 96 pixels (at 96 dpi), so height
= round((96/72.)*point_size).
* Note 2: At 120 DPI, 72pt is sent as h=120, and so on. Points are
always 1/72 ", so the real formula is height =
round((DPI/72.)*point_size). For more information on font sizes, see
this Planet SoC blog post: Week 7 Updates: Notifications and Font
Sizes
* s = bit field of text decoration; add/OR together:
* 1 = bold
* 2 = italic
* 4 = underline
* `<c>` = text color tag
* v = color (a name like "black", "white", or "rgb(253,0,0)",
"rgba(253,0,0,100)" (alpha), or "transparent")
* `<b>` = background color tag
* v = color
* `<i>` = image (emoticon/smiley)
* n - name: bigsmile growl mad scared tongue devil happy messed sidefrown
upset frazzled heart nerd sinister wink geek laugh oops smirk worried
googles mohawk pirate straight kiss
Known character entities:
Character | Entity
--------- | ------
" | &quot;
& | &amp;
' | &apos;
< | &lt;
> | &gt;
### Incoming Status Message
*msim_status*
Examples:
* |s|0|ss|Offline
* |s|1|ss|:-)|ls||ip|0|p|0
Index | Type | Description
----- | ---- | -----------
0 | text | s
1 | integer | 0 for offline (or hidden), 1 for online, 2 for idle, 5 for away
2 | text | ss
3 | text | Headline
4 | text | ls
5 | text |
6 | integer | 0
7 | text | p
8 | integer | 0
### Action Message
*msim_incoming_action*, *msim_send_typing*
Zaps are, in order (0-9): zap whack torch smooch hug bslap goose hi-five punk'd
raspberry. Zaps are sent with this msg:
* !!!ZAP_SEND!!!=RTE_BTN_ZAPS_n, where n is a 0-based index into zap array.
For typing notifications:
* %typing%
* %stoptyping%
#### Group Messages
*Trac ticket*: http://developer.pidgin.im/ticket/4691
Group messages seen coming from http://myspace.com/78744676 (or
http://myspace.com/myspaceim), a chatroom added to the buddy list by default:
* GroupCount=25;
* Offline= (someone's user ID)
* MsimMarkup-formatted messages
* ContactType=2
These messages also had:
Field | Type | Description
----- | ---- | -----------
f | integer | Chatroom ID, for example 78744676
cv | integer | Client version, build 1000
gid | integer | Group ID? 23
aid | integer | User ID of person talking in that chatroom, if applicable
When a user talks in a chatroom, f is set to the user ID of a user representing
the chatroom, and aid is set to the user ID of the user talking. Not sure how
gid fits into this. You appear to get chatroom messages if the chatroom user is
on your buddy list, even if you haven't joined the chatroom. (Note: need to
figure out terminology here, I've been using chatroom but MySpaceIM uses the
term 'group').
### Media Messages
*not implemented*
bm of 121 is used to send media.
Seems to be sent when someone first messages you. Example transcript:
```plaintext
(05:31:51 PM) someone: cmdtype=1&reqid=856000425340460813&contenttype=1&
(05:32:01 PM) someone: Hello
(05:32:04 PM) me: hi there
(05:32:07 PM) someone: cmdtype=1&reqid=856000425340466400&contenttype=1&
(conversation continues)
```
Sending background picture:
```
cmdtype=3&reqid=15704865745410042&contenttype=1&
```
Picture (less than 600K) invitation request:
```
cmdtype=4&reqid=15704865745421128&contenttype=4&filename=Winter.jpg
```
If picture is not accepted, or offer canceled:
```
cmdtype=5&reqid=15704865745413631&contenttype=4&accept=no
```
cmdtype
Code | Description
---- | -----------
1 | ??? Sent initially
3 | Send background image
4 | Picture invitation request
5 | Accept/deny picture invitation request
### Profile Message
This message contains information on the buddy from their profile. Sometimes it
is empty, sometimes it contains the following dictionary-encoded keys:
Name | Type | Description
---- | ---- | -----------
Age | integer | Age in years
AvatarURL | string | URL of avatar
BandName | string |
SongName | string |
ContactType | integer | 2
DisplayName | string |
Gender | string | M or F
Headline | string |
ImageURL | string | URL of JPEG image on MySpace Content Distribution Network
IMName | string | Instant messaging name, blank if user doesn't have MySpaceIM
UserName | string |
RoomLastLogin | integer |
Location | string | city, state, country
ShowAvatar | boolean | True or False
Example:
```plain
\bm\124\f\78744676\msg\Age=27AvatarUrl=BandName=cold war kidsContactType=2DisplayName=MySpaceIMGender=FHeadline=ImageURL=http:/1/1a895.ac- images.myspacecdn.com/101111/149/186/11111986894_m.jpgIMName=MySpaceIM Chat RoomLastLogin=128287884600000000Location=SANTA MONICA, California, USShowAvatar=FalseSongName=Hang Me Up To DryTotalFriends=119814UserName=myspaceim\final\
```
## Set Status Messages
To change your own status:
Key | Type | Description
--- | ---- | -----------
status | integer | Status code.
sesskey | integer | Session key.
statstring | string | User-settable status message (for online or away).
locstring | string | Location string? Sometimes "userinfo;"
Status codes:
Code | Description
---- | -----------
0 | Hidden/offline
1 | Online
2 | Idle
5 | Away
Unknown codes (tested 3, 4, and 6) are recognized as offline by the official
client.
Same code as in incoming status messages.
## Keepalives
From server:
Key | Type | Description
--- | ---- | -----------
ka | boolean | Presence indicates this is a keepalive message.
Sent every 3 minutes to keep connection alive.
## Add Buddy
*msim_add_buddy*
Key | Type | Description
--- | ---- | -----------
addbuddy | boolean | Presence indicates to add buddy.
sesskey | integer | Session key.
newprofileid | integer | Userid to add.
reason | text | Empty
The client also sends a persist message to update the buddy list. Example
sequence (after looked up userid), adding uid 6221:
* \addbuddy\\sesskey\420159774\newprofileid\6221\reason\\final\ - add buddy
* \blocklist\\sesskey\420159774\idlist\b-|6221|a+|6221\final - update blocklist
* \persist\1\sesskey\420159774\cmd\514\dsn\0\uid\180301984\lid\9\rid\31\body\ContactID=6221.GroupName=IM Friends.Position=1000.Visibility=1.NameSelect=0\final\ - update contact info
Errors:
Code | Message | Type
---- | ------- | ----
1539 | The profile requested is already a buddy. | Non-fatal
## Delete Buddy
*msim_remove_buddy*
Key | Type | Description
--- | ---- | -----------
delbuddy | boolean | Presence indicates to delete buddy.
sesskey | integer | Session key.
delprofileid | integer | Userid of buddy to delete.
The client also sends a persist message and updates the block list when deleting a buddy. Example message sequence:
* \delbuddy\\sesskey\97309878\delprofileid\175349942\final\ - delete buddy with numeric ID 175349942
* \persist\1\sesskey\97309878\cmd\515\dsn\0\uid\3656574\lid\8\rid\18\body\ContactID=175349942\final\ - delete from on-server buddy list?
* \blocklist\\sesskey\97309878\idlist\a-|175349942|b-|175349942\final\ - update block list; remove user (-) from accept (a) and block (b) list?
## Block List
*msim_add_buddy updates the blocklist, not implemented: User-settable
blocklists.*
Key | Type | Description
--- | ---- | -----------
blocklist | boolean | Presence indicates to change block list.
sesskey | integer | Session key.
idlist | list | Encoded list of buddies to block/unblock, see below.
`idlist` is constructed from one of the following format strings:
* a-|%lu|b-|%lu
* a-|%lu|b+|%lu - block userid %lu
* b-|%lu|a+|%lu - unblock userid %lu
where %lu is the userid. Current guess is that a is for accept list, b is for
block list, - removes and + adds, but this has not been proven. Example idlist,
when "Who can contact me: Anyone" and "Who can see when I'm online: Anyone" is
set:
* w0|c0|a-|*|b-|*|b+|blockeduser1...
Removes all users from accept list and block list, then adds blockeduser1
(userid).
If "Who can contact me: Only people on my Contact List" and "Who can see when
I'm online: Anyone", then idlist is:
* w0|c1|a-|*|a+|buddy1|buddy2|...|buddyN|b-|*
where buddyN is the userid of each buddy on the contact list. |a-|*| removes
all users from the accept list, |a+|...| adds only buddies to accept list,
|b-|* removes all buddies from blocklist.
Opcodes:
* w# = Who can see when I'm online? 0=Anyone, 1=Only people on my contact list
* c# = Who can contact me? 0=Anyone, 1=Only people on my contact list
* a- = remove from accept list
* a+ = add to accept list
* b- = remove from block list
* b+ = add to block list
* \* = all userids
## Get Info
Key | Type | Description
--- | ---- | -----------
getinfo | boolean | Presence indicates that this is a get info request.
sesskey | integer | Session key.
uid | integer | Userid to look up.
Examples:
```
\getinfo\\sesskey\53348262\uid\6221\final\
```
```
\getinfo\\sesskey\70517308\uid\180301984\final\
```
Specifics of this message's purpose are unknown.
See also the 1,0,2 persist message (they're often sent together).
## Set Info
Key | Type | Description
--- | ---- | -----------
setinfo | boolean | Presence indicates that this is a get info request.
sesskey | integer | Session key.
info | dictionary | Packed dictionary of information to set.
'info' dictionary has same fields as setinfo. Examples:
```
\setinfo\\sesskey\70517308\info\Age=20AvatarUrl=BandName=ContactType=1DisplayName=MySpaceIM Protocol Plugin for PidginGender=MImageURL=http:/1/1a513.ac-images.myspacecdn.com/1images01/118/1m_0ad6cfe1ae4b676622e98c6d4cb3cef0.pngLastLogin=128290072800000000Location=California, USShowAvatar=FalseSongName=TotalFriends=4UserName=msimprpl\final\
```
```
\setinfo\\sesskey\70517308\info\Age=20AvatarUrl=BandName=ContactType=1DisplayName=MySpaceIM Protocol Plugin for PidginGender=MImageURL=http:/1/1a513.ac-images.myspacecdn.com/1images01/118/1m_0ad6cfe1ae4b676622e98c6d4cb3cef0.pngLastLogin=128290072800000000Location=California, USShowAvatar=FalseSongName=TotalFriends=4UserName=msimprpl\final\
```
## Web Challenge Request (webchlg)
Key | Type | Description
--- | ---- | -----------
webchlg | boolean | Presence indicates a web challenge request.
sesskey | integer | Session key.
n | integer | 0, unknown.
See also 1,17,26 persistance request.
## Persist Messages
*msim_process_reply*, *msim_new_reply_callback*
Persist messages allow the client to send or request information to or from the server. Thanks to Nathan Peterson for reversing the structure of these commands.
Client sends a persistance request:
Key | Type | Description
--- | ---- | -----------
persist | integer | 1
sesskey | integer | Session key.
uid | integer | Your userid.
cmd | integer | Command type.
dsn | integer | Command family.
lid | integer | Command subcode.
rid | integer | Request/response ID. Client sends request with unique rid
body | dictionary | Dictionary of information.
cmd, dsn and lid uniquely identify each command.
Known cmd/dsn/lid combinations:
cmd | dsn | lid | Description
--- | --- | --- | -----------
1 | 0 | 1 | List all contacts
1 | 0 | 2 | Get contact information by ID
1 | 1 | 4 | Lookup IM information about yourself
1 | 1 | 7 | Lookup IM information by userid
1 | 2 | 6 | List all groups
1 | 4 | 3 | Lookup MySpace information by userid
1 | 4 | 5 | Lookup MySpace information about yourself
1 | 5 | 7 | Lookup MySpace information by username/email
1 | 7 | 18 | Get mail status
1 | 9 | 14 | Your username has been changed (UserName, Code=0 for ok). Also need to call \setinfo.
1 | 17 | 26 | Web challenge
1 | 21 | 18 | Get user song
1 | 101 | 20 | Server information
2 | 2 | 16 | ??? Group flags
2 | 9 | 14 | Check username availability
2 | 14 | 21 | Add all my friends from MySpace.com
2 | 15 | 22 | Add my top friends from MySpace.com
3 | 2 | 16 | ??? Delete something?
514 | 1 | 10 | Change user preferences
514 | 0 | 9 | Update contact information
514 | 16 | 25 | Invite to MySpaceIM
515 | 0 | 8 | Delete buddy, ContactID in buddy (see also delbuddy)
cmd appears to be a bitfield:
Bit | Description
--- | -----------
0-7 (0-255) | Command bits, 1=get, 2=action, 3=delete
8 (weight 256) | Set indicates reply, clear indicates request.
9 (weight 512) | Set indicates to an action, clear indicates to get information.
10 (weight 1024) | Set indicates an error, clear is normal.
So for example, a reply to 1,5,7 (lookup MySpace information by username/email) would have cmd,dsn,lid of 257,5,7, and a reply to 1,9,14 would be 258,9,14. These aren't listed separately in the list above because they're the same command.
Server responds with a persistance reply (persistr):
Key | Type | Description
--- | ---- | -----------
persistr | boolean | Presence indicates persistr message.
uid | integer | Your userid.
cmd | integer | Command. This appears to the client request cmd bitwise ANDed or added with 256.
dsn | integer | Subcommand - matches dsn of request.
lid | integer | Subcommand - matches lid of request.
rid | integer | Request/response ID - matches rid of request. Server sends responses back with same rid as in the client's request, allowing client to match responses to requests.
body | dictionary | Response information.
### 1,0,1: List all contacts
Request:
An empty body. Example:
```
\\persist\1\sesskey\46543777\cmd\1\dsn\0\uid\3656574\lid\1\rid\39\body\\final\
```
Reply has a key for each of the contacts. Keys:
Key | Type | Description | Example
--- | ---- | ----------- | -------
ContactID | integer | Userid of contact | 6221
Headline | text | Headline | :-)
Position | integer | Offset on buddy list | 0
GroupName | text | Group that buddy is located in | IM Friends
Visibility | integer | | 1
AvatarUrl | text | URL of avatar
ShowAvatar | boolean | Show avatar? True or False
LastLogin | integer | Login timestamp | 128177889600000000
IMName | text | Instant messaging name, blank if user doesn't have MySpaceIM
NickName | text |
NameSelect | integer | 0
OfflineMsg | text | Offline message
SkyStatus | integer | ? | 0
Example:
```
ContactID=6221.Headline=:-).Position=1.GroupName=IM Friends.Visibility=1.AvatarUrl=.ShowAvatar=False.LastLogin=128182824000000000.IMName=.NickName=.NameSelect=0.OfflineMsg=.SkyStatus=0
```
(repeats for additional contacts)
### 1,0,2: Get contact information
Get information on a contact.
Request:
Key | Values | Description
--- | ------ | -----------
ContactID | integer | Userid of contact.
Example, uid 180301984 looking up uid 6221:
```
\persist\1\sesskey\53348262\cmd\1\dsn\0\uid\180301984\lid\2\rid\7\body\ContactID=6221\final\
```
See also getinfo command.
Reply:
Key | Values | Description
--- | ------ | -----------
ContactID | integer | Userid of contact (actually present twice, identically).
Headline | text |
Position | integer | position in buddy list.
!GroupName | text | "Recent Contacts"
Visibility | integer | 2
!AvatarUrl | text |
!ShowAvatar | True/False |
IMName | text |
!NickName | text |
!NameSelect | integer | 0
### 1,1,4: Lookup IM Information about Yourself
Sent with an empty body.
Similar response as to 1,1,17, except also includes OfflineMessage field.
### 1,1,7: Lookup IM Information by UserID
*msim_lookup_user*
Used for looking up MySpaceIM information on a user, as opposed to purely
MySpace information.
Request body:
Key | Values | Description
--- | ------ | -----------
UserID | integer | The userid to lookup.
Reply body:
Key | Values | Description
--- | ------ | -----------
UserID | integer | 0
Sound | True/False |
!PrivacyMode | integer | "Who can contact me?" 0=Anyone, 1=Only people on my Contact List.
!ShowOnlyToList | True/False | "Who can see when I'm online?" False=Anyone, True=Only people on my Contact List.
!OfflineMessageMode | integer | "When I'm offline, receive and store messages from:" 0=Everyone, 1=Only people on my Contact List, 2=No one.
Headline | text |
Avatarurl | text |
Alert | integer |
!ShowAvatar | True/False |
IMName | text |
!ClientVersion | integer | Client build number.
!AllowBrowse | True/False |
IMLang | ??? | Language.
LangID | integer | Language ID.
### 1,2,6: List all groups
Request: TODO
Reply:
Key | Type | Description | Example
--- | ---- | ----------- | -------
GroupID | integer | Numeric ID of group | 21672248
GroupName | text | Textual name | IM Friends
Position | integer | Offset in buddy list | 1
GroupFlag | integer | Unknown | 131073
### 1,4,3: Lookup MySpace User Info by UID
*msim_lookup_user*, when called with a string of numbers
Lookup user information by userid. This command is called MySpaceUserInfo by
error messages.
Request:
Key | Values | Description
--- | ------ | -----------
UserID | integer | The userid to lookup.
Examples:
```
\persist\1\sesskey\70517308\cmd\1\dsn\4\uid\180301984\lid\3\rid\16\body\UserID=6221\final\
```
Reply:
Key | Values | Description
--- | ------ | -----------
UserName | text | Unique username. Present only if in request.
Email | text | Email address. Present only if in request. Fields below only present if user exists.
UserID | integer | Numeric user ID.
ImageURL | text | URL to image
DisplayName | text | Display name, need not be unique.
BandName | text |
SongName | text |
Age | integer | Age in years.
Gender | M/F | Gender.
Location | text | City, State, Country
!TotalFriends | integer | Total number of friends on MySpace.
(Same as 1,5,7 reply but also has TotalFriends).
Error messages are sent with cmd=1025 (error bit set), and following body:
Key | Type | Description
--- | ---- | -----------
UserID | integer | Userid of message request which had the error.
ErrorMessage | text | Textual description of error
Observed error messages:
* Request time elapsed configured has passed for MessageType: Read, DataType:
MySpaceUserInfo
* Persistence Queue Overflow
### 1,4,5: Lookup MySpace User Info About Yourself
Seems to be the same as 1,4,3 but looks up your information. You still need to
pass UserID=xxx in the request body.
### 1,5,7: Lookup MySpace User Info by String
*msim_lookup_user*, when called with a username
Lookup user information by username or email. Known as MySpaceUserInfoByString
in error messages.
In the body dictionary of the request, one of these keys is present:
Key | Values | Description
--- | ------ | -----------
UserName | text | The username to lookup.
Email | text | The email address to lookup.
Reply body:
Key | Values | Description
--- | ------ | -----------
UserName | text | Unique username. Present only if in request.
Email | text | Email address. Present only if in request. Fields below only present if user exists.
UserID | integer | Numeric user ID.
ImageURL | text | URL to image, mangled an unknown way.
DisplayName | text | Display name, need not be unique.
BandName | text |
SongName | text |
Age | integer | Age in years.
Gender | M/F | Gender.
Location | text | City, State, Country
Error reply, here cmd=1025 (error bit set):
Key | Type | Description
--- | ---- | -----------
UserName | integer | Username of message request which had the error.
ErrorMessage | text | Textual description of error. Once observed: Request time elapsed configured has passed for MessageType: Read, DataType: MySpaceUserInfoByString
### 1,7,18: Check Mail Status
*msim_check_mail*, *msim_check_mail_cb*
Checks for new mail, comments, or friend requests. You have to periodically
poll to see if you have any.
Request: empty
Example:
```
\persist\1\sesskey\53348262\cmd\1\dsn\7\uid\180301984\lid\18\rid\4\body\\final\\
```
Reply:
Key | Type | Description | Example
--- | ---- | ----------- | -------
Mail | boolean | Whether you have new mail | On
BlogComment | boolean | Whether you have new blog comments | On
ProfileComment | boolean | Whether you have new profile comments | On
FriendRequest | boolean | Whether you have new friend requests | On
PictureComment | boolean | Whether you have new picture comments | On
Example:
```
\persistr\\cmd\257\dsn\7\uid\180301984\lid\18\rid\4\body\Mail=On\final\\
```
### 1,17,26: Web Challenge
not implemented
Webchallenge is used to authenticate with the myspace.com website, so that
links to the website (such as for mail notification) do not require logging in
again through the web interface. From Scott Ellis: "I have the popup windows
for my notifications opening the same web pages as the official client, but
without the 'token' it will usually redirect to the myspace login page and say
'you must be logged in to do that'. Getting the web authentication sorted would
be a huge bonus."
Reply:
Key | Values | Description
--- | ------ | -----------
Challenge | integer | Challenge (present 3 times).
ChallengeData | binary | Base64 encoded 30 bytes (present 3 times).
Unknown purpose. Causes client to send an HTTP request to home.myspace.com: GET
/Modules/IM/Pages/UrlRedirector.aspx, with URL-encoded parameters:
Key | Values | Description
--- | ------ | -----------
challenge | X-Y-Z, 3 integers | X is as of yet unknown, Y is the uid, Z is the sesskey
response | binary | ??? base64-encoded data. Probably the result of an algorithm using the X-Y-Z above
target | text | Several options: searchfriends, profile, comment, message, probably more...
targetid | integer | The userid of the target profile for the target action
UrlRedirector.aspx replies with a simple HTML page that states "Object moved"
followed by a hyperlink and a cookie in the HTTP header. The cookie is
obviously our MySpace login validation. The client then proceeds to send an
HTTP request to the page the hyperlink points to.
These messages are currently ignored by msimprpl, and are not required for
basic functionality. Used for web authentication?
See also 'webchlg'.
### 1,21,28: Get User Song
*not implemented*
If the music note icon on the buddy list in the official client is clicked,
this message will be sent.
Request:
Key | Type | Description
--- | ---- | -----------
UserID | integer | Userid to get song information on.
Reply:
Key | Type | Description
--- | ---- | -----------
UserID | integer |
ProfileSong | text | URL to page with an embedded Flash media player
### 1,101,20: Server Information
*not implemented*
This message is sent without the client asking for it, so the response bit in
cmd is always set (cmd = 257). Sent upon connecting to the server, before
logging in. It contains various timers and limits:
Key | Type | Description
--- | ---- | -----------
AdUnitRefreshInterval | integer | 10
AlertPollInterval | integer | 180
ChatRoomUserIDs | list separated by ; | Userids for chatrooms
CurClientVersion | integer | 595, even though 673 is newer
EnableIMBrowse | True/False | False
MaxAddAllFriends | integer | 100
MaxContacts | integer | 1000
MinClientVersion | integer | 529
MySpaceNowTimer | integer | 720 (seconds)
PersistanceDataTimeout | integer | 900 (seconds)
UseWebChallenge | integer | 1
WebTicketGoHome | True/False | False
ChatRoomUserIDs is, as of 2007-04-15, a list of the following userids:
UserID | Username | Display Name
------ | -------- | ------------
78744676 | myspaceim | hi
142663391 | myspaceimchat | jorge
142910130 | myspaceimchat2 | jorge
123521495 | testbot5 | test
138528147 | myspacejorge4 | myspacejorge4
140271072 | TEST4MATTCHUNG2 | tester
163733130 | myspacecdn | jorge
None of these userids autoreply when IM'd.
### 2,9,14: Set username
Key | Type | Description
--- | ---- | -----------
UserName | text | Name to use
Example request:
```
\persist\1\sesskey\469958979\cmd\2\dsn\9\uid\240626417\lid\14\rid\28\body\UserName=msimprpl2\final\
```
Example reply:
```
\persistr\\cmd\258\dsn\9\uid\240626417\lid\14\rid\28\body\UserName=msimprpl2.Code=0\final\
```
This sets the username. \setinfo with with a UserName in the body is also sent
afterwards.
### 2,14,21: Add all my friends from MySpace.com
Sent when go to "Add all my friends" from File -> IM Set Up Wizard. Imports
your friends from the website to IM.
Request:
Key | Type | Description
--- | ---- | -----------
GroupName | text | "IM Friends", group to add contacts to?
Example:
```
\persist\1\sesskey\581636623\cmd\2\dsn\14\uid\3656574\lid\21\rid\39\body\GroupName=IM Friends\final\
```
Reply:
Key | Type | Description
--- | ---- | -----------
Completed | boolean | "True" if contacts were added
Example:
```
\persistr\\cmd\258\dsn\14\uid\3656574\lid\21\rid\39\body\Completed=True\final
```
Client then sends a 1,0,1 persistance request ("List all contacts") to get the
updated list. After getting all the buddies, it removes them from the blocklist
(b-) and adds to the accept list (a+, see blocklist command). After that, it
sends a 514,0,9 ("Set contact information") on each contact, in body passing
ContactID, GroupName, Position, Visibility, NickName, and NameSelect.
### 2,15,22: Add my top friends from MySpace.com
Sent when go to "Add my top friends" from File -> IM Set Up Wizard. Imports
your friends from the website to IM.
Request:
Key | Type | Description
--- | ---- | -----------
GroupName | text | "IM Friends", group to add contacts to?
Example:
```
\persist\1\sesskey\24577352\cmd\2\dsn\15\lid\22\rid\96\body\GroupName=IM Friends\final\
```
Reply:
Key | Type | Description
--- | ---- | -----------
Completed | boolean | "True" if contacts were added
Example:
```
\persistr\\cmd\258\dsn\15\uid\96902854\lid\22\rid\96\body\GroupName=IM Friends\034Completed=True\final\
```
### 514,0,9: Set contact information
Sets the location and group of a buddy.
Request:
Key | Type | Description
--- | ---- | -----------
ContactID | integer | Userid of contact.
GroupName | text | "Recent Contacts"
Position | integer | 0, 1000
Visibility | integer | 1, 2
NickName | text |
NameSelect | integer | 0
Example:
```
\persist\1\sesskey\70517308\cmd\514\dsn\0\uid\180301984\lid\9\rid\18\body\ContactID=6221\034GroupName=Recent Contacts\034Visibility=1NameSelect=0\final\
```
### 514,1,10: Change User Preferences
*not implemented*
body dictionary, of settings to change:
Key | Values | Description
--- | ------ | -----------
Sound | True/False | ???
PrivacyMode | integer | "Who can contact me?" 0=Anyone, 1=Only people on my Contact List.
ShowOnlyToList | True/False | "Who can see when I'm online?" False=Anyone, True=Only people on my Contact List.
OfflineMessageMode | integer | "When I'm offline, receive and store messages from:" 0=Everyone, 1=Only people on my Contact List, 2=No one.
Headline | text | Your profile headline.
Alert | integer | 1
ShowAvatar | True/False |
IMName | text | Your instant messenger name. Official client lets you change IM name capitalization and spacing.
### 514,16,25: Invite to MySpaceIM
*not implemented*
Request:
Key | Type | Description
--- | ---- | -----------
Recipient | integer | Userid to invite.
Subject | text | "Invite to IM"
Body | text | Entered message text.
This might be a generic command to send MySpace messages (not verified).
Client also sends this instant message:
Key | Type | Description
--- | ---- | -----------
bm | integer | 1
sesskey | integer | Session key.
t | integer | Userid to send message to.
cv | integer | Client version build number.
msg | text | "Invited to MySpaceIM on hh::mm PM on mm/dd/yy"
## Error Messages
*msim_error*
An error notice is sent from the server in certain situations.
Key | Type | Description
--- | ---- | -----------
error | boolean | Presence indicates this is an error message.
errmsg | string | ASCII English description of error.
err | integer | Error code.
fatal | boolean | Presence indicates error is fatal to the connection.
Known errors:
Code | Message | Type
---- | ------- | ----
1 | There was an error parsing an incoming request. | Fatal
2 | This request cannot be processed because you are not logged in. | Fatal
3 | This request cannot be processed because of an invalid session key. | Fatal
6 | This profile has been disconnected by another login. | Fatal
259 | The supplied email address is invalid. | Fatal
260 | The password provided is incorrect. | Fatal
267 | The network cannot accept authentications from the indicated version of the client. | Fatal
270 | Error getting contact list from DB (seen in #7584) | Fatal
4352 | Invalid user ID in persistence request. | Fatal
4608 | PM Restart | Unknown
Code 259 is no longer used if trying to login with an invalid email address,
circa client build 404. Instead, invalid email and invalid passwords both
return code 260. See
[MySpaceIM Info Disclosure: Silently Fixed](http://www.planb-security.net/2006/09/myspaceim-info-disclosure-silently.html)
## Logout
To logout:
Key | Type | Description
--- | ---- | -----------
logout | boolean | Presence indicates this is a logout message.
sesskey | integer | Session key.
## UDP Polling Protocol?
MySpaceIM appears to also use a UDP protocol, perhaps as a means of exchanging
status. During the messenger startup, it will transmit a number of UDP messages
from a single port, to a variety of addresses, presumably known servers. The
destination port varies, though this might be an artifact introduced through
NAT port mappings.
The initial packet sent to the remote servers has a reasonably constant format,
though the content and length both vary. The first two bytes appear to be a
sequence number and a flag bit, with the flag bit last. The third byte is
always 0x02, at least in the initial dialog. Afterwards, the packet content
varies more.
A sample packet capture can be found at
[capture file](http://mywebpages.comcast.net/rpapo/MySpaceIM.enc).
## Client/Executable Analysis
### MySpaceIM Setup
MySpaceIM_Setup.exe, which you can download at http://myspace.com/myspaceim, is
not the actual client. Instead, it fetches
http://im.myspace.com/nsis/currentversion.txt , parses the key=value pairs on
each line, and downloads $(SETUPURL)$(SETUPFILE) using HTTP. German, French,
Italian, and Spanish clients can also be downloaded. The version described in
this document is build '673.
The MySpaceIM client also occasionally checks
http://im.myspace.com/nsis/currentversion.txt to see if an upgrade is
available.
### Libraries/Code Used by MySpaceIM.exe build 673
Interesting strings found in executable:
String' | Comments
------- | --------
@(#)$Id: TRIONAN.C,v 1.4 2005/12/08 22:03:59 rkrueger Exp $ | libxml2
inflate 1.1.4 Copyright 1995-2002 Mark Adler | Inflate/deflate decompression/compression, RFC1950 from zlib
inflate 1.1.3 Copyright 1995-1998 Mark Adler | zlib, png
deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly | zlib
unzip 0.15 Copyright 1998 Gilles Vollant | zip archive files
Skinux Object Runtime Error | Skinux Engine for skinning
Copyright (C) 1998, Thomas G. Lane | JPEG library
Copyright (c) 1992-2004 by P.J. Plauger, licensed by Dinkumware, Ltd. ALL RIGHTS RESERVED. | Standard C++ library in VC++
gpsp.gamespy.com | [1], for finding other gamers (not used yet?)
\m\%d\xfer\%d %u %u | Unknown message. Near \gamename\.
63.208.226.223 | Mysterious host, blocks pings, owned by Level3
### myim: URLs
MySpaceIM registers the myim: URL scheme to invoke
C:\Program Files\MySpace\IM\MySpaceIM.exe %1. The URL includes a command
followed by URL-encoded parameters, for example: myim:addContact?uID=1&cID=2.
#### addContact
*msim_uri_handler_addContact_cb*
Adds user to contact list. Used on
http://collect.myspace.com/index.cfm?fuseaction=im.friendslist
Name | Value
---- | -----
uID | Your userid, or 0 for default
cID | Contact userid
auto | true if "Add all the people on this page to my IM List!" clicked, empty cID
#### sendIM
*msim_uri_handler_sendIM_cb*
Used in JavaScript posted at
http://developer.pidgin.im/attachment/ticket/194/section%20of%20code%20from%20myspaceJS032.js%20.txt
Name | Value
---- | -----
uID | Your userid, or 0 for default
cID | Contact userid
## Credits
The majority of this specification was produced from original research by
User:Jeff
Thanks also to Nathan Peterson for independently reverse-engineering parts of the protocol. Parts of this document were drawn from [it](http://myspaceim.pbwiki.com/).
Thanks also to Scott Ellis, developer of the
[MySpaceIM protocol plugin for Miranda IM](http://forums.miranda-im.org/showthread.php?p=122912),
for contributing to this document.
## Useful Links
* [Wikipedia page](http://en.wikipedia.org/wiki/MySpaceIM)
* [Pidgin wiki page](http://developer.pidgin.im/wiki/MySpaceIM)