jmanteau

Mon coin de toile - A piece of Web

Merge de fichiers KeepassX ou Keepass 1.x (.kdb)

Posted: Jan 28, 2012
Merge de fichiers KeepassX ou Keepass 1.x (.kdb)

J’ai eu le besoin de merger plusieurs fichiers base de données de Keepass. Si vous ne connaissez pas cet excellent gestionnaire de mot de passe allez faire un tour ici ! Son pendant Linux/Mac OS X est KeepassX compatible avec la branche 1.x de Keepass.

Ce script (rapidement fait) prend plusieurs fichiers d’export XML Keepass (Menu -> Exporter sous -> XML)

et les regroupent sous un fichier. Il prend l’entrée la plus récente en cas de conflit. Il affichera les conflits en sortie console.

La source est disponible ici pour ceux qui veulent la regarder et je l’ai également compilé ici pour ceux qui veulent faire un merge rapide.

Télécharger KeeMerge

Pour l’exécutable, le mettre dans le même dossier que les exports xml puis le lancer.

Il faut ensuite importer le merge.xml dans Keepass. Créer une nouvelle base puis Menu-> Importer -> XML Keepass 1.x.

from lxml import etree import datetime, glob class Password(object):     def init(self, node):         date= node.find(“lastmodtime”).text         self.lastmodtime= datetime.datetime.strptime(date,"%Y-%m-%dT%H:%M:%S")         self.uuid= node.find(“uuid”).text         self.username= node.find(“username”).text         self.password= node.find(“password”).text         self.title= node.find(“title”).text         self.node= node     def hash(self):         return hash(str(self.title)+str(self.lastmodtime)+str(self.uuid))     def eq(self,other):         return self.uuid==other.uuid and self.username==other.username and self.password==other.password and self.title==self.title     def str(self):         s = “%s (%s): [%s|%s] - %s” % (self.title,self.uuid,self.username,self.password,self.lastmodtime)         return s     def repr(self):         s = “%s (%s): [%s|%s] - %s” % (self.title,self.uuid,self.username,self.password,self.lastmodtime)         return s def getTree(file):     """     Give the root and tree of the XML file     """     parser = etree.XMLParser(strip_cdata=False)     tree = etree.parse(file, parser)     root= tree.getroot()     return tree ,root def getpasswords(file):     """     Parse and return all the password of an xml exported by Keepass     """     tree, root = getTree(file)     elements= []     for e in root:         elements.append(Password(e))     return elements def main():     # give me your xmls     xmls= glob.glob("*.xml")     # a dict uniq by the uuid of the node     uniquepasswords= dict()     # all your passwords are belong to us     passwords=[pwd for f in xmls for pwd in getpasswords(f)]     # let’s go marco     for pwd in passwords:         # do I know you ?         if pwd.uuid in uniquepasswords:             challenger= pwd             champion= uniquepasswords[pwd.uuid]             # If exact match, skips             if challenger != champion:                 # challenger modified recently ?                 if challenger.lastmodtime > champion.lastmodtime:                     print “####”                     print “%s” % (challenger)                     print “more recent than”                     print “%s” % (champion)                     print “Challenger wins”                     uniquepasswords[pwd.uuid]= challenger                 elif challenger.lastmodtime < champion.lastmodtime:                     print “####”                     print “%s” % (challenger)                     print “older than”                     print “%s” % (champion)                     print “Garbage”         else:             # hello you             uniquepasswords[pwd.uuid]= pwd     # Append xml nodes to root     root= etree.Element(“pwlist”)     for pwd in uniquepasswords.values():         root.append(pwd.node)     # Write to file     et = etree.ElementTree(root)     et.write(“merge.xml”, pretty_print=True, xml_declaration=True, encoding=‘utf-8’, standalone=‘yes’) if name == “main”:     main()