Various bugfixes, better password handling
This commit is contained in:
parent
4bd6bc5422
commit
3302ac774f
9 changed files with 91 additions and 43 deletions
2
MANIFEST
2
MANIFEST
|
|
@ -3,6 +3,7 @@ mmgen-addrgen
|
|||
mmgen-addrimport
|
||||
mmgen-keygen
|
||||
mmgen-passchg
|
||||
mmgen-pywallet
|
||||
mmgen-txcreate
|
||||
mmgen-txsend
|
||||
mmgen-txsign
|
||||
|
|
@ -30,7 +31,6 @@ mmgen/rpc/proxy.py
|
|||
mmgen/rpc/util.py
|
||||
scripts/bitcoind-walletunlock.py
|
||||
scripts/deinstall.sh
|
||||
scripts/pywallet.py
|
||||
tests/addr.py
|
||||
tests/bitcoin.py
|
||||
tests/mn_electrum.py
|
||||
|
|
|
|||
|
|
@ -163,7 +163,13 @@ if invoked_as == "addrgen":
|
|||
else:
|
||||
if not 'no_addresses' in opts: opts['print_secret'] = True
|
||||
|
||||
seed = get_seed(infile,opts)
|
||||
# Repeat on incorrect pw entry
|
||||
silent = False
|
||||
while True:
|
||||
seed = get_seed(infile,opts,silent=silent)
|
||||
silent = True
|
||||
if seed: break
|
||||
|
||||
seed_id = make_chksum_8(seed)
|
||||
addr_data = generate_addrs(seed, addr_list, opts)
|
||||
addr_data_str = format_addr_data(addr_data, seed_id, opts)
|
||||
|
|
|
|||
|
|
@ -66,9 +66,13 @@ infile = cmd_args[0]
|
|||
label,metadata,hash_preset,salt,enc_seed = get_data_from_wallet(infile,opts)
|
||||
seed_id,key_id = metadata[:2]
|
||||
oldp = "" if 'keep_old_passphrase' in opts else "old "
|
||||
passwd = " ".join(get_words("","",("Enter %spassphrase: " % oldp),opts))
|
||||
key = make_key(passwd, salt, hash_preset)
|
||||
seed = decrypt_seed(enc_seed, key, seed_id, key_id)
|
||||
|
||||
# Repeat on incorrect pw entry
|
||||
while True:
|
||||
passwd = " ".join(get_words("","",("Enter %spassphrase: " % oldp),opts))
|
||||
key = make_key(passwd, salt, hash_preset)
|
||||
seed = decrypt_seed(enc_seed, key, seed_id, key_id)
|
||||
if seed: break
|
||||
|
||||
changed = {}
|
||||
|
||||
|
|
|
|||
26
mmgen-txsign
26
mmgen-txsign
|
|
@ -109,7 +109,7 @@ if user_confirm("View transaction data? ",default_yes=False):
|
|||
view_tx_data(c,inputs_data,tx_hex,metadata)
|
||||
|
||||
# Are inputs mmgen addresses?
|
||||
infile,mmgen_addrs,other_addrs,keys = "",[],[],[]
|
||||
mmgen_addrs,other_addrs,keys = [],[],[]
|
||||
|
||||
for i in inputs_data:
|
||||
if verify_mmgen_label(i['account']):
|
||||
|
|
@ -121,9 +121,11 @@ if mmgen_addrs and not 'force_wallet_dat' in opts:
|
|||
# Check that all the seed IDs are the same:
|
||||
seed_ids = list(set([i['account'][:8] for i in mmgen_addrs]))
|
||||
while seed_ids:
|
||||
infile = False
|
||||
if cmd_args:
|
||||
infile = cmd_args.pop()
|
||||
ext = infile.split(".")[-1]
|
||||
found = False
|
||||
for e,o in (
|
||||
(wallet_ext, {}),
|
||||
(mn_ext, {"from_mnemonic":True}),
|
||||
|
|
@ -131,15 +133,29 @@ if mmgen_addrs and not 'force_wallet_dat' in opts:
|
|||
(brain_ext, {})
|
||||
):
|
||||
if e == ext:
|
||||
found = True
|
||||
if e == brain_ext:
|
||||
if "from_brain" in opts: o = opts
|
||||
else:
|
||||
msg("'--from-brain' option must be specified for brainwallet file")
|
||||
sys.exit(2)
|
||||
seed = get_seed(infile,o)
|
||||
silent = False
|
||||
while True:
|
||||
seed = get_seed(infile,o,silent=silent)
|
||||
silent = True
|
||||
if seed: break
|
||||
|
||||
if not found:
|
||||
msg("%s: invalid file extension" % ext)
|
||||
sys.exit(2)
|
||||
|
||||
elif "from_brain" in opts or "from_mnemonic" in opts or "from_seed" in opts:
|
||||
msg("Need data for seed ID %s" % seed_ids[0])
|
||||
seed = get_seed("",opts)
|
||||
silent = False
|
||||
while True:
|
||||
seed = get_seed("",opts,silent=silent)
|
||||
silent = True
|
||||
if seed: break
|
||||
else:
|
||||
msg("One of '-b', '-m' or '-s' must be specified for seed IDs: %s" %
|
||||
" ".join(seed_ids))
|
||||
|
|
@ -158,7 +174,9 @@ if mmgen_addrs and not 'force_wallet_dat' in opts:
|
|||
keys += [i['wif'] for i in generate_addrs(seed, seed_id_addrs, o)]
|
||||
else:
|
||||
msg("Supplied seed ID (%s) is incorrect" % seed_id)
|
||||
sys.exit(2)
|
||||
if infile:
|
||||
msg("Invalid input file: %s" % infile)
|
||||
sys.exit(2)
|
||||
|
||||
if other_addrs:
|
||||
if 'keys_from_file' in opts:
|
||||
|
|
|
|||
|
|
@ -151,8 +151,12 @@ if debug: display_user_random_data(usr_keys,key_timings)
|
|||
usr_rand_data = sha256(usr_keys).digest() + \
|
||||
sha256("".join(key_timings)).digest()
|
||||
|
||||
s = get_seed(infile,opts,no_wallet=True)
|
||||
if s: seed = s
|
||||
if 'from_mnemonic' in opts or 'from_brain' in opts or 'from_seed' in opts:
|
||||
silent = False
|
||||
while True:
|
||||
seed = get_seed(infile,opts,silent=silent)
|
||||
silent = True
|
||||
if seed: break
|
||||
else:
|
||||
# Truncate random data for smaller seed lengths
|
||||
seed = os_rand_data[0] + usr_rand_data
|
||||
|
|
|
|||
|
|
@ -108,7 +108,10 @@ def generate_addrs(seed, addrnums, opts):
|
|||
out.append(el)
|
||||
|
||||
w = opts['gen_what']
|
||||
if t_addrs == 1: w = w[:-1]
|
||||
if t_addrs == 1:
|
||||
import re
|
||||
w = re.sub('e*s$','',w)
|
||||
|
||||
sys.stderr.write("\rGenerated %s %s%s\n"%(t_addrs, w, " "*15))
|
||||
|
||||
return out
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ def get_seed_from_mnemonic(mn,wl):
|
|||
if len(mn) not in mnemonic_lens:
|
||||
msg("Bad mnemonic (%i words). Allowed numbers of words: %s" %
|
||||
(len(mn)," ".join([str(i) for i in mnemonic_lens])))
|
||||
sys.exit(2)
|
||||
return False
|
||||
|
||||
for w in mn:
|
||||
if w not in wl:
|
||||
msg("Bad mnemonic: '%s' is not in the wordlist" % w)
|
||||
sys.exit(2)
|
||||
return False
|
||||
|
||||
from binascii import unhexlify
|
||||
seed = unhexlify(baseNtohex(mn_base,mn,wl,mn_fill(mn)))
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@ def write_wallet_to_file(seed, passwd, key_id, salt, enc_seed, opts):
|
|||
if 'outdir' in opts:
|
||||
outfile = "%s/%s" % (opts['outdir'], outfile)
|
||||
|
||||
label = opts['label'] if 'label' in opts else "None"
|
||||
label = opts['label'] if 'label' in opts else "No Label"
|
||||
|
||||
from mmgen.bitcoin import b58encode_pad
|
||||
|
||||
|
|
@ -572,14 +572,15 @@ def write_walletdat_dump_to_file(wallet_id,data,num_keys,ext,what,opts):
|
|||
msg("wallet.dat %s saved to file '%s'" % (what,outfile))
|
||||
|
||||
|
||||
def compare_checksums(chksum1, desc1, chksum2, desc2):
|
||||
def compare_checksums(chksum1, desc1, chksum2, desc2):
|
||||
|
||||
if chksum1.lower() == chksum2.lower():
|
||||
msg("OK (%s)" % chksum1.upper())
|
||||
return True
|
||||
else:
|
||||
msg("ERROR!\nComputed checksum %s (%s) doesn't match checksum %s (%s)" \
|
||||
% (desc1,chksum1,desc2,chksum2))
|
||||
if debug:
|
||||
msg("ERROR!\nComputed checksum %s (%s) doesn't match checksum %s (%s)" \
|
||||
% (desc1,chksum1,desc2,chksum2))
|
||||
return False
|
||||
|
||||
def _is_hex(s):
|
||||
|
|
@ -588,7 +589,7 @@ def _is_hex(s):
|
|||
else: return True
|
||||
|
||||
|
||||
def check_mmseed_format(words):
|
||||
def _check_mmseed_format(words):
|
||||
|
||||
valid = False
|
||||
what = "%s data" % seed_ext
|
||||
|
|
@ -602,12 +603,10 @@ def check_mmseed_format(words):
|
|||
msg("Incorrect length of checksum (%s) in %s" % (chklen,what))
|
||||
else: valid = True
|
||||
|
||||
if valid == False:
|
||||
msg("Invalid %s data" % seed_ext)
|
||||
sys.exit(3)
|
||||
return valid
|
||||
|
||||
|
||||
def check_wallet_format(infile, lines, opts):
|
||||
def check_wallet_format(infile, lines, opts):
|
||||
|
||||
def vmsg(s):
|
||||
if 'verbose' in opts: msg(s)
|
||||
|
|
@ -638,9 +637,10 @@ def _check_chksum_6(chk,val,desc,infile):
|
|||
msg("%s checksum passed: %s" % (desc.capitalize(),chk))
|
||||
|
||||
|
||||
def get_data_from_wallet(infile,opts):
|
||||
def get_data_from_wallet(infile,opts,silent=False):
|
||||
|
||||
msg("Getting {} wallet data from file '{}'".format(proj_name,infile))
|
||||
if not silent:
|
||||
msg("Getting {} wallet data from file '{}'".format(proj_name,infile))
|
||||
|
||||
f = open_file_or_exit(infile, 'r')
|
||||
|
||||
|
|
@ -719,9 +719,11 @@ def get_words(infile,what,prompt,opts):
|
|||
return words
|
||||
|
||||
|
||||
def get_seed_from_seed_data(words):
|
||||
def _get_seed_from_seed_data(words):
|
||||
|
||||
check_mmseed_format(words)
|
||||
if not _check_mmseed_format(words):
|
||||
msg("Invalid %s data" % seed_ext)
|
||||
return False
|
||||
|
||||
stored_chk = words[0]
|
||||
seed_b58 = "".join(words[1:])
|
||||
|
|
@ -733,19 +735,23 @@ def get_seed_from_seed_data(words):
|
|||
seed = b58decode_pad(seed_b58)
|
||||
if seed == False:
|
||||
msg("Invalid b58 number: %s" % val)
|
||||
sys.exit(9)
|
||||
return False
|
||||
|
||||
msg("%s data produces seed ID: %s" % (seed_ext,make_chksum_8(seed)))
|
||||
return seed
|
||||
else:
|
||||
msg("Invalid checksum for {} seed".format(proj_name))
|
||||
sys.exit(9)
|
||||
return False
|
||||
|
||||
|
||||
def get_seed_from_wallet(infile,opts,
|
||||
prompt="Enter {} wallet passphrase: ".format(proj_name)):
|
||||
def get_seed_from_wallet(
|
||||
infile,
|
||||
opts,
|
||||
prompt="Enter {} wallet passphrase: ".format(proj_name),
|
||||
silent=False
|
||||
):
|
||||
|
||||
wdata = get_data_from_wallet(infile,opts)
|
||||
wdata = get_data_from_wallet(infile,opts,silent=silent)
|
||||
label,metadata,hash_preset,salt,enc_seed = wdata
|
||||
|
||||
if 'verbose' in opts: _display_control_data(*wdata)
|
||||
|
|
@ -770,8 +776,8 @@ def decrypt_seed(enc_seed, key, seed_id, key_id):
|
|||
msg_r("Checking key...")
|
||||
chk = make_chksum_8(key)
|
||||
if not compare_checksums(chk, "of key", key_id, "in header"):
|
||||
msg("Passphrase incorrect?")
|
||||
sys.exit(3)
|
||||
msg("Incorrect passphrase")
|
||||
return False
|
||||
|
||||
msg_r("Decrypting seed with key...")
|
||||
|
||||
|
|
@ -793,21 +799,22 @@ def decrypt_seed(enc_seed, key, seed_id, key_id):
|
|||
else:
|
||||
msg("Incorrect passphrase")
|
||||
|
||||
sys.exit(3)
|
||||
return False
|
||||
|
||||
if debug: msg("key: %s" % hexlify(key))
|
||||
|
||||
return dec_seed
|
||||
|
||||
|
||||
def get_seed(infile,opts,no_wallet=False):
|
||||
def get_seed(infile,opts,silent=False):
|
||||
if 'from_mnemonic' in opts:
|
||||
prompt = "Enter mnemonic: "
|
||||
what = "mnemonic"
|
||||
words = get_words(infile,"mnemonic data",prompt,opts)
|
||||
|
||||
wl = get_default_wordlist()
|
||||
from mmgen.mnemonic import get_seed_from_mnemonic
|
||||
return get_seed_from_mnemonic(words,wl)
|
||||
seed = get_seed_from_mnemonic(words,wl)
|
||||
elif 'from_brain' in opts:
|
||||
if 'quiet' not in opts:
|
||||
confirm_or_exit(
|
||||
|
|
@ -816,16 +823,22 @@ def get_seed(infile,opts,no_wallet=False):
|
|||
*_get_from_brain_opt_params(opts)),
|
||||
"continue")
|
||||
prompt = "Enter brainwallet passphrase: "
|
||||
what = "brainwallet"
|
||||
words = get_words(infile,"brainwallet data",prompt,opts)
|
||||
return _get_seed_from_brain_passphrase(words,opts)
|
||||
seed = _get_seed_from_brain_passphrase(words,opts)
|
||||
elif 'from_seed' in opts:
|
||||
prompt = "Enter seed in %s format: " % seed_ext
|
||||
what = "seed"
|
||||
words = get_words(infile,"seed data",prompt,opts)
|
||||
return get_seed_from_seed_data(words)
|
||||
elif no_wallet:
|
||||
return False
|
||||
seed = _get_seed_from_seed_data(words)
|
||||
else:
|
||||
return get_seed_from_wallet(infile, opts)
|
||||
return get_seed_from_wallet(infile, opts, silent=silent)
|
||||
|
||||
if infile and not seed:
|
||||
msg("Invalid %s file: %s" % (what,infile))
|
||||
sys.exit(2)
|
||||
|
||||
return seed
|
||||
|
||||
|
||||
def remove_blanks_comments(lines):
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -3,7 +3,7 @@ from distutils.core import setup
|
|||
|
||||
setup(
|
||||
name = 'mmgen',
|
||||
version = '0.6.4',
|
||||
version = '0.6.5',
|
||||
author = 'Philemon',
|
||||
author_email = 'mmgen-py@yandex.com',
|
||||
url = 'https://github.com/mmgen/mmgen',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue