Example #1
0
 def __init__(self):
     self.storage = Storage()
     self.config = Config()
     self.salt = self.config.get('option', 'salt')
     self.storage.load()
     self.database = self.storage.database
     self.password_type = PasswordType()
Example #2
0
 def __init__(self):
     self.config = Config()
     self.daemon = StaticDaemon()
Example #3
0
class Client:
    def __init__(self):
        self.config = Config()
        self.daemon = StaticDaemon()

    def color_print(self, input_color, mes):
        if input_color == 'r':
            fore = 31
        elif input_color == 'g':
            fore = 32
        elif input_color == 'b':
            fore = 36
        elif input_color == 'y':
            fore = 33
        else:
            fore = 37
        input_color = "\x1B[%d;%dm" % (1, fore)
        return "%s%s\x1B[0m" % (input_color, mes)

    def color_keyword(self, value, keyword=""):
        split = re.split(keyword, value)
        result = ""
        for i in range(0, len(split) - 1):
            result += split[i]
            result += self.color_print('r', keyword)
        result += split[len(split) - 1]
        return result

    def add_space(self, value, length=0):
        value += " " * length
        return value

    def to_text(self, table, origin_table):
        line_number = len(origin_table)
        if line_number <= 1:
            return
        column_number = len(origin_table[0])
        column_width = [0 for i in range(0, column_number)]
        for line in origin_table:
            for i in range(0, column_number):
                if column_width[i] < len(str(line[i])):
                    column_width[i] = len(str(line[i]))
        for i in range(0, line_number):
            for j in range(0, column_number):
                print(self.add_space(str(table[i][j]), column_width[j] - len(str(origin_table[i][j]))) + "\t", end="")
            print("\n", end="")

    def print_password(self, passwords, keyword="", show_key=True):
        table = []
        origin_table = []
        if show_key:
            table.append(["Id", "Mark", "Password", "Version", "Intro", "URL"])
            origin_table.append(["Id", "Mark", "Password", "Version", "Intro", "URL"])
            for password in passwords:
                table.append(
                    [password[0].id, self.color_keyword(password[0].mark, keyword), password[1], password[0].version,
                     self.color_keyword(password[0].intro, keyword), self.color_keyword(password[0].url, keyword)])
                origin_table.append(
                    [password[0].id, password[0].mark, password[1], password[0].version, password[0].intro,
                     password[0].url])
        else:
            table.append(["Id", "Mark", "Version", "Intro", "URL"])
            origin_table.append(["Id", "Mark", "Version", "Intro", "URL"])
            for password in passwords:
                table.append([password[0].id, self.color_keyword(password[0].mark, keyword), password[0].version,
                              self.color_keyword(password[0].intro, keyword),
                              self.color_keyword(password[0].url, keyword)])
                origin_table.append(
                    [password[0].id, password[0].mark, password[0].version, password[0].intro, password[0].url])
        self.to_text(table, origin_table)

    def do(self, args):
        if args.operate == "add" or args.operate == "a":
            password = Password()
            password.mark = str(args.mark)
            if args.url:
                password.url = str(args.url)
            if args.intro:
                password.intro = str(args.intro)
            if args.release:
                password.version = int(args.release)
            if args.length:
                password.length = int(args.length)
            if args.type:
                password.type = args.type
            if args.no_password or self.config.get("option", "add_without_mpw") == "1":
                self.daemon.add(password)
                return
            master_password = getpass.getpass("Please input your master password:"******"option", "mpw_check") == "1":
                if self.daemon.check_master_password(master_password) != 1:
                    print("Master Password Error. Please check or set your master password.")
                    return
            pw_id = self.daemon.add(password)
            result = self.daemon.get(master_password, [pw_id])
            self.print_password(result)
            return
        if args.operate == "del" or args.operate == "d":
            self.daemon.remove(args.id)
            return
        if args.operate == "ls" or args.operate == "l":
            if not args.mark:
                keyword = ""
            else:
                keyword = args.mark
            passwords = self.daemon.search(keyword)
            passwords = self.daemon.get("", [value.id for value in passwords])
            self.print_password(passwords, keyword, False)
            return
        if args.operate == "get" or args.operate == "g":
            master_password = getpass.getpass("Please input your master password:"******"option", "mpw_check") == "1":
                if self.daemon.check_master_password(master_password) != 1:
                    print("Master Password Error. Please check or set your master password.")
                    return
            if not args.mark:
                keyword = ""
            else:
                keyword = args.mark
            passwords = self.daemon.search(keyword)
            passwords = self.daemon.get(master_password, [value.id for value in passwords])
            self.print_password(passwords, keyword, True)
            return
        if not args.operate:
            if args.set_master_password:
                master_password = getpass.getpass("Please input your master password:"******"Please retype your master password:"******"Password didn't match. Please try again.")
                    return
                self.daemon.generate_master_password_check(master_password)
            return
Example #4
0
class StaticDaemon(Singleton):
    def __init__(self):
        self.storage = Storage()
        self.config = Config()
        self.salt = self.config.get('option', 'salt')
        self.storage.load()
        self.database = self.storage.database
        self.password_type = PasswordType()

    def search(self, keyword=""):
        result = []
        if keyword == "":
            for pid, password in self.database['passwords'].items():
                if password.available and not password.special:
                    result.append(password)
            return result
        for pid, password in self.database['passwords'].items():
            if (re.search(keyword, password.mark) or re.search(keyword, password.intro)) \
                    and password.available and not password.special:
                result.append(password)
        return result

    def add(self, password):
        self.storage.lock.acquire()
        result = self.search(password.mark)
        version = 0
        for ele in result:
            if version < ele.version:
                version = ele.version
        version += 1
        password.version = version
        password.sync_code = "A"
        self.database['passwords_num'] += 1
        password.id = self.database['passwords_num']
        if password.length < 8 or password.length > 32:
            raise PasswordError("Password length illegal", "Password length should between 8 and 32.", password)
        self.database['passwords'][str(password.id)] = password
        self.storage.lock.release()
        self.storage.save()
        return password.id

    def remove(self, password_id):
        self.storage.lock.acquire()
        if str(password_id) in self.database['passwords'].keys():
            self.database['passwords'][str(password_id)].available = False
            self.database['passwords'][str(password_id)].sync_code = "M"
        self.storage.save()

    def get(self, master_password, passwords_id):
        result = {}
        for pid in passwords_id:
            if str(pid) in self.database['passwords'].keys():
                password = self.database['passwords'][str(pid)]
                if password.special or not password.available:
                    continue
                key = self.calculate_key(master_password, password)
                result[password] = key

        def compare(x, y):
            x = x[0]
            y = y[0]
            if x.mark > y.mark:
                return 1
            if x.mark < y.mark:
                return -1
            if x.version > y.version:
                return 1
            if x.version < y.version:
                return -1
            return 0

        return sorted(result.items(), key=cmp_to_key(compare))

    def modify(self, master_password, password):
        self.storage.lock.acquire()
        password.sync_code = "M"
        if password.length < 4 or password.length > 32:
            raise PasswordError("Password length illegal", "Password length should between 4 and 32.", password)
        self.database['passwords'][str(password.id)].append(password)
        self.storage.lock.release()
        self.storage.save()

    def calculate_key(self, master_password, password):
        result = master_password + password.mark + str(password.version) + self.salt
        result = hashlib.sha512(
            (hashlib.sha512(result.encode('utf-8')).hexdigest() + "ImoutoPassword").encode("utf-8")).hexdigest()
        result = self.password_type.change(result, password.type, password.length)
        return result

    def check_master_password(self, master_password):
        check = None
        for id, password in self.database['passwords'].items():
            if password.special and password.mark == "MasterPasswordCheck":
                check = password
                break
        if not check:
            return -1
        if check.intro == self.calculate_key(master_password, check):
            return 1
        else:
            return 0

    def generate_master_password_check(self, master_password):
        self.storage.lock.acquire()
        pid = 0
        password = Password()
        if self.check_master_password(master_password) != -1:
            for key,item in self.database['passwords'].items():
                if item.special and item.mark == "MasterPasswordCheck":
                    pid = item.id
                    password.sync_code = "M"
                    break
        else:
            self.database['passwords_num'] += 1
            pid = self.database['passwords_num']
            password.sync_code = "A"
        password.id = pid
        password.special = True
        password.mark = "MasterPasswordCheck"
        password.intro = self.calculate_key(master_password, password)
        self.database['passwords'][str(pid)] = password
        self.storage.save()
        self.storage.lock.release()