Source code for dispass.cli

# Copyright (c) 2011-2012 Benjamin Althues <benjamin@babab.nl>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import getpass

import digest
from dispass import versionStr

try:
    import curses
    hasCurses = True
except ImportError:
    hasCurses = False

[docs]class CLI: '''Command Line Interface handling''' passphraseLength = 30 '''Length of output passphrase, default is 30''' promptDouble = False '''Boolean. Prompt for password twice''' def __init__(self): '''Set `useCurses` to True or False. Depending on the availability of curses ''' self.useCurses = hasCurses
[docs] def setCurses(self, useCurses): '''Optionally override `self.useCurses` :Parameters: - `useCurses`: Boolean ''' if useCurses and not hasCurses: self.useCurses = False else: self.useCurses = useCurses
[docs] def setLength(self, length): '''Optionally override length of output passphrase :Parameters: - `length`: Integer. Length of output passphrase ''' self.passphraseLength = length
[docs] def setPrompt(self, promptDouble=False): '''Set options for the passwordPrompt) :Parameters: - `promptDouble`: Boolean. Prompt 2x and compare passwords ''' self.promptDouble = promptDouble
[docs] def passwordPrompt(self): '''Prompt for password. Returns password''' while True: inp = getpass.getpass() if self.promptDouble: inp2 = getpass.getpass("Password (again): ") if inp == inp2: break; else: print "Passwords do not match. Please try again." else: break return inp
[docs] def interactive(self, labels): '''Start interactive prompt, generating and showing the passprase(s) :Parameters: - `labels`: List or dict of labels to use for passprase generation ''' password = self.passwordPrompt() if isinstance(labels, list): labelmap = [] for i in labels: labelmap.append((i, self.passphraseLength)) hashedLabels = digest.digestPasswordDict(dict(labelmap), password) divlen = len(max(labels, key=len)) + 2 elif isinstance(labels, dict): hashedLabels = digest.digestPasswordDict(labels, password) label_list = [] for label, length in hashedLabels.iteritems(): label_list.append(label) divlen = len(max(label_list, key=len)) + 2 del password if self.useCurses: stdscr = curses.initscr() curses.noecho() curses.cbreak() stdscr.addstr(0, 0, versionStr + " - press 'q' to quit", curses.A_BOLD) stdscr.addstr(1, 0, "Your passphrase(s)", curses.A_BOLD) j = 3 for label, passphrase in hashedLabels.iteritems(): stdscr.addstr(j, 0, label, curses.A_BOLD) stdscr.addstr(j, divlen, passphrase, curses.A_REVERSE) j += 1 stdscr.refresh() while True: c = stdscr.getch() if c == ord('q'): break curses.nocbreak() curses.echo() curses.endwin() else: for label, passphrase in hashedLabels.iteritems(): print "{:{fill}} {}".format(label, passphrase, fill=divlen)