#!/usr/bin/python3 # -*- coding: utf-8 -*- # # script to manipulate password file # # Copyright (C) 2017 AleaJactaEst # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import bcrypt import argparse import sys import os import getpass __VERSION__ = '1.0' class PasswordFile: def __init__(self, passwordfile, createfile, password_comand_line, username, password): self.passwordfile = passwordfile self.users = {} if not password_comand_line: if password is not None: raise Exception("password in command line (but option disable to read this password).") else: self.password = None elif password is None: raise Exception("Missing password.") else: self.password = password self.username = username if not os.path.exists(self.passwordfile): if createfile: with open(self.passwordfile, 'wt', encoding='utf-8') as fp: fp.write('\n') else: raise Exception("%s does not exist." % self.passwordfile) else: self.__load__() def __load__(self): with open(self.passwordfile, 'rt') as fp: for line in fp: line = line.strip() if not line: continue username, password = line.split(':', maxsplit=1) self.users.setdefault(username, password) def save(self): with open(self.passwordfile, 'wt', encoding='utf-8') as fp: for user in sorted(self.users): fp.write('%s:%s\n' % (user, self.users[user])) def update(self): if self.password is None: self.password = getpass.getpass('New password:') check = getpass.getpass('Re-type new password:') if self.password != check: raise Exception("password verification error") hashed_password = bcrypt.hashpw(self.password.encode('utf-8'), bcrypt.gensalt()).decode('utf8') self.users[self.username] = hashed_password print("Adding password for user %s" % self.username) def verify(self): if self.password is None: self.password = getpass.getpass('Enter password:') if bcrypt.checkpw(self.password.encode('utf-8'), self.users[self.username].encode('utf-8')): print("Password for user %s correct." % self.username) else: raise Exception("password verification failed.") def delete(self): if self.username in self.users: del self.users[self.username] def root(passwordfile, create, password_comand_line, username, password, delete, verify): pf = PasswordFile(passwordfile, create, password_comand_line, username, password) if delete: pf.delete() pf.save() elif verify: pf.verify() else: pf.update() pf.save() def main(args=sys.argv[1:]): """ Main function :param list args: root password """ parser = argparse.ArgumentParser(description='password manager') parser.add_argument('--version', action='version', version='%(prog)s ' + __VERSION__) parser.add_argument('-c', '--create', action='store_true', help='create a new file', default=False) parser.add_argument('-D', '--delete', action='store_true', help='delete username', default=False) parser.add_argument('-v', '--verify', action='store_true', help='Verify password for the specified user.', default=False) parser.add_argument('-b', '--password-comand-line', action='store_true', help='Use the password from the command line rather than prompting for it.', default=False) parser.add_argument('passwordfile', type=str, help='file contains all password') parser.add_argument('username', type=str) parser.add_argument('password', type=str, nargs='?') param = parser.parse_args(args) root(param.passwordfile, param.create, param.password_comand_line, param.username, param.password, param.delete, param.verify) if __name__ == '__main__': main()