tags:

views:

588

answers:

2

I'm writing a simple python script that will interface with the AIM servers using the OSCAR protocol. It includes a somewhat complex handshake protocol. You essentially have to send a GET request to a specific URL, receive XML or JSON encoded reply, extract a special session token and secret key, then generate a response using the token and the key.

I tried to follow these steps to a tee, but the process fails in the last one. Here is my code:

class simpleOSCAR:
  def __init__(self, username, password):
 self.username = username
 self.password = password

 self.open_aim_key = 'whatever'
 self.client_name = 'blah blah blah'
 self.client_version = 'yadda yadda yadda'


  def authenticate(self):

 # STEP 1
 url = 'https://api.screenname.aol.com/auth/clientLogin?f=json'
        data = urllib.urlencode( [
                 ('k', self.open_aim_key), 
     ('s', self.username),
                 ('pwd', self.password), 
     ('clientVersion', self.client_version),
                 ('clientName', self.client_name)]
    )

 response = urllib2.urlopen(url, data)
 json_response = simplejson.loads(urllib.unquote(response.read()))

 session_secret = json_response['response']['data']['sessionSecret']
 host_time = json_response['response']['data']['hostTime']
 self.token = json_response['response']['data']['token']['a']

 # STEP 2
 self.session_key = base64.b64encode(hmac.new(self.password, session_secret, sha256).digest())

 #STEP 3
 uri = "http://api.oscar.aol.com/aim/startOSCARSession?"

 data = urllib.urlencode([ 
                    ('a', self.token),  
     ('clientName', self.client_name),
     ('clientVersion', self.client_version),
     ('f', 'json'),
     ('k', self.open_aim_key), 
     ('ts', host_time), 
                                 ]
    )
 urldata = uri+data
 hashdata = "GET&" + urllib.quote("http://api.oscar.aol.com/aim/startOSCARSession?") + data

 digest = base64.b64encode(hmac.new(self.session_key, hashdata, sha256).digest())

 urldata =  urldata + "&sig_sha256=" + digest

 print urldata + "\n"

 response = urllib2.urlopen(urldata)
 json_response = urllib.unquote(response.read())

 print json_response

if __name__ == '__main__':
so = simpleOSCAR("aimscreenname", "somepassword")
so.authenticate()

I get the following response from the server:

{ "response" : {
                 "statusCode":401, 
                 "statusText":"Authentication Required. statusDetailCode 1014",
                 "statusDetailCode":1014, 
                 "data":{
                           "ts":1235878395
                         }
               }
}

I tried troubleshooting it in various ways, but the URL's I generate look the same as the ones shown in the signon flow example. And yet, it fails.

Any idea what I'm doing wrong here? Am I hashing the values wrong? Am I encoding something improperly? Is my session timing out?

A: 

URI Encode your digest?

-moxford

Tried that and it didn't work. Plus the examples in the docs explicitly show you not to URI encode it.Good try though. Thanks!
Tuxmentat
+1  A: 

Try using Twisted's OSCAR support instead of writing your own? It hasn't seen a lot of maintenance, but I believe it works.

Glyph