Add method _api_account_version_and_salt.

master
Ethan Dalool 2020-03-23 20:00:51 -07:00
parent ac442ced7f
commit bb8a5081c5
1 changed files with 25 additions and 10 deletions

View File

@ -80,6 +80,20 @@ class Mega:
raise error_for_code(json_resp) raise error_for_code(json_resp)
return json_resp[0] return json_resp[0]
def _api_account_version_and_salt(self, email):
"""
The `us0` request returns a dictionary like
{'v': 1} if the account is a v1 account, or
{'v': 2, 's': '*salt*'} if the account is v2 or higher.
This function will return a tuple (version, salt) where salt is None
if the version is 1.
"""
resp = self._api_request({'a': 'us0', 'user': email})
account_version = resp['v']
user_salt = resp.get('s', None)
return (account_version, user_salt)
def _api_start_session(self, user, user_hash=None): def _api_start_session(self, user, user_hash=None):
""" """
The `us` request returns a dictionary like The `us` request returns a dictionary like
@ -110,16 +124,12 @@ class Mega:
def _login_user(self, email, password): def _login_user(self, email, password):
logger.info('Logging in user...') logger.info('Logging in user...')
email = email.lower() email = email.lower()
get_user_salt_resp = self._api_request({'a': 'us0', 'user': email}) (account_version, user_salt) = self._api_account_version_and_salt(email)
user_salt = None logger.debug('User account is version %d.', account_version)
try: if account_version >= 2:
user_salt = base64_to_a32(get_user_salt_resp['s']) user_salt = base64_to_a32(user_salt)
except KeyError: # Parameters specified by MEGA's webclient security.js, search for
# v1 user account # "numOfIterations" and deriveKeyWithWebCrypto to cross-reference.
password_aes = prepare_key(str_to_a32(password))
user_hash = stringhash(email, password_aes)
else:
# v2 user account
pbkdf2_key = hashlib.pbkdf2_hmac( pbkdf2_key = hashlib.pbkdf2_hmac(
hash_name='sha512', hash_name='sha512',
password=password.encode(), password=password.encode(),
@ -129,6 +139,11 @@ class Mega:
) )
password_aes = str_to_a32(pbkdf2_key[:16]) password_aes = str_to_a32(pbkdf2_key[:16])
user_hash = base64_url_encode(pbkdf2_key[-16:]) user_hash = base64_url_encode(pbkdf2_key[-16:])
else:
password_a32 = str_to_a32(password)
password_aes = prepare_key(password_a32)
user_hash = stringhash(email, password_aes)
resp = self._api_start_session(email, user_hash) resp = self._api_start_session(email, user_hash)
if isinstance(resp, int): if isinstance(resp, int):
raise RequestError(resp) raise RequestError(resp)