DISCLAIMER
I am only keeping this post up for archival purposes, as an idea that had potential, but couldn’t be implemented with its current environment.
Hey.
So in the previous post, I had mentioned that I had planned to contribute to Escargot’s development. Well, I’m doing this just now.
Ever since I found out about Escargot, I had wanted to implement real Microsoft accounts to get email support up and running (if it even works), also because it is really the only types of accounts MSN/WLM Messenger can fully support (ahem RST & tokens ahem).
Speaking of RST, that’s how Escargot can use real accounts instead of asking you to link whatever email address to the database. Apparently, https://login.live.com/RST.srf (basically post-Nexus auth) is still up, and from a few test POSTs, it seems to work as well as it would back in 2005 and up (as in it supports both MSN 7.5 and WLM methods of RST.srf authentication).
All you really have to do to get real accounts working on Escargot is to, in layman’s terms, by the time MSN/WLM Messenger connects to Escargot’s RST.srf (NotRST.srf; even though I’ve seen code to setup an “RST.srf” and "RST2.srf"on the HTTP port of the server, which I assume is for debugging purposes), set up a proxy gateway on the server to the actual RST.srf, retrieve the data, parse the XML and find the token value. If so, store it, and if the user hasn’t connected to the Escargot service before, setup a table in the database for that user and continue on with the rest of the authentication. In this case, there would only be one password field in the table, which would only contain the MD5 hash of the password, for people using MD5-based versions of MSN Messenger, which is the only caveat with this kind of method. Also, this would eliminate the need to generate a PUID and CID for a user.
Honestly, aside from setting up the RST request (if you are using the modified MSIDCRL DLL), it wouldn’t be too hard to implement real accounts onto the server, aside from modifying everything else intertwined with the auth process (I had to modify the AuthService and TokenData classes to accept and add tokens alongside creating them, pretty sure there’s probably more for me to modify and tweak). But there is a catch…
RST settings.
Yup. The RST request settings are not the same when it comes to authentication. While MSN 7.5 used the messenger.msn.com URL to get your token, with WLM, the URL has changed to messengerclear.live.com. Also, now that we have WLM support we may need to set a different GUID (For WLM, it’s {CFE80F9D-180F-4399-82AB-413F33A1FA11}; For MSN, it’s {7108E71A-9926-4FCB-BCC9-9A9D3F32E423}). And policies. You can’t get access to them to implement in your RST request with the replacement MSIDCRL library we have right now, so we’re basically at a dead end unless we just shove a hardcoded one in (which I wouldn’t recommend). “So what do we do,” you ask?
We try to get the policies in our request somehow.
Either in an “X-Policy” HTTP variable or we actually try to implement the SOAP request(s) as closely as we can, we can do it. Now I wouldn’t really do that because the replacement MSIDCRL library is written in C++, and I’m not really a fluent or even good enough programmer in C++ (really, I can get the hang of Python and some other languages), nor am I the best at reverse-engineering, but what I can say is that we would have two libraries, one for MSN 7.5 (msidcrl) and one for WLM (msidcrl40), or if we stick to HTTP variables, just implement the policy in the already existing MSIDCRL library. But here’s another problem. Very little people are programmers or reverse-engineerers in this forum. Not really a big issue, but it does put a halt in progress of certain things. Also, as of now, we (or I, at least) don’t know how or where MSN sends the policy variable to what MSIDCRL function (or if not, how does MSIDCRL obtain the policy variable?).
Oh, yeah! I almost forgot, real accounts with Tweener. Basically the same method as RST, but just grab the token, store it, and then use this method to get login cookies as mentioned here: https://github.com/msndevs/protocol-docs/wiki/Authentication
So thanks for reading this one wild ride of a post and I hope you enjoyed your time (this took me hours to type up and finalize).
Also here are some code snippets of my escapades to prove that I’m not just throwing words around (haven’t made much progress though):
http.py:
async def handle_rst(req):
from lxml.objectify import fromstring as parse_xml
body = await req.read()
rst_hdr = {“Content-Type”: “text/xml”}
rst_proxy = requests.post(headers=rst_hdr, data=body)
rst_proxy_resp = rst_proxy.text
rst_resp_xml = parse_xml(rst_proxy_resp)
auth.py:
class AuthService:
def init(self, *, time = None):
if time is None:
time = time_builtin
self._time = time
// List[TokenData], ordered by TokenData.expiry
self._ordered =
// Dict[token, idx]
self._bytoken = {}
self._idxbase = 0
def create_token(self, purpose, data, token, *, lifetime = 30):
self._remove_expired()
td = TokenData(purpose, data, token, self._time() + lifetime)
assert td.token not in self._bytoken
idx = bisect.bisect_left(self._ordered, td)
self._ordered.insert(idx, td)
self._bytoken[td.token] = idx + self._idxbase
return td.token
@total_ordering
class TokenData:
def init(self, purpose, data, token, expiry):
self.token = (gen_salt(20) if token is None else token) # This is because tokens are also generated for IM sessions last time I checked
self.purpose = purpose
self.expiry = expiry
self.data = data