2020-03-12 16:59:55 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
#
|
2024-10-18 10:32:06 +00:00
|
|
|
# MMGen Wallet, a terminal-based cryptocurrency wallet
|
2026-02-11 13:02:12 +00:00
|
|
|
# Copyright (C)2013-2026 The MMGen Project <mmgen@tuta.io>
|
2020-03-12 16:59:55 +00:00
|
|
|
#
|
2023-11-17 13:35:42 +00:00
|
|
|
# Project source code repository: https://github.com/mmgen/mmgen-wallet
|
2020-03-12 16:59:55 +00:00
|
|
|
# Licensed according to the terms of GPL Version 3. See LICENSE for details.
|
|
|
|
|
|
|
|
|
|
"""
|
2025-03-29 09:30:15 +00:00
|
|
|
test.cmdtest_d.tool: tool tests for the MMGen cmdtest.py test suite
|
2020-03-12 16:59:55 +00:00
|
|
|
"""
|
|
|
|
|
|
2026-05-17 18:03:32 +00:00
|
|
|
import os
|
2023-10-03 14:27:57 +00:00
|
|
|
|
2026-05-17 18:03:32 +00:00
|
|
|
from mmgen.cfg import gc
|
2023-10-03 14:27:57 +00:00
|
|
|
from mmgen.util import suf
|
|
|
|
|
from mmgen.color import cyan
|
|
|
|
|
|
2023-10-03 14:27:57 +00:00
|
|
|
from ..include.common import (
|
|
|
|
|
vmsg,
|
|
|
|
|
read_from_file,
|
|
|
|
|
write_to_file,
|
|
|
|
|
cmp_or_die,
|
|
|
|
|
joinpath,
|
|
|
|
|
getrand
|
|
|
|
|
)
|
2025-03-29 09:30:15 +00:00
|
|
|
from .include.common import hincog_fn, incog_id_fn, hincog_offset, tool_enc_passwd, ref_dir
|
|
|
|
|
from .base import CmdTestBase
|
|
|
|
|
from .main import CmdTestMain
|
2020-03-12 16:59:55 +00:00
|
|
|
|
2024-10-18 10:32:14 +00:00
|
|
|
class CmdTestTool(CmdTestMain, CmdTestBase):
|
2020-03-12 16:59:55 +00:00
|
|
|
"interactive 'mmgen-tool' commands"
|
|
|
|
|
networks = ('btc',)
|
|
|
|
|
segwit_opts_ok = False
|
|
|
|
|
tmpdir_nums = [9]
|
|
|
|
|
enc_infn = 'tool_encrypt.in'
|
|
|
|
|
cmd_group = (
|
2024-10-18 10:32:14 +00:00
|
|
|
('tool_find_incog_data',
|
|
|
|
|
(9, '‘mmgen-tool find_incog_data’', [[[hincog_fn], 1], [[incog_id_fn], 1]])
|
|
|
|
|
),
|
|
|
|
|
('tool_rand2file',
|
|
|
|
|
(9, '‘mmgen-tool rand2file’', [])
|
|
|
|
|
),
|
|
|
|
|
('tool_encrypt',
|
|
|
|
|
(9, '‘mmgen-tool encrypt’ (random data)', [])
|
|
|
|
|
),
|
|
|
|
|
('tool_decrypt',
|
|
|
|
|
(9, '‘mmgen-tool decrypt’ (random data)', [[[enc_infn+'.mmenc'], 9]])
|
|
|
|
|
),
|
|
|
|
|
('tool_twview_bad_comment',
|
|
|
|
|
(9, '‘mmgen-tool twview’ (with bad comment)', [])
|
|
|
|
|
),
|
|
|
|
|
('tool_decrypt_keystore',
|
|
|
|
|
(9, '‘mmgen-tool decrypt_keystore’', [])
|
|
|
|
|
),
|
|
|
|
|
('tool_decrypt_geth_keystore',
|
|
|
|
|
(9, '‘mmgen-tool decrypt_geth_keystore’', [])
|
|
|
|
|
),
|
|
|
|
|
('tool_api',
|
|
|
|
|
(9, 'tool API (initialization, config methods, wif2addr)', [])
|
|
|
|
|
),
|
|
|
|
|
# ('tool_encrypt_ref', (9, '‘mmgen-tool encrypt’ (reference text)', [])),
|
2020-03-12 16:59:55 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def tool_rand2file(self):
|
2022-10-17 18:37:22 +00:00
|
|
|
from mmgen.util2 import parse_bytespec
|
2024-10-18 10:32:14 +00:00
|
|
|
for nbytes in ('1', '1023', '1K', '1048575', '1M', '1048577', '123M'):
|
2021-09-29 21:17:57 +00:00
|
|
|
t = self.spawn(
|
|
|
|
|
'mmgen-tool',
|
2024-10-18 10:32:14 +00:00
|
|
|
['-d', self.tmpdir, '-r0', 'rand2file', 'rand2file.out', nbytes],
|
|
|
|
|
extra_desc='({} byte{})'.format(nbytes, suf(parse_bytespec(nbytes)))
|
2021-09-29 21:17:57 +00:00
|
|
|
)
|
2020-03-12 16:59:55 +00:00
|
|
|
t.expect('random data written to file')
|
|
|
|
|
t.read()
|
|
|
|
|
t.p.wait()
|
|
|
|
|
t.ok()
|
|
|
|
|
t.skip_ok = True
|
|
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
def tool_encrypt(self):
|
2024-10-18 10:32:14 +00:00
|
|
|
infile = joinpath(self.tmpdir, self.enc_infn)
|
|
|
|
|
write_to_file(infile, getrand(1033), binary=True)
|
|
|
|
|
t = self.spawn('mmgen-tool', ['-d', self.tmpdir, self.usr_rand_arg, 'encrypt', infile])
|
2020-03-12 16:59:55 +00:00
|
|
|
t.usr_rand(self.usr_rand_chars)
|
2024-10-18 10:32:14 +00:00
|
|
|
t.hash_preset('data', '1')
|
|
|
|
|
t.passphrase_new('data', tool_enc_passwd)
|
2020-03-12 16:59:55 +00:00
|
|
|
t.written_to_file('Encrypted data')
|
|
|
|
|
return t
|
|
|
|
|
|
2024-10-18 10:32:14 +00:00
|
|
|
def tool_decrypt(self, f1):
|
2020-03-12 16:59:55 +00:00
|
|
|
out_fn = 'tool_encrypt.out'
|
2024-10-18 10:32:14 +00:00
|
|
|
t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'decrypt', f1, 'outfile='+out_fn, 'hash_preset=1'])
|
|
|
|
|
t.passphrase('data', tool_enc_passwd)
|
2020-03-12 16:59:55 +00:00
|
|
|
t.written_to_file('Decrypted data')
|
2024-10-18 10:32:14 +00:00
|
|
|
d1 = self.read_from_tmpfile(self.enc_infn, binary=True)
|
|
|
|
|
d2 = self.read_from_tmpfile(out_fn, binary=True)
|
|
|
|
|
cmp_or_die(d1, d2)
|
2020-03-12 16:59:55 +00:00
|
|
|
return t
|
|
|
|
|
|
2024-10-18 10:32:14 +00:00
|
|
|
def tool_find_incog_data(self, f1, f2):
|
2020-03-12 16:59:55 +00:00
|
|
|
i_id = read_from_file(f2).rstrip()
|
2021-09-29 21:17:57 +00:00
|
|
|
vmsg(f'Incog ID: {cyan(i_id)}')
|
2024-10-18 10:32:14 +00:00
|
|
|
t = self.spawn('mmgen-tool', ['-d', self.tmpdir, 'find_incog_data', f1, i_id])
|
2021-09-29 21:17:57 +00:00
|
|
|
o = t.expect_getend(f'Incog data for ID {i_id} found at offset ')
|
2026-05-17 18:03:32 +00:00
|
|
|
if not gc.platform == 'win32':
|
2020-03-12 16:59:55 +00:00
|
|
|
os.unlink(f1) # causes problems with MSYS2
|
2024-10-18 10:32:14 +00:00
|
|
|
cmp_or_die(hincog_offset, int(o))
|
2020-03-12 16:59:55 +00:00
|
|
|
return t
|
|
|
|
|
|
|
|
|
|
def tool_twview_bad_comment(self): # test correct operation of get_tw_label()
|
2023-05-23 12:12:33 +00:00
|
|
|
t = self.spawn(
|
|
|
|
|
'mmgen-tool',
|
|
|
|
|
['twview'],
|
2024-10-18 10:32:14 +00:00
|
|
|
env = {'MMGEN_BOGUS_UNSPENT_DATA': joinpath(ref_dir, 'bad-comment-unspent.json')},
|
2024-03-08 14:13:23 +00:00
|
|
|
exit_val = 2)
|
2022-02-05 13:32:55 +00:00
|
|
|
t.expect('cannot be converted to TwComment')
|
2020-03-12 16:59:55 +00:00
|
|
|
return t
|
2020-06-08 17:03:21 +00:00
|
|
|
|
2024-10-18 10:32:14 +00:00
|
|
|
def _decrypt_keystore(self, cmd, fn, pw, chk):
|
2025-03-18 20:09:59 +03:00
|
|
|
if self.cfg.no_altcoin:
|
2022-05-03 21:01:05 +00:00
|
|
|
return 'skip'
|
2024-10-18 10:32:14 +00:00
|
|
|
t = self.spawn('mmgen-tool', ['-d', self.tmpdir, cmd, fn])
|
|
|
|
|
t.expect('Enter passphrase: ', pw+'\n')
|
2023-11-30 10:53:40 +00:00
|
|
|
t.expect(chk)
|
2022-04-28 11:00:53 +00:00
|
|
|
return t
|
|
|
|
|
|
2023-11-30 10:53:40 +00:00
|
|
|
def tool_decrypt_keystore(self):
|
|
|
|
|
return self._decrypt_keystore(
|
|
|
|
|
cmd = 'decrypt_keystore',
|
|
|
|
|
fn = 'test/ref/altcoin/98831F3A-keystore-wallet.json',
|
|
|
|
|
pw = 'abc',
|
2024-10-18 10:32:14 +00:00
|
|
|
chk = read_from_file('test/ref/98831F3A.bip39').strip())
|
2023-11-30 10:53:40 +00:00
|
|
|
|
|
|
|
|
def tool_decrypt_geth_keystore(self):
|
|
|
|
|
return self._decrypt_keystore(
|
|
|
|
|
cmd = 'decrypt_geth_keystore',
|
|
|
|
|
fn = 'test/ref/ethereum/geth-wallet.json',
|
|
|
|
|
pw = '',
|
|
|
|
|
chk = '9627ddb68354f5e0ff45fb2da49d7a20a013b7257a83ef4adbbbd87aeaccc75e')
|
|
|
|
|
|
2020-06-08 17:03:21 +00:00
|
|
|
def tool_api(self):
|
2022-05-03 21:01:05 +00:00
|
|
|
t = self.spawn(
|
|
|
|
|
'tool_api_test.py',
|
2025-03-18 20:09:59 +03:00
|
|
|
(['no_altcoin'] if self.cfg.no_altcoin else []),
|
2024-10-18 10:32:14 +00:00
|
|
|
cmd_dir = 'test/misc')
|
|
|
|
|
t.expect('legacy.*compressed.*segwit.*bech32', regex=True)
|
2020-06-08 17:03:21 +00:00
|
|
|
return t
|