Beispiel #1
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 #2
0
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)
Beispiel #3
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