def init_daemon(config_options): config = SimpleConfig(config_options) wallet_path = config.get_wallet_path() if not WalletStorage.files_are_matched_by_path(wallet_path): print("Error: Wallet file not found.") print("Type 'electrum-sv create' to create a new wallet, " "or provide a path to a wallet with the -w option") sys.exit(0) storage = WalletStorage(wallet_path) if storage.is_encrypted(): if 'wallet_password' in config_options: print( 'Warning: unlocking wallet with commandline argument \"--walletpassword\"' ) password = config_options['wallet_password'] elif config.get('password'): password = config.get('password') else: password = prompt_password('Password:'******'password'] = password
def _on_filename(filename): # A relative path will be relative to the folder we offered in the choose dialog. # An absolute path will not get joined to the dialog folder (no-op). path = os.path.join(wallet_folder, filename) try: self.storage = WalletStorage(path, manual_upgrades=True) self.next_button.setEnabled(True) except IOError: self.storage = None self.next_button.setEnabled(False) if self.storage: if not self.storage.file_exists(): msg =_("This file does not exist.") + '\n' \ + _("Press 'Next' to create this wallet, or choose another file.") pw = False elif self.storage.file_exists() and self.storage.is_encrypted(): msg = '\n'.join([ _("This file is encrypted."), _('Enter your password or choose another file.'), ]) pw = True else: msg = _("Press 'Next' to open this wallet.") pw = False else: msg = _('Cannot read file') pw = False self.msg_label.setText(msg) if pw: self.pw_label.show() self.pw_e.show() self.pw_e.setFocus() else: self.pw_label.hide() self.pw_e.hide()
def attempt_open( klass, wallet_path: str) -> Tuple[bool, bool, Optional['WalletWizard']]: """ Returns a tuple containing: `is_valid` - indicates the open action should proceed. `was_aborted` - indicates the user performed an action to abort the process. `wizard` - optionally present for valid cases where the wallet cannot be opened directly (migration is required). """ entry = create_file_state(wallet_path) was_aborted = False if entry is not None: storage = WalletStorage(wallet_path) try: password = request_password(None, storage, entry) if password is not None: if entry.requires_upgrade: migration_context = MigrationContext( entry, storage, password) # We hand off the storage reference to the wallet wizard to close. storage = None return True, False, klass( migration_data=migration_context) return True, False, None was_aborted = True finally: if storage is not None: storage.close() return False, was_aborted, None
def run_non_RPC(config): """Most commands should go through the daemon or RPC, especially commands that operate on wallets.""" cmdname = config.get('cmd') def get_wallet_path() -> str: wallet_path = config.get_cmdline_wallet_filepath() if wallet_path is None: sys.exit("error: no wallet path provided") final_path = WalletStorage.canonical_path(wallet_path) if WalletStorage.files_are_matched_by_path(wallet_path): sys.exit(f"error: wallet already exists: {final_path}") return final_path if cmdname in {'create_wallet', 'create_account'}: if not config.cmdline_options.get('nopasswordcheck'): password = prompt_password("Password:"******"error: wallet creation requires a password") if cmdname == 'create_wallet': wallet_path = get_wallet_path() storage = WalletStorage.create(wallet_path, password) storage.close() print(f"Wallet saved in '{wallet_path}'") sys.exit(0) elif cmdname == 'create_account': wallet_path = config.get_cmdline_wallet_filepath() storage = WalletStorage.create(wallet_path, password) parent_wallet = Wallet(storage) # create an account for the Wallet (only random new seeds supported - no importing) text_type = KeystoreTextType.EXTENDED_PRIVATE_KEY text_match = os.getenv("ELECTRUMSV_ACCOUNT_XPRV") if not text_match: # generate a random account seed data = urandom(64) coin = bitcoinx.BitcoinRegtest xprv = bitcoinx.BIP32PrivateKey._from_parts( data[:32], data[32:], coin) text_match = xprv.to_extended_key_string() keystore = instantiate_keystore_from_text(text_type, text_match, password, derivation_text=None, passphrase=None, watch_only=False) parent_wallet.create_account_from_keystore(keystore) print(f"New standard (bip32) account created for: '{wallet_path}'") sys.exit(0) else: sys.exit("error: unrecognised command")
def test_wallet_storage_database_nonexistent_creates(tmp_path) -> None: wallet_filepath = os.path.join(tmp_path, "walletfile") storage = WalletStorage(wallet_filepath) try: assert type(storage._store) is DatabaseStore assert storage.get("migration") == DatabaseStore.CURRENT_MIGRATION finally: storage.close()
def validate_password(storage: WalletStorage, password: str) -> bool: try: storage.check_password(password) except InvalidPassword: pass else: return True return False
def test_wallet_storage_new() -> None: base_storage_path = tempfile.mkdtemp() wallet_filepath = os.path.join(base_storage_path, "walletfile") storage = WalletStorage(wallet_filepath) assert type(storage._store) is DatabaseStore assert storage.get("wallet_author") == "ESV" assert storage.get("seed_version") == DatabaseStore.INITIAL_SEED_VERSION key = storage.get("tx_store_aeskey") assert type(key) is str
def init_cmdline(config_options, server): config = SimpleConfig(config_options) cmdname = config.get('cmd') cmd = known_commands[cmdname] if cmdname == 'signtransaction' and config.get('privkey'): cmd.requires_wallet = False cmd.requires_password = False if cmdname in ['payto', 'paytomany'] and config.get('unsigned'): cmd.requires_password = False if cmdname in ['payto', 'paytomany'] and config.get('broadcast'): cmd.requires_network = True wallet_path = config.get_wallet_path() if cmd.requires_wallet and not WalletStorage.files_are_matched_by_path( wallet_path): print("Error: Wallet file not found.") print("Type 'electrum-sv create' to create a new wallet, " "or provide a path to a wallet with the -w option") sys.exit(0) # instantiate wallet for command-line storage = WalletStorage(wallet_path) # important warning if cmd.name in ['getprivatekeys']: print("WARNING: ALL your private keys are secret.", file=sys.stderr) print( "Exposing a single private key can compromise your entire wallet!", file=sys.stderr) print( "In particular, DO NOT use 'redeem private key' services " "proposed by third parties.", file=sys.stderr) # commands needing password if cmd.requires_wallet and server is None or cmd.requires_password: if config.get('password'): password = config.get('password') else: password = prompt_password('Password:'******'password'] = password if cmd.name == 'password': new_password = prompt_password('New password:'******'new_password'] = new_password return cmd, password
def get_wallet_path() -> str: wallet_path = config.get_cmdline_wallet_filepath() if wallet_path is None: sys.exit("error: no wallet path provided") final_path = WalletStorage.canonical_path(wallet_path) if WalletStorage.files_are_matched_by_path(wallet_path): sys.exit(f"error: wallet already exists: {final_path}") return final_path
def test_read_dictionary_from_file(self): some_dict = {"a": "b", "c": "d"} contents = json.dumps(some_dict) with open(self.wallet_path, "w") as f: contents = f.write(contents) storage = WalletStorage(self.wallet_path, manual_upgrades=True) self.assertEqual("b", storage.get("a")) self.assertEqual("d", storage.get("c"))
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) # net = None # if "testnet" in wallet_filename: # net = SVTestnet # elif "mainnet" in wallet_filename: # net = SVMainnet # else: # raise Exception(f"unable to identify wallet network for {wallet_filename}") wallet_filename = storage_info.filename wallet_path = os.path.join(temp_dir, wallet_filename) password = "******" storage = WalletStorage(wallet_path) if "passworded" in wallet_filename: storage.decrypt(password) try: parent_wallet = ParentWallet(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 if "standard" in wallet_filename: is_bip39 = "bip39" in wallet_filename check_legacy_parent_of_standard_wallet(parent_wallet, is_bip39=is_bip39, password=password) elif "imported_privkey" in wallet_filename: check_legacy_parent_of_imported_privkey_wallet(parent_wallet) elif "imported_address" in wallet_filename: check_legacy_parent_of_imported_address_wallet(parent_wallet) elif "multisig" in wallet_filename: check_legacy_parent_of_multisig_wallet(parent_wallet) elif "hardware" in wallet_filename: check_legacy_parent_of_hardware_wallet(parent_wallet) else: raise Exception(f"unrecognised wallet file {wallet_filename}")
def _attempt_open_wallet(self, wallet_path: str, change_page: bool = False) -> bool: if not os.path.exists(wallet_path): MessageBox.show_error(_("Unable to open a deleted wallet.")) return False entry: Optional[FileState] = None for entry in self._recent_wallet_entries.values(): if entry.path == wallet_path: break else: entry = create_file_state(wallet_path) if entry is None: MessageBox.show_error( _("Unrecognised or unsupported wallet file.")) return False if entry.is_too_modern: MessageBox.show_error( _("The selected wallet cannot be opened as it is from a later " "version of ElectrumSV.")) return False password: str = None wizard: WalletWizard = self.wizard() storage = WalletStorage(entry.path) try: password = request_password(self, storage, entry) if password is None: return False if change_page: self._force_completed = True if entry.requires_upgrade: self._next_page_id = WalletPage.MIGRATE_OLDER_WALLET migration_page = wizard.page( WalletPage.MIGRATE_OLDER_WALLET) migration_page.set_migration_data(entry, storage, password) # Give the storage object to the migration page, which we are going to. storage = None wizard.next() else: assert entry.storage_kind == StorageKind.DATABASE, \ f"not a database {entry.storage_kind}" wizard.set_wallet_path(entry.path) wizard.accept() finally: # We may have handed off the storage and are no longer responsible for closing it. if storage is not None: storage.close() return True
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)
async def create_new_wallet(self, request): """only for regtest for the moment...""" try: vars = await self.argparser( request, required_vars=[VNAME.PASSWORD, VNAME.WALLET_NAME], check_wallet_availability=False) create_filepath = str( Path(self.wallets_path).joinpath(vars[VNAME.WALLET_NAME])) self.check_if_wallet_exists(create_filepath) storage = WalletStorage.create(create_filepath, vars[VNAME.PASSWORD]) storage.close() parent_wallet = self.app_state.daemon.load_wallet(create_filepath) # create an account for the Wallet with the same password via an imported seed text_type = KeystoreTextType.EXTENDED_PRIVATE_KEY text_match = 'tprv8ZgxMBicQKsPd4wsdaJ11eH84eq4hHLX1K6Mx8EQQhJzq8jr25WH1m8hgGkCqnks' \ 'JDCZPZbDoMbQ6QtroyCyn5ZckCmsLeiHDb1MAxhNUHN' keystore = instantiate_keystore_from_text(text_type, text_match, vars[VNAME.PASSWORD], derivation_text=None, passphrase=None) parent_wallet.create_account_from_keystore(keystore) await self._load_wallet(vars[VNAME.WALLET_NAME]) response = {"new_wallet": create_filepath} return good_response(response) except Fault as e: return fault_to_http_response(e)
def test_wallet_storage_json_path_nonexistent_errors() -> None: base_storage_path = tempfile.mkdtemp() nonexistent_storage_path = os.path.join(base_storage_path, "nonexistent", "walletfile") with pytest.raises(OSError): storage = WalletStorage(nonexistent_storage_path)
def run_non_RPC(config): """Most commands should go through the daemon or RPC, especially commands that operate on wallets.""" cmdname = config.get('cmd') def get_wallet_path() -> str: wallet_path = config.get_cmdline_wallet_filepath() if wallet_path is None: sys.exit("error: no wallet path provided") final_path = WalletStorage.canonical_path(wallet_path) if WalletStorage.files_are_matched_by_path(wallet_path): sys.exit(f"error: wallet already exists: {final_path}") return final_path if cmdname == 'create_wallet': wallet_path = get_wallet_path() password = prompt_password("Password:"******"error: wallet creation requires a password") storage = WalletStorage.create(wallet_path, password) storage.close() print(f"Wallet saved in '{wallet_path}'") sys.exit(0) else: sys.exit("error: unrecognised command")
def _on_filename(filename: str) -> None: pw = False self._storage_existing = None # A relative path will be relative to the folder we offered in the choose dialog. # An absolute path will not get joined to the dialog folder (no-op). path = os.path.join(wallet_folder, filename) if WalletStorage.files_are_matched_by_path(path): try: self._storage_existing = WalletStorage( path, manual_upgrades=True) except IOError: self.next_button.setEnabled(False) msg = _('Cannot read file') else: self.next_button.setEnabled(True) if self._storage_existing.is_encrypted(): msg = '\n'.join([ _("This file is encrypted."), _('Enter your password or choose another file.'), ]) pw = True else: msg = _("Press 'Next' to open this wallet.") else: msg = _("This file does not exist.") if os.access(wallet_folder, os.W_OK): self.next_button.setEnabled(True) msg += "\n" + _( "Press 'Next' to create this wallet, or choose another file." ) self._path_new = path else: self.next_button.setEnabled(False) msg += "\n" + _("You do not have write access " + "to this folder to create a new wallet.") self.msg_label.setText(msg) if pw: self.pw_label.show() self.pw_e.show() self.pw_e.setFocus() else: self.pw_label.hide() self.pw_e.hide()
def test_encrypt_message(self): key = WalletStorage.get_eckey_from_password('secret_password77') public_key = key.public_key msgs = [bytes([0] * 555), b'cannot think of anything funny'] for plaintext in msgs: ciphertext1 = public_key.encrypt_message(plaintext) ciphertext2 = public_key.encrypt_message(plaintext) self.assertEqual(plaintext, key.decrypt_message(ciphertext1)) self.assertEqual(plaintext, key.decrypt_message(ciphertext2)) self.assertNotEqual(ciphertext1, ciphertext2)
def _get_recently_opened_wallets(self): return [{ 'name': os.path.basename(file_path), 'path': file_path, 'is_encrypted': WalletStorage(file_path, manual_upgrades=True).is_encrypted, } for file_path in app_state.config.get('recently_open', []) if os.path.exists(file_path)]
def test_legacy_wallet_backup_hybrid() -> None: # We only need to test for one hybrid wallet, and test permutations of backup cases against it. wallet_filename = "19_testnet_standard_electrum" source_wallet_path = os.path.join(TEST_WALLET_PATH, wallet_filename) temp_dir = tempfile.mkdtemp() wallet_path = os.path.join(temp_dir, wallet_filename) shutil.copyfile(source_wallet_path, wallet_path) shutil.copyfile(source_wallet_path + DATABASE_EXT, wallet_path) # We do not care about loading the data, this is purely a test of the renaming. storage = WalletStorage(source_wallet_path, manual_upgrades=True)
def create_new_wallet(parent: QWidget, initial_dirpath: str) -> Optional[str]: create_filepath, __ = QFileDialog.getSaveFileName(parent, _("Enter a new wallet file name"), initial_dirpath) assert not os.path.exists(create_filepath) dirpath, filename = os.path.split(create_filepath) if not dirpath or not os.path.isdir(dirpath) or not os.access(dirpath, os.R_OK | os.W_OK): MessageBox.show_error(_("The selected directory is not accessible.")) return None name_edit = QLabel(filename) fields = [ (QLabel(_("Wallet") +":"), name_edit), ] from .password_dialog import ChangePasswordDialog, PasswordAction from .wallet_wizard import PASSWORD_NEW_TEXT d = ChangePasswordDialog(parent, PASSWORD_NEW_TEXT, _("Create New Wallet"), fields, kind=PasswordAction.NEW) success, _old_password, new_password = d.run() if not success or not new_password.strip(): return None from electrumsv.storage import WalletStorage storage = WalletStorage(create_filepath) storage.put("password-token", pw_encode(os.urandom(32).hex(), new_password)) storage.close() return create_filepath
def run_offline_command(config, config_options): cmdname = config.get('cmd') cmd = known_commands[cmdname] password = config_options.get('password') if cmd.requires_wallet: wallet_path = config.get_wallet_path() if not WalletStorage.files_are_matched_by_path(wallet_path): print("Error: wallet does not exist at given path") sys.exit(1) storage = WalletStorage(wallet_path) wallet = Wallet(storage) else: wallet = None if cmd.requires_password: try: wallet.check_password(password) except InvalidPassword: print( "Error: This password cannot access the wallet's private data." ) sys.exit(1) if cmd.requires_network: print("Warning: running command offline") # arguments passed to function args = [config.get(x) for x in cmd.params] # decode json arguments if cmdname not in ('setconfig', ): args = [json_decode(arg) for arg in args] # options kwargs = {} for x in cmd.options: kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)) cmd_runner = Commands(config, wallet, None) func = getattr(cmd_runner, cmd.name) result = func(*args, **kwargs) # save wallet if wallet: wallet.save_storage() return result
def __init__(self, config, daemon, plugins): self.config = config self.network = daemon.network storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists: print("Wallet not found. try 'electrum-sv create'") exit() if storage.is_encrypted(): password = getpass.getpass('Password:'******'updated', 'banner']) self.commands = [ _("[h] - displays this help text"), _("[i] - display transaction history"), _("[o] - enter payment order"), _("[p] - print stored payment order"), _("[s] - send stored payment order"), _("[r] - show own receipt addresses"), _("[c] - display contacts"), _("[b] - print server banner"), _("[q] - quit"), ] self.num_commands = len(self.commands)
def start_new_window(self, path, uri, is_startup=False): '''Raises the window for the wallet if it is open. Otherwise opens the wallet and creates a new window for it.''' for w in self.windows: if w.wallet.storage.path == path: w.bring_to_top() break else: try: wallet = app_state.daemon.load_wallet(path, None) if not wallet: storage = WalletStorage(path, manual_upgrades=True) wizard = InstallWizard(storage) try: wallet = wizard.start_gui(is_startup=is_startup) except UserQuit: pass except UserCancelled: pass except GoBack as e: logger.error( '[start_new_window] Exception caught (GoBack) %s', e) finally: wizard.terminate() if not wallet: return wallet.start_threads(app_state.daemon.network) app_state.daemon.add_wallet(wallet) except Exception as e: logger.exception("") if '2fa' in str(e): d = QMessageBox(QMessageBox.Warning, _('Error'), '2FA wallets are not unsupported.') d.exec_() else: d = QMessageBox(QMessageBox.Warning, _('Error'), 'Cannot load wallet:\n' + str(e)) d.exec_() return w = self._create_window_for_wallet(wallet) if uri: w.pay_to_URI(uri) w.bring_to_top() w.setWindowState(w.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive) # this will activate the window w.activateWindow() return w
def run_offline_command(config, config_options): cmdname = config.get('cmd') cmd = known_commands[cmdname] password = config_options.get('password') if cmd.requires_wallet: storage = WalletStorage(config.get_wallet_path()) if storage.is_encrypted(): storage.decrypt(password) parent_wallet = ParentWallet(storage) else: parent_wallet = None # check password if cmd.requires_password and parent_wallet.has_password(): try: parent_wallet.check_password(password) except InvalidPassword: print("Error: This password does not decode this wallet.") sys.exit(1) if cmd.requires_network: print("Warning: running command offline") # arguments passed to function args = [config.get(x) for x in cmd.params] # decode json arguments if cmdname not in ('setconfig', ): args = [json_decode(arg) for arg in args] # options kwargs = {} for x in cmd.options: kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)) cmd_runner = Commands(config, parent_wallet, None) func = getattr(cmd_runner, cmd.name) result = func(*args, **kwargs) # save wallet if parent_wallet: parent_wallet.save_storage() return result
def __init__(self, config, daemon, plugins): self.config = config self.network = daemon.network storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists(): print("Wallet not found. try 'electrum-sv create'") exit() if storage.is_encrypted(): password = getpass.getpass('Password:'******'') self.encoding = locale.getpreferredencoding() self.stdscr = curses.initscr() curses.noecho() curses.cbreak() curses.start_color() curses.use_default_colors() curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE) curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_CYAN) curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE) self.stdscr.keypad(1) self.stdscr.border(0) self.maxy, self.maxx = self.stdscr.getmaxyx() self.set_cursor(0) self.w = curses.newwin(10, 50, 5, 5) disable_verbose_logging() self.tab = 0 self.pos = 0 self.popup_pos = 0 self.str_recipient = "" self.str_description = "" self.str_amount = "" self.str_fee = "" self.history = None if self.network: self.network.register_callback(self.update, ['updated']) self.tab_names = [ _("History"), _("Send"), _("Receive"), _("Addresses"), _("Contacts"), _("Banner") ] self.num_tabs = len(self.tab_names)
def create_new_wallet(parent: QWidget, initial_dirpath: str) -> Optional[str]: create_filepath, __ = QFileDialog.getSaveFileName( parent, _("Enter a new wallet file name"), initial_dirpath) if not create_filepath: return None # QFileDialog.getSaveFileName uses forward slashes for "easier pathing".. correct this. create_filepath = os.path.normpath(create_filepath) if os.path.exists(create_filepath): MessageBox.show_error( _("Overwriting existing files not supported at this time.")) return None dirpath, filename = os.path.split(create_filepath) if not create_filepath.endswith(DATABASE_EXT): if os.path.exists(create_filepath + DATABASE_EXT): MessageBox.show_error( _("The file name '{}' is already in use.").format(filename)) return None if not dirpath or not os.path.isdir(dirpath) or not os.access( dirpath, os.R_OK | os.W_OK): MessageBox.show_error(_("The selected directory is not accessible.")) return None name_edit = QLabel(filename) fields = [ (QLabel(_("Wallet") + ":"), name_edit), ] from .password_dialog import ChangePasswordDialog, PasswordAction from .wallet_wizard import PASSWORD_NEW_TEXT d = ChangePasswordDialog(parent, PASSWORD_NEW_TEXT, _("Create New Wallet"), fields, kind=PasswordAction.NEW) success, _old_password, new_password = d.run() if not success or not new_password.strip(): return None from electrumsv.storage import WalletStorage storage = WalletStorage.create(create_filepath, new_password) storage.close() return create_filepath
def test_decrypt_message(self): key = WalletStorage.get_eckey_from_password('pw123') self.assertEqual( b'me<(s_s)>age', key.decrypt_message( 'QklFMQMDFtgT3zWSQsa+Uie8H/WvfUjlu9UN9OJtTt3KlgKeSTi6SQfuhcg1uIz9hp3WIUOFGTLr4RNQBdjPNqzXwhkcPi2Xsbiw6UCNJncVPJ6QBg==' )) self.assertEqual( b'me<(s_s)>age', key.decrypt_message( 'QklFMQKXOXbylOQTSMGfo4MFRwivAxeEEkewWQrpdYTzjPhqjHcGBJwdIhB7DyRfRQihuXx1y0ZLLv7XxLzrILzkl/H4YUtZB4uWjuOAcmxQH4i/Og==' )) self.assertEqual( b'hey_there' * 100, key.decrypt_message( 'QklFMQLOOsabsXtGQH8edAa6VOUa5wX8/DXmxX9NyHoAx1a5bWgllayGRVPeI2bf0ZdWK0tfal0ap0ZIVKbd2eOJybqQkILqT6E1/Syzq0Zicyb/AA1eZNkcX5y4gzloxinw00ubCA8M7gcUjJpOqbnksATcJ5y2YYXcHMGGfGurWu6uJ/UyrNobRidWppRMW5yR9/6utyNvT6OHIolCMEf7qLcmtneoXEiz51hkRdZS7weNf9mGqSbz9a2NL3sdh1A0feHIjAZgcCKcAvksNUSauf0/FnIjzTyPRpjRDMeDC8Ci3sGiuO3cvpWJwhZfbjcS26KmBv2CHWXfRRNFYOInHZNIXWNAoBB47Il5bGSMd+uXiGr+SQ9tNvcu+BiJNmFbxYqg+oQ8dGAl1DtvY2wJVY8k7vO9BIWSpyIxfGw7EDifhc5vnOmGe016p6a01C3eVGxgl23UYMrP7+fpjOcPmTSF4rk5U5ljEN3MSYqlf1QEv0OqlI9q1TwTK02VBCjMTYxDHsnt04OjNBkNO8v5uJ4NR+UUDBEp433z53I59uawZ+dbk4v4ZExcl8EGmKm3Gzbal/iJ/F7KQuX2b/ySEhLOFVYFWxK73X1nBvCSK2mC2/8fCw8oI5pmvzJwQhcCKTdEIrz3MMvAHqtPScDUOjzhXxInQOCb3+UBj1PPIdqkYLvZss1TEaBwYZjLkVnK2MBj7BaqT6Rp6+5A/fippUKHsnB6eYMEPR2YgDmCHL+4twxHJG6UWdP3ybaKiiAPy2OHNP6PTZ0HrqHOSJzBSDD+Z8YpaRg29QX3UEWlqnSKaan0VYAsV1VeaN0XFX46/TWO0L5tjhYVXJJYGqo6tIQJymxATLFRF6AZaD1Mwd27IAL04WkmoQoXfO6OFfwdp/shudY/1gBkDBvGPICBPtnqkvhGF+ZF3IRkuPwiFWeXmwBxKHsRx/3+aJu32Ml9+za41zVk2viaxcGqwTc5KMexQFLAUwqhv+aIik7U+5qk/gEVSuRoVkihoweFzKolNF+BknH2oB4rZdPixag5Zje3DvgjsSFlOl69W/67t/Gs8htfSAaHlsB8vWRQr9+v/lxTbrAw+O0E+sYGoObQ4qQMyQshNZEHbpPg63eWiHtJJnrVBvOeIbIHzoLDnMDsWVWZSMzAQ1vhX1H5QLgSEbRlKSliVY03kDkh/Nk/KOn+B2q37Ialq4JcRoIYFGJ8AoYEAD0tRuTqFddIclE75HzwaNG7NyKW1plsa72ciOPwsPJsdd5F0qdSQ3OSKtooTn7uf6dXOc4lDkfrVYRlZ0PX' ))
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 validatePage(self) -> bool: # Called when 'Next' or 'Finish' is clicked for last-minute validation. result = self.isComplete() if result: new_password = self._password_layout.new_pw.text().strip() # If we are going to exit then create the empty wallet. wizard: WalletWizard = self.wizard() wallet_filepath = wizard.get_wallet_path() storage = WalletStorage(wallet_filepath) storage.put("password-token", pw_encode(os.urandom(32).hex(), new_password)) storage.close() return result