prpw/kp2xml-to-prpwxml

120 lines
3.3 KiB
Plaintext
Raw Normal View History

2024-08-12 00:43:57 +00:00
#!/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")
2024-08-20 11:58:29 +00:00
env.cli = false
2024-08-12 00:43:57 +00:00
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)