def cryptobox_command(options): """ @param options: dictionary with options @type options: namedtuple, Values @return: succes indicator @rtype: bool """ Events = Events() try: if options.acommand: if options.acommand == "open_folder": if options.dir: p = os.path.join(options.dir, options.cryptobox) open_folder(p) output_json({"log": "open " + p}) else: message_json("no folder given(-f)") elif options.acommand == "hash": if not options.input: message_json("need input (-i)") path = options.input output_json({"hash": make_hash_path(path)}) return elif options.acommand == "check_new_release": if not options.server: message_json("server mising") if not options.compiled: message_json("compiled mising") log_json("options.compiled: " + options.compiled) current_hash = make_hash_path(options.compiled) hash_url = urlparse.urljoin(options.server, "/st/data/cba_main.hash.json") log_json("hash_url: " + hash_url) result = urllib2.urlopen(hash_url).read() result_json = json.loads(result) new_release = not (current_hash == result_json["hash"]) output_json( {"new_release": new_release, "current_hash": current_hash, "hash_server": result_json["hash"]} ) return elif options.acommand == "download_new_release": if not options.server: message_json("server mising") output_json({"msg": "Downloading Cryptobox.dmg"}) download_url = urlparse.urljoin(options.server, "/st/data/Cryptobox.dmg") tempfile_cb = download_server( None, options, download_url, output_name_item_percentage="global_progress" ) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) root = Tkinter.Tk() root.withdraw() file_path = tkFileDialog.asksaveasfilename( parent=None, message="Cryptobox", initialfile="Cryptobox.dmg" ) if file_path: if os.path.exists(os.path.dirname(file_path)): if os.path.exists(tempfile_cb): os.rename(tempfile_cb, file_path) cleanup_tempfiles() return elif options.acommand == "delete_blobs": if not options.dir: message_json("dir mising") return if not options.cryptobox: message_json("cryptobox mising") return blobpath = os.path.join(options.dir, options.cryptobox) blobpath = os.path.join(blobpath, ".cryptobox") blobpath = os.path.join(blobpath, "blobs") if os.path.exists(blobpath): shutil.rmtree(blobpath, True) message_json("encrypted cache emptied") return elif options.acommand == "open_website": if not options.username: message_json("username mising") return if not options.password: message_json("password missing") return if not options.cryptobox: message_json("cryptobox missing") return m = Memory() m = authorize_user(m, options, force=True) if not m.has_get("authorized"): message_json("Username or password is not correct") else: encoded_token = b64_encode_safe("session_token:" + m.get("session_token")) private_key = b64_encode_safe(m.get("private_key")) webbrowser.open_new_tab( options.server + options.cryptobox + "/autologin/" + options.username + "/" + encoded_token + "/" + private_key ) else: print "cba_main.py:267", "unknown command" return if options.motivation: qlist = msgpack.load(open("quotes.list")) q = qlist[random.randint(0, len(qlist)) - 1] output_json({"motivation": q[0] + "\n\n- " + q[1]}) return # noinspection PyUnusedLocal single_instance = singleton.SingleInstance() if options.decrypt: if options.remove: print "cba_main.py:281", "option remove (-r) cannot be used together with decrypt (dataloss)" return False if options.sync: print "cba_main.py:285", "option sync (-s) cannot be used together with decrypt (hashmismatch)" return False if options.check: print "cba_main.py:289", "option check (-o) cannot be used together with decrypt (hashmismatch)" return False if not options.password: print "cba_main.py:293", "No password given (-p or --password)" return False if options.username or options.cryptobox: if not options.username: print "cba_main.py:298", "No username given (-u or --username)" return False if not options.cryptobox: print "cba_main.py:302", "No cryptobox given (-b or --cryptobox)" return False if isinstance(options, dict): options = Dict2Obj(options) if options.version: return "0.1" if not options.numdownloadthreads: options.numdownloadthreads = 2 else: options.numdownloadthreads = int(options.numdownloadthreads) options.numdownloadthreads = 8 if not options.dir: print "cba_main.py:319", "Need DIR -f or --dir to continue" return False if not options.cryptobox: print "cba_main.py:323", "No cryptobox given -b or --cryptobox" return False options.basedir = options.dir ensure_directory(options.basedir) options.dir = os.path.join(options.dir, options.cryptobox) if not options.decrypt: if quick_lock_check(options): output_json({"locked": True}) return False if not options.encrypt: restore_hidden_config(options) ensure_directory(options.dir) datadir = get_data_dir(options) if options.clear == "1": if os.path.exists(datadir): shutil.rmtree(datadir) output_json({"info_message": "cryptobox cache removed: " + str(datadir)}) else: output_json({"info_message": "cryptobox cache already removed: " + str(datadir)}) return ensure_directory(datadir) if not datadir: print "cba_main.py:351", "datadir is None" memory = Memory() memory.load(datadir) memory.replace("cryptobox_folder", options.dir) if not os.path.exists(options.basedir): print "cba_main.py:357", "DIR [", options.dir, "] does not exist" return False if options.sync: if not options.username: print "cba_main.py:362", "No username given (-u or --username)" return False if not options.password: print "cba_main.py:366", "No password given (-p or --password)" return False if options.logout: result, memory = on_server(memory, options, "logoutserver", {}, memory.get("session")) return result[0] elif options.treeseq: memory = authorize_user(memory, options) tree_seq = get_tree_sequence(memory, options) if tree_seq: output_json({"tree_seq": tree_seq}) return True elif options.password and options.username and options.cryptobox and (options.sync or options.check): memory = authorize_user(memory, options, force=True) if not memory.get("connection"): return if not memory.get("authorized"): message_json("Username or password is not correct") output_json({"instruction": "lock_buttons_password_wrong"}) return if memory.get("authorized"): if options.check: if quick_lock_check(options): return False ensure_directory(options.dir) Events.event("check get_server_index") serverindex, memory = get_server_index(memory, options) Events.event("check make_local_index") localindex = make_local_index(options) Events.event("check get_sync_changes") memory, options, file_del_server, file_downloads, file_uploads, dir_del_server, dir_make_local, dir_make_server, dir_del_local, file_del_local, server_path_nodes, unique_content, rename_server, rename_dirs, rename_local_dirs = get_sync_changes( memory, options, localindex, serverindex ) all_synced = all_item_zero_len( [ file_del_server, file_downloads, file_uploads, dir_del_server, dir_make_local, dir_make_server, dir_del_local, file_del_local, rename_server, rename_dirs, ] ) outputdict = { "file_del_server": file_del_server, "file_downloads": file_downloads, "file_uploads": file_uploads, "dir_del_server": dir_del_server, "dir_make_local": dir_make_local, "dir_make_server": dir_make_server, "dir_del_local": dir_del_local, "file_del_local": file_del_local, "all_synced": all_synced, "rename_file_server": rename_server, "rename_folder_server": rename_dirs, "rename_local_dirs": rename_local_dirs, } output_json(outputdict) elif options.sync: if options.encrypt: message_json("sync and encrypt called together") return False if quick_lock_check(options): message_json("cryptobox is locked, nothing can be added now first decrypt (-d)") return False ensure_directory(options.dir) Events.event("check sync_server") localindex, memory = sync_server(memory, options) # Events.report_measurements() salt = secret = None if options.encrypt: salt, secret, memory, localindex = index_and_encrypt(memory, options) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) if options.decrypt: if not options.clear == "1": if not secret: if memory.has("salt_b64"): salt = base64.decodestring(memory.get("salt_b64")) if not salt: raise Exception("decrypt, no salt") secret = password_derivation(options.password, salt) memory = decrypt_and_build_filetree(memory, options, secret) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) reset_cryptobox_local(options) memory.save(datadir) if options.remove and salt and secret: hide_config(options, salt, secret) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) finally: pass return True
def get_sync_changes(memory, options, localindex, serverindex): """ get_sync_changes @type memory: Memory @type options: optparse.Values, instance @type localindex: dict @type serverindex: dict @rtype (memory, options, file_del_server, file_downloads, file_uploads, dir_del_server, dir_make_local, dir_make_server, dir_del_local, file_del_local, server_path_nodes, unique_content): tuple """ Events = Events() memory = wait_for_tasks(memory, options, "waiting for server to finish tasks") if False: print_pickle_variable_for_debugging(memory, "memory") print_pickle_variable_for_debugging(localindex, "localindex") print_pickle_variable_for_debugging(serverindex, "serverindex") Events.event("parse_serverindex") dirname_hashes_server, server_path_nodes, unique_content, unique_dirs = parse_serverindex(serverindex) # server dirs Events.event("dirs_on_server") dir_del_server_tmp, dir_make_local, memory = dirs_on_server(memory, options, unique_dirs) del unique_dirs #local dirs Events.event("dirs_on_local") dir_make_server, dir_del_local = dirs_on_local(memory, options, localindex, dirname_hashes_server, serverindex) del dirname_hashes_server # find new files on server Events.event("diff_new_files_on_server") memory, file_del_server, file_downloads = diff_new_files_on_server(memory, options, server_path_nodes, dir_del_server_tmp) #local files Events.event("diff_files_locally") file_uploads, file_del_local, memory, localindex = diff_files_locally(memory, options, localindex, serverindex) file_del_local = [x for x in file_del_local if os.path.dirname(x) not in [y["dirname"] for y in dir_del_local]] # check for dir renames server_dir_renames = onlocal_dir_rename(dir_del_server_tmp, dir_make_server, localindex, options, serverindex) for old_dir, new_dir in server_dir_renames: file_uploads = [x for x in file_uploads if not x["rel_path"].startswith(new_dir)] dir_del_server_tmp = [x for x in dir_del_server_tmp if old_dir not in x] dir_make_server = [x for x in dir_make_server if new_dir not in x["relname"]] local_dir_renames = onserver_dir_rename(dir_del_local, dir_make_local, localindex, serverindex) for old_dir, new_dir in local_dir_renames: file_downloads = [x for x in file_downloads if not x["dirname_of_path"].startswith(new_dir)] dir_make_local = [x for x in dir_make_local if new_dir not in x["relname"]] dir_del_local = [x for x in dir_del_local if old_dir not in x["relname"]] # filter out file uploads from dirs to delete Events.event("find dirs to delete") dir_del_local = tuple([x for x in dir_del_local if x["dirname"] not in [os.path.dirname(y["local_path"]) for y in file_uploads]]) Events.event("find dirs to make on server") dirnames_file_upload = [os.path.dirname(y["local_path"]) for y in file_uploads] dir_make_server = [x for x in dir_make_server if x["dirname"] not in dirnames_file_upload] # filter out dirs to make from file_uploads: Events.event("prune folder making") dir_make_server_tmp = [] for dms in dir_make_server: add = True for fu in file_uploads: if dms["dirname"] in fu["local_path"]: add = False if add: dir_make_server_tmp.append(dms) dir_make_server = dir_make_server_tmp # prune directories to delete from files to download Events.event("prune folder deleting") dir_del_server = [] file_download_dirs = list(set([x["dirname_of_path"] for x in file_downloads])) for dds_path in dir_del_server_tmp: if len(file_downloads) > 0: #for dfl in file_download_dirs: if dds_path not in file_download_dirs: dir_del_server.append(dds_path) else: dir_del_server.append(dds_path) def add_size_relpath(lf): lf["size"] = os.stat(lf["local_path"]).st_size return f file_uploads = [add_size_relpath(f) for f in file_uploads] file_uploads = sorted(file_uploads, key=lambda k: k["size"]) Events.event("check_renames_server") renames_files, file_uploads, file_del_server, localindex = check_renames_server(memory, options, localindex, serverindex, file_uploads, file_del_server, dir_del_server) del serverindex file_del_server = tuple([f for f in file_del_server if os.path.dirname(f) not in dir_del_server]) Events.event("store_localindex") memory = store_localindex(memory, localindex) del Events renames_server = list(renames_files) rename_files_server = frozenset(renames_server) rename_folders_server = frozenset(server_dir_renames) return memory, options, file_del_server, file_downloads, file_uploads, tuple(dir_del_server), dir_make_local, tuple(dir_make_server), dir_del_local, tuple(file_del_local), server_path_nodes, unique_content, tuple(rename_files_server), tuple(rename_folders_server), tuple(local_dir_renames)
def cryptobox_command(options): """ @param options: dictionary with options @type options: namedtuple, Values @return: succes indicator @rtype: bool """ Events = Events() try: if options.acommand: if options.acommand == "open_folder": if options.dir: p = os.path.join(options.dir, options.cryptobox) open_folder(p) output_json({"log": "open " + p}) else: message_json("no folder given(-f)") elif options.acommand == "hash": if not options.input: message_json("need input (-i)") path = options.input output_json({"hash": make_hash_path(path)}) return elif options.acommand == "check_new_release": if not options.server: message_json("server mising") if not options.compiled: message_json("compiled mising") log_json("options.compiled: " + options.compiled) current_hash = make_hash_path(options.compiled) hash_url = urlparse.urljoin(options.server, "/st/data/cba_main.hash.json") log_json("hash_url: " + hash_url) result = urllib2.urlopen(hash_url).read() result_json = json.loads(result) new_release = not (current_hash == result_json["hash"]) output_json({ "new_release": new_release, "current_hash": current_hash, "hash_server": result_json["hash"] }) return elif options.acommand == "download_new_release": if not options.server: message_json("server mising") output_json({"msg": "Downloading Cryptobox.dmg"}) download_url = urlparse.urljoin(options.server, "/st/data/Cryptobox.dmg") tempfile_cb = download_server( None, options, download_url, output_name_item_percentage="global_progress") output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) root = Tkinter.Tk() root.withdraw() file_path = tkFileDialog.asksaveasfilename( parent=None, message="Cryptobox", initialfile='Cryptobox.dmg') if file_path: if os.path.exists(os.path.dirname(file_path)): if os.path.exists(tempfile_cb): os.rename(tempfile_cb, file_path) cleanup_tempfiles() return elif options.acommand == "delete_blobs": if not options.dir: message_json("dir mising") return if not options.cryptobox: message_json("cryptobox mising") return blobpath = os.path.join(options.dir, options.cryptobox) blobpath = os.path.join(blobpath, ".cryptobox") blobpath = os.path.join(blobpath, "blobs") if os.path.exists(blobpath): shutil.rmtree(blobpath, True) message_json("encrypted cache emptied") return elif options.acommand == "open_website": if not options.username: message_json("username mising") return if not options.password: message_json("password missing") return if not options.cryptobox: message_json("cryptobox missing") return m = Memory() m = authorize_user(m, options, force=True) if not m.has_get("authorized"): message_json("Username or password is not correct") else: encoded_token = b64_encode_safe("session_token:" + m.get("session_token")) private_key = b64_encode_safe(m.get("private_key")) webbrowser.open_new_tab(options.server + options.cryptobox + "/autologin/" + options.username + "/" + encoded_token + "/" + private_key) else: print "cba_main.py:267", "unknown command" return if options.motivation: qlist = msgpack.load(open("quotes.list")) q = qlist[random.randint(0, len(qlist)) - 1] output_json({"motivation": q[0] + "\n\n- " + q[1]}) return #noinspection PyUnusedLocal single_instance = singleton.SingleInstance() if options.decrypt: if options.remove: print "cba_main.py:281", "option remove (-r) cannot be used together with decrypt (dataloss)" return False if options.sync: print "cba_main.py:285", "option sync (-s) cannot be used together with decrypt (hashmismatch)" return False if options.check: print "cba_main.py:289", "option check (-o) cannot be used together with decrypt (hashmismatch)" return False if not options.password: print "cba_main.py:293", "No password given (-p or --password)" return False if options.username or options.cryptobox: if not options.username: print "cba_main.py:298", "No username given (-u or --username)" return False if not options.cryptobox: print "cba_main.py:302", "No cryptobox given (-b or --cryptobox)" return False if isinstance(options, dict): options = Dict2Obj(options) if options.version: return "0.1" if not options.numdownloadthreads: options.numdownloadthreads = 2 else: options.numdownloadthreads = int(options.numdownloadthreads) options.numdownloadthreads = 8 if not options.dir: print "cba_main.py:319", "Need DIR -f or --dir to continue" return False if not options.cryptobox: print "cba_main.py:323", "No cryptobox given -b or --cryptobox" return False options.basedir = options.dir ensure_directory(options.basedir) options.dir = os.path.join(options.dir, options.cryptobox) if not options.decrypt: if quick_lock_check(options): output_json({"locked": True}) return False if not options.encrypt: restore_hidden_config(options) ensure_directory(options.dir) datadir = get_data_dir(options) if options.clear == "1": if os.path.exists(datadir): shutil.rmtree(datadir) output_json({ "info_message": "cryptobox cache removed: " + str(datadir) }) else: output_json({ "info_message": "cryptobox cache already removed: " + str(datadir) }) return ensure_directory(datadir) if not datadir: print "cba_main.py:351", "datadir is None" memory = Memory() memory.load(datadir) memory.replace("cryptobox_folder", options.dir) if not os.path.exists(options.basedir): print "cba_main.py:357", "DIR [", options.dir, "] does not exist" return False if options.sync: if not options.username: print "cba_main.py:362", "No username given (-u or --username)" return False if not options.password: print "cba_main.py:366", "No password given (-p or --password)" return False if options.logout: result, memory = on_server(memory, options, "logoutserver", {}, memory.get("session")) return result[0] elif options.treeseq: memory = authorize_user(memory, options) tree_seq = get_tree_sequence(memory, options) if tree_seq: output_json({"tree_seq": tree_seq}) return True elif options.password and options.username and options.cryptobox and ( options.sync or options.check): memory = authorize_user(memory, options, force=True) if not memory.get("connection"): return if not memory.get("authorized"): message_json("Username or password is not correct") output_json({"instruction": "lock_buttons_password_wrong"}) return if memory.get("authorized"): if options.check: if quick_lock_check(options): return False ensure_directory(options.dir) Events.event("check get_server_index") serverindex, memory = get_server_index(memory, options) Events.event("check make_local_index") localindex = make_local_index(options) Events.event("check get_sync_changes") memory, options, file_del_server, file_downloads, file_uploads, dir_del_server, dir_make_local, dir_make_server, dir_del_local, file_del_local, server_path_nodes, unique_content, rename_server, rename_dirs, rename_local_dirs = get_sync_changes( memory, options, localindex, serverindex) all_synced = all_item_zero_len([ file_del_server, file_downloads, file_uploads, dir_del_server, dir_make_local, dir_make_server, dir_del_local, file_del_local, rename_server, rename_dirs ]) outputdict = { "file_del_server": file_del_server, "file_downloads": file_downloads, "file_uploads": file_uploads, "dir_del_server": dir_del_server, "dir_make_local": dir_make_local, "dir_make_server": dir_make_server, "dir_del_local": dir_del_local, "file_del_local": file_del_local, "all_synced": all_synced, "rename_file_server": rename_server, "rename_folder_server": rename_dirs, "rename_local_dirs": rename_local_dirs } output_json(outputdict) elif options.sync: if options.encrypt: message_json("sync and encrypt called together") return False if quick_lock_check(options): message_json( "cryptobox is locked, nothing can be added now first decrypt (-d)" ) return False ensure_directory(options.dir) Events.event("check sync_server") localindex, memory = sync_server(memory, options) #Events.report_measurements() salt = secret = None if options.encrypt: salt, secret, memory, localindex = index_and_encrypt( memory, options) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) if options.decrypt: if not options.clear == "1": if not secret: if memory.has("salt_b64"): salt = base64.decodestring(memory.get("salt_b64")) if not salt: raise Exception("decrypt, no salt") secret = password_derivation(options.password, salt) memory = decrypt_and_build_filetree(memory, options, secret) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) reset_cryptobox_local(options) memory.save(datadir) if options.remove and salt and secret: hide_config(options, salt, secret) output_json({"msg": ""}) output_json({"item_progress": 0}) output_json({"global_progress": 0}) finally: pass return True