Example #1
0
    def _read_file(self, filename: str, password: str = '') -> dict:
        """ Reads the data from filename and returns the account dictionary,
        the encrypted master key, and the decrypted master key.

        """

        # Read from the file if it exists.
        with pathlib_path(filename) as pass_file:
            lzma_data = pass_file.read_bytes() if pass_file.is_file() else b''

        # Get the json data out of the file data or an empty json dict of
        # the file was empty.
        if lzma_data:
            json_data = lzma_decompress(lzma_data).decode()
        else:
            json_data = '{}'

        accounts_dict = json_loads(json_data)

        # Pop the master key out of the accounts dictionary so it won't be
        # operated on or listed.  Also if no master key is found, create
        # one.
        encrypted_key = bytes.fromhex(accounts_dict.pop(self.MASTER_KEY_DIGEST, ''))

        if not encrypted_key:
            if not password:
                # Get the password to encrypt the master key.
                password = self._ask_pass('password')
        else:
            # Get the password to decrypt the key.
            password = self._ask_pass('password', verify=False)

        return CryptData(password, encrypted_key), accounts_dict
Example #2
0
    def decompress(self, source, cursor, compressedbytes, uncompressedbytes=None):
        if self.algo == uproot.const.kZLIB:
            from zlib import decompress as zlib_decompress
            return zlib_decompress(cursor.bytes(source, compressedbytes))

        elif self.algo == uproot.const.kLZMA:
            try:
                from lzma import decompress as lzma_decompress
            except ImportError:
                try:
                    from backports.lzma import decompress as lzma_decompress
                except ImportError:
                    raise ImportError("Install lzma package with:\n    pip install backports.lzma\nor\n    conda install -c conda-forge backports.lzma\n(or just use Python >= 3.3).")
            return lzma_decompress(cursor.bytes(source, compressedbytes))

        elif self.algo == uproot.const.kOldCompressionAlgo:
            raise NotImplementedError("ROOT's \"old\" algorithm (fCompress 300) is not supported")

        elif self.algo == uproot.const.kLZ4:
            try:
                from lz4.block import decompress as lz4_decompress
            except ImportError:
                raise ImportError("Install lz4 package with:\n    pip install lz4\nor\n    conda install -c anaconda lz4")

            if uncompressedbytes is None:
                raise ValueError("lz4 needs to know the uncompressed number of bytes")
            return lz4_decompress(cursor.bytes(source, compressedbytes), uncompressed_size=uncompressedbytes)

        else:
            raise ValueError("unrecognized compression algorithm: {0}".format(self.algo))
Example #3
0
    def __init__(self, bsp):
        from .bsp_file import BSPFile
        self._bsp: BSPFile = bsp
        self._lump: LumpInfo = bsp.lumps_info[self.lump_id]
        self._bsp.reader.seek(self._lump.offset)
        if self._lump.compressed:
            reader = self._bsp.reader
            lzma_id = reader.read_fourcc()
            assert lzma_id == "LZMA", f"Unknown compressed header({lzma_id})"
            decompressed_size = reader.read_uint32()
            compressed_size = reader.read_uint32()
            prob_byte = reader.read_int8()
            dict_size = reader.read_uint32()

            pb = prob_byte // (9 * 5)
            prob_byte -= pb * 9 * 5
            lp = prob_byte // 9
            lc = prob_byte - lp * 9
            my_filters = [
                {"id": lzma.FILTER_LZMA2, "dict_size": dict_size,"pb": pb, "lp": lp, "lc": lc},
            ]
            self.reader = ByteIO(
                byte_object=lzma_decompress(reader.read_bytes(compressed_size), lzma.FORMAT_RAW, filters=my_filters))
        else:
            self.reader = ByteIO(byte_object=self._bsp.reader.read_bytes(self._lump.size))
Example #4
0
def read_file(filename: str, password: str = "") -> tuple:
    """ Reads the data from filename and returns the account dictionary, the
    encrypted master key, and the decrypted master key.

    """

    # Read from the file if it exists.
    with pathlib_path(filename) as pass_file:
        lzma_data = pass_file.read_bytes() if pass_file.is_file() else b""

    # Get the json data out of the file data or an empty json dict of
    # the file was empty.
    if lzma_data:
        json_data = lzma_decompress(lzma_data).decode()
    else:
        json_data = "{}"

    accounts_dict = json_loads(json_data)

    # Pop the master key out of the accounts dictionary so it won't be
    # operated on or listed.  Also if no master key is found, create
    # one.
    encrypted_key = bytes.fromhex(accounts_dict.pop(MASTER_KEY_DIGEST, ""))
    encrypted_key, master_key = get_master_key(encrypted_key, password)

    return accounts_dict, encrypted_key, master_key
Example #5
0
def read_file(filename: str) -> dict:
    """ Reads the data from filename and returns the account dictionary.

    """

    # Read from the file if it exists.
    with pathlib_path(filename) as pass_file:
        lzma_data = pass_file.read_bytes() if pass_file.is_file() else b''

    # Get the json data out of the file data or an empty json dict of
    # the file was empty.
    if lzma_data:
        json_data = lzma_decompress(lzma_data).decode()
    else:
        json_data = '{}'

    # Load the json data into a dictionary.
    return json_loads(json_data)
Example #6
0
def _decompressfcn(compression, objlen, debug=False):
    algo, level = compression
    if algo == "zlib":
        # skip 9-byte header for ROOT's custom frame:
        # https://github.com/root-project/root/blob/master/core/zip/src/Bits.h#L646
        if debug:

            def out(x):
                print("decompressing {0} bytes".format(len(x) - 9))
                return zlib_decompress(x[9:])

            return out
        else:
            return lambda x: zlib_decompress(x[9:])

    elif algo == "lzma":
        # skip 9-byte header for LZMA, too:
        # https://github.com/root-project/root/blob/master/core/lzma/src/ZipLZMA.c#L81
        if debug:

            def out(x):
                print("decompressing {0} bytes".format(len(x) - 9))
                return lzma_decompress(x[9:])

            return out
        else:
            return lambda x: lzma_decompress(x[9:])

    elif algo == "lz4":
        # skip 9-byte header plus 8-byte hash: are there any official ROOT versions without the hash?
        # https://github.com/root-project/root/blob/master/core/lz4/src/ZipLZ4.cxx#L38
        if debug:

            def out(x):
                print("decompressing {0} bytes".format(len(x) - 9 - 8))
                return lz4_decompress(x[9 + 8:], uncompressed_size=objlen)

            return out
        else:
            return lambda x: lz4_decompress(x[9 + 8:],
                                            uncompressed_size=objlen)

    else:
        raise NotImplementedError("cannot decompress \"{0}\"".format(algo))
    def get_frames(self):
        replay_frames = lzma_decompress(self.data).decode('utf-8').split(",")
        offset = int(replay_frames[1].split("|")[0]) + int(
            replay_frames[0].split("|")[0])
        replay_frames = [frame.split("|") for frame in replay_frames[2:-2]]

        time = offset
        absolute_frames = []
        times = []
        for frame in replay_frames:
            time += int(frame[0])
            if frame[0] == '0':
                absolute_frames.pop()
                times.pop()
            absolute_frames.append(
                [time, float(frame[1]),
                 float(frame[2]),
                 int(frame[3])])
            times.append(time)

        return absolute_frames, times
Example #8
0
def read_file(filename: str, password: str = '') -> tuple:
    """ Reads the data from filename and returns the account dictionary, the
    encrypted master key, and the decrypted master key.

    """

    # Read from the file if it exists.
    with pathlib_path(filename) as pass_file:
        lzma_data = pass_file.read_bytes() if pass_file.is_file() else b''

    # Get the json data out of the file data or an empty json dict of
    # the file was empty.
    if lzma_data:
        json_data = lzma_decompress(lzma_data).decode()
    else:
        json_data = '{}'

    accounts_dict = json_loads(json_data)

    # Pop the master key out of the accounts dictionary so it won't be
    # operated on or listed.  Also if no master key is found, create
    # one.
    encrypted_key = bytes.fromhex(accounts_dict.pop(MASTER_KEY_DIGEST, ''))

    if not encrypted_key:
        if not password:
            # Get the password to encrypt the master key.
            password = get_pass('password')

        # Generate the largest key possible.
        master_key = Random.new().read(KEY_LEN)

        # Encrypt the key.
        encrypted_key = encrypt_key(master_key, password)
    else:
        # Get the password to decrypt the key.
        password = get_pass('password', verify=False)
        master_key = decrypt_key(encrypted_key, password)

    return accounts_dict, encrypted_key, master_key
Example #9
0
def main(args: dict) -> int:
    """ Read the password file, decrypt it and print the requested info.

    """

    filename = args.pop('filename')
    account = args.pop('account')
    remove_account = args.pop('remove_account')
    password = args.pop('password')

    if account:
        # Get the sha256 hash of the account name.
        hashed_account = bytes_to_str(SHA256.new(account.encode()).digest())

        # Create the information dictionary from the info list supplied
        # by the user.
        info_dict = list_to_dict(args.pop('info_list'), args['info_seperator'])

        if info_dict:
            # Put the non hashed account name in the info dict so it is
            # not lost.
            info_dict['Account Name'] = account

            # Get the secret information.
            for key, value in info_dict.items():
                if value == '{secret}':
                    secret = get_pass(key)
                    info_dict[key] = secret
    else:
        # No account name was given.
        hashed_account = ''

    # Create the file if it doesn't exist.
    if not os_isfile(filename):
        open_mode = 'w+b'
    else:
        open_mode = 'rb'

    with open(filename, open_mode) as pass_file:
        # Read all the data from the file.
        lzma_data = pass_file.read()

    # Get the json data out of the file data or an empty json dict of
    # the file was empty.
    if lzma_data:
        json_data = lzma_decompress(lzma_data).decode()
    else:
        json_data = '{}'

    # Load the json data into a dictionary.
    accounts_dict = json_loads(json_data)

    aes_key_digest = bytes_to_str(SHA512.new(b'\x00aes_key\x00').digest())
    aes_key_enc = str_to_bytes(accounts_dict.pop(aes_key_digest, ''))
    aes_key_enc, aes_key = get_aes_key(aes_key_enc)

    if not hashed_account:
        if args.get('list_account_info', False):
            # List all accounts if none where given, but list was requested.
            account_str = ''
            for account_data in accounts_dict.values():
                # account_dict = crypt_to_dict(account_data, password)
                account_dict = crypt_to_dict_key(account_data, aes_key)
                if account_dict:
                    account_str += '\n' + dict_to_str(account_dict)
            import pydoc
            pydoc.pager(account_str)
        elif args.get('re-encrypt', False):
            # Try to re-encrypt every account.
            encrypt_pass = get_pass('encryption password')
            tmp_accounts_dict = accounts_dict.copy()
            for account_hash, account_data in accounts_dict.items():
                account_dict = crypt_to_dict(account_data, password=password,
                                             skip_invalid=True)
                # account_dict = crypt_to_dict_key(account_data, aes_key)
                if account_dict:
                    # new_account_data = dict_to_crypt(account_dict, encrypt_pass)
                    new_account_data = dict_to_crypt_key(account_dict, aes_key)
                else:
                    print("Invalid password.  Account will use the old password")
                tmp_accounts_dict[account_hash] = new_account_data
            tmp_accounts_dict[aes_key_digest] = bytes_to_str(aes_key_enc)
            write_file(filename, tmp_accounts_dict)
            return 0
        elif args.get('search', ''):
            search_str = args['search'].lower()

            # String to store all matching account information.
            account_str = ''

            for account_data in accounts_dict.values():
                # Search through every account that can be decrypted with
                # the password, or ask for a password for each account.
                # account_dict = crypt_to_dict(account_data, password=password,
                #                              skip_invalid=True)
                account_dict = crypt_to_dict_key(account_data, aes_key)

                # If the password could decrypt the account, info search
                # throuth every key and value in the account.
                if account_dict:
                    for key, value in account_dict.items():
                        if search_str in key.lower() or search_str in value.lower():
                            account_str += '\n' + dict_to_str(account_dict)
                            # Don't add the same account more than once.
                            break
            import pydoc
            pydoc.pager(account_str)
    else:
        # Pop the requested account out of the dictionary, so it can be
        # modified, removed, or just printed to stdout.
        account_data = accounts_dict.pop(hashed_account, '')

        # Don't do anything with the account_data if it is to be
        # removed.
        if remove_account:
            accounts_dict[aes_key_digest] = bytes_to_str(aes_key_enc)
            write_file(filename, accounts_dict)
            return 0

        # If there was account data, then put the decrypted dictionary in
        # account_dict.  Otherwise put an empty dictionary.
        if account_data:
            # account_dict = crypt_to_dict(account_data, skip_invalid=False)
            account_dict = crypt_to_dict_key(account_data, aes_key)
        else:
            account_dict = {}

        # Update the account info if new data was supplied.
        if info_dict:
            account_dict.update(info_dict)

            # Remove items from account_dict for which info_dict has an
            # empty value.  (i.e. to remove items from an accounts info
            # the user needs to supply and empty value after the
            # sperator.
            for key, value in info_dict.items():
                if not value.strip():
                    account_dict.pop(key)

            # Encrypt the account_dict.
            # account_data = dict_to_crypt(account_dict)
            account_data = dict_to_crypt_key(account_dict, aes_key)

        # Print the account info.
        if args.get('list_account_info', False) and account_dict:
            import pydoc
            pydoc.pager(dict_to_str(account_dict))

        # Put the accounts data back into the dictionary.
        accounts_dict[hashed_account] = account_data
        accounts_dict[aes_key_digest] = bytes_to_str(aes_key_enc)

        # Write accounts_dict to the password file.
        write_file(filename, accounts_dict)

    return 0
            file_corrupted = True
    # lzma
    elif algo_bytes == "XZ":
        uncompressed_bytes = fd_root.read(num_compressed_bytes)
        try:
            from lzma import decompress as lzma_decompress
        except ImportError:
            try:
                from backports.lzma import decompress as lzma_decompress
            except ImportError:
                raise ImportError(
                    "Install lzma package with:\n pip install backports.lzma\nor\n conda install -c conda-forge backports.lzma\n(or just use Python >= 3.3)."
                )

        try:
            lzma_decompress(uncompressed_bytes)
        except Exception, e:
            print("Corrupted basket")
            print(seek)
            print(num_uncompressed_bytes)
            print(e)
            file_corrupted = True
    # lz4
    elif algo_bytes == "L4":
        print("Unsupported algorithm: " + algo_bytes + " , skipping...")
        try:
            import xxhash
        except ImportError:
            raise ImportError(
                "Install xxhash package with:\n    pip install xxhash\nor\n    conda install -c conda-forge python-xxhash"
            )
Example #11
0
 def dump_frames(self, file):
     readable_data = lzma_decompress(self.data).decode('utf-8')
     readable_data = readable_data.replace(",", "\n")
     with open(file, "w") as f:
         f.write(readable_data)
Example #12
0
 def out(x):
     print("decompressing {0} bytes".format(len(x) - 9))
     return lzma_decompress(x[9:])