Skip to content

Instantly share code, notes, and snippets.

@j605
Created October 9, 2011 13:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j605/1273689 to your computer and use it in GitHub Desktop.
Save j605/1273689 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import sys, string, hashlib, getpass
ask_silent = getpass.getpass
def ask_normal(str):
sys.stderr.write(str)
return sys.stdin.readline()[0:-1] # remove the newline
def ask_master():
mastone = 'x'
masttwo = 'y'
while mastone != masttwo:
mastone = ask_silent("Enter the master password: ")
masttwo = ask_silent("Retype the master password: ")
if mastone != masttwo:
sys.stderr.write("Password entries don't match, try again\n")
return mastone
def ask_length():
passlength = 'ten'
while type(passlength) != type(10):
try:
passlength = int(ask_normal("Enter desired number of characters: "))
except ValueError:
sys.stderr.write("Please enter a number.\n")
return passlength
def generate(master, reason, length):
characters = string.ascii_letters + string.digits # add other characters that can be used in your passwords here
hash = hashlib.sha256()
len_to_go = length
pwd = ''
while len_to_go:
hash.update(master)
hash.update(reason)
binary_pass = [ord(c) for c in hash.digest()]
pwd_part = ''.join([characters[i % len(characters)] for i in binary_pass])[0:len_to_go]
len_to_go -= len(pwd_part)
pwd += pwd_part
return pwd
def main_console(argv):
if '-s' in argv or '--silent' in argv:
global ask_normal
ask_normal = getpass.getpass
else:
sys.stderr.write('Warning, by default the reason and password length are not'
' read as passwords (your console will show what you type). If you do not '
' want this, use the -s or --silent option.\n')
if '-u' in argv or '--unsafe' in argv:
master = ask_silent("Enter the master password: ")
else:
master = ask_master()
reason = ask_normal("Enter the reason: ")
length = ask_length()
sys.stderr.write('Your password is:\n')
sys.stdout.write(generate(master, reason, length) + '\n')
class PWGen_Window:
def __init__(self, gtk, silent, unsafe):
self.gtk = gtk
self.silent = silent
self.unsafe = unsafe
self.window = self.gtk.Window(self.gtk.WINDOW_TOPLEVEL)
self.window.set_title("PWGen")
self.window.connect("destroy", lambda w: self.gtk.main_quit())
self.vbox = self.gtk.VBox()
self.add_mastone()
self.add_masttwo()
self.add_reason()
self.add_size()
self.add_buttons()
self.pwlabel = self.gtk.Label()
self.pwlabel.set_size_request(200, 20)
self.vbox.pack_start(self.pwlabel, True, True, 5)
self.window.add(self.vbox)
self.window.show_all()
self.clip = self.gtk.Clipboard()
def add_mastone(self):
box = self.gtk.HBox()
label = self.gtk.Label("The master password:")
label.set_size_request(165, 20)
label.set_alignment(0, 0.5)
box.pack_start(label, False, True, 5)
self.mastone = self.gtk.Entry()
self.mastone.set_visibility(False)
box.pack_start(self.mastone, True, True, 5)
self.vbox.pack_start(box, False, False, 2)
def add_masttwo(self):
if self.unsafe:
self.masttwo = None
else:
box = self.gtk.HBox()
label = self.gtk.Label("Retype master password:")
label.set_size_request(165, 20)
label.set_alignment(0, 0.5)
box.pack_start(label, False, True, 5)
self.masttwo = self.gtk.Entry()
self.masttwo.set_visibility(False)
box.pack_start(self.masttwo, True, True, 5)
self.vbox.pack_start(box, False, False, 2)
def add_reason(self):
box = self.gtk.HBox()
label = self.gtk.Label("the reason:")
label.set_size_request(165, 20)
label.set_alignment(0, 0.5)
box.pack_start(label, False, True, 5)
self.reason = self.gtk.Entry()
if self.silent:
self.reason.set_visibility(False)
box.pack_start(self.reason, True, True, 5)
self.vbox.pack_start(box, False, False, 2)
def add_size(self):
box = self.gtk.HBox()
label = self.gtk.Label("the password size:")
label.set_size_request(165, 20)
label.set_alignment(0, 0.5)
box.pack_start(label, False, True, 5)
self.size = self.gtk.Entry()
self.size.set_text('10')
if self.silent:
self.size.set_visibility(False)
box.pack_start(self.size, True, True, 5)
self.vbox.pack_start(box, False, False, 2)
def add_buttons(self):
box = self.gtk.HBox()
self.show_button = self.gtk.Button("Show password")
self.show_button.connect("clicked", self.show_pwcallback)
box.pack_start(self.show_button, True, True, 5)
self.clip_button = self.gtk.Button("Copy password to clipboard")
self.clip_button.connect("clicked", self.clip_pwcallback)
box.pack_start(self.clip_button, True, True, 5)
self.vbox.pack_start(box, False, False, 2)
def show_pwcallback(self, data):
if self.pwlabel.get_text():
self.pwlabel.set_text('')
self.show_button.set_label("Show password")
else:
pwd = self.generate()
if not pwd:
return
self.pwlabel.set_text(pwd)
self.show_button.set_label("Clear password")
def clip_pwcallback(self, data):
pwd = self.generate()
if not pwd:
return
self.clip.set_text(pwd)
def generate(self):
mastone = self.mastone.get_text()
if self.masttwo:
masttwo = self.masttwo.get_text()
reason = self.reason.get_text()
if self.masttwo and mastone != masttwo:
dialog = self.gtk.MessageDialog(parent = self.window,
flags = self.gtk.DIALOG_MODAL | self.gtk.DIALOG_DESTROY_WITH_PARENT,
type = self.gtk.MESSAGE_WARNING,
buttons = self.gtk.BUTTONS_OK,
message_format = "\nThe master password is incorrect.")
dialog.run()
dialog.destroy()
return
try:
size = int(self.size.get_text())
except ValueError:
dialog = self.gtk.MessageDialog(parent = self.window,
flags = self.gtk.DIALOG_MODAL | self.gtk.DIALOG_DESTROY_WITH_PARENT,
type = self.gtk.MESSAGE_WARNING,
buttons = self.gtk.BUTTONS_OK,
message_format = "\nNeed a number for size.")
dialog.run()
dialog.destroy()
return
return generate(mastone, reason, size)
def main_gtk(argv):
import pygtk
pygtk.require('2.0')
import gtk
silent = False
if '-s' in argv or '--silent' in argv:
silent = True
unsafe = False
if '-u' in argv or '--unsafe' in argv:
unsafe = True
window = PWGen_Window(gtk, silent, unsafe)
gtk.main()
def usage(argv):
sys.stderr.write('usage: {0:s} [options]\n'.format(argv[0])
+ 'possible options are:\n'
+ ' -c, --console Don\'t open the GUI.\n'
+ ' -s, --silent Don\'t show the reason and password size.\n'
+ ' -u, --unsafe Don\'t ask to confirm the master password.\n\n')
def main(argv):
if '-h' in argv or '--help' in argv:
usage(argv)
return
if '-c' in argv or '--console' in argv:
main_console(argv)
else:
main_gtk(argv)
if __name__ == '__main__':
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment