Protocols/OSCAR/Sign On/clientLogin

From NINA Wiki
Revision as of 04:04, 27 March 2020 by AD (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
OSCAR Protocol
IntroductionTermsClients
Basic
DatatypesFLAPSNACTLV
UUIDsErrorsTool IDs
Host Interaction
Rate LimitsMigrationMessages
Other Services
ADMINADVERTALERT
BARTBOSBUCPCHAT
CHAT_NAV
Tutorials
Sign OnBARTRendezvous
ICBMLocateBuddies
Foodgroups
OSERVICE (0x0001)
LOCATE (0x0002)
BUDDY (0x0003)
ICBM (0x0004)
ADVERT (0x0005)
INVITE (0x0006)
ADMIN (0x0007)
POPUP (0x0008)
PD (0x0009)
USER_LOOKUP (0x000A)
STATS (0x000B)
TRANSLATE (0x000C)
CHAT_NAV (0x000D)
CHAT (0x000E)
ODIR (0x000F)
BART (0x0010)
FEEDBAG (0x0013)
ICQ (0x0015)
BUCP (0x0017)
ALERT (0x0018)
PLUGIN (0x0022)
UNNAMED_FG_24 (0x0024)
MDIR (0x0025)
ARS (0x044A)


This is for the clientLogin sign on method. This web-based login can be used by both OSCAR clients and WebAPI clients.

The clientLogin method allows the client to collect the user name and password and make a simple web service call to retrieve authentication credentials. These credentials are then used in future web service calls to sign requests to help against man in the middle and reply attacks.

Authentication and requesting the BOSS connection normally requires two web service calls.

  1. The clientLogin call checks the key, loginId, and password and performs any rate limit or captcha challenges
  2. The startOSCARSession call requests a BOSS connection and returns where the client needs to connect to and a one time use cookie to present to the BOSS server for authentication. This call requires an OAuth style URL signing which is described along with clientLogin. URL signing requires the computers clock to be accurate or the use of hostTime returned by clientLogin, parameters are in alphabetical order, and percent-encoding uses upper case characters.

Step #1 - Authentication Request

The client should collect the loginId and password for the user. It should not do any length or character validations. A POST web service call should be made to:

https://api.screenname.nina.bz/auth/clientLogin?f=[FORMAT]

...with a POST body of...

k=[KEY]&s;=[LOGINID]&pwd;=[PASSWORD]&clientVersion;=[CLIENTVERSION]&clientName;=[clientName]

...and a content type of application/x-www-form-urlencoded with the following values:

[FORMAT]
Format to return the response in; XML, AMF3, PHP, JSON are all supported
[KEY]
Client key obtained from here
[LOGINID]
URI encoded loginId entered by the user
[PASSWORD]
URI encoded password entered by the user
[clientVersion]
A single number representing the client version number for metrics and tracking, usually the build number
[clientName]
URI encoded friendly name representing the client being used

Example:

URL:

https://api.screenname.nina.bz/auth/clientLogin?f=xml

POST Data:

k=thekey&s;=chattingChuck&pwd;=WeakPassword&clientVersion;=3&clientName;=Cool+Client

Assuming correct loginId, password, and no CAPTCHA challenge, a good response will look like the following:

<response xmlns="https://api.login.nina.bz">
  <statusCode>200</statusCode>
  <statusText>OK</statusText>
  <data>
    <token>
      <expiresIn>86400</expiresIn>      <a>%2FwEAAAAAm3uC7kLggQUTUxDaptz5ddrYlsBinH5jBpi3aKVFOwRZUdy4VC3HBXkdtUaFOTM8E9og492eGQi3X0cIrwRfN5SsuA%2BE9nGhXtbQt%2BHoaa8Fw9yMTuuuks3%2F8ZRh0IyGOaLWhQssgtB3vEoEEQPSc4ZZcUARXm0b3GBfEW5E3QGjTvi6tRPsVpmnfSQ%3D</a>
    </token>
    <sessionSecret>m3UPFGcH5hmKSv24</sessionSecret>
  </data>
</response>

Extract the token->a and sessionSecret elements and save for later.

Step #2 - Authentication Reply

There can be several intermediate replies before a successful authentication is completed. These include incorrect passwords, need for extra credentials, or the need for the user to complete a CAPTCHA challenge. To test if a client supports CAPTCHA challenges correctly it can add an extra parameter of forceRateLimit=true. It is recommended that all clients test CAPTCHA support.

When successfully authenticated, the token->a and sessionSecret need to be extracted from the results (see Step #1). The sessionSecret is used to generate a sessionKey that will be used on future calls. For example, the startOSCARSession service, the start page, and the expressions page all require the sessionKey.

The sessionKey is calculated using:

sessionKey = hmac_sha256_base64($sessionSecret, $password);

For example, if the sessionSecret was "AB123FO" and the user's password was "weakpassword", then the sessionKey would be "ZyCaA1QlF8oBzh0QXeXNCf+7qUItBaiXwk3xOVcFZhY=" Historically some hmac_sha256_base64 do not return valid base64 data. All these APIs require valid base64 data, so check the implementation being used.

Example: This example is based on this and the previous step.

$sessionKey = hmac_sha256_base64("m3UPFGcH5hmKSv24", "WeakPassword");

It will look something like:

$sessionKey = "wEOki901gedaIeJbMAy5k+hv4iJgfvshgM+cWtk+s1g=";

Step #3 - Start OSCAR Session Request

Once successfully authenticated, the client needs to connect to the BOSS server to start the AIM session. This is done by requesting a BOSS reservation and then connecting to the BOSS server. Requesting the BOSS reservation is done with a startOSCARSession WIM call.

This call requires an OAuth style URL signing which is described along with clientLogin. URL signing requires the computers clock to be accurate or the use of hostTime returned by clientLogin, parameters are in alphabetical order, and percent-encoding uses upper case characters.

[FORMAT]
Format to return the response in: XML, AMF3, PHP, JSON are all supported
[KEY]
Client key obtained from here
[TOKEN]
The URI encoded token extracted from clientLogin
[clientVersion]
A single number representing the client version number for metrics and tracking
[clientName]
A URI encoded friendly name representing the client being used
[TIME]
The current time, in seconds, since UNIX EPOCH
[USETLS]
Should the connection to BOSS use TLS
$uri = "http://api.oscar.nina.bz/aim/startOSCARSession";
$queryString = "a=[TOKEN]&clientName;=CLIENTNAME]&clientVersion;=[CLIENTVERSION]&f;=[FORMAT]&k;=[KEY]&ts;=[TIME]&useTLS;=[USETLS]";
$hashData= "GET&" . uri_encode($uri) . "&" . uri_encode($queryString);
$digest = hmac_sha256_base64($hashData, $sessionKey);
$url = $uri . "?" . $queryString . "&sig;_sha256=$digest";

The above will look something like this:

$uri = "http://api.oscar.nina.bz/aim/startOSCARSession";
$queryString = "a=" 
   . uri_encode("%2FwEAAAAAm3uC7kLggQUTUxDaptz5ddrYlsBinH5jBpi3aKVFOwRZUdy4VC3HBXkdtUaFOTM8E9og492eGQi3X0cIrwRfN5SsuA" 
       . "%2BE9nGhXtbQt%2BHoaa8Fw9yMTuuuks3%2F8ZRh0IyGOaLWhQssgtB3vEoEEQPSc4ZZcUARXm0b3GBfEW5E3QGjTvi6tRPsVpmnfSQ%3D") 
   . "&clientName;=" . uri_encode("Cool Client")
   . "&clientVersion;=3&f;=xml&k;=thekey&ts;=1203799990";
$hashData= "GET&" . uri_encode($uri) . "&" . uri_encode($queryString);
$digest = hmac_sha256_base64($hashData, $sessionKey);
$url = $uri . "?" . $queryString . "&sig;_sha256=$digest";
// The above $url may also have the parameter of _sha25sig_sha256 instead of the client so chooses.

The above variables should have the values that look something like:

$queryString = "a=%252FwEAAAAAm3uC7kLggQUTUxDaptz5ddrYlsBinH5jBpi3aKVFOwRZUdy4VC3HBXkdtUaFOTM8E9og492eGQi3X0cIrwRfN5SsuA%252BE9nGhXtbQt%252BHoaa8Fw9yMTuuuks3%252F8ZRh0IyGOaLWhQssgtB3vEoEEQPSc4ZZcUARXm0b3GBfEW5E3QGjTvi6tRPsVpmnfSQ%253D&clientName;=Cool%20Client&clientVersion;=3&f;=xml&k;=thekey&ts;=1203799990";

$hashData = "GET&http;%3A%2F%2Fapi.oscar.aol.com%2Faim%2FstartOSCARSession&a;%3D%25252FwEAAAAAm3uC7kLggQUTUxDaptz5ddrYlsBinH5jBpi3aKVFOwRZUdy4VC3HBXkdtUaFOTM8E9og492eGQi3X0cIrwRfN5SsuA%25252BE9nGhXtbQt%25252BHoaa8Fw9yMTuuuks3%25252F8ZRh0IyGOaLWhQssgtB3vEoEEQPSc4ZZcUARXm0b3GBfEW5E3QGjTvi6tRPsVpmnfSQ%25253D%26clientName%3DCool%2520Client%26clientVersion%3D3%26f%3Dxml%26k%3Dthekey%26ts%3D1203799990";

$digest = "WrxLjKmMfXpM3beElxc5HpARu/yuoMX4pvhVW2T6B+w=";

$url = "http://api.oscar.aol.com/aim/startOSCARSession?a=%252FwEAAAAAm3uC7kLggQUTUxDaptz5ddrYlsBinH5jBpi3aKVFOwRZUdy4VC3HBXkdtUaFOTM8E9og492eGQi3X0cIrwRfN5SsuA%252BE9nGhXtbQt%252BHoaa8Fw9yMTuuuks3%252F8ZRh0IyGOaLWhQssgtB3vEoEEQPSc4ZZcUARXm0b3GBfEW5E3QGjTvi6tRPsVpmnfSQ%253D&clientName;=Cool%20Client&clientVersion;=3&f;=xml&k;=thekey&ts;=1203799990&sig;_sha256=WrxLjKmMfXpM3beElxc5HpARu/yuoMX4pvhVW2T6B+w=";

Assuming no errors, a reply like the following should be received:

<response xmlns="http://developer.nina.bz/xsd/aim.xsd">
  <statusCode>200</statusCode>
  <statusText>Ok</statusText>
  <data>
    <host>192.168.1.1</host>
    <port>9343</port>   <cookie>yoOR9mTV9hGH2vHNXtDytoHTu4q/yYpzkQzrs9L0GKg9ePe29nfS6J0+mIJD0ibMndzjde1AsumqQ6q+1pW95IyNHIhLxDm0PKF+aV8Mg05WZ7guQwiaNGPGXOq5qHI4kIyuVFU1kb9suwStkn+awsySalirJvTJbnbws2RqEV7MsBNF99MUJl+PEHuvEtqAAPuq0HvUGiFqPLC25D+cTYFmLMRwoQPtqIaHHAlaxo+kSWDTAKLzXGZ1JS/6Jd1p2HqPaBjCXuawVFpbwJT+DepJojJHGA4YMGh+YxM8dIfG8IH28w3/cqMZB/RDKaqZX+p0/AH4eqg34+BtYrfq/g==</cookie>
  </data>
</response>

Step #4 - Start OSCAR Session Reply

On a successful startOSCARSession, the backend will return where the BOSS server is running, the cookie to present to the BOSS server, and the certname that should be validated when connecting to BOSS if TLS was selected. At this point the client should connect to BOSS using FLAP or FLAP over TLS and start sending SNACs back and forth.

BE SURE to decode (base64) the cookie value before sending it in the next step.

Next steps: