Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 171 lines (148 sloc) 5.09 KB
#!/usr/bin/python2
"""
For Keepass 2.x (v4) files
pip2 install gtk pykeepass
"""
import string
import random
import getpass
import subprocess
from time import sleep
from pykeepass import PyKeePass
chars = string.ascii_letters + string.digits + string.punctuation
def generate_password(length=32):
rng = random.SystemRandom()
return ''.join([rng.choice(chars) for i in range(length)])
def get_entries(db):
return [entry for entry in db.entries if entry.title != 'Meta-Info']
def search_entries(db, query):
results = []
query = query.lower()
for entry in get_entries(db):
content = ' '.join([entry.title,
entry.url or '',
entry.notes or ''])
if query in content.lower():
results.append(entry)
return results
def add_entry(db, group_name, title, username, url='', notes='', password='', password_length=32, overwrite=False):
group_names = [group.name for group in db.groups]
if group_name not in group_names:
raise KeyError('"{}" is not an existing group'.format(group_name))
if not password:
password = generate_password(length=password_length)
group = db.find_groups_by_name(group_name, first=True)
db.add_entry(
destination_group=group,
title=title,
username=username,
password=password,
url=url,
notes=notes,
force_creation=not overwrite)
return password
def new_entry(db):
print('Groups:')
data = {}
for i, group in enumerate(db.groups):
print('[{}] {}'.format(i, group.name))
data['group_name'] = None
while data['group_name'] is None:
inp = raw_input('Select #: ')
try:
data['group_name'] = db.groups[int(inp)].name
except (ValueError, IndexError):
pass
required = ['title', 'username']
optional = ['url', 'notes', 'password']
for key in required + optional:
data[key] = None
while data[key] is None or (not data[key] and key in required):
note = 'required' if key in required else 'optional'
data[key] = raw_input('{} ({}): '.format(key.title(), note))
if not data['password']:
data['password'] = generate_password()
while True:
print('Data:')
for k, v in data.items():
print(' {}: {}'.format(k,v))
ok = raw_input('Ok? [y/n] ')
if ok.lower() == 'y':
break
else:
key = None
while key not in data:
key = raw_input('Change key: ')
data[key] = None
while data[key] is None or (not data[key] and key in required):
note = 'required' if key in required else 'optional'
data[key] = raw_input('{} ({}): '.format(key.title(), note))
return add_entry(db, **data)
def search(db):
query = raw_input('Search: ')
selected = None
while selected is None:
entries = search_entries(db, query)
if entries:
print('\nResults\n--------')
for i, entry in enumerate(entries):
print('[{}] {}'.format(i, entry.title))
while selected is None:
inp = raw_input('Select #: ')
try:
selected = entries[int(inp)]
except ValueError:
query = inp
break
except IndexError:
pass
else:
print('No results')
query = raw_input('Search: ')
return selected
def load_db(filename):
db = None
while db is None:
try:
masterkey = getpass.getpass()
db = PyKeePass(filename, password=masterkey)
except IOError:
print('Incorrect password')
return db
if __name__ == '__main__':
import os
import gtk
print('Keepass')
filename = os.path.expanduser('~/docs/pass.kdbx')
try:
db = load_db(filename)
clipboard = gtk.Clipboard()
print('Commands: new, get, list, quit')
while True:
cmd = raw_input('> ')
if cmd == 'new':
password = new_entry(db)
clipboard.set_text(password)
print('Copied password to clipboard\n')
db.save()
elif cmd == 'get':
selected = search(db)
print('Username: {}'.format(selected.username))
if selected.notes:
print(selected.notes)
# refocus last-focused window and type in password
subprocess.Popen(['bspc', 'node', '-f', 'last']).wait()
subprocess.Popen(['xdotool', 'type', selected.password]).wait()
sleep(0.1) # give xdotool a sec
exit(0)
elif cmd == 'list':
for entry in get_entries(db):
print(entry.title)
elif cmd == 'quit':
print('')
exit(0)
else:
print('Unrecognized command')
except (KeyboardInterrupt, EOFError):
print('')
exit(0)