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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 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() |
