Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 47 additions & 13 deletions megaclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,39 @@ def login(self):
sid = binascii.unhexlify('0' + sid if len(sid) % 2 else sid)
self.sid = base64urlencode(sid[:43])

def processfile(self, file):
def processfile(self, file, users_keys):
if file['t'] == 0 or file['t'] == 1:
key = file['k'][file['k'].index(':') + 1:]
key = decrypt_key(base64_to_a32(key), self.master_key)
if file['t'] == 0:
k = file['k'] = (key[0] ^ key[4], key[1] ^ key[5], key[2] ^ key[6], key[3] ^ key[7])
iv = file['iv'] = key[4:6] + (0, 0)
meta_mac = file['meta_mac'] = key[6:8]
else:
k = file['k'] = key
attributes = base64urldecode(file['a'])
attributes = dec_attr(attributes, k)
file['a'] = attributes
keys = dict(keypart.split(':',1) for keypart in file['k'].split('/'))
uid = file['u']
key = None
if uid in keys :
# normal file or folder
key = decrypt_key(base64_to_a32( keys[uid] ), self.master_key)
elif 'su' in file and 'sk' in file and ':' in file['k']:
# Shared folder
user_key = decrypt_key(base64_to_a32(file['sk']),self.master_key)
key = decrypt_key(base64_to_a32(keys[file['h']]),user_key)
if file['su'] not in users_keys :
users_keys[file['su']] = {}
users_keys[file['su']][file['h']] = user_key
elif file['u'] and file['u'] in users_keys :
# Shared file
for hkey in users_keys[file['u']] :
user_key = users_keys[file['u']][hkey]
if hkey in keys :
key = keys[hkey]
key = decrypt_key(base64_to_a32(key),user_key)
break
if key is not None :
if file['t'] == 0:
k = file['k'] = (key[0] ^ key[4], key[1] ^ key[5], key[2] ^ key[6], key[3] ^ key[7])
iv = file['iv'] = key[4:6] + (0, 0)
meta_mac = file['meta_mac'] = key[6:8]
else:
k = file['k'] = key
attributes = base64urldecode(file['a'])
attributes = dec_attr(attributes, k)
file['a'] = attributes
elif file['t'] == 2:
self.root_id = file['h']
file['a'] = {'n': 'Cloud Drive'}
Expand All @@ -79,11 +99,25 @@ def processfile(self, file):
file['a'] = {'n': 'Rubbish Bin'}
return file

def init_sharedkeys(self,files,users_keys) :
# Init shared keys that comes from shared folders that aren't shared anymore
ok_dict = {}
for ok_item in files['ok'] :
user_key = decrypt_key(base64_to_a32(ok_item['k']),self.master_key)
ok_dict[ok_item['h']] = user_key
for s_item in files['s'] :
if s_item['u'] not in users_keys :
users_keys[s_item['u']] = {}
if s_item['h'] in ok_dict :
users_keys[s_item['u']][s_item['h']] = ok_dict[s_item['h']]

def getfiles(self):
files = self.api_req({'a': 'f', 'c': 1})
files_dict = {}
users_keys={}
self.init_sharedkeys(files,users_keys)
for file in files['f']:
files_dict[file['h']] = self.processfile(file)
files_dict[file['h']] = self.processfile(file,users_keys)
return files_dict

def downloadfile(self, file, dest_path):
Expand Down