Introduction
The MSN messenger protocol allows developers to create their own version of MSN. There are many reasons why you may want to develop your own Messenger version. It could be for organisational purposes or to add more features. This article explains how to use the Messenger protocol. This article only explains how to get authenticated. It does not explain how to send messages between users. You can also download the source sample to get a better understanding.
Connecting To MSN
In order to successfully login to MSN Messenger you need to get authenticated. This happens in three phases. In every phase, the program you develop (Client) sends a series of commands to a MSN server. The server responds with a series of commands, which consist of a number of parameters. Let's have a look at the three phases.
Authentication Server
The first thing you need to do is connect to the authentication server. The original MSN client uses the host messenger.hotmail.com
and port 1863
. The code below uses the TcpClient
Class from the System.Net.Sockets
package to connect to the host messenger.hotmail.com
using port 1863
.
TcpClient msnTcp = new TcpClient();
try
{
msnTcp.Connect("messenger.hotmail.com", 1863);
if (msnTcp.Connected)
{
}
else
{
}
}
catch (UriFormatException UFE)
{
}
Once you are connected to the authentication server you need to send the first of many commands to the server. Every command you send to the server must include a transaction ID. A transaction ID is a number which increments by one every time you send a command to the MSN server. The response from the server includes the transaction ID that was sent previously to the server. This is to acknowledge that the server is responding to the correct command. Let's begin with the first command we need to send to the MSN server.
The first command is the version command. The client (in this case your program) sends the versions that it can support to the server and waits for the server to respond. The command looks like the following:
VER 1 MSNP8 CVR0
Before we can use this command we need to setup a NetworkStream
, StreamReader
and StreamWriter
. The code below initialises the three Classes mentioned:
NetworkStream networkStream = msnTcp.GetStream();
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
A NetworkStream
object is used for sending and receiving byte data over the TCP/IP. This is done using TcpClient.GetStream()
. The StreamReader
Class is used to read the response from the server and the StreamWriter
Class is used to send data to the server.
We can now use the streamWriter
object to send our first command to the server. The following code sends the VER
command to the server with a transaction ID. Note the transaction ID starts from 1
.
streamWriter.WriteLine("VER 1 MSNP8 CVR0");
streamWriter.Flush(); </td />
After sending the command we need to read the response from the server. This is done using the following code:
string strVersion = streamReader.ReadLine();
At this stage the Client and the server have agreed on a version in which they will communicate. We can use a message box to display the response. The response should be something like the following:
VER 1 MSNP8 CVR0
Notice that the server has responded with the same transaction ID that was included in the VER
command.
Next we need to send a CVR
command. The CVR
command sends version information about a client and operating system to the server. The server will reply with information about the version of the client that users are currently recommended to use. The CVR
command includes information about the language you speak, the name and version of your client, and the name and version of your OS. The CVR
command has a Transaction ID and 8 parameters. Details of the parameters are listed below.
- The first parameter is a hexadecimal number specifying your locale identifier (e.g. "
0x0409
" For U.S. English)
- The second parameter is your OS type (e.g. "
win
" for Windows)
- The third parameter is your OS version (e.g. "
4.10
" for Windows 98)
- The fourth parameter is the architecture of your computer (e.g. "
i386
" for Intel-compatible PCs of type 386 or above)
- The fifth parameter is your client name (e.g. "
MSMSGR
" for the official MSN Messenger client)
- The sixth parameter is your client version (e.g. "
6.0.0602
")
- The seventh parameter is always "
MSMSGS
" in the official client
- The eighth parameter is your passport.
The following code below uses the streamWriter
object to send the CVR
command.
streamWriter.WriteLine("CVR 2 0x0409 win 4.10 i386 MSNMSGR 6.2.0208
MSMSGS yourPassport@hotmail.com");
streamWriter.Flush();
Change yourPassport@hotmail.com
to the name of your hotmail passport. The code below will use the streamReader
object to read the response from the server.
string strCVR = streamReader.ReadLine();
The server will respond with a message like the following:
CVR 2 7.0.0816 7.0.0816 6.2.0208
http://msgr.dlservice.microsoft.com/download/4/b/c/
4bc83bb2-18dd-486f-943f-332a9b3e01dc/Install_MSN_Messenger_DL.exe
http://messenger.msn.com
The CVR
response from the server includes five parameters:
- The first parameter is a recommended version of the client for you to use, or "
1.0.0000
" if your client information is not recognised
- The second parameter is identical to the first
- The third parameter is the minimum version of the client that is safe for you to use, or the current version if your client information is not recognised
- The fourth parameter is a URL to download the recommended version of the client
- The fifth parameter is a URL where you can go to get more information about the client
After receiving the response to the CVR
command, we need to send a USR
command. The USR
command consists of three parameters:
- The first parameter is the authentication system which is
TWN
- The second parameter is the letter
I
(Initiating authentication)
- And finally the third parameter is the account name that you want to log on with
The server will respond with an XFR
. This indicates that you should now connect to the Notification Server. The IP address and port number is included in the response. The code below will send the USR
command using the streamWriter
object.
streamWriter.WriteLine(""USR 3 TWN I yourPassport@hotmail.com");
streamWriter.Flush();
Let's get the response from the server using the streamReader
object.
string strUSR = streamReader.ReadLine();
The server will respond with a message like the following:
XFR 3 NS 207.46.106.83:1863 0 65.54.239.140:1863
This message is very important as it indicates the IP address and Port number to connect to the Notification Server (NS). The IP address in this case is 207.46.106.83
and the port number is 1863
. We need to extract this information from the response. The following code will extract the IP address and the port number from the response.
Note: The IP address and port number that follows after the 0
indicates the IP address of the current server you are connected to.
string[] split_server_response;
split_server_response = strUsr.Split(' ');
string[] split_ip_from_port;
split_ip_from_port = split_server_response[3].Split(':');
string strNSAddress = split_ip_from_port[0];
string strNSPort = split_ip_from_port[1];
The variable strNSAddresss
now stores the IP address to the Notification Server and the variable strNSPort
contains the port number.
Phase one is now complete. We need to move onto phase two. Phase two is very similar to phase 1. We connect to the new Notification Server (NS) using the IP address and port number obtained from phase one. This phase gets us connected and logs us in using our passport password. The Notification Server (NS) contains information such as our status. It also tells us which of our contacts are online.
Notification Server
We need to create a connection to the Notification Server (NS) using the new IP address and port number obtained from phase one. The following code below creates a connection to the Notification Server.
TcpClient msnTcp = new TcpClient();
try
{
msnTcp.Connect(strNSAddress, int.Parse(strNSPort));
if (msnTcp.Connected)
{
}
else
{
}
}
catch (UriFormatException UFE)
{
}
Once again we need to setup a NetworkStream
, StreamReader
and StreamWriter
. The code below initialises the three Classes mentioned:
NetworkStream networkStream = msnTcp.GetStream();
StreamWriter streamWriter = new StreamWriter(networkStream);
StreamReader streamReader = new StreamReader(networkStream);
Now we can begin to send commands to the Notification Server (NS). Once again we need to send the VER
, CVR
and USR
commands. We can copy and paste the same code from phase one. The code below will send the VER
, CVR
and USR
commands to the Notification Server (NS).
streamWriter.WriteLine("VER 4 MSNP8 CVR0");
streamWriter.Flush();
strVersion = streamReader.ReadLine();
streamWriter.WriteLine
("CVR 5 0x0409 win 4.10 i386 MSNMSGR 6.2.0208
MSMSGS yourPassport@hotmail.com = streamReader.ReadLine();
streamWriter.WriteLine("USR 6 TWN I yourPassport@hotmail.com");
streamWriter.Flush();
strUsr = streamReader.ReadLine(); ");
streamWriter.Flush();
strCVR
Again replace yourPassport@hotmail.com
with your own passport account. Now in phase one when we reached this stage of the commands, the server responded with an XFR
command which indicated that we should connect to the Notification Server (NS). But this time the server will respond with a ChallengeString
. However in case the server is busy or is down for maintenance, the server may respond with another XFR
command indicating that you should connect to another Notification Server (NS). For this article we will assume that the server responded with a ChallengeString
.
What you should receive is a message like the following:
USR 6 TWN S lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,
ct=1062764229,kpp=1,
kv=5,ver=2.1.0173.1,tpf=43f8a4c8ed940c04e3740be46c4d1619
Above the ChallengeString
is highlighted in bold. We need to extract this ChallengeString
. The code given below will extract the ChallengeString
from the message:
string[] split_response = strUsr.Split(' ');
ChallengeString = split_response[4];
In order for the authentication of your passport account to be verified you need to generate a Ticket using the ChallengeString
. The Ticket is generated using your account (yourPassport@hotmail.com
), password and the ChallengeString
. I will not explain this part, however the download includes a Class named MSN_GetTicket.cs. You can read more about the Ticket from this link.
After generating the Ticket you need to send a USR
command to the Notification Server which includes the Ticket. The code below will send a USR
command with a Ticket to the Notification Server.
streamWriter.WriteLine("USR 7 TWN S " + Ticket);
streamWriter.Flush();
If all is successful, the server should respond with a status OK message. The message should include your passport account and your MSN Friendly name.
Phase two is now complete and you can move to phase three. Phase three is the Dispatch Server.
Dispatch Server
The Dispatch server allows you to send messages to your online friends. You need to send Commands to the Dispatch Server (DS) indicating the user you want to have an instant message with.
As I mentioned at the beginning of this article, I will only deal with the authentication part. I will write a separate article on the Dispatch Server at a later date. The download includes three MSN Classes:
- MSN_Authentication.cs
- MSN_NotificationServer.cs
- MSN_GetTicket.cs
Although there may seem to be a lot of code for an authentication, the code is actually very simple. I have included methods in the Classes, that get the response from the server so that you can see the responses from the server.
You can get more tutorials here.