Beispiel #1
0
def write_entry(kdbx_file,
                kdbx_password,
                group_path,
                entry_title,
                entry_username,
                entry_password,
                entry_url,
                entry_notes,
                entry_tags,
                kdbx_keyfile=None,
                force_creation=False,
                outfile=None):
    logging.info('Attempt to write entry "{}: {}:{}" to {}'.format(
        entry_title, entry_username, entry_password, group_path))
    samba_db = False
    if kdbx_file.startswith('smb://'):
        samba_db = True
        smb_kdbx_file = smb_retrieve(kdbx_file)
    kp = PyKeePass(smb_kdbx_file if samba_db else kdbx_file,
                   password=kdbx_password,
                   keyfile=kdbx_keyfile)
    dest_group = kp.find_groups_by_path(group_path, first=True)
    kp.add_entry(destination_group=dest_group,
                 title=entry_title,
                 username=entry_username,
                 password=entry_password,
                 url=entry_url,
                 notes=entry_notes,
                 tags=entry_tags,
                 force_creation=force_creation)

    if outfile:
        if outfile.startswith('smb://'):
            file_written = kp.save()
            smb_send(file_written.name, outfile)
            logging.info('Sent database file to {}'.format(outfile))
        else:
            file_written = kp.save(kdbx_file)
            logging.info('KeePass DB written to {}'.format(file_written.name))
    else:
        if samba_db:
            file_written = kp.save()
            smb_send(file_written.name, kdbx_file)
            logging.info('Sent database file to {}'.format(kdbx_file))
        else:
            file_written = kp.save(kdbx_file)
            logging.info('KeePass DB written to {}'.format(file_written.name))
Beispiel #2
0
class GroupFunctionTests(unittest.TestCase):

    # get some things ready before testing
    def setUp(self):
        self.kp = PyKeePass(os.path.join(base_dir, 'test.kdbx'),
                            password='******',
                            keyfile=os.path.join(base_dir, 'test.key'))

    #---------- Finding groups -----------

    def test_find_groups_by_name(self):
        results = self.kp.find_groups_by_name('subgroup')
        self.assertEqual(len(results), 1)
        results = self.kp.find_groups_by_name('subgroup', first=True)
        self.assertEqual(results.name, 'subgroup')
        g = self.kp.find_groups(name='foobar_group', first=True)
        results = self.kp.find_groups(group=g, name='.*group.*', regex=True)
        self.assertEqual(len(results), 2)
        results = self.kp.find_groups(group=g,
                                      name='.*group.*',
                                      regex=True,
                                      recursive=False)
        self.assertEqual(len(results), 1)

    def test_find_groups_by_path(self):
        results = self.kp.find_groups_by_path('/foobar_group/subgroup/')
        self.assertIsInstance(results[0], Group)
        results = self.kp.find_groups_by_path('/foobar_group/subgroup/',
                                              first=True)
        self.assertEqual(results.name, 'subgroup')

    def test_find_groups_by_uuid(self):
        results = self.kp.find_groups_by_uuid('lRVaMlMXoQ/U5NDCAwJktg==',
                                              first=True)
        self.assertIsInstance(results, Group)
        results = self.kp.find_groups(uuid='^lRVaMlMX|^kwTZdSoU', regex=True)
        self.assertEqual(len(results), 2)

    def test_find_groups_by_notes(self):
        results = self.kp.find_groups(notes='group notes')
        self.assertEqual(len(results), 1)
        self.assertEqual(results[0].uuid, 'lRVaMlMXoQ/U5NDCAwJktg==')

    def test_find_groups(self):
        results = self.kp.find_groups(path='/foobar_group/subgroup/')
        self.assertIsInstance(results[0], Group)
        results = self.kp.find_groups_by_path('/foobar_group/subgroup/',
                                              first=True)
        self.assertEqual(results.name, 'subgroup')

    def test_groups(self):
        results = self.kp.groups

        self.assertEqual(len(results), 6)

    #---------- Adding/Deleting Groups -----------

    def test_add_delete_move_group(self):
        notes_text = "this is a note for a group!"
        base_group = self.kp.add_group(self.kp.root_group,
                                       'base_group',
                                       notes=notes_text)
        sub_group = self.kp.add_group(base_group, 'sub_group')
        sub_group2 = self.kp.add_group(base_group, 'sub_group2')

        self.assertEqual(base_group.notes, notes_text)
        base_group.notes = ''
        self.assertEqual(base_group.notes, '')

        results = self.kp.find_groups_by_path('base_group/sub_group/',
                                              first=True)
        self.assertIsInstance(results, Group)
        self.assertEqual(results.name, sub_group.name)

        self.kp.move_group(sub_group2, sub_group)
        results = self.kp.find_groups(path='base_group/sub_group/sub_group2/',
                                      first=True)
        self.assertEqual(results.name, sub_group2.name)

        self.kp.delete_group(sub_group)
        results = self.kp.find_groups_by_path('base_group/sub_group/',
                                              first=True)
        self.assertIsNone(results)

        # ---------- Groups representation -----------

    def test_print_groups(self):
        self.assertIsInstance(self.kp.groups.__repr__(), str)
Beispiel #3
0
class KeepassLoader:

    kp = NotImplemented
    database_path = ""
    password_try = ""
    password_check = ""
    password = ""
    group_list = []

    def __init__(self, database_path, password):
        self.kp = PyKeePass(database_path, password)
        self.database_path = database_path

    def add_group(self, name, icon, note, parent_group):
        group = Group(name, icon, note, parent_group)
        self.kp.add_group(group.get_parent_group(), group.get_name())
        self.group_list.append(group)

    def add_entry(self, group_path, entry_name, username, password, url, notes,
                  icon):
        entry = Entry(group_path, entry_name, username, password, url, notes,
                      icon)
        self.kp.add_entry(self.kp.find_groups_by_path(entry.get_group_path()),
                          entry.get_entry_name(),
                          entry.get_username(),
                          entry.get_password(),
                          url=entry.get_url(),
                          notes=entry.get_notes(),
                          icon=entry.get_icon())

    def get_entries(self, group_path):
        group = self.kp.find_groups_by_path(group_path, first=True)
        #group = self.kp.find_groups(name="Untergruppe", first=True)
        print(group)
        print(group.entries)
        entry_list = []
        for entry in group.entries:
            entry_list.append(
                Entry(group, entry.title, entry.username, entry.password,
                      entry.url, entry.notes, entry.icon))
        return entry_list

    def get_groups(self):
        group_list = []
        groups = self.kp.groups
        for group in groups:
            if group.path != "/":
                group_list.append(
                    Group(group.name,
                          group.path,
                          icon=group.icon,
                          notes="",
                          parent_group=group.parent_group))
        return group_list

    #we wanted to turn off the automatic saving after each action and connect it instead to a button
    def save(self):
        self.kp.save()

    #this method sets the initial password for the newly created database
    def set_database_password(self, new_password):
        self.kp.set_credentials(new_password)
        self.save()

    #this method changes the password of existing database (therefore the old password must be typed in to prevent others changing your password)
    def change_database_password(self, old_password, new_password):
        if self.password == old_password:
            self.kp.set_credentials(new_password)
            self.save()

    #
    # Return the database filesystem path
    #

    def get_database(self):
        print(self.database_path)
        return self.database_path

    #
    # Return the root group of the database instance
    #

    def get_root_group(self):
        return self.kp.root_group

    #
    # Set the first password entered by the user (for comparing reasons)
    #

    def set_password_try(self, password):
        self.password_try = password

    #
    # Set the second password entered by the user (for comparing reasons)
    #

    def set_password_check(self, password):
        self.password_check = password

    #
    # Compare the first password entered by the user with the second one
    #

    def compare_passwords(self):
        if self.password_try == self.password_check:
            if self.password_try == "" and self.password_check == "":
                return False
            else:
                return True
        else:
            return False
Beispiel #4
0
class KeeFinder(object):
    def __init__(self, db_path, db_pass, verbosity):
        self.db = PyKeePass(db_path, db_pass)
        self.verbosity = verbosity
        self.found_entries = list()

    def find(self, strings):
        if not isinstance(strings, list):
            raise TypeError("Passed value has to be list type")
        self.found_entries = self._find_entries(strings[-1])
        if not self.found_entries:
            return
        if len(strings) > 1:
            self.found_entries = self._find_in_entries(self.found_entries,
                                                       strings[:-1])

    def print_found(self):
        if not self.found_entries:
            print('Nothing found')
            return
        for entr in self.found_entries:
            self._print_entry(entr, self.verbosity)

    def _find_entries(self, substring, glob=True):
        search_string = substring.lower()
        res = list()
        if glob:
            search_string = '.*%s.*' % search_string
        method_names = ['title', 'username', 'url', 'password', 'path']
        for method_name in method_names:
            method = getattr(self.db, 'find_entries_by_%s' % method_name)
            results = method(search_string, regex=True, flags='i')
            for result in results:
                if result not in res:
                    res.append(result)

        root_group = self.db.find_groups_by_path('/')
        res_groups = list()
        # Now any group in res_groups will have a substring in path
        self._find_groups(substring, root_group, res_groups)
        for grp in res_groups:
            # As group has substring in path, it means any entry in this group
            # will have this substring in path too. There is no other way to do
            # this, sorry
            group_entries = self.db.find_entries_by_title('.*',
                                                          regex=True,
                                                          group=grp)
            for entr in group_entries:
                if entr not in res:
                    res.append(entr)
        return res

    def _find_in_entries(self, entries, entry_names):
        survivors = entries.copy()
        while entry_names:
            entry_name = entry_names.pop()
            for index, entr in enumerate(entries):
                if not self._find_in_entry(entry_name, entr):
                    survivors.remove(entr)
            survivors = self._find_in_entries(survivors, entry_names)
        return survivors

    def _find_in_entry(self, substring, entr):
        substring = substring.lower()
        if isinstance(entr, entry.Entry):
            subentries = [
                entr.group.path, entr.title, entr.username, entr.password,
                entr.url
            ]
        elif isinstance(entr, group.Group):
            subentries = [entr.path]
        for subentry in subentries:
            if subentry and (substring in subentry.lower()):
                return True
        return False

    def _find_groups(self, name, root_groups, result=[]):
        for grp in root_groups:
            if name.lower() in grp.path.lower():
                result.append(grp)
            subgroups = grp.subgroups
            self._find_groups(name, subgroups, result)

    def _print_entry(self, entr, verbosity):
        info = dict()

        def _get_fields(count):
            _info = dict()
            fields = ('group', 'username', 'password', 'title', 'url')
            if count == 2:
                fields = fields[:3]
            for field in fields:
                if field == 'group':
                    _info[field] = entr.group.path
                else:
                    _info[field] = getattr(entr, field)
            return _info

        if not verbosity:
            print(entr.password)
        elif verbosity == 1:
            print("%s - %s" % (entr.group.path, entr.username),
                  file=sys.stderr)
            print(entr.password, end="")
            sys.stdout.flush()
            print("", file=sys.stderr)
        else:
            info = _get_fields(verbosity)

        if info:
            pprint.pprint(info)
            print()