def __init__(self, **kwargs): '''Get app settings from options''' self.make_commit = kwargs.pop('make_commit') self.password = kwargs.pop('password') self.signing_key = kwargs.pop('signing_key') self.testnet = kwargs.pop('testnet') self.wallet_path = kwargs.pop('wallet') script_config = read_config() if script_config: self.make_commit = (self.make_commit or script_config.get('make_commit', False)) self.signing_key = (self.signing_key or script_config.get('signing_key', False)) self.testnet = (self.testnet or script_config.get('testnet', False)) self.wallet_path = (self.wallet_path or script_config.get('wallet', False)) if self.wallet_path: self.wallet_path = os.path.expanduser(self.wallet_path) self.config_options = {'cwd': os.getcwd()} self.config_options['password'] = self.password self.config_options['testnet'] = self.testnet self.config_options['wallet_path'] = self.wallet_path self.config = SimpleConfig(self.config_options) if self.config.get('testnet'): constants.set_testnet() self.storage = WalletStorage(self.config.get_wallet_path())
def test_password_for_storage_encryption(storage: WalletStorage, password: str) -> bool: try: storage.decrypt(password) except InvalidPassword: return False else: return True
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) db = WalletDB(storage.read(), manual_upgrades=True) self.assertEqual("b", db.get("a")) self.assertEqual("d", db.get("c"))
def test_check_need_confirm_password(self): wiz = self.wizard storage = WalletStorage(self.wallet_path) d = {'wallet_type': 'standard', "seed_version": FINAL_SEED_VERSION} d['wallet_type'] = '2of3' d['x1/'] = X1_VIEW_ONLY d['x2/'] = X2 db = WalletDB(json.dumps(d), manual_upgrades=True) db.write(storage) storage = WalletStorage(self.wallet_path) wiz.continue_multisig_setup(storage) wiz.unfinished_check_password = storage.check_password assert wiz.check_need_confirm_password() wiz.unfinished_check_password = None assert not wiz.check_need_confirm_password() wiz.keystores[1].update_password(None, 'test') assert wiz.check_need_confirm_password()
def test_continue_multisig_setup(self): wiz = self.wizard storage = WalletStorage(self.wallet_path) d = {'wallet_type': 'standard', "seed_version": FINAL_SEED_VERSION} d['wallet_type'] = '2of3' d['x1/'] = X1 db = WalletDB(json.dumps(d), manual_upgrades=True) assert db.check_unfinished_multisig() db.write(storage) storage = WalletStorage(self.wallet_path) wiz.continue_multisig_setup(storage) assert wiz.unfinished_multisig assert wiz.unfinished_enc_version == StorageEncryptionVersion.PLAINTEXT assert not wiz.unfinished_check_password assert wiz.last_method == 'continue_multisig_setup_dialog' last_args = wiz.last_args assert last_args[0:2] == (2, 3) # m, n assert last_args[2] == wiz.keystores # keystores assert len(last_args[2]) == 1 k1 = last_args[2][0] assert type(k1) == BIP32_KeyStore assert k1.get_root_fingerprint() == '3f635a63' assert last_args[3] == wiz.choose_keystore # run_next d['x2/'] = X2 db = WalletDB(json.dumps(d), manual_upgrades=True) assert db.check_unfinished_multisig() db.write(storage) storage = WalletStorage(self.wallet_path) wiz.continue_multisig_setup(storage) assert wiz.unfinished_multisig assert wiz.unfinished_enc_version == StorageEncryptionVersion.PLAINTEXT assert not wiz.unfinished_check_password assert wiz.last_method == 'continue_multisig_setup_dialog' last_args = wiz.last_args assert last_args[0:2] == (2, 3) # m, n assert last_args[2] == wiz.keystores # keystores assert len(last_args[2]) == 2 k1, k2 = last_args[2] assert type(k1) == BIP32_KeyStore assert k1.get_root_fingerprint() == '3f635a63' assert type(k2) == BIP32_KeyStore assert k2.get_root_fingerprint() == 'e54b06c8' assert last_args[3] == wiz.choose_keystore # run_next
def test_update_password_with_app_restarts(self): wallet_str = '{"addr_history":{"t1KxfKCSdEQsnY4geXEmHi4zYeFCjFBq9Vn":[],"t1N5aE1koddeuH3ubZQcvP6Ac39QLr5HZ9T":[],"t1XqFtMbqGC3Yv6zbj6SzKArJnzU1e2zZxM":[]},"addresses":{"change":[],"receiving":["t1KxfKCSdEQsnY4geXEmHi4zYeFCjFBq9Vn","t1XqFtMbqGC3Yv6zbj6SzKArJnzU1e2zZxM","t1N5aE1koddeuH3ubZQcvP6Ac39QLr5HZ9T"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}' db = WalletDB(wallet_str, manual_upgrades=False) storage = WalletStorage(self.wallet_path) wallet = Wallet(db, storage, config=self.config) asyncio.run_coroutine_threadsafe(wallet.stop(), self.asyncio_loop).result() storage = WalletStorage(self.wallet_path) # if storage.is_encrypted(): # storage.decrypt(password) db = WalletDB(storage.read(), manual_upgrades=False) wallet = Wallet(db, storage, config=self.config) wallet.check_password(None) wallet.update_password(None, "1234") with self.assertRaises(InvalidPassword): wallet.check_password(None) with self.assertRaises(InvalidPassword): wallet.check_password("wrong password") wallet.check_password("1234")
def test_update_password_of_standard_wallet(self): wallet_str = '''{"addr_history":{"t1K6oh6QT515QVxDT3qXvwMHpzfPm6cBNRi":[],"t1Kb24NfXZQ8iUa7FZHfD6ptCaK1kxZSfFT":[],"t1LA42A5ebDf388JtBXv2gibYfaoFB4NuCN":[],"t1Lcs9qhHHADiJcFWRkq119jJAimcfLJj3M":[],"t1MLG4B8rFdK3V5WxGCXmuyoCux2C4TYL6o":[],"t1MZNCHxd7SZb9aZXEs7AVGSWhwgjPoyHKy":[],"t1N7sudLZrCgcSmi6sZx3zQvarhY9hooRuc":[],"t1Qfv1H4J11Zh2rnmG6yH4HK14Ge6diB1xf":[],"t1RZycn9hxkQ1yjLvY64Z6dFPvUYsyL4N4h":[],"t1RekPbNKi66nsLfxKd2MNeenxgPxYosVQe":[],"t1SSk8u5NdJzyBqzcZvXoctV5Zc3Vm9JWgr":[],"t1SrejMeUovTdR4B1YQ1L1rH8DycCgGvXw7":[],"t1Sv8T7LUPFRzNZp1v3hzQZHGmokQ7WJfh9":[],"t1J5Nhb4A9goHkNkYCF7nCj94n2aowBe767":[],"t1WnRi2hcZJ7bCPgpfvYnDSzf2gMHYgj61X":[],"t1WwagmnSnq7dW2aTDce1uH8G6bkYese4ea":[],"t1ZKpT5AdaUiBApE5CoJxayUCYqotAuVAbX":[],"t1ZPSh9sq9EEReXGa3L1vUE4Jn4ZsGZpYeU":[],"t1ZaNqHFaDQQRyKgk6E7UhmEYacaWaRKBNg":[],"t1ax4TopTgGSHpoFq2jZ1mpKwGugwNuA9dq":[],"t1bPaTLA8H2eq47XWmvNR3jWFQn1jxboBjQ":[],"t1cGtxxPBNo4m6zLDRK7ry2FXbyihKqPe51":[],"t1cgZa12AJCUQXNK7uNehvQM9QmHzqXYo9r":[],"t1ci6EiwmnvLWqEzmW33StfFyQgvxXwxDWM":[],"t1eshyYrgcRtCfo66jvcdJ94CtpfgqWB1bA":[],"t1gdjJX88Sd1SF3TDoCbvwpMn6j1nWhjo23":[]},"addresses":{"change":["t1ZaNqHFaDQQRyKgk6E7UhmEYacaWaRKBNg","t1ZKpT5AdaUiBApE5CoJxayUCYqotAuVAbX","t1N7sudLZrCgcSmi6sZx3zQvarhY9hooRuc","t1Sv8T7LUPFRzNZp1v3hzQZHGmokQ7WJfh9","t1SrejMeUovTdR4B1YQ1L1rH8DycCgGvXw7","t1bPaTLA8H2eq47XWmvNR3jWFQn1jxboBjQ"],"receiving":["t1MZNCHxd7SZb9aZXEs7AVGSWhwgjPoyHKy","t1LA42A5ebDf388JtBXv2gibYfaoFB4NuCN","t1SSk8u5NdJzyBqzcZvXoctV5Zc3Vm9JWgr","t1ax4TopTgGSHpoFq2jZ1mpKwGugwNuA9dq","t1gdjJX88Sd1SF3TDoCbvwpMn6j1nWhjo23","t1Lcs9qhHHADiJcFWRkq119jJAimcfLJj3M","t1cGtxxPBNo4m6zLDRK7ry2FXbyihKqPe51","t1K6oh6QT515QVxDT3qXvwMHpzfPm6cBNRi","t1Kb24NfXZQ8iUa7FZHfD6ptCaK1kxZSfFT","t1MLG4B8rFdK3V5WxGCXmuyoCux2C4TYL6o","t1ci6EiwmnvLWqEzmW33StfFyQgvxXwxDWM","t1Qfv1H4J11Zh2rnmG6yH4HK14Ge6diB1xf","t1WwagmnSnq7dW2aTDce1uH8G6bkYese4ea","t1RZycn9hxkQ1yjLvY64Z6dFPvUYsyL4N4h","t1cgZa12AJCUQXNK7uNehvQM9QmHzqXYo9r","t1RekPbNKi66nsLfxKd2MNeenxgPxYosVQe","t1J5Nhb4A9goHkNkYCF7nCj94n2aowBe767","t1WnRi2hcZJ7bCPgpfvYnDSzf2gMHYgj61X","t1ZPSh9sq9EEReXGa3L1vUE4Jn4ZsGZpYeU","t1eshyYrgcRtCfo66jvcdJ94CtpfgqWB1bA"]},"keystore":{"seed":"cereal wise two govern top pet frog nut rule sketch bundle logic","type":"bip32","xprv":"xprv9s21ZrQH143K29XjRjUs6MnDB9wXjXbJP2kG1fnRk8zjdDYWqVkQYUqaDtgZp5zPSrH5PZQJs8sU25HrUgT1WdgsPU8GbifKurtMYg37d4v","xpub":"xpub661MyMwAqRbcEdcCXm1sTViwjBn28zK9kFfrp4C3JUXiW1sfP34f6HA45B9yr7EH5XGzWuTfMTdqpt9XPrVQVUdgiYb5NW9m8ij1FSZgGBF"},"pruned_txo":{},"seed_type":"standard","seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[619,310,840,405]}''' db = WalletDB(wallet_str, manual_upgrades=False) storage = WalletStorage(self.wallet_path) wallet = Wallet(db, storage, config=self.config) wallet.check_password(None) wallet.update_password(None, "1234") with self.assertRaises(InvalidPassword): wallet.check_password(None) with self.assertRaises(InvalidPassword): wallet.check_password("wrong password") wallet.check_password("1234")
def test_write_dictionary_to_file(self): storage = WalletStorage(self.wallet_path) db = WalletDB('', manual_upgrades=True) some_dict = { u"a": u"b", u"c": u"d", u"seed_version": FINAL_SEED_VERSION} for key, value in some_dict.items(): db.put(key, value) db.write(storage) with open(self.wallet_path, "r") as f: contents = f.read() d = json.loads(contents) for key, value in some_dict.items(): self.assertEqual(d[key], value)
def __init__(self, config: 'SimpleConfig', daemon: 'Daemon', plugins: 'Plugins'): self.config = config self.network = network = daemon.network if config.get('tor_auto_on', True): if network: proxy_modifiable = config.is_modifiable('proxy') if not proxy_modifiable or not network.detect_tor_proxy(): print(network.TOR_WARN_MSG_TXT) c = '' while c != 'y': c = input("Continue without Tor (y/n)?") if c == 'n': exit() storage = WalletStorage(config.get_wallet_path()) if not storage.file_exists(): print("Wallet not found. try 'electrum-zcash create'") exit() if storage.is_encrypted(): password = getpass.getpass('Password:'******'Can not open unfinished multisig wallet') exit() self.wallet = Wallet(db, storage, config=config) self.wallet.start_network(self.network) self.contacts = self.wallet.contacts locale.setlocale(locale.LC_ALL, '') 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) if getattr(storage, 'backup_message', None): msg_key = 'Press any key to continue...' self.stdscr.addstr(f'{storage.backup_message}\n\n{msg_key}') self.stdscr.getch() self.stdscr.border(0) self.maxy, self.maxx = self.stdscr.getmaxyx() self.set_cursor(0) self.w = curses.newwin(10, 50, 5, 5) console_stderr_handler.setLevel(logging.CRITICAL) 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 self.txid = [] util.register_callback(self.update, ['wallet_updated', 'network_updated']) self.tab_names = [ _("History"), _("Send"), _("Receive"), _("Addresses"), _("Contacts"), _("Banner") ] self.num_tabs = len(self.tab_names)
class SignApp(object): def __init__(self, **kwargs): '''Get app settings from options''' self.make_commit = kwargs.pop('make_commit') self.password = kwargs.pop('password') self.signing_key = kwargs.pop('signing_key') self.testnet = kwargs.pop('testnet') self.wallet_path = kwargs.pop('wallet') script_config = read_config() if script_config: self.make_commit = (self.make_commit or script_config.get('make_commit', False)) self.signing_key = (self.signing_key or script_config.get('signing_key', False)) self.testnet = (self.testnet or script_config.get('testnet', False)) self.wallet_path = (self.wallet_path or script_config.get('wallet', False)) if self.wallet_path: self.wallet_path = os.path.expanduser(self.wallet_path) self.config_options = {'cwd': os.getcwd()} self.config_options['password'] = self.password self.config_options['testnet'] = self.testnet self.config_options['wallet_path'] = self.wallet_path self.config = SimpleConfig(self.config_options) if self.config.get('testnet'): constants.set_testnet() self.storage = WalletStorage(self.config.get_wallet_path()) def load_wallet(self, storage): print('Lodaing wallet: %s' % self.config.get_wallet_path()) password = None if storage.is_encrypted(): if storage.is_encrypted_with_hw_device(): plugins = Plugins(self.config, 'cmdline') password = get_passwd_for_hw_device_encrypted_storage(plugins) storage.decrypt(password) else: password = get_password(storage.decrypt) db = WalletDB(self.storage.read(), manual_upgrades=True) if db.requires_upgrade(): print('Error: Wallet db need to be upgraded.' ' Do it with the wallet app') sys.exit(1) self.wallet = Wallet(db, self.storage, config=self.config) if self.wallet.has_password() and not password: password = get_password(self.wallet.check_password) self.config_options['password'] = password def commit_latest_version(self): commit_msg = COMMIT_MSG_TEMPLATE.format(fname=LATEST_VER_FNAME, version=ELECTRUM_VERSION) print('commiting: %s' % commit_msg) os.system('git add ./%s' % LATEST_VER_FNAME) os.system('git commit -m "%s"' % commit_msg) def run(self): self.load_wallet(self.storage) if self.signing_key: address = self.signing_key else: address = SIGNING_KEYS[0] message = ELECTRUM_VERSION password = self.config_options.get('password') print('Signing version: %s' % message) print('with address: %s' % address) sig = self.wallet.sign_message(address, message, password) sig = base64.b64encode(sig).decode('ascii') content = { 'version': ELECTRUM_VERSION, 'signatures': { address: sig } } content_json = json.dumps(content, indent=4) print(content_json) with open('./%s' % LATEST_VER_FNAME, 'w') as fd: fd.write('%s\n' % content_json) if self.make_commit: self.commit_latest_version()
return password num_tested += 1 if num_tested % 5000 == 0: print( f"> tested {num_tested} passwords so far... most recently tried: {password!r}" ) if __name__ == '__main__': if len(sys.argv) < 2: print("ERROR. usage: bruteforce_pw.py <path_to_wallet_file>") sys.exit(1) path = sys.argv[1] config = SimpleConfig() storage = WalletStorage(path) if not storage.file_exists(): print(f"ERROR. wallet file not found at path: {path}") sys.exit(1) if storage.is_encrypted(): test_password = partial(test_password_for_storage_encryption, storage) print(f"wallet found: with storage encryption.") else: db = WalletDB(storage.read(), manual_upgrades=True) wallet = Wallet(db, storage, config=config) if not wallet.has_password(): print("wallet found but it is not encrypted.") sys.exit(0) test_password = partial(test_password_for_keystore_encryption, wallet) print(f"wallet found: with keystore encryption.") password = bruteforce_loop(test_password)