From a3d9bef8aa6b79ab82a0ce931ecc6c25e7c79ded Mon Sep 17 00:00:00 2001 From: Fierelier Date: Mon, 12 Aug 2024 02:43:57 +0200 Subject: [PATCH] Add kp2xml-to-prpwxml script --- kp2xml-to-prpwxml | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100755 kp2xml-to-prpwxml diff --git a/kp2xml-to-prpwxml b/kp2xml-to-prpwxml new file mode 100755 index 0000000..abd99d1 --- /dev/null +++ b/kp2xml-to-prpwxml @@ -0,0 +1,118 @@ +#!/usr/bin/env lua +basepath = (debug.getinfo(1, "S").source:sub(2):match("(.*[/\\])") or "./"):sub(1,-2) + +local function main(arg) + package.path = basepath .. "/lib/?.lua;" .. basepath .. "/lib/?/main.lua;" .. package.path + require("prpw") + local inputf = arg[1] + local outputf = arg[2] + local parseFile = require('xmllpegparser').parseFile + local kpxml = parseFile(inputf) + env.run({"create",outputf}) + env.run({"open",outputf}) + local entries = env.xmlFindTags(env.db,"entries")[1] + + local kpbinaries = env.xmlFindTags(kpxml,"KeePassFile")[1] + kpbinaries = env.xmlFindTags(kpbinaries,"Meta")[1] + kpbinaries = env.xmlFindTags(kpbinaries,"Binaries")[1] + local kpentries = env.xmlFindTags(kpxml,"KeePassFile")[1] + kpentries = env.xmlFindTags(kpentries,"Root")[1] + kpentries = env.xmlFindTags(kpentries,"Group")[1] + + local function getEntries(group) + local rtn = {} + local len = 0 + for i,entry in pairs(group.children) do + if entry.tag == "Group" then + for _,v in ipairs(getEntries(entry)) do + len = len + 1 + rtn[len] = v + end + end + + if entry.tag == "Entry" then + len = len + 1 + rtn[len] = entry + end + end + return rtn + end + + local function xmlFind(xml,tag,attr,value) + local rtn = {} + local len = 0 + + local function checkTag(xml,tag) + if tag == nil then return true end + if xml.tag == tag then return true end + return false + end + + local function checkAttrName(xml,attr) + if attr == nil then return true end + if xml.attrs[attr] ~= nil then return true end + return false + end + + local function checkAttrValue(xml,attr,value) + if value == nil then return true end + if xml.attrs[attr] == value then return true end + return false + end + + for i,v in pairs(xml.children) do + if ( + checkTag(v,tag) and + checkAttrName(v,attr) and + checkAttrValue(v,attr,value) + ) then + len = len + 1 + rtn[len] = v + end + end + + return rtn + end + + kpentries = getEntries(kpentries) + for i,kpentry in pairs(kpentries) do + local title = "unknown" + for i,kpfield in pairs(xmlFind(kpentry,"String")) do + if xmlFind(kpfield,"Key")[1].children[1].text == "Title" then + title = xmlFind(kpfield,"Value")[1].children[1].text + end + end + + local entry = env.run({"entry_add",title}) + + for i,kpfield in pairs(xmlFind(kpentry,"String")) do + local fieldName = xmlFind(kpfield,"Key")[1].children[1].text + local fieldValue = xmlFind(kpfield,"Value")[1].children[1] + if fieldValue == nil then + fieldValue = {} + fieldValue.text = "" + end + fieldValue = fieldValue.text + local protected = (kpfield.attrs.ProtectedInMemory == "True") + if fieldName == "UserName" then fieldName = "username" end + if fieldName == "Password" then fieldName = "password" end + if fieldName ~= "Title" then + env.run({"field_set",entry.attrs.id,fieldName,fieldValue}) + if protected then + env.run({"field_set_type",entry.attrs.id,fieldName,"text-secret"}) + end + end + end + + for i,kpfield in pairs(xmlFind(kpentry,"Binary")) do + local fieldName = xmlFind(kpfield,"Key")[1].children[1].text + local binaryRef = xmlFind(kpfield,"Value","Ref")[1].attrs.Ref + local fieldValue = xmlFind(kpbinaries,"Binary","ID",binaryRef)[1].children[1].text + env.run({"field_set",entry.attrs.id,fieldName,fieldValue}) + env.run({"field_set_type",entry.attrs.id,fieldName,"data"}) + end + end + env.run({"save"}) +end + +main(arg)