📄 msntest.cs
字号:
return new ServerCommand(line);
}
}
/// <summary>
/// This function closes the connection, if its open
/// </summary>
public void Dispose()
{
if( _socket != null )
{
_reader.Close();
_writer.Close();
_stream.Close();
_socket.Close();
_socket = null;
}
}
public int Connect(string UserName, string UserPassword)
{
string host = "messenger.hotmail.com";
int port = 1863;
string ChallengeString;
ServerCommand ServCom;
try
{
while( true )
{
ConnectSocket(host, port);
// Login and provide the current version you want to use
WriteCommand("VER", "MSNP9 CVRO", true);
ServCom = ReadCommand();
// check return value
if (ServCom.CommandName != "VER")
{
return 1;
}
// act like a real msn client and send some information
WriteCommand("CVR","0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS " + UserName, true);
ServCom = ReadCommand();
// check return value
if (ServCom.CommandName != "CVR")
{
return 1;
}
// This indicates that you want to connect this user
WriteCommand("USR", "TWN I " + UserName, true);
ServCom = ReadCommand();
// If the server provided the USR answer, than you have got a challenges
// You need this challenge to get a valid clienticket
if (ServCom.CommandName == "USR")
{
ChallengeString = ServCom.Param(3);
break;
}
// if the command is nog XFR, then whe don't know what to do anymore
if (ServCom.CommandName != "XFR")
{
return 1;
}
else
{
Console.WriteLine("Redirected to other server");
}
// If we get here, then we have to change servers, get the IP number
string[] arIP = ServCom.Param(2).Split(':');
host = arIP[0];
// Also get the portnumber
port = int.Parse(arIP[1]);
// close the current connection
Dispose();
}
// Get a valid ticket
string clientticket = GetClientTicket(UserPassword, UserName, ChallengeString);
if (clientticket == "401")
{
// if the code is 401, then most likely there was a error in
// your username password combination
return 401;
}
else if (clientticket == "0")
{
// unknown error occured
return 1;
}
else
{
// finnaly send a valid ticket ID back to the server
WriteCommand("USR", "TWN S " + clientticket, true);
ServCom = ReadCommand();
// if the response is USR <trans> OK then we are succesfully connected
if (ServCom.CommandName != "USR" && ServCom.Param(1) != "OK")
{
return 1;
}
// retrieve the correct username (is always the same, but who cares)
// and retrieve you screenname that you have provided last time
_UserName = ServCom.Param(2);
_ScreenName = ServCom.Param(3);
// Change the status in online, so can other see you come online
WriteCommand("CHG", "NLN", true);
return 0;
}
}
catch (Exception ex)
{
Console.WriteLine("Unknown error occured errocode: " + ex.Message);
return 1;
}
}
/// <summary>
/// This function asks a valid login adres, to connect to
/// </summary>
/// <returns>true if succeed</returns>
public bool GetLoginServerAddres()
{
// Make a request to the server, this adresses are being used in the MSN messenger
HttpWebRequest ServerRequest = (HttpWebRequest)WebRequest.Create("https://nexus.passport.com/rdr/pprdr.asp");
// Get the result
HttpWebResponse ServerResponse = (HttpWebResponse)ServerRequest.GetResponse();
if (ServerResponse.StatusCode == HttpStatusCode.OK)
{
string retrieveddata = ServerResponse.Headers.ToString();
PassportUrls = new ArrayList();
// Pick up the header en split
string[] result = ServerResponse.Headers.Get("PassportURLs").Split(',');
foreach (string s in result)
{
// The actual adres is provided behind the '=' sign
PassportUrls.Add(s.Substring(s.IndexOf('=') + 1));
}
ServerResponse.Close();
return true;
}
else
{
ServerResponse.Close();
return false;
}
}
/// <summary>
/// This function connects to a login server to request a valid ticket,
/// that will be used to login on the MSN servers
/// </summary>
/// <param name="Password">The password of the user, this is just plain text. The connection is HTTPS
/// <param name="Username">The complete username</param>
/// <param name="ChallengeString">A challenge string that you have got, wile connecting to a msn server
/// <returns>a valid ticket, that you send back to the server to get connected</returns>
public string GetClientTicket(string Password, string Username, string ChallengeString)
{
// First get a valid login adres for the initial server
if (GetLoginServerAddres())
{
// On the position of DALOGIN is a valid URL, for login
string uri = "https://" + PassportUrls[DALOGIN];
HttpWebRequest ServerRequest;
HttpWebResponse ServerResponse;
try
{
while( true )
{
Console.WriteLine("Connecting to: " + uri);
// Make a new request
ServerRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
ServerRequest.AllowAutoRedirect = false;
ServerRequest.Pipelined = false;
ServerRequest.KeepAlive = false;
ServerRequest.ProtocolVersion = new Version(1,0);
// Send the authentication header
ServerRequest.Headers.Add("Authorization", "Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + Username.Replace("@", "%40") + ",pwd=" + Password + "," + ChallengeString + "\n");
// Pick up the result
ServerResponse = (HttpWebResponse)ServerRequest.GetResponse();
// If the statuscode is OK, then there is a valid return
if (ServerResponse.StatusCode == HttpStatusCode.OK)
{
// Pick up the information of the authentications
string AuthenticationInfo = ServerResponse.Headers.Get("Authentication-Info");
// Get the startposition of the ticket id (note it is between two quotes)
int startposition = AuthenticationInfo.IndexOf('\'');
// Get the endposition
int endposition = AuthenticationInfo.LastIndexOf('\'');
// Substract the startposition of the endposition
endposition = endposition - startposition ;
// Close connection
ServerResponse.Close();
// Generate a new substring and return it
return AuthenticationInfo.Substring(startposition + 1, endposition -1 );
}
// If the statuscode is 302, then there is a redirect, read the new adres en connect again
else if (ServerResponse.StatusCode == HttpStatusCode.Found)
{
uri = ServerResponse.Headers.Get("Location");
}
}
}
catch (WebException e)
{
// If the statuscode is 401, then an exeption occurs
// Think that your password + username combination is not correct
// return number so that calling functions knows what to do
if (e.Status == WebExceptionStatus.ProtocolError)
{
return "401";
}
else
{
return "0";
}
}
}
return "0";
}
}
/// <summary>
/// This class is uses, to use the result of the server in a easy way
/// </summary>
public class ServerCommand
{
// The command name of the response
private string _cmdID;
// The entire response
private string _line;
// The parameters of the response (without transactionID, and divided with a space)
private string[] _params;
/// <summary>
/// Constructor for parsing the result line from the streamreader
/// </summary>
/// <param name="line"></param>
public ServerCommand(string line)
{
_line = line;
// always 3 characters command
_cmdID = line.Substring(0, 3);
if (!(_cmdID == "QNG"))
{
_params = line.Substring(4).Split(' ');
}
}
/// <summary>
/// This constructor makes a valid object
/// but the command name idicates that there was something wrong
/// </summary>
public ServerCommand()
{
_line = "";
_cmdID = "ERROR";
}
public string CommandName
{
get { return _cmdID; }
}
public string Param(int index)
{
return _params[index];
}
public int ParamCount
{
get { return _params.Length; }
}
public string Line
{
get { return _line; }
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -