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)
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
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)
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)