mmgen-passchg: improve secure wallet deletion logic

This commit is contained in:
The MMGen Project 2022-02-11 13:41:03 +00:00
commit 9e3d8d92de
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
3 changed files with 40 additions and 13 deletions

View file

@ -1 +1 @@
13.1.dev19
13.1.dev20

View file

@ -220,16 +220,40 @@ if invoked_as == 'passchg':
if not ( opt.force_update or data_changed(('passwd','hash_preset','label')) ):
die(1,'Password, hash preset and label are unchanged. Taking no action')
if invoked_as == 'passchg' and ss_in.infile.dirname == g.data_dir:
m1 = yellow('Confirmation of default wallet update')
m2 = 'update the default wallet'
confirm_or_raise(m1,m2,exit_msg='Password not changed')
ss_out.write_to_file(desc='New wallet',outdir=g.data_dir)
bmsg('Securely deleting old wallet')
from .fileutil import shred_file
shred_file(
ss_in.infile.name,
verbose = opt.verbose )
if invoked_as == 'passchg':
def secure_delete(fn):
bmsg('Securely deleting old wallet')
from .fileutil import shred_file
shred_file( fn, verbose = opt.verbose )
def rename_old_wallet_maybe(silent):
# though very unlikely, old and new wallets could have same Key ID and thus same filename.
# If so, rename old wallet file before deleting.
old_fn = ss_in.infile.name
if os.path.basename(old_fn) == ss_out._filename():
if not silent:
ymsg(
'Warning: diverting old wallet {old_fn!r} due to Key ID collision. ' +
'Please securely delete or move the diverted file!' )
os.rename( old_fn, old_fn+'.divert' )
return old_fn+'.divert'
else:
return old_fn
if ss_in.infile.dirname == g.data_dir:
confirm_or_raise(
message = yellow('Confirmation of default wallet update'),
action = 'update the default wallet',
exit_msg = 'Password not changed' )
old_wallet = rename_old_wallet_maybe(silent=True)
ss_out.write_to_file( desc='New wallet', outdir=g.data_dir )
secure_delete( old_wallet )
else:
old_wallet = rename_old_wallet_maybe(silent=False)
ss_out.write_to_file()
if keypress_confirm(f'Securely delete old wallet {old_wallet!r}?'):
secure_delete( old_wallet )
elif invoked_as == 'gen' and not opt.outdir and not opt.stdout:
from .filename import find_file_in_dir
if (

View file

@ -290,7 +290,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
assert ext == ocls.ext,f'incorrect file extension: {ext}'
return t
def passchg(self,wf,pf,label_action='cmdline',dfl_wallet=False):
def passchg(self,wf,pf,label_action='cmdline',dfl_wallet=False,delete=False):
silence()
self.write_to_tmpfile(pwfile,get_data_from_file(pf))
end_silence()
@ -319,10 +319,13 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
t.expect_getend('has been changed to ')
else:
t.written_to_file(capfirst(wcls.desc))
t.expect( 'Securely delete .*: ', ('y' if delete else 'n' ), regex=True )
if delete:
t.expect( 'Securely deleting' )
return t
def passchg_keeplabel(self,wf,pf):
return self.passchg(wf,pf,label_action='keep')
return self.passchg(wf,pf,label_action='keep',delete=True)
def passchg_usrlabel(self,wf,pf):
return self.passchg(wf,pf,label_action='user')