Beispiel #1
0
def server_path_to_shortid(memory, options, path):
    path = save_encode_b64(path)
    payload = {"path": path}
    result, memory = on_server(memory, options, "pathtoshortid", payload=payload, session=memory.get("session"))

    if result[0]:
        return result[1]
    return None
Beispiel #2
0
def get_server_index(memory, options):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    @return: index
    @rtype: dict, Memory
    """
    if not memory.has("session"):
        if memory.has("authorized"):
            memory.delete("authorized")

    if not memory.has("session"):
        memory = authorize_user(memory, options)

    if not memory.get("authorized"):
        raise NotAuthorized("get_server_index")

    tree_seq = get_tree_sequence(memory, options)

    if tree_seq:
        memory.replace("tree_seq", tree_seq)

    result, memory = on_server(memory, options, "tree", payload={'listonly': True}, session=memory.get("session"))
    if not result[0]:
        if memory.has("authorized"):
            memory.delete("authorized")

        memory = authorize_user(memory, options)
        result, memory = on_server(memory, options, "tree", payload={'listonly': True}, session=memory.get("session"))
        if not result[0]:
            raise TreeLoadError()

    serverindex = result[1]

    dirlistfiles = [os.path.dirname(x["doc"]["m_path_p64s"]) for x in serverindex["doclist"] if x["doc"]["m_nodetype"] == "file"]
    dirlistfolders = [x["doc"]["m_path_p64s"] for x in serverindex["doclist"] if x["doc"]["m_nodetype"] == "folder"]
    dirlistserver = dirlistfiles
    dirlistserver.extend(dirlistfolders)
    serverindex["dirlist"] = tuple(list(set(dirlistserver)))
    serverindex["doclist"] = tuple(serverindex["doclist"])
    memory.replace("serverindex", serverindex)
    return serverindex, memory
Beispiel #3
0
def instruct_server_to_delete_items(memory, options, short_node_ids_to_delete, progress_message):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    @type short_node_ids_to_delete: list
    @type progress_message: str
    """
    if len(short_node_ids_to_delete) > 0:
        payload = {"tree_item_list": short_node_ids_to_delete}
        result, memory = on_server(memory, options, "docs/delete", payload=payload, session=memory.get("session"))
        memory = wait_for_tasks(memory, options, progress_message)
    return memory
Beispiel #4
0
def instruct_server_to_rename_path(memory, options, path1, path2):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    @type path1: str
    @type path2: str
    """
    payload = {"path1": path1,
               "path2": path2}

    result, memory = on_server(memory, options, "docs/renamepath", payload=payload, session=memory.get("session"))
    memory = wait_for_tasks(memory, options)
    return memory
Beispiel #5
0
def instruct_server_to_changename(memory, options, path1, path2):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    @type path1: str
    @type path2: str
    """
    serverindex = memory.get("serverindex")
    node_short_id = path_to_server_shortid(options, serverindex, path1)
    nodename = os.path.basename(path2)
    payload = {"node_short_id": node_short_id,
               "nodename": nodename}

    result, memory = on_server(memory, options, "docs/changename", payload=payload, session=memory.get("session"))
    memory = wait_for_tasks(memory, options)
    return memory
Beispiel #6
0
def get_tree_sequence(memory, options):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    """
    clock_tree_seq, memory = on_server(memory, options, "clock", {}, memory.get("session"))

    if clock_tree_seq:
        if len(clock_tree_seq) > 1:
            if clock_tree_seq[1]:
                if isinstance(clock_tree_seq[1], int):
                    return clock_tree_seq[1]
                else:
                    if len(clock_tree_seq[1]) > 0:
                        return int(clock_tree_seq[1])

    return None
Beispiel #7
0
def instruct_server_to_make_folders(memory, options, dirs_make_server):
    """
    @type memory: Memory
    @type options: optparse.Values, instance
    @type dirs_make_server: tuple
    @rtype: Memory
    """
    foldernames = [dir_name["dirname"].replace(options.dir, "") for dir_name in dirs_make_server]
    for dir_name in foldernames:
        memory = add_path_history(dir_name, memory)

    for foldername in foldernames:
        payload = {"foldername": foldername}
        result, memory = on_server(memory, options, "docs/makefolder", payload=payload, session=memory.get("session"))
    wait_for_tasks(memory, options)
    serverindex, memory = get_server_index(memory, options)
    return serverindex, memory
Beispiel #8
0
def wait_for_tasks(memory, options, result_message_param=None):
    """
    wait_for_tasks
    @type memory: Memory
    @type options: optparse.Values, instance
    """
    initial_num_tasks = -1

    while True:
        session = None

        if memory.has("session"):
            session = memory.get("session")

        result, memory = on_server(memory, options, "crypto_tasks", payload={}, session=session)

        if result:
            if len(result) > 1:
                if result[1]:
                    num_tasks = len([x for x in result[1] if x["m_command_object"] != "StorePassword"])

                    if initial_num_tasks == -1:
                        initial_num_tasks = num_tasks

                    if not result_message_param:
                        result_message = "waiting for tasks to finish on server"
                    else:
                        result_message = result_message_param
                    update_progress(initial_num_tasks - num_tasks, initial_num_tasks, result_message)
                    if num_tasks == 0:
                        return memory

                    if not result_message:
                        if num_tasks > 3:
                            time.sleep(1)
                            if num_tasks > 6:
                                log_json("waiting for tasks " + str(num_tasks))

                else:
                    return memory

        if not result_message_param:
            time.sleep(1)
        else:
            time.sleep(0.5)
Beispiel #9
0
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
Beispiel #10
0
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