#!/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") env.cli = false 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)