#!/usr/bin/env python
import os, sys, md5, shelve
from Crypto.Cipher import Blowfish
from optparse import OptionParser
from getpass import getpass
try:
database = shelve.open("%s/.zpass/zpass.dbm" % os.environ["HOME"])
except:
print "Cant create file database, check permissions"
sys.exit(1)
def show_record(record):
if database.has_key(record):
record = database[record]
print "Your username is: \n%s " % _decode_data(record[0])
print "Your password is: \n%s" % _decode_data(record[1])
print "Additional information: \n%s" % _decode_data(record[2])
else:
print "No such record. Execute '%s -l' to list all records avialable" % sys.argv[0]
def add_record(record):
if database.has_key(record):
print "This record already exists"
else:
username = raw_input("Please enter an username:\n")
password = raw_input("Please enter an password:\n")
comment = raw_input("Please enter additional information:\n")
database[record] = map(_encode_data, (username, password, comment))
database.close()
def list_records():
for key in database.keys():
if key != '__passphrase':
print key
def modify_record(record):
if not database.has_key(record):
print "No such record in database"
else:
username = raw_input("Please enter an username: (leave blank to retain old username)\n")
password = raw_input("Please enter an password: (leave blank to retain old password)\n")
comment = raw_input("Please enter an comment: (leave blank to retain old comment)\n")
if not username:
username = _decode_data(database[record][0])
if not password:
password = _decode_data(database[record][1])
if not comment:
comment = _decode_data(database[record][2])
database[record] = map(_encode_data, (username, password, comment))
database.close()
def delete_record(record):
if not database.has_key(record):
print "No such record in database"
else:
yesno = raw_input("Are you sure you want to delete %s? (y/n): " % record)
if yesno == 'y':
del database[record]
print "Record %s successfully deleted" % record
else:
print "The only allowed variants is 'y' for yes, and 'n' for no"
database.close()
def controller():
parser = OptionParser(description="Python password reminder", prog="zpass", version="0.1", usage="%prog [-a|s|m|d|l|h|v] [arg1]")
parser.add_option('--add', '-a', metavar="record", help="Add new record to database")
parser.add_option('--show', '-s', metavar="record", help="Show record data")
parser.add_option('--modify', '-m', metavar="record", help="Modify record data in database")
parser.add_option('--delete', '-d', metavar="record", help="Delete record data from database")
parser.add_option('--list', '-l', action="store_true", help="List all record names in database")
options, arguments = parser.parse_args()
if len(arguments) != 0:
parser.error("You should use option and one record name")
elif options.add and options.show:
parser.error("options -a and -s are mutually exclusive")
elif options.add:
add_record(options.add)
elif options.show:
show_record(options.show)
elif options.list:
list_records()
elif options.modify:
modify_record(options.modify)
elif options.delete:
delete_record(options.delete)
def check_passphrase():
global user_passphrase
user_passphrase = getpass("Please enter an passphrase\n")
if database.has_key('__passphrase'):
if not md5.new(user_passphrase).hexdigest() == database['__passphrase']:
print "Wrong passphrase"
sys.exit(1)
else:
database['__passphrase'] = md5.new(user_passphrase).hexdigest()
return controller()
def _encode_data(value):
return Blowfish.new(user_passphrase, Blowfish.MODE_CFB).encrypt(value)
def _decode_data(value):
return Blowfish.new(user_passphrase, Blowfish.MODE_CFB).decrypt(value)
check_passphrase()