def export_keepass(creds, password): db = Database() groups = {} for c in creds: # Create the group if we havent yet if c.group.name not in groups.keys(): groups[c.group.name] = db.create_group(title=c.group.name) kpg = groups[c.group.name] # Add tags list to the end of the description tags = '\n\nTags: ' for t in c.tags.all(): tags += '[' tags += t.name tags += '] ' desc = str(c.description) + tags # Create the entry kpg.create_entry( title=c.title, username=c.username, password=c.password, url=c.url, notes=desc, ) # Send the response response = HttpResponse(mimetype='application/x-keepass') db.save(response, password=password) response['Content-Disposition'] = 'attachment; filename=RatticExport.kdb' response['Content-Length'] = response.tell() return response
def export_keepass(creds, password): db = Database() groups = {} for c in creds: # Create the group if we havent yet if c.group.name not in groups.keys(): groups[c.group.name] = db.create_group(title=c.group.name) kpg = groups[c.group.name] # Add tags list to the end of the description tags = "\n\nTags: " for t in c.tags.all(): tags += "[" tags += t.name tags += "] " desc = unicode(c.description) + tags # Create the entry e = kpg.create_entry(title=c.title, username=c.username, password=c.password, url=c.url, notes=desc) if c.attachment: e.binary_desc = c.attachment_name e.binary = c.attachment.read() # Send the response response = HttpResponse(content_type="application/x-keepass") db.save(response, password=password) response["Content-Disposition"] = "attachment; filename=RatticExport.kdb" response["Content-Length"] = response.tell() return response
def test_init_new(self): """ Test initializing new database. """ db = Database() db.create_default_group() exp_g = model.Group(title="Internet", icon=1, level=0, id=1, db=db, parent=db.root) self.assertEquals(1, len(db.groups)) self.assertEquals(exp_g.__dict__, db.groups[0].__dict__) self.assertEquals([], db.groups[0].entries)
def test_load_file(self): """ Test loading from file path. """ db = Database() kdb = os.path.join(RESOURCES_DIR, 'example.kdb') with self.assertRaisesRegexp(ValueError, r'Password and/or keyfile is required.'): db.load(kdb) db.load(kdb, password='******') self.assertEquals(kdb, db.filepath)
def test_load_stream(self): """ Test loading from stream. """ db = Database() kdb = os.path.join(RESOURCES_DIR, 'example.kdb') with open(kdb, 'rb') as fp: stream = BytesIO(fp.read()) stream.seek(0) with self.assertRaisesRegexp(ValueError, r'Password and/or keyfile is required.'): db.load(stream) stream.seek(0) db.load(stream, password='******')
def test_load(self): """ Test loading database """ db = Database() kdb = os.path.join(RESOURCES_DIR, 'example.kdb') db.load(kdb, password='******') #print(db.groups) # Make assertions about the structure. top_groups = [g.title for g in db.root.children] self.assertEquals(['Internet', 'eMail', 'Backup'], top_groups) self.assertEquals(['A1', 'B1', 'C1'], [g.title for g in db.root.children[0].children]) self.assertEquals(set(['AEntry1', 'AEntry2', 'AEntry3']), set([e.title for e in db.root.children[0].children[0].entries])) self.assertEquals(['A2'], [g.title for g in db.root.children[0].children[0].children])
def test_cred_export(self): # Grab the file data = { 'password': '******', } resp = self.data.norm.post(reverse('cred.views.download'), data) # Check for the right headers self.assertEqual(resp.status_code, 200) self.assertEqual(resp['content-type'], 'application/x-keepass') self.assertRegexpMatches(resp['content-disposition'], 'attachment; filename=\w+\.\w+') # Check the DB we got keepassdb = StringIO(resp.content) db = Database(keepassdb, 'testpass') testcred = filter(lambda x: x.title == 'secret', db.entries)[0] self.assertEqual(testcred.username, 'peh!') self.assertEqual(testcred.password, 's3cr3t') # Check the audit log CredAudit.objects.get( cred=self.data.cred.id, user=self.data.unorm.id, audittype=CredAudit.CREDEXPORT, )
def run(self, host): """Load variables from a keepass database.""" password = environ.get('KEEPASS_PASSWORD') if password is None: password = utils.getpass.getpass('Enter your keepass password: '******'KEEPASS_DIR', path.join(basedir, 'secret_vars')) kpdb = environ.get('KEEPASS_DB', DEFAULT_DB) filename = path.join(kpdir, '%s.kdb' % kpdb) try: keepassdb = Database(filename, password=password) except Exception as e: args = filename, e.message raise errors.AnsibleError('Unable to open %s ("%s")' % args) results = dict() for group in keepassdb.groups: if group.title != 'ansible': continue for entry in group.entries: results['%s_url' % entry.title] = entry.url results['%s_username' % entry.title] = entry.username results['%s_password' % entry.title] = entry.password results['%s_comment' % entry.title] = entry.notes # Decode the key=value pairs found in the notes. lines = entry.notes.split('\n') if len(lines) == len(list(l for l in lines if '=' in l)): for line in lines: key, value = map(unicode.strip, line.split('=', 1)) results['_'.join([entry.title, key])] = value return results
def test_load(self): """ Test loading database """ db = Database() kdb = os.path.join(RESOURCES_DIR, 'example.kdb') db.load(kdb, password='******') #print(db.groups) # Make assertions about the structure. top_groups = [g.title for g in db.root.children] self.assertEquals(['Internet', 'eMail', 'Backup'], top_groups) self.assertEquals(['A1', 'B1', 'C1'], [g.title for g in db.root.children[0].children]) self.assertEquals( set(['AEntry1', 'AEntry2', 'AEntry3']), set([e.title for e in db.root.children[0].children[0].entries])) self.assertEquals( ['A2'], [g.title for g in db.root.children[0].children[0].children])
def keepass(filep, password): groups = [] entries = [] groupstack = [] db = Database(filep, password) _walkkeepass(groups, entries, groupstack, db.root) return {'tags': groups, 'entries': entries}
class DB: def __init__(self, db_filename, passwd): self.logger = logging.getLogger('keepass_merge') self.db = Database(db_filename, passwd) self.backup = self.db.groups[-1] self.uuids = [x.uuid for x in self.db.entries] self.groups = [x.id for x in self.db.groups] def get_group(self, group_id): return [x for x in self.db.groups if x.id == group_id][0] def get_entry(self, uuid): return [x for x in self.db.entries if x.uuid == uuid][0] def merge_entry(self, other): """ Assumes the same title and group. """ self_entry = self.get_entry(other.uuid) if self_entry.modified < other.modified: self.logger.debug('update %s', other.title) other_spec = make_new_entry_spec(other) self.db.create_entry(self_entry.group, **other_spec) self.db.move_entry(self_entry, self.backup) elif self_entry.modified == other.modified: self.logger.debug('same %s', other.title) else: self.logger.debug('just backup %s', other.title) copy_spec = make_new_entry_spec(other) self.db.create_entry(self.backup, **copy_spec) def update(self, other): for entry in other.db.entries: if entry.uuid not in self.uuids: if entry.group_id == self.backup.id: continue if entry.group_id in self.groups: group = self.get_group(entry.group_id) else: self.logger.debug('make group %s', entry.group.title) group = self.db.create_group(title=entry.group.title, icon=entry.group.icon) self.db.create_entry(group, **make_new_entry_spec(entry)) else: self.merge_entry(entry) def __getattr__(self, attr): return getattr(self.db, attr)
def export_keepass(creds, password, filename='RatticExport.kdb'): db = Database() groups = {} for c in creds: # Create the group if we havent yet if c.group.name not in groups.keys(): groups[c.group.name] = db.create_group(title=c.group.name) kpg = groups[c.group.name] # Add tags list to the end of the description tags = '\n\nTags: ' for t in c.tags.all(): tags += '[' tags += t.name tags += '] ' desc = unicode(c.description) + tags # Create the entry e = kpg.create_entry( title=c.title, username=c.username, password=c.password, url=c.url, notes=desc, ) if c.attachment: e.binary_desc = c.attachment_name e.binary = c.attachment.read() # Send the response response = HttpResponse(content_type='application/x-keepass') db.save(response, password=password) response['Content-Disposition'] = 'attachment; filename=' + filename response['Content-Length'] = response.tell() return response
def test_export(self): """ Really basic XML-export smoke test. """ # This is a pretty half-hearted smoke test currently. db = Database(os.path.join(RESOURCES_DIR, 'example.kdb'), password='******') exporter = XmlExporter() output = exporter.export(db) tree = ET.fromstring(output) entries = tree.findall('.//entry') s1 = set([e.find('./title').text.strip() for e in entries]) s2 = set([e.title for e in db.entries if e.title != 'Meta-Info']) self.assertEquals(s2, s1)
def test_move_within_group(self): """ Test moving an entry within the same group. """ db = Database(os.path.join(RESOURCES_DIR, 'example.kdb'), password='******') new_parent = self.get_group_by_name(db, 'A1') entry = self.get_entry_by_name(db, 'AEntry2') self.assertEquals(["AEntry2", "AEntry1", "AEntry3"], [e.title for e in new_parent.entries]) entry.move(entry.group, 1) self.assertEquals(["AEntry1", "AEntry2", "AEntry3"], [e.title for e in new_parent.entries])
def test_move_index(self): """ Test moving group to another location in same parent. """ db = Database(os.path.join(RESOURCES_DIR, 'example.kdb'), password='******') i_g = db.root.children[0] self.assertEquals(['A1', 'B1', 'C1'], [g.title for g in i_g.children]) group = self.get_group_by_name(db, 'C1') orig_parent = group.parent group.move(orig_parent, 0) self.assertIs(orig_parent, group.parent) i_g = db.root.children[0] # Internet self.assertEquals(['C1', 'A1', 'B1'], [g.title for g in i_g.children])
def test_move(self): """ Test moving group to another level. """ db = Database(os.path.join(RESOURCES_DIR, 'example.kdb'), password='******') group = self.get_group_by_name(db, 'B1') new_parent = self.get_group_by_name(db, 'A1') print(new_parent) group.move(new_parent) print("After move: " + repr(group.parent)) self.assertEquals(new_parent, group.parent) a1 = db.root.children[0].children[0] # Internet A1 self.assertEquals(['A2', 'B1'], [g.title for g in a1.children])
def test_load_stream(self): """ Test loading from stream. """ db = Database() kdb = os.path.join(RESOURCES_DIR, 'example.kdb') with open(kdb, 'rb') as fp: stream = BytesIO(fp.read()) stream.seek(0) with self.assertRaisesRegexp( ValueError, r'Password and/or keyfile is required.'): db.load(stream) stream.seek(0) db.load(stream, password='******')
def test_move_index(self): """ Test moving an entry to a new group with index. """ db = Database(os.path.join(RESOURCES_DIR, 'example.kdb'), password='******') new_parent = self.get_group_by_name(db, "A1") entry = self.get_entry_by_name(db, "B1Entry1") orig_parent = entry.group self.assertEquals("B1", orig_parent.title) self.assertEquals(["AEntry2", "AEntry1", "AEntry3"], [e.title for e in new_parent.entries]) entry.move(new_parent, 0) self.assertIs(new_parent, entry.group) self.assertEquals(["B1Entry1", "AEntry2", "AEntry1", "AEntry3"], [e.title for e in new_parent.entries])
def test_init_missing_fil(self): """ Test initialization w/ invalid file. """ with self.assertRaises(IOError): db = Database('./missing-path.kdb')
def __init__(self, db_filename, passwd): self.logger = logging.getLogger('keepass_merge') self.db = Database(db_filename, passwd) self.backup = self.db.groups[-1] self.uuids = [x.uuid for x in self.db.entries] self.groups = [x.id for x in self.db.groups]
""" A simple example showing iterating over the tree. """ from keepassdb import Database def print_group(group, level=0): print(" " * level) + group.title for entry in group.entries: print(" " * level) + " -" + entry.title for child in group.children: print_group(child, level + 1) if __name__ == '__main__': db = Database('./example.kdb', password='******') print_group(db.root)
def test_save(self): """ Test creating and saving a database. """ db = Database() i_group = db.create_default_group() e_group = db.create_group(title="eMail") e1 = i_group.create_entry(title="FirstEntry", username="******", password="******", url="http://example.com") e2 = i_group.create_entry(title="SecondEntry", username="******", password="******", url="http://example.com") e3 = e_group.create_entry(title="ThirdEntry", username="******", password="******", url="http://example.com") ser = db.to_dict(hierarchy=True, hide_passwords=True) with self.assertRaisesRegexp(ValueError, r"Unable to save without target file."): db.save(password='******') stream = BytesIO() db.save(dbfile=stream, password='******') stream.seek(0) with self.assertRaises(exc.AuthenticationError): db.load(dbfile=stream, password='******') stream.seek(0) db.load(dbfile=stream, password='******') self.maxDiff = None self.assertEquals(ser, db.to_dict(hierarchy=True, hide_passwords=True))