Пример #1
0
def create_file_state(wallet_path: str) -> Optional[FileState]:
    if not os.path.exists(wallet_path):
        return None

    try:
        storage = WalletStorage(wallet_path)
    except Exception:
        logger.exception("problem looking at selected wallet '%s'",
                         wallet_path)
        return None

    is_too_modern = False
    try:
        storage_info = categorise_file(wallet_path)
        if storage_info.kind == StorageKind.HYBRID:
            return None

        wallet_action = WalletAction.OPEN
        password_state = PasswordState.UNKNOWN

        if storage_info.kind == StorageKind.FILE:
            text_store = storage.get_text_store()
            try:
                text_store.attempt_load_data()
            except IOError:
                # IOError: storage.py:load_data() raises when selected file cannot be parsed.
                return None
            if storage.get("use_encryption"):
                # If there is a password and the wallet is not encrypted, then the private data
                # is encrypted.
                password_state = PasswordState.PASSWORDED
            elif text_store.is_encrypted():
                # If there is a password and the wallet is encrypted, then the private data is
                # encrypted and the file is encrypted.
                password_state = PasswordState.PASSWORDED | PasswordState.ENCRYPTED
            else:
                # Neither the private data is encrypted or the file itself.
                password_state = PasswordState.NONE
        else:
            assert storage_info.kind == StorageKind.DATABASE
            password_state = PasswordState.PASSWORDED
            database_store = storage.get_database_store()
            is_too_modern = database_store.get("migration") > MIGRATION_CURRENT

        requires_upgrade = storage.requires_split(
        ) or storage.requires_upgrade()
    finally:
        storage.close()

    name = get_wallet_name_from_path(wallet_path)
    modification_time = os.path.getmtime(wallet_path)
    return FileState(name, wallet_path, wallet_action, storage_info.kind,
                     password_state, requires_upgrade, modification_time,
                     is_too_modern)
Пример #2
0
    def _attempt_open_wallet(self,
                             wallet_path: str,
                             change_page: bool = False) -> bool:
        try:
            storage = WalletStorage(wallet_path)
        except Exception:
            logger.exception("problem looking at selected wallet '%s'",
                             wallet_path)
            MessageBox.show_error(
                _("Unrecognised or unsupported wallet file."))
            return False

        try:
            storage_info = categorise_file(wallet_path)
            if storage_info.kind == StorageKind.HYBRID:
                MessageBox.show_error(
                    _("Unrecognised or unsupported wallet file."))
                return False

            wallet_type = StorageKind.FILE if storage.is_legacy_format(
            ) else StorageKind.DATABASE
            if wallet_type == StorageKind.FILE:
                text_store = storage.get_text_store()
                text_store.attempt_load_data()
                if storage.get("use_encryption") or text_store.is_encrypted():
                    # If there is a password and the wallet is not encrypted, then the private data
                    # is encrypted. If there is a password and the wallet is encrypted, then the
                    # private data is encrypted and the file is encrypted.
                    self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_REQUEST
                else:
                    # Neither the private data is encrypted or the file itself.
                    self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_ADDITION
            else:
                self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_REQUEST
        finally:
            storage.close()

        self._force_completed = True

        wizard: WalletWizard = self.wizard()
        wizard.set_wallet_action(WalletAction.OPEN)
        wizard.set_wallet_type(wallet_type)
        wizard.set_wallet_path(wallet_path)

        if change_page:
            wizard.next()

        return True
Пример #3
0
def test_legacy_wallet_loading(storage_info: WalletStorageInfo) -> None:
    # When a wallet is composed of multiple files, we need to know which to load.
    wallet_filenames = []
    if storage_info.kind != StorageKind.DATABASE:
        wallet_filenames.append(storage_info.filename)
    if storage_info.kind in (StorageKind.DATABASE, StorageKind.HYBRID):
        wallet_filenames.append(storage_info.filename + DATABASE_EXT)

    temp_dir = tempfile.mkdtemp()
    for _wallet_filename in wallet_filenames:
        source_wallet_path = os.path.join(TEST_WALLET_PATH, _wallet_filename)
        wallet_path = os.path.join(temp_dir, _wallet_filename)
        shutil.copyfile(source_wallet_path, wallet_path)

    wallet_filename = storage_info.filename
    wallet_path = os.path.join(temp_dir, wallet_filename)

    if "testnet" in wallet_filename:
        Net.set_to(SVTestnet)

    if storage_info.kind == StorageKind.HYBRID:
        pytest.xfail("old development database wallets not supported yet")

    password = None
    storage = WalletStorage(wallet_path)
    if "passworded" in wallet_filename:
        password = "******"
        text_store = storage.get_text_store()
        text_store.load_data(text_store.decrypt(password))
    if "encrypted" in wallet_filename:
        password = "******"
        check_no_password = False

    storage.upgrade(password is not None, password)

    try:
        wallet = Wallet(storage)
    except FileNotFoundError as e:
        if sys.version_info[:3] >= (3, 8, 0):
            msg = "Could not find module 'libusb-1.0.dll' (or one of its dependencies)."
            if msg in e.args[0]:
                pytest.xfail("libusb DLL could not be found")
                return
        raise e
    except OSError as e:
        if sys.version_info[:3] < (3, 8, 0):
            if "The specified module could not be found" in e.args[1]:
                pytest.xfail("libusb DLL could not be found")
                return
        raise e

    old_password = password
    password = "******"
    wallet.update_password(password, old_password)

    if "standard" in wallet_filename:
        is_bip39 = "bip39" in wallet_filename
        check_legacy_parent_of_standard_wallet(wallet, is_bip39=is_bip39,
            password=password)
    elif "imported_privkey" in wallet_filename:
        check_legacy_parent_of_imported_privkey_wallet(wallet)
    elif "imported_address" in wallet_filename:
        check_legacy_parent_of_imported_address_wallet(wallet)
    elif "multisig" in wallet_filename:
        check_legacy_parent_of_multisig_wallet(wallet)
    elif "hardware" in wallet_filename:
        check_legacy_parent_of_hardware_wallet(wallet)
    else:
        raise Exception(f"unrecognised wallet file {wallet_filename}")

    if "testnet" in wallet_filename:
        Net.set_to(SVMainnet)
Пример #4
0
def test_legacy_wallet_loading(storage_info: WalletStorageInfo) -> None:
    # When a wallet is composed of multiple files, we need to know which to load.
    wallet_filenames = []
    if storage_info.kind != StorageKind.DATABASE:
        wallet_filenames.append(storage_info.filename)
    if storage_info.kind in (StorageKind.DATABASE, StorageKind.HYBRID):
        wallet_filenames.append(storage_info.filename + DATABASE_EXT)

    temp_dir = tempfile.mkdtemp()
    for _wallet_filename in wallet_filenames:
        source_wallet_path = os.path.join(TEST_WALLET_PATH, _wallet_filename)
        wallet_path = os.path.join(temp_dir, _wallet_filename)
        shutil.copyfile(source_wallet_path, wallet_path)

    wallet_filename = storage_info.filename
    wallet_path = os.path.join(temp_dir, wallet_filename)

    if "testnet" in wallet_filename:
        Net.set_to(SVTestnet)

    if storage_info.kind == StorageKind.HYBRID:
        pytest.xfail("old development database wallets not supported yet")

    password = None
    storage = WalletStorage(wallet_path)
    if "passworded" in wallet_filename:
        password = "******"
        text_store = storage.get_text_store()
        text_store.load_data(text_store.decrypt(password))
    if "encrypted" in wallet_filename:
        password = "******"
        check_no_password = False

    storage.upgrade(password is not None, password)

    try:
        wallet = Wallet(storage)
    except OSError as e:
        if "is not a valid Win32 application" not in e.args[1]:
            raise e
        pytest.xfail("Missing libusb for this architecture")
        return

    old_password = password
    password = "******"
    wallet.update_password(password, old_password)

    if "standard" in wallet_filename:
        is_bip39 = "bip39" in wallet_filename
        check_legacy_parent_of_standard_wallet(wallet,
                                               is_bip39=is_bip39,
                                               password=password)
    elif "imported_privkey" in wallet_filename:
        check_legacy_parent_of_imported_privkey_wallet(wallet)
    elif "imported_address" in wallet_filename:
        check_legacy_parent_of_imported_address_wallet(wallet)
    elif "multisig" in wallet_filename:
        check_legacy_parent_of_multisig_wallet(wallet)
    elif "hardware" in wallet_filename:
        check_legacy_parent_of_hardware_wallet(wallet)
    else:
        raise Exception(f"unrecognised wallet file {wallet_filename}")

    if "testnet" in wallet_filename:
        Net.set_to(SVMainnet)