Skip to content
leecher1337 edited this page May 24, 2015 · 28 revisions

There's lots of ways to authenticate.

Microsoft accounts

Microsoft accounts are the ones that look like email addresses, previously known as "passport", and have many similarities with previous MSN login methods.

web-compact-ticket method

This method works for HTTPS longpolling connections, using http headers and cookies, and is the outlook.com web client uses.

Getting the cookies using a browser widget

This is based on the method that the skype clients use for microsoft account, but just getting the resulting cookies.

Open a browser to

https://login.live.com/oauth20_authorize.srf?client_id=00000000480BC46C&scope=service::skype.com::MBI_SSL&response_type=token&redirect_uri=https://login.live.com/oauth20_desktop.srf

Allow the user to log in as normal. When they're done, the browser will be redirected to https://login.live.com/oauth20_desktop.srf with an enormous fragment. The fragment might be useful, but what the webclient requires is the three cookies MSPAuth, MSPProf, WLSSC.

note that this client ID is the only one with access to the service::skype.com::MBI_SSL scope (as far as we know), previously created oauth2 clients ids (such as those needed for the now-defunct MSN XMPP gateway) won't work here.

Similarly, the redirect_uri parameter can't be changed to something more useful, returning this error in the fragment:

The provided value for the input parameter redirect_uri is not valid. The expected value is https://login.live.com/oauth20_desktop.srf or a URL which matches the redirect URI registered for this client application.

See also:

Login without a browser

Request the same URL as the previous section. Keep the MSPOK cookie.

Buried in the Javascript is a HTML <input> element, with name="PPFT". Keep the value attribute of this element.

Using the same query string as the first request, POST to https://login.live.com/ppsecure/post.srf, with the MSPOK cookie and a body consisting of url-encoded parameters:

Parameter Notes
PPFT The PPFT value you got from the first request
login Microsoft account name
password Password for that account

If all goes well, you are redirected to the same place as the previous section. If not, look for sErrTxt: followed by a Javascript string, the string including an error message.

Authenticating with HTTPS method and cookies

When sending HTTPS requests to the gateway, include the X-MSN-Auth: Use-Cookie header and the MSPAuth, MSPProf, WLSSC cookies from above

Then, when sending the ATH command, use <user><web-compact-ticket /></user> as the whole payload.

ATH 2 CON\USER 37

<user><web-compact-ticket /></user>

The outlook.com web client seems to request a UIC too from https://skypewebexperience.live.com/v1/User/Initialization (with cookies + the trouterurl and connectionid POST parameters). If requested correctly, the UIC is in the MappingContainer field of the json response.

Authenticating with oauth

The Location: HTTP-Header field in the 302 redirect from post.srf above contains a redirect-URL of oauth20_desktop.srf which contains an access_token and a refresh_token which you should extract (note that it's URLencoded, of course!):

Location: https://login.live.com/oauth20_desktop.srf?lc=1031#access_token=....very long base64 string here....&token_type=bearer&expires_in=86400&scope=service::skype.com::MBI_SSL&refresh_token=....another base64 string....&state=999&user_id=...some hex int64...

There is also expires_in parameter in seconds that specifies the number of seconds from now on when the acquired token expires. Currently this is always 1 day.

Using the refresh_token, POST to https://login.live.com/oauth20_token.srf with parameters client_id=00000000480BC46C&scope={requested scope}&grant_type=refresh_token&refresh_token={refresh_token} as described in the OAuth docs by Microsoft. The requested scope can be one of the following:

Scope Description
service::login.skype.com::MBI_SSL Required for Login on real Skype Login-Server using i.e. skylogin. This is the way Skype does it.
service::ssl.live.com::MBI_SSL To be used as <ssl-compact-ticket> on ATH CON\USER
service::contacts.msn.com::MBI_SSL Used for Contact list handling already known from MSNP18
service::m.hotmail.com::MBI_SSL ActiveSync contactlist auth token, if you want (and can) use it.
service::skype.com::MBI_SSL Used i.e. to get skype_token for cloud based APIs

You get back a bunch of JSON data to parse including the same parameters as in the OAuth Location: response above. You need to extract the access_token from there:

{ "access_token":"....some base64 encoded token you need...", "expires_in":86400, "refresh_token":"...base64 encoded refresh token, not needed...", "scope":"...the scope that you requested...", "token_type":"bearer", "user_id":"...your user_id..." }

ssl-compact-ticket method (Skylogin)

This method can be used to authenticate with the help of our SkyLogin library and the Skype login-Servers.

Getting the ssl-compact ticket with OAuth.

Just fetch the service::ssl.live.com::MBI_SSL token via the method mentioned above.

Getting the UIC

The UIC is required to successfully logon. First, fetch a service::login.skype.com::MBI_SSL token via the method mentioned above. Call SkyLogin_PerformLoginOAuth() with that token as a parameter. Then call SkyLogin_GetCredentialsUIC() with an output buffer of 1024 bytes to fill in UIC.

If it was successful, do login with:

ATH 2 CON\USER 110

<user>
  <ssl-compact-ticket>t={service::ssl.live.com::MBI_SSL token}</ssl-compact-ticket>
  <uic>{UIC acquired from Skylogin}</uic>
  <id>{Your MSN username}</id>
  <alias>{Username of Skype Partner account}</alias>
</user>

If you don't have the username of the Skype Partner account, you can get it from Skylogin with SkyLogin_GetUser().

ssl-compact-ticket method (chatservice.live.com)

This method can be used to authenticate with just plain Web-Calls without the need to use our Skylogin-Library.

Getting the ssl-compact ticket with SOAP.

Useful for clients that are migrating from earlier protocol versions, the same SOAP request explained here still works: http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO ("Computing the return value" is irrelevant, however)

Use the following parameters:

  • POST to https://login.live.com/RST.srf
  • Domain: chatservice.live.com (for <wsa:Address> below)
  • Policy Ref URI: MBI_SSL (for <wsse:PolicyReference URI="MBI_SSL"> below)
  • Set the user's username and password in <wsse:Username> and <wsse:Password>.

Here's a SOAP payload to request only this token:

<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
   xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"
   xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
   xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust"
   xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL">
   <Header>
       <wsse:Security>
           <wsse:UsernameToken Id="user">
               <wsse:Username>username@hotmail.com</wsse:Username>
               <wsse:Password>password-here</wsse:Password>
           </wsse:UsernameToken>
       </wsse:Security>
   </Header>
   <Body>
       <ps:RequestMultipleSecurityTokens Id="RSTS">
           <wst:RequestSecurityToken Id="RST0">
               <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
               <wsp:AppliesTo>
                   <wsa:EndpointReference>
                       <wsa:Address>chatservice.live.com</wsa:Address>
                   </wsa:EndpointReference>
               </wsp:AppliesTo>
               <wsse:PolicyReference URI="MBI_SSL"></wsse:PolicyReference>
           </wst:RequestSecurityToken>
       </ps:RequestMultipleSecurityTokens>
   </Body>
</Envelope>

You might want to add more entries to RequestMultipleSecurityTokens to access other sites, such as soap contact lists. That's explained in MSNPiki. TODO: move that over here.

Once you get that reply, the interesting part is here:

[snip]
<wst:RequestedSecurityToken>
    <wsse:BinarySecurityToken Id="Compact0">t=.............very long base64 string here...............&amp;p=</wsse:BinarySecurityToken>
</wst:RequestedSecurityToken>

Id="Compact0" corresponds to Id="RST0"

And just copy that ticket inside <ssl-compact-ticket> as follows

ATH 2 CON\USER 110

<user>
  <ssl-compact-ticket>t=.........very long base64 string here.........</ssl-compact-ticket>
  <ssl-site-name>chatservice.live.com</ssl-site-name>
</user>

Getting the UIC

The UIC is required to successfully logon. It can be fetched from https://skypewebexperience.live.com/v1/User/Initialization (with cookies + the trouterurl and connectionid POST parameters and Content-Type aplication/json):

{"trouterurl":"https://","connectionid":"a"}

You get back:

{"TPC":{
  "Issuer":"edf",
  "Se":"1431768898344",
  "Signature":"zv58LRCrIoPQO8kPdv4hGDEGKWwro-0CP3JWk_ifESE",
  "Sp":"connect",
  "Sr":"a",
  "St":"1431687780344"
 },
 "MappingContainer":"AAAAAAO...Ss0IdRg==",
 "MappingSkypeName":"X",
 "MappingStatus":"ACTIVE",
 "RegistrationId":"4b94d72f-ba0b-483c-9967-3adcc47a4601",
 "SupportsSkypeCalling":true,
 "SupportsChat":true,
 "registrationTTLRefreshSeconds":13230
}

If requested correctly, the UIC is in the MappingContainer field of the json response.

If it was successful, do login with:

ATH 2 CON\USER 110

<user>
  <ssl-compact-ticket>{BinarySecurityToken from SOAP request}</ssl-compact-ticket>
  <uic>{UIC from MappingContainer}</uic>
  <ssl-site-name>chatservice.live.com</ssl-site-name>
</user>

Skype usernames

Logging in with skype usernames requires using a bunch of cryptography to generate the UIC as well.

There's a python implementation of skype username login here: https://github.com/uunicorn/pyskype We wrote our own C implementation (the already mentioned SkyLogin library) that you can use as a library for your client: https://github.com/msndevs/skylogin

The login flow with a Skype username is easer than all the OAuth stuff required for MSN accounts mentioned above. On CNT call, you get a nonce:

CNT 5 CON 126

<connect-response>
  <ver>2</ver>
  <qostest>false</qostest>
  <nonce>3d97e3ac-4df8-3d88-c35f-e96242d1efcd</nonce>
</connect-response> 

User Skylogin SkyLogin_PerformLogin() with username and password to login to Skype server. Then generate the UIC with SkyLogin_CreateUICString() using the given nonce and you get back a UIC if login succeeds. Then just login with that UIC:

ATH 2 CON\USER 110

<user><uic>{your UIC}</uic><id>{Your Skype Username}</id></user>

Flowchart for login process

#After ATH After you sent your ATH and login succeeded, you receive an auth-response:

ATH 6 CON 131

<auth-response>
  <new-thread-allowed>false</new-thread-allowed>
  <p2p-migration-allowed>false</p2p-migration-allowed>
</auth-response>

Following that, you need to introduce your client to the server by sending the BND CON\MSGR command to the server:

BND 7 CON\MSGR 180

<msgr>
  <ver>2</ver>
  <altVersions><ver>1</ver></altVersions>
  <client>
    <name>Skype</name>
    <ver>0/6.16.0.105/259/</ver>
  </client>
  <epid>EB80C4E5-10DC-11D2-8C04-00A0C94C5D75</epid>
</msgr>

epid is an UUID identifying your machine. This is already known from earlier MSN versions. verspecifies the protocol version you support. In Version 2, you can register for status notifications and get and must send Registration: MIME-Headers.

The server replies with a BND answer and a nonce that you need to auth with:

BND 7 CON 660
UtcTime: 1431516231
Set-Registration: ....long base64 string....
Registration-Token-Expiry: 1431602631
Context: 1B8D4AA7AD8F8D02

<msgr-response>
  <ver>2</ver>
  <utctime>1431514361</utctime>
  <nonce>1489346893432768563572687681</nonce>
  <sample-window>0</sample-window>
</msgr-response>

You need to calculate a challenge from the Nonce to authenticate yourself as official client. The algorithm is the same as with earlier CHL-Answers in protocol. This involves calculation based on Protocol Challenge and Product ID. You can use:

Key Value
productKey YMM8C_H7KCQ2S_KL
productId PROD0090YUAUV{2B

After calculating the challenge from it, issue a PUT MSGR\CHALLENGE with that in order to login:

PUT 8 MSGR\CHALLENGE 531
Registration: ....long base64 string you received from Set-Registration answer....

<challenge>
  <appId>PROD0090YUAUV{2B</appId>
  <response>c99982d67ac970226e97c23b686d06cc</response>
</challenge>

appId is the productKey to be sent. As an answer you receive another ATH CON reply:

ATH 0 CON 158
Context: 1B8D4AA7AD8F8D02

<auth-response>
  <new-thread-allowed>false</new-thread-allowed>
  <p2p-migration-allowed>false</p2p-migration-allowed>
</auth-response>

Now you are successfully logged in and can propagate your online status with PUT MSGR\PRESENCE etc.

skype_token (Cloud based APIs)

If you want to use the cloud based APIs, i.e. for Sharing images with other contacts via the Microsoft servers (don't expecty any privacy by using MSN protocol anyway, everything is stored and logged on Microsoft's servers), you need another token, the skype_token. Here is how to get it:

Fetch service::skype.com::MBI_SSL OAuth token

Get the service::skype.com::MBI_SSL OAuth token like described in Authenticating with oauth.

Request skypetoken

POST https://api.skype.com/rps/skypetoken with the following headers:

scopes:         client
clientVersion:  0/7.4.85.102/259/
access_token:   {skype.com oauth token}
partner:        999

and you will receive the token as json:

{
    "expiresIn": 86400,
    "skypetoken": "....base64 skype token..."
}
Clone this wiki locally