This is my findings on version 16 of Yahoo's YMSG protocol.
cs101.msg.sp1.yahoo.com - cs130.msg.sp1.yahoo.com
cs101.msg.ac4.yahoo.com - cs130.msg.ac4.yahoo.com
Rekkanoryo says connect to http://vcs1.msg.yahoo.com/capacity (http://cs1.msg.vip.ogk.yahoo.co.jp/capacity for Yahoo Japan) and use the IP address specified as CS_IP_ADDRESS for our server.
First we send the usual empty packet type 4C just to tell the server we are about to login
Next we send packet type 57 which only contains field type 1 containing our username
Yahoo's reply to this is packet type 57 which contains the following fields
1 - Our username 13 - Something to do with our status. Should be set to 2 in this reply 94 - The challenge stringWe then take the challenge string and use it to retrieve this url
https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=&login=USERNAME&passwd=PASSWORD&chal=CHALLENGESTRINGThe reply to this will depend on if we have the correct information or not. The first line of the response will always be an integer indicating various things.
ymsgr=OURTOKENIt has a third line as well but this serves no purpose to us.
https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=&token=OURTOKENAgain the first line of the reply is an intger to indicate the status with 0 being good and 100 meaning something is wrong.
crumb=OURCRUMBThe next two lines contain our Y= cookie and T= cookie respectively. The last line is the life of the cookie.
Function for hashing the crumb Public Function ProcessAuth16(ByVal Crumb As String, ByVal Challenge As String) Dim Crypt As String = String.Join(String.Empty, New String() {Crumb, Challenge}) Dim Hash As Byte() = HashAlgorithm.Create("MD5").ComputeHash(Encoding.[Default].GetBytes(Crypt)) Dim Auth As String = Convert.ToBase64String(Hash).Replace("+", ".").Replace("/", "_").Replace("=", "-") Return Auth.ToString End FunctionHere is the function as used in Pidgin
/* This is the y64 alphabet... it's like base64, but has a . and a _ */ static const char base64digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; /* This is taken from Sylpheed by Hiroyuki Yamamoto. We have our own tobase64 function * in util.c, but it has a bug I don't feel like finding right now ;) */ static void to_y64(char *out, const unsigned char *in, gsize inlen) /* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */ { for (; inlen >= 3; inlen -= 3) { *out++ = base64digits[in[0] >> 2]; *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)]; *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; *out++ = base64digits[in[2] & 0x3f]; in += 3; } if (inlen > 0) { unsigned char fragment; *out++ = base64digits[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (inlen > 1) fragment |= in[1] >> 4; *out++ = base64digits[fragment]; *out++ = (inlen < 2) ? '-' : base64digits[(in[1] << 2) & 0x3c]; *out++ = '-'; } *out = '\0'; }We now send packet type 54 to our server with the following fields:
1 - username 0 - username 277 - The Y cookie not including the Y= part 278 - The T cookie not including the T= part 307 - Our hash created using the Y64 function 244 - Rekkanoryo says this is internal build number. I just use 2097087 2 - username 2 - Not sure why we use 2 again but this one just contains the character 1 98 - Country but best just use us 135 - Messenger version number. Currently I use 9.0.0.1389And that's it. We have successfully logged in using YMSG version 16.