from catacomb.pwsafe import *
###--------------------------------------------------------------------------
+### Python version portability.
+
+def _text(bin): return bin
+def _bin(text): return text
+
+def _excval(): return SYS.exc_info()[1]
+
+###--------------------------------------------------------------------------
### Utilities.
## The program name.
def moan(msg):
"""Issue a warning message MSG."""
- print >>stderr, '%s: %s' % (prog, msg)
+ stderr.write('%s: %s\n' % (prog, msg))
def die(msg):
"""Report MSG as a fatal error, and exit."""
def cmd_create(av):
## Default crypto-primitive selections.
- cipher = 'blowfish-cbc'
- hash = 'rmd160'
+ cipher = 'rijndael-cbc'
+ hash = 'sha256'
mac = None
## Parse the options.
elif o in ('-m', '--mac'): mac = a
elif o in ('-h', '--hash'): hash = a
elif o in ('-d', '--database'): dbty = a
- else: raise 'Barf!'
+ else: raise Exception("barf")
if len(args) > 2: return 1
if len(args) >= 1: tag = args[0]
else: tag = 'pwsafe'
def cmd_find(av):
if len(av) != 1: return 1
with PW(file) as pw:
- try: print pw[av[0]]
- except KeyError, exc: die("Password `%s' not found" % exc.args[0])
+ try: print(_text(pw[_bin(av[0])]))
+ except KeyError: die("Password `%s' not found" % _excval().args[0])
def cmd_store(av):
if len(av) < 1 or len(av) > 2: return 1
vpp = C.getpass("Confirm passphrase `%s': " % tag)
if pp != vpp: die("passphrases don't match")
elif av[1] == '-':
- pp = stdin.readline().rstrip('\n')
+ pp = _bin(stdin.readline().rstrip('\n'))
else:
- pp = av[1]
- pw[av[0]] = pp
+ pp = _bin(av[1])
+ pw[_bin(av[0])] = pp
def cmd_copy(av):
if len(av) < 1 or len(av) > 2: return 1
if len(av) >= 3: pat = av[1]
else: pat = None
for k in pw_in:
- if pat is None or fnmatch(k, pat): pw_out[k] = pw_in[k]
+ ktext = _text(k)
+ if pat is None or fnmatch(ktext, pat): pw_out[k] = pw_in[k]
def cmd_list(av):
if len(av) > 1: return 1
if len(av) >= 1: pat = av[0]
else: pat = None
for k in pw:
- if pat is None or fnmatch(k, pat): print k
+ ktext = _text(k)
+ if pat is None or fnmatch(ktext, pat): print(ktext)
def cmd_topixie(av):
if len(av) > 2: return 1
with PW(file) as pw:
pix = C.Pixie()
if len(av) == 0:
- for tag in pw: pix.set(tag, pw[tag])
+ for tag in pw: pix.set(tag, pw[_bin(tag)])
else:
- tag = av[0]
+ tag = _bin(av[0])
if len(av) >= 2: pptag = av[1]
else: pptag = av[0]
pix.set(pptag, pw[tag])
def cmd_del(av):
if len(av) != 1: return 1
with PW(file, writep = True) as pw:
- tag = av[0]
+ tag = _bin(av[0])
try: del pw[tag]
- except KeyError, exc: die("Password `%s' not found" % exc.args[0])
+ except KeyError: die("Password `%s' not found" % _excval().args[0])
+
+def cmd_xfer(av):
+
+ ## Parse the command line.
+ try: opts, args = getopt(av, 'd:', ['database='])
+ except GetoptError: return 1
+ dbty = 'flat'
+ for o, a in opts:
+ if o in ('-d', '--database'): dbty = a
+ else: raise Exception("barf")
+ if len(args) != 1: return 1
+ try: dbcls = StorageBackend.byname(dbty)
+ except KeyError: die("Unknown database backend `%s'" % dbty)
+
+ ## Create the target database.
+ with StorageBackend.open(file) as db_in:
+ with dbcls.create(args[0]) as db_out:
+ for k, v in db_in.iter_meta(): db_out.put_meta(k, v)
+ for k, v in db_in.iter_passwds(): db_out.put_passwd(k, v)
commands = { 'create': [cmd_create,
'[-c CIPHER] [-d DBTYPE] [-h HASH] [-m MAC] [PP-TAG]'],
'changepp' : [cmd_changepp, ''],
'copy' : [cmd_copy, 'DEST-FILE [GLOB-PATTERN]'],
'to-pixie' : [cmd_topixie, '[TAG [PIXIE-TAG]]'],
- 'delete' : [cmd_del, 'TAG']}
+ 'delete' : [cmd_del, 'TAG'],
+ 'xfer': [cmd_xfer, '[-d DBTYPE] DEST-FILE'] }
###--------------------------------------------------------------------------
### Command-line handling and dispatch.
def version():
- print '%s 1.0.0' % prog
- print 'Backend types: %s' % \
- ' '.join([c.NAME for c in StorageBackend.classes()])
+ print('%s 1.0.0' % prog)
+ print('Backend types: %s' %
+ ' '.join([c.NAME for c in StorageBackend.classes()]))
def usage(fp):
- print >>fp, 'Usage: %s COMMAND [ARGS...]' % prog
+ fp.write('Usage: %s COMMAND [ARGS...]\n' % prog)
def help():
version()
- print
+ print('')
usage(stdout)
- print '''
+ print('''
Maintains passwords or other short secrets securely.
Options:
-f, --file=FILE Where to find the password-safe file.
Commands provided:
-'''
+''')
for c in sorted(commands):
- print '%s %s' % (c, commands[c][1])
+ print('%s %s' % (c, commands[c][1]))
## Choose a default database file.
if 'PWSAFE' in environ:
elif o in ('-f', '--file'):
file = a
else:
- raise 'Barf!'
+ raise Exception("barf")
if len(argv) < 1:
usage(stderr)
exit(1)
c = 'find'
try:
if commands[c][0](argv):
- print >>stderr, 'Usage: %s %s %s' % (prog, c, commands[c][1])
+ stderr.write('Usage: %s %s %s\n' % (prog, c, commands[c][1]))
exit(1)
except DecryptError:
die("decryption failure")