Skip to content
wtv-411 edited this page Dec 18, 2023 · 13 revisions

The Andurill login services for MSN TV 2 were hosted on both the trusted SG (sgN.trusted.msntv.msn.com) and headwaiter servers as .aspx web services and ran over HTTPS. They mostly aided in authenticating user accounts on a box subscribed to the MSN TV service and allowing boxes to fetch MSN Dial-up access numbers if it was configured to use MSN Internet Access. They also operate in an unorthodox manner, utilizing JavaScript that make use of the MSN TV 2's ActiveX controls to tell boxes what to do for each login step.

Based on the contents of various event logs from old MSN TV 2 boxes, each web service used for Anduril login before 2006 was hosted on an individual ASPX web service. But circa late 2006, these services, at least on the trusted SG servers, were consolidated into a single web service located at the endpoint /connection/GatePage.aspx where each service was accessed by specifying a phase query parameter, as well as a purpose parameter clarifying if the requests are for normal login, a relogin attempt, "nightly" login, or some other purpose. Anduril services in this document will be referred to in the format service::purpose.

Disclaimer

While this document will cover all parts of the Anduril login process, we only have concrete information on the Bootstrap/Kickstart service and some of the BoxCheck service. The code for Bootstrap was saved by zefie on his Midnight Channel archive site, which also gives some hints as to how the box was supposed to contact the BoxCheck service. Everything else covered is based off guesswork from reverse engineering the MSN TV 2 ActiveX controls and decoding event logs on used MSN TV 2 boxes, which shed some more light on how the service worked.

This document also won't go over cases where the services would have to throw an error response to the MSN TV 2, mostly because those cases are undocumented. According to the MSN TV 2 application's source code, though, it's very likely that these errors were simple 4xx or 5xx errors.

Login Flow

Bootstrap::Authorize (Kickstart)

  • Endpoints: /connection/GatePage.aspx?phase=Bootstrap&purpose=Authorize (SG), /connection/kickstart.aspx (Headwaiter, also used on SG servers pre-2006)

  • Methods Used: GET

The first Anduril login service contacted by the MSN TV 2 once a user connects to the MSN TV service. The Bootstrap service, also known as Kickstart, quite literally is a simple script that prepares the box to communicate with further login services, and is contacted by simply making the service panel navigate to it.

If the box is already registered on MSN TV, then it will store a URL to Bootstrap hosted from one of the trusted SG servers in its persistent service list with the ID connection::login. If this service doesn't exist or if the box is having trouble contacting Bootstrap from this service's URL, however, then the box will contact it from default URL https://headwaiter.trusted.msntv.msn.com/connection/kickstart.aspx.

Once the MSN TV 2 has contacted this service, the server will send it this HTML:

<HTML>
  <HEAD>
   <title id="title"></title>
  </HEAD>
  <body>
   <iframe id=checkmail style="display:none"></iframe>
   <script language="javascript">
    var tvShell = new ActiveXObject("MSNTV.TVShell");
 function IsNightlyEnabled() {
     var taskScheduler = tvShell.TaskScheduler;
     var updateTask = null;
     for (var i = 0; ((i < taskScheduler.Count) && (updateTask == null)); i++) {
         if (taskScheduler.Item(i).Caller == 'NightlyUpdate') {
             updateTask = taskScheduler.Item(i);
         }
     }
     if (updateTask != null) {
         return(true);
     }
     else {
         return(false);
     }
 }
 function GotoBoxCheck() {
     var url = 'https://sg1.trusted.msntv-thrash.msn.com/connection/GatePage.aspx?phase=BoxCheck&purpose=Authorize';
     var parms='';
     parms += 'BoxId=' + tvShell.SystemInfo.BoxIDService + '&';
     parms += 'WANProvider=' + tvShell.ConnectionManager.WANProvider + '&';
     parms += 'version=' + encodeURIComponent(tvShell.SystemInfo.LastVersion) + '&';
     if ((tvShell.ConnectionManager.MSNIAManager != null) && (tvShell.ConnectionManager.MSNIAManager.CurrentConnector != null)) parms += 'ConnectorName=' + encodeURIComponent(tvShell.ConnectionManager.MSNIAManager.CurrentConnector.Name) + '&';
     if (tvShell.UserManager.CurrentUser != null) parms += 'domain=' + encodeURIComponent(tvShell.UserManager.CurrentUser.Domain) + '&';
     parms += 'NumRedirects=0&';
     parms += 'NightlyEnabled=' + IsNightlyEnabled() + '&';
     parms += 'x=y';
     var myPanel = tvShell.PanelManager.Item('service');
     if (myPanel) myPanel.PostToURL(url, parms);
 }
 var progressPanel = tvShell.PanelManager.Item('progress');
 function SetProgress(text, percent) {
     if (progressPanel) {
         progressPanel.Document.SetProgressText(text);
         progressPanel.Document.SetProgressPercent(percent);
     }
 }
 function IsServicePanel() {
     if ((window.name == null) || ((window.name != null) && (window.name.toLowerCase() != 'service'))) {
         return(false);
     }
     return(true);
 }
 function DontContinue() {
     var currentUser = tvShell.UserManager.CurrentUser;
     if (currentUser != null && currentUser.IsAuthorized) {
         window.location.replace(tvShell.UserManager.CurrentUser.ServiceList.Item('home::home').URL);
     }
     else {
         tvShell.ConnectionManager.ServiceState = 'ReSignIn';
     }
 }
 if (!IsServicePanel()) {
     DontContinue();
 }
 else {
     tvShell.MeteringManager.Stop();
     SetProgress('thrash/sg1 [1.5.336.20] Please wait while we sign you into MSN TV.', 10);
     GotoBoxCheck();
 }
   </script>
  </body>
 </HTML>

What the Bootstrap script will first do when it executes is check if it is running in the service browser panel by checking the window.name property. If it isn't, then it will call the function DontContinue(), where it will either redirect the user to the MSN TV home page if the user is already logged in, or set the ServiceState in the TVShell ConnectionManager to ReSignIn, which will cancel login and point the MSN TV 2 browser to the login page.

If the script is running in the service panel, then it will do three things:

  • Stop the MSN TV 2's MeteringManager
  • Set the progress bar to 10% and the progress text to "Please wait while we sign you into MSN TV." (On non-production servers, the service name and version number are prepended to the string).
  • Call function GotoBoxCheck()

The JavaScript function GotoBoxCheck will gather some information on the MSN TV 2 box running the service script, including its box ID, and instruct the service panel to send them as URL-encoded POST parameters to the BoxCheck HTTPS service:

Parameter Value
BoxId The unique ID of the current user's MSN TV 2 box
WANProvider The type of connection being used to connect to the MSN TV 2 service. Value is obtained from the WANProvider property in the TVShell ConnectionManager. Known values are BYOAEN (Ethernet), MSNIANB (MSN Dial-up), and BYOANB (non-MSN dial up)
version Version of the MSN TV 2 firmware the box is running
ConnectorName Optional. Only sent by Bootstrap if MSNIAManager variable from ConnectionManager is defined (user is connecting with MSN Dial-up) and has a connector. Purpose unknown
domain Domain name of current user's email address
NumRedirects Only known value used is 0. Not sure if this parameter ever got used
NightlyEnabled Boolean value that tells the service if the box has a task for NightlyUpdate. true if the task is present, false if it isn't
x y. Not sure why this parameter is here

By 2006, if this service was contacted from the original kickstart.aspx URL on headwaiter, then it would simply use the newer URL for BoxCheck on an available trusted SG server for the box to connect to.

BoxCheck::Authorize ("Login")

  • Endpoints: /connection/GatePage.aspx?phase=BoxCheck&purpose=Authorize (SG), /connection/Login.aspx (Used on SG servers pre-2006)

  • Methods Used: POST

This service takes in the parameters sent to it by the last service (Bootstrap/Kickstart), and presumably does some actual server-side validation to check if the box ID in the BoxID parameter is authentic or has an active subscription to MSN TV.

If the box ID is valid, but does not have an active MSN TV subscription, then what the service exactly did is currently unknown. It is assumed that the BoxCheck service would automatically authorize the box and send it to the registration servers, considering that the headwaiter and SG servers share parts of the Anduril login services.

If the box ID is valid and also has an active subscription, then it will do the following:

  • The service script sent from the server will first configure the UTC time on the box using the function tvShell.DeviceControl.SetClock(hh, mm, ss, mo, dd, yyyy).
    • While this function and SetTimeZone are known to work correctly when executed on a real MSN TV 2 box, the ClockSet variable in DeviceControl remains false once the box is logged in with the current scripts used for testing. This variable is used by the MSN TV 2 browser application to at least determine if it is authorized to access offline apps (Music, Photos, Videos). If the ClockSet variable is false, then the MSN TV 2 will refuse to run them at all. It is currently unknown how to make this variable true.
  • If the box is connecting with MSN Dial-up (WANProvider is set to MSNIANB), the script will then check if the box has up to date MSN access numbers by checking if it has an MSNIA connector for LocalPOP and if the phonebook of said connector has access numbers (the phonebook is considered "expired" if it no longer has any access numbers). While the original code used for this purpose is lost, it is likely the script checked if the LocalPOP connector existed in either the CurrentConnector property of MSNIAManager or in the MSNIAManager.Connectors array, create it if it didn't already exist, and call Poptimize() on the connector using the box's area code and exchange, if both were set (e.g., connector.Poptimize("0", areaCode, exchange)).
    • Calling Poptimize() would make the MSN TV 2 contact an external web service hosted on http://poptimize.msn.com/poptimize.dll, which would give the MSN TV 2 the access numbers it would need to dial locally. This service is still up and is still used for MSN Dial-up, but the specific request the MSN TV 2 sends no longer works on the servers. Poptimization is covered here.
    • The LocalPOP connector, if it doesn't exist, is likely created with code similar to the following code snippet:
      var connector = GetConnectorByName("LocalPOP");
      if (connector == null) {
         connector = tvShell.ConnectionManager.MSNIAManager.Connectors.Add("modem");
         connector.AreaCode = "";
         connector.Exchange = "";
         connector.DialingFlags = 0x00001000; //DIALFLAG_ISLOCAL
         connector.Name = "LocalPOP";
         connector.LocationName = "LocalPOP";
         tvShell.ConnectionManager.Save(); // Make sure to save new connector
      }
    • It's assumed that if the local MSN access numbers were updated by the BoxCheck script, then it would set the ErrorCode property in tvShell.ConnectionManager.WANManager to ConnectError_Reconnect (integer value 9) and terminate execution, which would tell the box to go to the access numbers page to show the user which numbers they want to use. Whether this is 100% accurate to how the original script would work cannot be verified at the moment.
  • The script will then initiate account authentication through Passport if the current user account has been set by the box for the service to authenticate. If the current user has not been set on the box and the script has not performed poptimization, it would immediately return the user to the login screen (i.e., set the tvShell.ConnectionManager.ServiceState property to ReSignIn).
  • If user authentication is successful, and specifically if the request for the MSN TV token is successful, then a callback configured by the service script will tell the service panel to go to UserCheck, using the Passport token for MSN TV as a query parameter.
    • Example: https://sg1.trusted.msntv-thrash.msn.com/connection/GatePage.aspx?phase=UserCheck&purpose=Authorize&t={URL-encoded token data}&p=...
    • Up until very late into the service's life, the token in the UserCheck URL did not appear to have been URL-encoded.
  • If user authentication on Passport fails, then the script will be notified via callback. How the script handles that error is mostly undocumented, though. What is known, however, is that if Passport login encountered an error, it would make the service panel go to a URL that likely prompted the MSN TV 2 to quit login and show the user an error message.
    • Prior to 2006, this URL was https://sgN.trusted.msntv.msn.com/connection/Errors.aspx?category=ClientLoginManager&code=-2130706175&elapsedTime=1000&BoxID={BoxID}&x=y.

It's not entirely known what would happen if the box ID is not authentic or is restricted.

UserCheck::Authorize(Auth)

  • Endpoints: /connection/GatePage.aspx?phase=UserCheck&purpose=Authorize&t={t}&p={p}... (SG), /connection/Auth.aspx?t={t}&p={p}... (Used on SG servers pre-2006)

  • Methods Used: GET(?)

This service will check if the Passport token data sent in the query parameters is valid. If it is, then a service script is sent to the box that effectively unlocks it and gives it all the necessary information it needs to use the MSN TV service. It is known that the token data is sent to this service as parameters, but there may also be other parameters sent to this service that have not been captured by the event logs that have been analyzed thus far. This service is also pretty involved, and unfortunately, doesn't have its original service script archived. Most of the functionality of this script has been able to be recreated through reverse engineering the MSN TV 2 browser application's code as well as using knowledge obtained from MSN TV 2 event logs, so this page will attempt to describe most of what this script does as accurately as possible.

The script will first tell the box to add a bunch of services to both the current user's service list and the box's persistent global service list. A list of known services used by the MSN TV 2 service can be found here.

  • The user's service list contains most of the main services needed to communicate with MSN TV, and this list is only kept for as long as the user's session is active (before the user signs out or powers off the box). This service list is stored in the CurrentUser object from tvShell.UserManager as ServiceList
  • The persistent service list contains services that the box will most likely need to contact when it's not connected to MSN TV (login services, password reset, etc.), and is saved globally on the box. This service list can be accessed from the tvShell.ServiceList object, and is stored on the third partition of the MSN TV 2's CompactFlash in Shell\ServiceList\Services.dat. To save the contents of the persistent service list to the box, call tvShell.ServiceList.Save()
  • Some services, such as Mail, Home, and System Info, need to manually have their shortcut keys defined when added to the current user's service list. This is done by setting the KeyCode property on the individual Service object:
    • home::home (Home page service) keycode: 0xAC
    • mail::listmail (Mail inbox) keycode: 0xB4
    • SystemInfo::home (System information) keycode: 0xAB
    • search::main (MSN TV Search) keycode: 0xAA
  • A service can be marked as "safe" by setting its Safe property to true. The purpose of this isn't entirely clear, although it might be related to the window.external.SafeGetServiceURL function. Services that aren't meant to be directly used by the MSN TV 2 browser usually don't tend to have the Safe property set to true.
  • The Messenger client on the MSN TV 2 makes use of services in the user's service list in order to work. If the user is authorized to use the feature, the services messenger::root and messenger::passport will be set.
    • messenger::root specifies the host name and port of the Messenger server to connect to in the form of an HTTP URL (e.g., http://contoso.com:1863) and is a safe service. The MSN TV home page (at least the dial-up version) will check the presence of this service to determine if it should open the Messenger panel or show an error message to the user. It's likely that if the user wasn't authorized to use Messenger, the service would simply not be added by UserCheck.
    • messenger::passport is also required to be present in the service list for Messenger to work, but its purpose is unknown and likely needs a certain value, as otherwise login will not fully work on Messenger.

Here is an example script showing how UserCheck would have added the services:

    // User ServiceList - for main MSN TV services
    tvShell.UserManager.CurrentUser.ServiceList.Clear();
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('home::home');
    entry.URL = 'http://msntv.msn.com/pages/home/home.aspx?WANProvider=' + tvShell.ConnectionManager.WANProvider;
    entry.KeyCode = 0xAC; // VK_BROWSER_HOME
    entry.Safe = true;
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('home::bgmusic');
    entry.URL = 'http://msn.com';
    entry.Safe = true;
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('mail::listmail');
    entry.URL = 'http://mail-sg3.msntv.msn.com/apps/mail/listmail.aspx';
    entry.KeyCode = 0xB4; // VK_LAUNCH_MAIL
    entry.Safe = true;
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('chat::home'); // TRUSTED SERVICE
    entry.URL = 'https://www.msn.com';
    entry.Safe = true;
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('messenger::root');
    entry.URL = 'http://messenger.hotmail.com:1863';
    entry.Safe = true;
    entry = tvShell.UserManager.CurrentUser.ServiceList.Add('messenger::passport');
    entry.URL = 'value';
    ...
    // ServiceList - For services that will persist on the box
    tvShell.ServiceList.Clear();
    entry = tvShell.ServiceList.Add('home::cinemanow');
    entry.URL = 'http://g.msn.com/5TVANDURIL/4000'; // "http://msntv.msn.com/Pages/UsingMSNTV/ComingSoon.aspx?id=feature1" - This never really became anything more than a coming soon page.
    entry = tvShell.ServiceList.Add('msn::radioplus');
    entry.URL = 'http://radio.msn.com/asx/generate.aspx';
    entry = tvShell.ServiceList.Add('msn::musicnews');
    entry.URL = 'http://www.msnbc.msn.com/id/3032433/';
    entry = tvShell.ServiceList.Add('connection::popupcontrol');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/PopupControlWhiteList.ashx';
    entry = tvShell.ServiceList.Add('connection::reconnect');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/GatePage.aspx?phase=Bootstrap&purpose=ReAuthorize';
    entry = tvShell.ServiceList.Add('connection::nightly_login');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/GatePage.aspx?phase=Bootstrap&purpose=Nightly';
    entry = tvShell.ServiceList.Add('mail::check');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/apps/connection/CheckMail.aspx?phase=CheckMail&purpose=CheckMail';
    entry.Safe = true;
    entry = tvShell.ServiceList.Add('home::videoplus');  // only for broadband users
    entry.URL = 'http://msntv.msn.com/pages/msnvideo/main.aspx';
    entry.Safe = true;
    entry = tvShell.ServiceList.Add('home::musicvideo'); // only for broadband users
    entry.URL = 'http://msntv.msn.com/pages/msnvideo/main.aspx?p=music';
    entry.Safe = true;
    entry = tvShell.ServiceList.Add('connection::resetpassword');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/GatePage.aspx?phase=Bootstrap&purpose=ResetPassword';
    entry = tvShell.ServiceList.Add('connection::pagepatch');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/PagePatch.ashx';
    entry = tvShell.ServiceList.Add('connection::login');
    entry.URL = 'https://sg3.trusted.msntv.msn.com/connection/GatePage.aspx?phase=Bootstrap&purpose=Authorize';
    entry.Description = 'prod/sg3 [3.2.634.29]'; // give login service a description of the server it is hosted from
    entry = tvShell.ServiceList.Add('ctags::main');
    entry.URL = 'http://c.msn.com/c.gif?di=1455&pi=68206&tp=http%3a%2f%2fmsntv.msn.com%2fclient%2f';
    tvShell.ServiceList.Save();

As shown in the example, both the user and global service list should be cleared before adding in services at this stage.

The script should then set the time zone using the function tvShell.DeviceControl.SetTimeZone(normalOffset, normalName, daylightOffset, daylightName). Since the time zone was a setting that could be configured on an MSN TV user account, it is believed that this service took care of setting the time zone.

  • The way SetTimeZone works is that the server specifies the normal time offset and name, and optionally sets the daylight offset and name if appropriate. The daylight offset is the amount of minutes to add to the normal offset to account for daylight savings time.
  • This function has a quirk where if a box connects after a cold boot and this function is executed in a service script, the time will be offset 2 hours ahead of the actual time. This will correct itself on subsequent logins. It is unknown why this occurs or if/how this was worked around in the original service scripts.

The script will then tell the box to set its service state in ConnectionManager to the string Authorized, which tells it that it has been authorized to use the MSN TV service. It then directly sets the URL of the main panel to the MSN TV home page using the URL from the home::home service, and clears any previous history from the browser to prevent it from being saved:

tvShell.ConnectionManager.ServiceState = 'Authorized';

tvShell.PanelManager.Item('main').GotoURL(tvShell.UserManager.CurrentUser.ServiceList.Item('home::home').URL);
tvShell.PanelManager.Item('main').ClearTravelLog();
tvShell.PanelManager.Item('main').NoBackToMe = true;

The MSN TV 2 browser application will detect this, and play a sound when it goes to the home page right after sign-in.

The script then sets the current user as authorized by calling tvShell.UserManager.SetCurrentUserIsAuthorized(true). This will trigger an event in the MSN TV 2 application to load and show the status bar at the bottom, as well as initiate Messenger and other functions. The script is also speculated to set the LastLoginTime property and some variables related to offline apps in tvShell.UserManager and saves it to the box:

var dt = new Date();
tvShell.UserManager.LastLoginTime = dt.getTime() / 1000 + dt.getTimezoneOffset() * 60;
tvShell.UserManager.OfflineAppMaxAccessDays = 20;
tvShell.UserManager.OfflineAppMaxAccessTimes = 20;
tvShell.UserManager.Save();

It's also believed that UserCheck and other service scripts will perform other tasks before finishing the login process:

  • It's been observed in event logs from 2006 onward that UserCheck will call IDCRL to authenticate to the mail service right before or after making the box go to the home page: IDCRLAuthenticateToService( mail.services.live.com, MBI). What this was exactly used for is unknown at the moment, although it might have been used to contact another web service to check for new mail right as the user signs in.
  • The UserCheck service script may in fact call other functions that are yet to be documented that allow the MSN TV 2 box to fully work with the MSN TV service. There are cases that the box will contact web services that clearly expect some sort of authentication (i.e., Mail, Discuss, Music Home feeds) while not directly providing any data that could be treated as such. It's very likely that UserCheck or some other Anduril login script would configure this in some way that is totally undocumented right now. There's also the issue of being able to fully unlock access to offline apps, which relies on the DeviceControl ClockSet variable to be set to true. Using scripts based off our current knowledge of how Anduril login works, this variable does not change its value after the MSN TV 2 signs in.
  • The metering manager may also actually be configured and used for something. From some testing, this involves specifying a web service for the metering manager to contact, how often to contact it, and a random GUID for the session ID. How the web service for metering works is undocumented.

Re-login

The relogin service is used by MSN TV 2 if it detects that it has been forcibly disconnected from the MSN TV service. It is very similar to the normal login services, but it works more discretely to let the user continue doing whatever they were originally doing up until they got disconnected.

Bootstrap::ReAuthorize

  • Endpoints: /connection/GatePage.aspx?phase=Bootstrap&purpose=ReAuthorize (SG, likely from 2006 onward)

  • Methods Used: GET

Identical to Bootstrap::Authorize. The script will send the BoxCheck request to BoxCheck::ReAuthorize instead of the normal BoxCheck endpoint.

BoxCheck::ReAuthorize

  • Endpoints: /connection/GatePage.aspx?phase=BoxCheck&purpose=ReAuthorize (SG, likely from 2006 onward)

  • Methods Used: POST

Identical to BoxCheck::Authorize. UserCheck request is sent to UserCheck::ReAuthorize URL.

UserCheck::ReAuthorize

  • Endpoints: /connection/GatePage.aspx?phase=UserCheck&purpose=ReAuthorize&t={t}&p={p} (SG, likely from 2006 onward)

  • Methods Used: GET(?)

Similar to UserCheck::Authorize. According to MSN TV 2 event logs, once the script sent by this service was executed, it would not auto-redirect the user to the MSN TV home page, and it would not set the current user as authorized (likely because they would already be recognized as authorized by the box).

Mail check

MSN TV 2 allows for an account with a saved password to be checked for new mail at a specific time. When the MSN TV 2 is plugged in and turned off, and the time reaches the one specified for mail checks, the box will temporarily turn on and connect to the mail::check service to check if the account has new mail.

CheckMail

  • Endpoints: /apps/connection/CheckMail.aspx?phase=CheckMail&purpose=CheckMail (SG)

  • Methods Used: GET

This service is the one specified in the local mail::check service that would have been defined by the login servers. It would send over a script to automatically authenticate the target user for mail services by calling an IDCRL function and passing the mail domain to it (mail.services.live.com or www.hotmail.msn.com). In event logs, it is shown that the page triggers a call to the function IDCRLAuthCredentialToService, but it's likely that the original script would have called IDCRLAuthenticateUserWithSavedPwd, although this cannot be verified at the moment. Once the user is authenticated, the script will get the token and pass it to the next service, CheckMail2.

CheckMail2

  • Endpoints: /apps/connection/CheckMail2.aspx?t={t}&p={p} (SG)

  • Methods Used: GET(?)

Validates the mail token retrieved from the previous CheckMail service to determine if it can check the target user's inbox for new mail. How this script originally worked is unknown, but it would presumably check if the user had new mail, and if they did, would light up the message light on the MSN TV 2 box and turn it back off.

Nightly login

TODO

Passport

When the MSN TV 2 contacts the BoxCheck service, it will authenticate the current user's account through the service script after it has checked the user's box ID on the server side. All accounts registered on the MSN TV 2 service were Microsoft accounts (formerly known as Passport and Windows Live ID), and thus have to authenticate on the Passport (account) servers. On the box, this is done with the LoginManager class in the TVShell ActiveX control.

There are two methods of initiating Passport authentication on the MSN TV 2: one only works on firmware versions 5.x and uses the newer IDCRL authentication system, which has example code for it stored in the MSN TV 2 firmware as idcrl.js. The other method is present in older firmware versions and does not rely on IDCRL, but is currently undocumented.

5.x (IDCRL)

In the BoxCheck service script, various IDCRL related variables are defined. These include status codes meant to be used for event logging, which are present in the firmware's idcrl.js script, and more importantly, an array containing a list of services for each service environment (production, PPE, and integration) that the MSN TV 2 should authenticate on with the current user account. The services are stored as sequential arguments in a single array, with each service consisting of the domain of the service, its service policy, and two integers that have an unknown purpose and usually have a value of 0. The array will look something like this:

 var serviceArgs = new Array(); // [ProductionArgs, PPEArgs, INTArgs]
 var ProductionArgs = new Array("msntv.msn.com", "MBI",  0,  0,  
							   "mail.services.live.com", "MBI",  0,  0,
							   "livefilestore.com", "MBI",  0,  0,
							   "messenger.msn.com", "?id=507",  0,  0,
							   "spaces.live.com", "MBI",  0,  0
							  ); // Production service
 var PPEArgs = new Array(); // Pre-production environment
 var INTArgs = new Array(); // Integration service
 serviceArgs[0] = ProductionArgs;
 serviceArgs[1] = PPEArgs;
 serviceArgs[2] = INTArgs;

The msntv.msn.com service is required for the login process, as that will give the box a token it needs to send to the next service (UserCheck).

When the service script is ready to start IDCRL authentication, it will first determine the service environment to use for authentication. The environment the script should get its services from is determined from the domain of the current user's email address. Based on the GetServiceFlavorFromEmail function from idcrl.js:

 function GetServiceFlavorFromEmail(email)
 {
    var service= email.substr(email.indexOf("@")+1).toLowerCase();
    if(service.indexOf("testdrive")>=0 || service.indexOf("-ppe")>=0)
 		return 1;
    else if(service.indexOf("-int")>=0)
         return 2;
    else
         return 0;
 }

If the domain part of the email address contains the string testdrive (testdrive.webtv.net?) or a -ppe suffix, then the script will use the arguments for the pre-production environment. If the domain contans the -int suffix, then the arguments for the integration environment are used. Otherwise, the production environment arguments will be used.

Then it's believed that the script will also add some services to the current user's service list using information from the chosen service arguments to tell local MSN TV 2 applications (Messenger, Favorites) how to authenticate. Some of the known services created this way include:

Service Notes URL Description Value
messenger::ServiceTarget Likely used for Passport login on Messenger messenger.msn.com None
Skydrive::AuthServer Used to authenticate on Passport for MSN TV favorites sync service Observed as favorites.live.com and spaces.live.com Service policy for Favorites/Spaces service
Livefilestore::AuthServer TBD Observed as livefilestore.com Service policy for livefilestore.com
chat::ServiceTarget Likely used back when MSN TV Chat used the MSN Chat servers. This service was no longer used once MSN TV Chat switched to IRC Observed as chat.msn.com Service policy for MSN Chat

At some point in the script, it will also use the MSN TV event sink ActiveX control to set a callback on the LoginManager for the function IDCRLOnAuthStateChanged, which will trigger whenever IDCRL authentication is finished:

 var sink = new ActiveXObject("MSNTV.MultipleEventSink");
 ...
 function IDCRLOnAuthStateChanged(result,authState,requestStatus, user, serviceTarget,servicePolicy,token,webFlowUrl)
 {
    tvShell.Message("IDCRLOnAuthStateChanged target = " + target + " policy = " + policy);
    tvShell.Message("token="+token);
    tvShell.EventLog.Important("OnIDCRLAuthStateChanged: result = "+ GetResultCode(result)+"\n authState = "+ GetResultCode(authState)+"\n requestStatus = "+GetResultCode(requestStatus)+"\n user = "+user+"\n webFlowUrl = "+webFlowUrl);
     if(tvShell.UserManager.CurrentUser.EMail!=user ||
         (isIDCRLErrorCode(authState)  || getIDCRLCode(authState) != 0x03) || 
         ( isIDCRLErrorCode(requestStatus) || getIDCRLCode(requestStatus) != 0x00)){
         tvShell.EventLog.Important("IDCRLOnAuthStateChanged error.    Target=" + serviceTarget);
         ...
 	}
    ...
 }
 sink.AttachEvent(tvShell.LoginManager, 'IDCRLOnAuthStateChanged', IDCRLOnAuthStateChanged);

Once the script has everything ready to initiate IDCRL login, it will call these two functions:

tvShell.LoginManager.IDCRLInitialize(serviceflavor);
tvShell.LoginManager.IDCRLLogonAndAuthToServices(serviceArgs[serviceflavor]);

These functions will both initialize IDCRL with the service environment ID, and then give it the list of services to authenticate on. Before firmware 5.5, the IDCRLLogonAndAuthToServices function also required another parameter, which would be an integer and usually had a value of 0. Then the IDCRL control will contact the login servers at login.live.com and authenticate the user account there.

Login Callback

Once IDCRL login succeeds or fails, it will trigger the IDCRLOnAuthStateChanged event previously registered on the MSN TV event sink for each service it attempted to authenticate to. Information sent to the callback function includes the email of the user who was authenticated, a token if authentication succeeded for the current service target, and various status codes.

While what the original service script would do when this callback is triggered is currently undocumented, it is known for certain that the callback function would require a token for the msntv.msn.com service. If it received that token, then after receiving all tokens for every other service, it would add the URL encoded t and p tokens sent for msntv.msn.com as query parameters to the URL for UserCheck before making the service panel navigate to it. BoxCheck would not care about any other services that happened to fail authentication. If authentication for msntv.msn.com fails, then the script was expected to handle the error gracefully.

Pre-5.x

The method used to initiate user authentication on MSN TV 2 firmware versions older than 5.x is completely undocumented. It is believed that the method used is easier to use than the IDCRL login, though, as the Passport control (TVPassport.DLL in the NK.BIN XIP) has a few simple-looking functions for login, one of which only taking three parameters:

interface ILoginManager : IDispatch {
    ....
    [id(0x0000000a)]
    HRESULT Login();
    [id(0x0000000b)]
    HRESULT Authenticate(
                    [in, optional, defaultvalue("")] BSTR username, 
                    [in, optional, defaultvalue("")] BSTR Password, 
                    [in, optional, defaultvalue("")] BSTR LoginURL);
    [id(0x0000000c)]
    HRESULT Logout();
    ...
};