X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/05a8254234de3a315ed1ec33c26b56826678834d..63ba6dfae101afe3102e0c3c3fb6318c34a207f8:/pwsafe diff --git a/pwsafe b/pwsafe index 45086ad..50a5878 100644 --- a/pwsafe +++ b/pwsafe @@ -27,7 +27,8 @@ ###--------------------------------------------------------------------------- ### Imported modules. -import gdbm as G +from __future__ import with_statement + from os import environ from sys import argv, exit, stdin, stdout, stderr from getopt import getopt, GetoptError @@ -52,28 +53,6 @@ def die(msg): moan(msg) exit(1) -def chomp(pp): - """Return the string PP, without its trailing newline if it has one.""" - if len(pp) > 0 and pp[-1] == '\n': - pp = pp[:-1] - return pp - -def asciip(s): - """Answer whether all of the characters of S are plain ASCII.""" - for ch in s: - if ch < ' ' or ch > '~': return False - return True - -def present(s): - """ - Return a presentation form of the string S. - - If S is plain ASCII, then return S unchanged; otherwise return it as one of - Catacomb's ByteString objects. - """ - if asciip(s): return s - return C.ByteString(s) - ###-------------------------------------------------------------------------- ### Subcommand implementations. @@ -90,114 +69,77 @@ def cmd_create(av): except GetoptError: return 1 for o, a in opts: - if o in ('-c', '--cipher'): - cipher = a - elif o in ('-m', '--mac'): - mac = a - elif o in ('-h', '--hash'): - hash = a - else: - raise 'Barf!' - if len(args) > 2: - return 1 - if len(args) >= 1: - tag = args[0] - else: - tag = 'pwsafe' + if o in ('-c', '--cipher'): cipher = a + elif o in ('-m', '--mac'): mac = a + elif o in ('-h', '--hash'): hash = a + else: raise 'Barf!' + if len(args) > 2: return 1 + if len(args) >= 1: tag = args[0] + else: tag = 'pwsafe' ## Set up the database. if mac is None: mac = hash + '-hmac' PW.create(file, C.gcciphers[cipher], C.gchashes[hash], C.gcmacs[mac], tag) def cmd_changepp(av): - if len(av) != 0: - return 1 - pw = PW(file, 'w') - pw.changepp() + if len(av) != 0: return 1 + with PW(file, writep = True) as pw: pw.changepp() def cmd_find(av): - if len(av) != 1: - return 1 - pw = PW(file) - try: - print pw[av[0]] - except KeyError, exc: - die('Password `%s\' not found.' % exc.args[0]) + 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]) def cmd_store(av): - if len(av) < 1 or len(av) > 2: - return 1 + if len(av) < 1 or len(av) > 2: return 1 tag = av[0] - if len(av) < 2: - pp = C.getpass("Enter passphrase `%s': " % tag) - vpp = C.getpass("Confirm passphrase `%s': " % tag) - if pp != vpp: - raise ValueError, "passphrases don't match" - elif av[1] == '-': - pp = stdin.readline() - else: - pp = av[1] - pw = PW(file, 'w') - pw[av[0]] = chomp(pp) + with PW(file, writep = True) as pw: + if len(av) < 2: + pp = C.getpass("Enter passphrase `%s': " % tag) + vpp = C.getpass("Confirm passphrase `%s': " % tag) + if pp != vpp: die("passphrases don't match") + elif av[1] == '-': + pp = stdin.readline().rstrip('\n') + else: + pp = av[1] + pw[av[0]] = pp def cmd_copy(av): - if len(av) < 1 or len(av) > 2: - return 1 - pw_in = PW(file) - pw_out = PW(av[0], 'w') - 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] + if len(av) < 1 or len(av) > 2: return 1 + with PW(file) as pw_in: + with PW(av[0], writep = True) as pw_out: + 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] def cmd_list(av): - if len(av) > 1: - return 1 - pw = PW(file) - if len(av) >= 1: - pat = av[0] - else: - pat = None - for k in pw: - if pat is None or fnmatch(k, pat): - print k + if len(av) > 1: return 1 + with PW(file) as pw: + if len(av) >= 1: pat = av[0] + else: pat = None + for k in pw: + if pat is None or fnmatch(k, pat): print k def cmd_topixie(av): - if len(av) > 2: - return 1 - pw = PW(file) - pix = C.Pixie() - if len(av) == 0: - for tag in pw: - pix.set(tag, pw[tag]) - else: - tag = av[0] - if len(av) >= 2: - pptag = av[1] + 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]) else: - pptag = av[0] - pix.set(pptag, pw[tag]) + tag = 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 - pw = PW(file, 'w') - tag = av[0] - try: - del pw[tag] - except KeyError, exc: - die('Password `%s\' not found.' % exc.args[0]) - -def cmd_dump(av): - db = gdbm.open(file, 'r') - k = db.firstkey() - while True: - if k is None: break - print '%r: %r' % (present(k), present(db[k])) - k = db.nextkey(k) + if len(av) != 1: return 1 + with PW(file, writep = True) as pw: + tag = av[0] + try: del pw[tag] + except KeyError, exc: die("Password `%s' not found" % exc.args[0]) commands = { 'create': [cmd_create, '[-c CIPHER] [-h HASH] [-m MAC] [PP-TAG]'], @@ -207,8 +149,7 @@ commands = { 'create': [cmd_create, 'changepp' : [cmd_changepp, ''], 'copy' : [cmd_copy, 'DEST-FILE [GLOB-PATTERN]'], 'to-pixie' : [cmd_topixie, '[TAG [PIXIE-TAG]]'], - 'delete' : [cmd_del, 'TAG'], - 'dump' : [cmd_dump, '']} + 'delete' : [cmd_del, 'TAG']} ###-------------------------------------------------------------------------- ### Command-line handling and dispatch.