def _load_pwdb(self): #################################################################### """reload passworddb""" #################################################################### LOGGER.info("Reloading Password Database") self.pwdb = PasswordDB() self.pwdb.load_from_directory(self.args["pwstore"])
def _run_command_execution(self): #################################################################### """Run function for class.""" #################################################################### passworddb = PasswordDB() passworddb.load_from_directory(self.args["pwstore"]) Interactive(self.args, passworddb).cmdloop_with_keyboard_interrupt() yield "Goodbye"
def test_read_write(self): """Test read write to the password db""" passworddb = PasswordDB() passwordentry = passworddb.load_password_data(self.file1) passworddb.pwdb[self.file2] = passworddb.pwdb[self.file1] passworddb.save_password_data(self.file2, overwrite=True) with open(self.file1, 'r') as file1: with open(self.file2, 'r') as file2: self.assertTrue(file1.read() == file2.read())
def _run_command_execution(self): """ Run function for class. """ #################################################################### passworddb = PasswordDB() passworddb.load_from_directory(self.args['pwstore']) filtered_pdb = util.dictionary_filter( path.join(self.args['pwstore'], self.args['pwname']), passworddb.pwdb, [self.args['identity'], 'recipients'] ) self.recipient_list.append(str(self.args['identity'])) self.recipient_list = list(set(self.recipient_list)) print("The following users will receive the password:"******", ".join(self.recipient_list)) print("The following password files have matched:") print(*filtered_pdb.keys(), sep="\n") correct_distribution = input("Are these lists correct? (y/N) ") if correct_distribution and correct_distribution.lower()[0] == 'y': passworddb.pwdb = filtered_pdb db_len = len(passworddb.pwdb.keys()) i = 0 self.progress_bar(i, db_len) for dist_pass, _ in passworddb.pwdb.items(): password = PasswordEntry() password.read_password_data(dist_pass) if self.args['identity'] in password.recipients.keys(): # we shouldn't modify escrow on distribute self.args['min_escrow'] = None self.args['escrow_users'] = None plaintext_pw = password.decrypt_entry( self.identities.iddb[self.args['identity']], passphrase=self.passphrase, card_slot=self.args['card_slot']) password.read_password_data(dist_pass) password.add_recipients(secret=plaintext_pw, distributor=self.args['identity'], recipients=self.recipient_list, identitydb=self.identities, passphrase=self.passphrase, card_slot=self.args['card_slot'], pwstore=self.args['pwstore'] ) password.write_password_data(dist_pass) i += 1 self.progress_bar(i, db_len) # format the progress bar appropriately after the loop print("") else: print("Exiting due to wrong password list")
def _run_command_execution(self): """ Run function for class. """ #################################################################### myidentity = self.identities.iddb[self.args['identity']] passworddb = PasswordDB() crypt_pass = False for fpath, _, files in walk(self.args['pwstore']): for passwordname in files: passwordpath = path.join(fpath, passwordname) passworddb.load_password_data(passwordpath) if not self.args['nocrypto']: crypt_pass = getpass.getpass( "Please enter a password for the encryption: ") verify_pass = getpass.getpass( "Please enter again for verification: ") if crypt_pass != verify_pass: raise PasswordMismatchError() self._iterate_pdb(myidentity, passworddb, crypt_pass)
def _run_command_execution(self): """ Run function for class. """ #################################################################### passworddb = PasswordDB() passworddb.load_from_directory(self.args['pwstore']) result = {} for pwname, passwordentry in passworddb.pwdb.items(): if self.args['recovery'] and passwordentry.escrow: for rec_list in passwordentry.escrow.keys(): recipients = passwordentry.escrow[rec_list]['recipients'] for key, value in recipients.items(): if key == self.args['identity']: result[pwname] = { 'name': passwordentry.metadata['name'], 'group': rec_list, 'stake_holders': list(recipients.keys()), 'distributor': value['distributor'], 'minimum_shares': passwordentry.escrow[rec_list]['metadata']['minimum_escrow'] } elif not self.args['recovery'] and self.args['identity'] in passwordentry.recipients.keys(): result[pwname] = { 'name': passwordentry.metadata['name'], 'distributor': passwordentry.recipients[self.args['identity']]['distributor'] } if 'filter' in self.args and self.args['filter']: result = dictionary_filter(self.args['filter'], result) print("Passwords for '%s':" % self.args['identity']) for key, value in result.items(): print("%s\n %s\n %s" % ( self.color_print(key + ":", "first_level"), self.color_print("Distributor: ", "second_level") + value['distributor'], self.color_print("Name: ", "second_level") + value['name'] ))
def __init__(self, cli, iddb=None, pwdb=None): ################################################################## """Intialization function for class. Register with argparse""" ################################################################## self.cli = cli # default certpath to none because connect string is allowed self.args = {} self.recipient_list = [] self.escrow_and_recipient_list = [] self.identities = iddb if iddb else IdentityDB() self.pwdbcached = pwdb is not None self.passworddb = pwdb if pwdb else PasswordDB() self.session = None self.identity = None cli.register(self, self.name, self.description)
def __init__(self, args, pwdb): Cmd.__init__(self) # manually remove interpreter from command line so that argparse doesn't try to use it # This needs to be removed before the PkInterace init sys.argv.remove("interpreter") pkinterface.PkInterface.__init__(self) self.pwdb = pwdb if pwdb else PasswordDB() self.parser.error = pkparse_error # Hold onto args passed on the command line self.args = args # change our cwd so users can tab complete self._change_pwstore() # We basically need to grab the first argument and ditch it self.parsedargs = {}
class Interactive(Cmd, pkinterface.PkInterface): #################################################################### """This class implements the interactive interpreter functionality""" #################################################################### intro = f"""Welcome to PKPass (Public Key Based Password Manager) v{VERSION}! Type ? to list commands""" prompt = "pkpass> " def __init__(self, args, pwdb): Cmd.__init__(self) # manually remove interpreter from command line so that argparse doesn't try to use it # This needs to be removed before the PkInterace init sys.argv.remove("interpreter") pkinterface.PkInterface.__init__(self) self.pwdb = pwdb if pwdb else PasswordDB() self.parser.error = pkparse_error # Hold onto args passed on the command line self.args = args # change our cwd so users can tab complete self._change_pwstore() # We basically need to grab the first argument and ditch it self.parsedargs = {} def cmdloop_with_keyboard_interrupt(self): #################################################################### """handle keyboard interrupts""" #################################################################### breaker = False first = True while breaker is not True: try: if first: self.cmdloop() else: self.cmdloop(intro="") breaker = True except KeyboardInterrupt: first = False sys.stdout.write("\n") def _load_pwdb(self): #################################################################### """reload passworddb""" #################################################################### LOGGER.info("Reloading Password Database") self.pwdb = PasswordDB() self.pwdb.load_from_directory(self.args["pwstore"]) def _change_pwstore(self): #################################################################### """Change directory""" #################################################################### direc = self.args["pwstore"] if "pwstore" in self.args and direc and path.isdir(direc): chdir(direc) def _reload_config(self): #################################################################### """Change affected globals in interpreter""" #################################################################### # We still need to be able to reload other things like recipients # database config = self.args["config"] config_args = self.args try: config_args = collect_args({"config": config}) if not config_args: config_args = self.args except ParserError: LOGGER.error("Error parsing config file") config_args = self.args finally: self.args = config_args self.args["config"] = config self.args = handle_filepath_args(self.args) self._change_pwstore() self._load_pwdb() def precmd(self, line): #################################################################### """Fix command line arguments, this is a hack to allow argparse function as we expect""" #################################################################### sys.argv = [sys.argv[0]] sys.argv.extend(line.split()) return line def postcmd(self, stop, line): #################################################################### """Fix command line arguments, this is a hack to allow argparse function as we expect""" #################################################################### if str(line) == "edit" or "--no-cache" in line: self._reload_config() elif str(line.split()[0]) in [ "create", "delete", "import", "generate", "rename", ]: self._load_pwdb() return Cmd.postcmd(self, stop, line) def _append_slash_if_dir(self, path_arg): #################################################################### """Appending slashes for autocomplete_file_path""" #################################################################### if path_arg and path.isdir(path_arg) and path_arg[-1] != sep: return path_arg + sep return path_arg def autocomplete_file_path(self, _, line, begidx, endidx): #################################################################### """File path autocompletion, used with the cmd module complete_* series functions""" #################################################################### before_arg = line.rfind(" ", 0, begidx) if before_arg == -1: return None # arg not found fixed = line[before_arg + 1:begidx] # fixed portion of the arg arg = line[before_arg + 1:endidx] pattern = arg + "*" completions = [] for fpath in glob(pattern): fpath = self._append_slash_if_dir(fpath) completions.append(fpath.replace(fixed, "", 1)) return completions def default(self, line): #################################################################### """If we don't have a proper subcommand passed""" #################################################################### LOGGER.error( "Command '%s' not found, see help (?) for available commands", line) return False def do_exit(self, _): #################################################################### """Exit the application""" #################################################################### return True def do_version(self, _): #################################################################### """Print the version of PkPass""" #################################################################### print(VERSION) def do_edit(self, _): #################################################################### """Edit your configuration file, with $EDITOR""" #################################################################### try: call([environ["EDITOR"], self.args["config"]]) return False except (IOError, SystemExit): return False def do_git(self, line): #################################################################### """If your password store is git back, you can control git from here""" #################################################################### call(["git"] + line.split()) return False