Changed login() behaviour

Previously, the ac2dm was meant to be saved in the application state, and later used for
subsequent logins, along with the gsfId. This is not correct, because the app needs it
only for the first login, and then remains unused in the application state.

The correct behaviour is to save the gsfId and the authSubToken, and provide only these two
values for subsequent logins

Signed-off-by: Domenico Iezzi <domenico.iezzi.201@gmail.com>
This commit is contained in:
Domenico Iezzi 2017-10-04 11:32:56 +02:00
parent 8b5eec3322
commit 2276f8db2c
3 changed files with 27 additions and 35 deletions

View File

@ -13,14 +13,14 @@ Check the test.py module for a simple example.
An important note about login function:
```
def login(self, email, password, ac2dmToken=None, gsfId=None)
def login(self, email=None, password=None, gsfId=None, authSubToken=None)
```
for first time logins, you should only provide email and password.
The module will take care of retrieving an ac2dm token, registering
"your device" to the google account you supplied, and retrieving
a Google Service Framework ID (which basically is the android ID of a device).
The module will take care of initalizing the api,upload device information
to the google account you supplied, and retrieving
a Google Service Framework ID (which, from now on, will be the android ID of a device).
For the next logins you **should** save the ac2dm master token and the gsfId (androidId), and provide them as parameters to the login function. If you login again with email and password only, this is the equivalent of deleting the google account from you device and re-initalize it every time.
For the next logins you **should** save the gsfId and the authSubToken, and provide them as parameters to the login function. If you login again with email and password only, this is the equivalent of re-initalizing your android device with a google account.
# API reversing

View File

@ -51,7 +51,6 @@ class GooglePlayAPI(object):
ACCOUNT = "HOSTED_OR_GOOGLE"
authSubToken = None
ac2dmToken = None
gsfId = None
def __init__(self, debug=False):
@ -94,13 +93,6 @@ class GooglePlayAPI(object):
if self.debug:
print("authSubToken: " + authSubToken)
def setAc2dmToken(self, ac2dmToken):
self.ac2dmToken = ac2dmToken
# put your auth token in config.py to avoid multiple login requests
if self.debug:
print("ac2dmToken: " + ac2dmToken)
def getDefaultHeaders(self):
"""Return the default set of request headers, which
can later be updated, based on the request type"""
@ -118,7 +110,7 @@ class GooglePlayAPI(object):
headers["Authorization"] = "GoogleLogin auth=%s" % self.authSubToken
return headers
def checkin(self, email):
def checkin(self, email, ac2dmToken):
headers = self.getDefaultHeaders()
headers["Content-Type"] = "application/x-protobuffer"
@ -138,7 +130,7 @@ class GooglePlayAPI(object):
request2.id = response.androidId
request2.securityToken = response.securityToken
request2.accountCookie.append("[" + email + "]")
request2.accountCookie.append(self.ac2dmToken)
request2.accountCookie.append(ac2dmToken)
stringRequest = request2.SerializeToString()
res2 = requests.post(self.CHECKINURL, data=stringRequest,
headers=headers, verify=ssl_verify)
@ -163,28 +155,19 @@ class GooglePlayAPI(object):
response = googleplay_pb2.ResponseWrapper.FromString(res.content)
def login(self, email, password, ac2dmToken=None, gsfId=None):
def login(self, email=None, password=None, gsfId=None, authSubToken=None):
"""Login to your Google Account.
For first time login you should provide:
* email
* password
For the following logins you need to provide all parameters (you
should save gsfId and ac2dmToken somewhere"""
encryptedPass = self.encrypt_password(email, password).decode('utf-8')
if (all( [each != None for each in [email, password, ac2dmToken, gsfId]] )):
# this means that we already setup our account, we just need to get
# a token
self.setAc2dmToken(ac2dmToken)
self.gsfId = gsfId
self.getAuthSubToken(email, encryptedPass)
# check if token is valid with a simple search
self.search('firefox', 1, None)
else:
For the following logins you need to provide:
* gsfId
* authSubToken"""
if email is not None and password is not None:
# First time setup, where we obtain an ac2dm token and
# upload device information
if (email is None or password is None):
raise Exception("You should provide both email and pass")
encryptedPass = self.encrypt_password(email, password).decode('utf-8')
# AC2DM token
params = {
"Email": email,
@ -209,19 +192,27 @@ class GooglePlayAPI(object):
k, v = d.split("=")[0:2]
params[k.strip().lower()] = v.strip()
if "auth" in params:
self.setAc2dmToken(params["auth"])
ac2dmToken = params["auth"]
elif "error" in params:
raise LoginError("server says: " + params["error"])
else:
raise LoginError("Auth token not found.")
self.gsfId = self.checkin(email)
self.gsfId = self.checkin(email, ac2dmToken)
if self.debug:
print("Google Services Framework Id: %s" % "{0:x}".format(self.gsfId))
self.getAuthSubToken(email, encryptedPass)
if self.debug:
print("Uploading device configuration")
self.uploadDeviceConfig()
elif gsfId is not None and authSubToken is not None:
# no need to initialize API
self.gsfId = gsfId
self.setAuthSubToken(authSubToken)
# check if token is valid with a simple search
self.search('firefox', 1, None)
else:
raise LoginError('Either (email,pass) or (gsfId, authSubToken) is needed')
def getAuthSubToken(self, email, passwd):
params = {

View File

@ -6,16 +6,17 @@ EMAIL = "maracaiboez"
PASSWD = "fjgozwjmkwyvvutt"
testApps = ['com.cpuid.cpu_z']
server = GooglePlayAPI(True)
server = GooglePlayAPI(debug=True)
try:
print('\nLogging in with email and password\n')
server.login(EMAIL, PASSWD, None, None)
ac2dmToken = server.ac2dmToken
gsfId = server.gsfId
authSubToken = server.authSubToken
print('\nNow trying secondary login with ac2dm token and gsfId saved\n')
server.login(EMAIL, PASSWD, ac2dmToken, gsfId)
server = GooglePlayAPI(debug=True)
server.login(None, None, gsfId, authSubToken)
apps = server.search('telegram', 1, None)
print('\nFound those apps:\n')