Protocols/MSNP/MSNP13/SOAPTweener
MSNP Protocol |
Version 13 |
General |
Overview • Changes |
Challenges • Sharing Folders |
Example Session |
SOAP Address Book |
Retrieving the lists |
Updating the membership lists |
Updating the AB |
Other features using SOAP |
Offline Messaging |
Passport 3.0 authentication |
Overview |
Introduction • Terms • Clients |
Reference |
Error List • Commands • Relying Party Suite • Spotlife |
Services |
XMPP • HTTP Gateway • Tabs • Activities |
Documentation |
Development Tools • MSNP Grid |
Polygamy • URLs used by MSN |
Documents |
Protocol Versions |
Version 21 |
Version 18 |
Version 16 |
Version 15 |
Version 14 |
Version 13 |
Version 12 |
Version 11 |
Version 9 |
Version 8 |
Version 2 |
MSNC |
Introduction • P2P • Object Descriptor • Display Pictures • File Transfer |
Scenarios |
Microsoft Messenger for Mac |
MSNP on WebTV (MSNTV) |
Passport 3.0
Since 1 April 2006, Microsoft has begun removing the old way of authenticating, called 'Passport 1.4', and has replaced it with 'Passport 3.0'. Every client that still uses Passport 1.4 will eventually receive 401 Unauthorized responses, whether using SSL or not, with an 'Account locked out' message.
The new way of authenticating uses SOAP.
Unlike Passport 1.4, only SSL works successfully. Otherwise you will receive an error (S:ClientInvalid Request).
SOAP Request
The target URL for the SOAP request is https://loginnet.passport.com/RST.srf. The server does not discriminate on User Agent.
You will need the tweener ticket from the USR TWN S command received from the NS. URL decode the ticket, then replace the commas (,) with ampersands (&). You must then XML encode (HTML encode) the username, password and ticket.
Below is an example of the SOAP request sent to the server by the official client.
POST /RST.srf HTTP/1.1\r\n Accept: text/*\r\n User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n Host: loginnet.passport.com\r\n Content-Length: 3098\r\n Connection: Keep-Alive\r\n Cache-Control: no-cache\r\n \r\n <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust"> <Header> <ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo"> <ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp> <ps:BinaryVersion>4</ps:BinaryVersion> <ps:UIVersion>1</ps:UIVersion> <ps:Cookies></ps:Cookies> <ps:RequestParams>AQAAAAIAAABsYwQAAAAzMDg0</ps:RequestParams> </ps:AuthInfo> <wsse:Security> <wsse:UsernameToken Id="user"> <wsse:Username>alice@passport.com</wsse:Username> <wsse:Password>password</wsse:Password> </wsse:UsernameToken> </wsse:Security> </Header> <Body> <ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" 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>http://Passport.NET/tb</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> </wst:RequestSecurityToken> <wst:RequestSecurityToken Id="RST1"> <wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType> <wsp:AppliesTo> <wsa:EndpointReference> <wsa:Address>messenger.msn.com</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <wsse:PolicyReference URI="?lc=1033&id=507&tw=40&fs=1&ru=http://messenger.msn.com&ct=1144076956&kpp=1&kv=7&ver=2.1.6000.1&rn=NgNNrtGr&tpf=de8dd66124cd310ab344aa850bc5aa9b"></wsse:PolicyReference> </wst:RequestSecurityToken> </ps:RequestMultipleSecurityTokens> </Body> </Envelope>
SOAP Response
Redirect
Just as with Passport 1.4, you may get redirected to a new server. Simply connect to the new server (indicated in bold below) and re-submit your SOAP request (above).
HTTP/1.1 200 OK\r\n Connection: close\r\n Date: Mon, 03 Apr 2006 15:09:17 GMT\r\n Server: Microsoft-IIS/6.0\r\n PPServer: PPV: 30 H: BAYPPLOGN3B12 V: 0\r\n Content-Type: text/html; charset=iso-8859-1\r\n Expires: Mon, 03 Apr 2006 15:08:17 GMT\r\n Cache-Control: no-cache\r\n Pragma: no-cache\r\n P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"\r\n Content-Length: xxx\r\n \r\n <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/' xmlns:wsse='http://schemas.xmlsoap.org/ws/2002/04/secext' xmlns:psf='http://schemas.microsoft.com/Passport/SoapServices/SOAPFault'> <S:Header> <psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault"> <psf:serverVersion>1</psf:serverVersion> <psf:authstate>0x80048800</psf:authstate> <psf:reqstatus>0x80048852</psf:reqstatus> <psf:serverInfo Path="Live1" RollingUpgradeState="Unknown" LocVersion="0" ServerTime="2006-07-20T06:06:59Z">TK2PPMLOG3B05 2006.05.16.18.44.49</psf:serverInfo> <psf:cookies/> <psf:response/> </psf:pp> </S:Header> <S:Fault> <faultcode>psf:Redirect</faultcode> <psf:redirectUrl>https://login.live.com/pp400/RST.srf</psf:redirectUrl> <faultstring>Authentication Failure</faultstring> </S:Fault> </S:Envelope>
Success
If all went well, you will receive the following reply from the server. If the username or password were incorrect, you will receive a SOAP:Fault reply for each sub-request ("RequestSecurityToken") that failed.
Remember to XML decode (HTML decode) the token received (in bold below)!
HTTP/1.1 200 OK\r\n Connection: close\r\n Date: Mon, 03 Apr 2006 15:09:17 GMT\r\n Server: Microsoft-IIS/6.0\r\n PPServer: PPV: 30 H: BAYPPLOGN3B12 V: 0\r\n Content-Type: text/html; charset=iso-8859-1\r\n Expires: Mon, 03 Apr 2006 15:08:17 GMT\r\n Cache-Control: no-cache\r\n Pragma: no-cache\r\n P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"\r\n Content-Length: 6495\r\n \r\n <?xml version="1.0" encoding="utf-8" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Header> <psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault"> <psf:serverVersion>1</psf:serverVersion> <psf:PUID> See Protocols/MSNP/Passport Unique ID for more info </psf:PUID> <psf:configVersion>3.0.869.0</psf:configVersion> <psf:uiVersion>3.0.869.0</psf:uiVersion> <psf:authstate>0x48803</psf:authstate> <psf:reqstatus>0x0</psf:reqstatus> <psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="2006-04-03T15:09:17Z">BAYPPLOGN3B12 2006.01.27.13.57.29</psf:serverInfo> <psf:cookies/> <psf:response/> </psf:pp> </S:Header> <S:Body> <wst:RequestSecurityTokenResponseCollection xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault"> <wst:RequestSecurityTokenResponse> <wst:TokenType>urn:passport:legacy</wst:TokenType> <wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"> <wsa:EndpointReference> <wsa:Address>http://Passport.NET/tb</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <wst:LifeTime> <wsu:Created>2006-04-03T15:09:17Z</wsu:Created> <wsu:Expires>2006-04-04T15:09:17Z</wsu:Expires> </wst:LifeTime> <wst:RequestedSecurityToken> <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="BinaryDAToken0" Type="http://www.w3.org/2001/04/xmlenc#Element"> <EncryptionMethod algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"></EncryptionMethod> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:KeyName>http://Passport.NET/STS</ds:KeyName> </ds:KeyInfo> <CipherData> <CipherValue>AfiQDIvIPHyZ/aJmpm/hoaJCzRMYbhNZT1VZDvuoYuXpWLBVCa+dHstPX7/3qaq0YbAzROTU6mi0ovQ6BYOVD8tgwb3yzfdm6OMd77RWKpZMMc3sLKEbxzutc6tpG7euj0Y5nlIyCRUFJATcqpvOOFS3EYchcOe7UG5si/w+4CUnPk+YG/X2+lJt6yEaD7+oxu7vCueResAJoqwi2fOu/3hSh0k9Meqd4QYmaijkLZT3jy+GQu/8Jku6f+o0DiKoQzg0JYfaKV7ROfznRXWxUoUiigv7EiAcgG+Ri9kaB0E54QecOuh23mCoiowVdDexh19Ep24Am1KexozOXuLdwEsO5S3IHSdC0xZzFl3Fa4XKRFeEfeYJ6OFvTu9FoiLq+c9XX7OmroVbaOWE1Bi4C8es2bObPjkxg5JEl2M6vFlWEJUbTQ==</CipherValue> </CipherData> </EncryptedData> </wst:RequestedSecurityToken> <wst:RequestedTokenReference> <wsse:KeyIdentifier ValueType="urn:passport"></wsse:KeyIdentifier> <wsse:Reference URI="#BinaryDAToken0"></wsse:Reference> </wst:RequestedTokenReference> <wst:RequestedProofToken> <wst:BinarySecret>UDmOO8Ep5vU+vQUjcziMW6fI43rIeKLD</wst:BinarySecret> </wst:RequestedProofToken> </wst:RequestSecurityTokenResponse> <wst:RequestSecurityTokenResponse> <wst:TokenType>urn:passport:legacy</wst:TokenType> <wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"> <wsa:EndpointReference> <wsa:Address>messenger.msn.com</wsa:Address> </wsa:EndpointReference> </wsp:AppliesTo> <wst:LifeTime> <wsu:Created>2006-04-03T15:09:17Z</wsu:Created> <wsu:Expires>2006-04-03T15:17:37Z</wsu:Expires> </wst:LifeTime> <wst:RequestedSecurityToken> <wsse:BinarySecurityToken Id="PPToken1">t=7rl6lZ8V0AwqPJX7V0sI7UTeVeSI2IsNyUs54yhGxkw75Wk3FKmZPRlt5HRk5zTutPTRdA4Z0HZlSEzrNDATrJkbticILv0GB7UV1hs18Lv3!htfM2GRQhudbsLMYI2Tylbfp!3WDZYNo$&p=7p*vh1jxRHI5149VnAwA9pzqQhV4NspMqdEpizzDolZdz6lDrkjisFoc4tKXlmxb5dIe7JKgr5Qmr8ULvHcU0bX6XUbcVQ4ra1dkLzpNltx47fkxjHLMJJiCFq*uOn9ijQLDNtw752hZvd0duHXMygF3y9rKDMhr27*WSs!10nbysjJ7gn70SyRWibFc1rnQlRHyCdf6ZTBhw$</wsse:BinarySecurityToken> </wst:RequestedSecurityToken> <wst:RequestedTokenReference> <wsse:KeyIdentifier ValueType="urn:passport"></wsse:KeyIdentifier> <wsse:Reference URI="#PPToken1"></wsse:Reference> </wst:RequestedTokenReference> </wst:RequestSecurityTokenResponse> </wst:RequestSecurityTokenResponseCollection> </S:Body> </S:Envelope>
Example code
The following code has been written in pseudo code, and can be freely translated to any language, such as PHP, Perl, C, C#, etc.
var url = "https://loginnet.passport.com/RST.srf";
var ticket = url_decode("lc=1033,id=507,tw=40,fs=1,ru=http%3A%2F%2Fmessenger%2Emsn%2Ecom,ct=1144678795,kpp=1,kv=7,ver=2.1.6000.1,rn=henwjH6T,tpf=9fae2e057425cab598a766a38ccd447a"); ticket = string_replace(ticket, ",", "&");
var body = "<?xml ..... " + // Snip! "<wsse:Username>" + html_encode(user) + "</wsse:Username>" + "<wsse:Password>" + html_encode(password) + "</wsse:Password>" + // Snip! "<wsse:PolicyReference URI=\"?" + html_encode(ticket) + "\"></wsse:PolicyReference>" + // Snip! "</Envelope>";
var request = new HTTPRequest(url); request->body = body;
var response = request->get_response();
if response->succeeded then begin var twnticket = response->body; twnticket = twnticket->getbetween("<wsse:BinarySecurityToken Id="PPToken1">", "</wsse:BinarySecurityToken>");
return html_decode(twnticket); end else throw new Exception("Could not fetch ticket");
Implementations
Example implementations of this method are available:
- C#: PP30_SecurityToken.cs (By Eon (formerly Darkener Daemon EX))
- Java: AuthTWN.java (By Tom van der Woerdt)
- Perl: AuthPP3.pm (By Siebe "Inky" Tolsma)
- PHP: tweener.class.php (By Mark "MPMC") - Info
- PHP: wlm_pp3_class.php (By Nowan190 for ToutMessenger)
- Python: TweenerAuthetication.py (By Thomas "Turtlesoup" Dimson)
- VB .NET: PP3.vb (By Jay)