184 lines
5.4 KiB
Python
Executable File
184 lines
5.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import datetime
|
|
import shutil
|
|
import json
|
|
|
|
from pykeepass import PyKeePass
|
|
from urllib.parse import urlparse
|
|
|
|
shutil.copyfile("in.kdbx", "out.kdbx")
|
|
|
|
kp = PyKeePass("out.kdbx", password="test")
|
|
|
|
groupLabels = {
|
|
"passwords.Password": "Passwords",
|
|
"webforms.WebForm": "Logins",
|
|
"wallet.membership.Membership": "Memberships",
|
|
"securenotes.SecureNote": "Notes",
|
|
"wallet.government.Passport": "Passports",
|
|
"wallet.computer.UnixServer": "Servers",
|
|
"wallet.computer.Router": "Routers",
|
|
"wallet.financial.BankAccountUS": "Bank Accounts",
|
|
"wallet.financial.CreditCard": "Credit Cards",
|
|
"wallet.computer.License": "Licenses",
|
|
}
|
|
groups = {}
|
|
|
|
def getGroup(item):
|
|
group = groups.get(item["typeName"])
|
|
if group:
|
|
return group
|
|
|
|
label = groupLabels.get(item["typeName"])
|
|
if not label:
|
|
raise Exception("Unknown type name {}".format(item["typeName"]))
|
|
|
|
group = kp.add_group(kp.root_group, label)
|
|
groups[item["typeName"]] = group
|
|
return group
|
|
|
|
def getField(item, designation):
|
|
secure = item["secureContents"]
|
|
if "fields" in secure:
|
|
for field in secure["fields"]:
|
|
d = field.get("designation")
|
|
if d == designation:
|
|
return field["value"]
|
|
|
|
return None
|
|
|
|
|
|
with open("in.1pif/data.1pif", "r") as fp:
|
|
data = fp.read().strip().split("***5642bee8-a5ff-11dc-8314-0800200c9a66***")
|
|
|
|
for line in data:
|
|
if line.strip() == "":
|
|
continue
|
|
|
|
item = json.loads(line.strip())
|
|
if item.get("trashed"):
|
|
continue
|
|
|
|
group = getGroup(item)
|
|
|
|
entry = kp.add_entry(group, item["title"], "", "")
|
|
secure = item["secureContents"]
|
|
|
|
# Username
|
|
if "username" in secure:
|
|
entry.username = secure["username"]
|
|
else:
|
|
entry.username = getField(item, "username")
|
|
|
|
# Password
|
|
if "password" in secure:
|
|
entry.password = secure["password"]
|
|
else:
|
|
entry.password = getField(item, "password")
|
|
|
|
# Other web fields
|
|
if "fields" in secure:
|
|
for field in secure["fields"]:
|
|
d = field.get("designation")
|
|
if d != "username" and d != "password":
|
|
entry.set_custom_property("Web field: {}".format(field["name"]), field["value"])
|
|
|
|
# Password history
|
|
if "passwordHistory" in secure:
|
|
for p in secure["passwordHistory"]:
|
|
d = datetime.datetime.fromtimestamp(p["time"])
|
|
entry.set_custom_property("Password history ({})".format(d), p["value"])
|
|
|
|
# Find URL in fields
|
|
if not entry.url:
|
|
if "htmlAction" in secure:
|
|
entry.url = secure["htmlAction"]
|
|
|
|
# Membership fields
|
|
if "membership_no" in secure and not entry.username:
|
|
entry.username = secure["membership_no"]
|
|
|
|
# Passport fields
|
|
if "number" in secure and not entry.username:
|
|
entry.username = secure["number"]
|
|
|
|
# Router fields
|
|
if "network_name" in secure and not entry.username:
|
|
entry.username = secure["network_name"]
|
|
if "wireless_password" in secure and not entry.password:
|
|
entry.password = secure["wireless_password"]
|
|
|
|
# Bank account
|
|
if "iban" in secure and not entry.username:
|
|
entry.username = secure["iban"]
|
|
if "swift" in secure and not entry.username:
|
|
entry.username = secure["swift"]
|
|
if "routingNo" in secure and not entry.username:
|
|
entry.username = secure["routingNo"]
|
|
if "accountNo" in secure and not entry.username:
|
|
entry.username = secure["accountNo"]
|
|
if "telephonePin" in secure and not entry.password:
|
|
entry.password = secure["telephonePin"]
|
|
|
|
# Credit card
|
|
if "ccnum" in secure and not entry.username:
|
|
entry.username = secure["ccnum"]
|
|
if "pin" in secure and not entry.password:
|
|
entry.password = secure["pin"]
|
|
|
|
# Sections
|
|
if "sections" in secure:
|
|
for s in secure["sections"]:
|
|
t = s["title"]
|
|
if "fields" in s:
|
|
for f in s["fields"]:
|
|
v = f.get("v")
|
|
if not v:
|
|
continue
|
|
k = f["k"]
|
|
ft = "{} - {}".format(t, f["t"])
|
|
if t == "":
|
|
ft = f["t"]
|
|
if k == "string" or k == "concealed" or k == "menu" or k == "cctype" or k == "monthYear":
|
|
entry.set_custom_property(ft, str(v))
|
|
elif k == "date":
|
|
d = datetime.datetime.fromtimestamp(v)
|
|
entry.set_custom_property(ft, str(d))
|
|
else:
|
|
raise Exception("Unknown k: {}".format(k))
|
|
|
|
# Notes
|
|
if "notesPlain" in secure:
|
|
entry.notes = secure["notesPlain"]
|
|
|
|
# URLs
|
|
settings = {
|
|
"Allow": [],
|
|
"Deny": [],
|
|
"Realm": "",
|
|
}
|
|
applySettings = False
|
|
|
|
if "location" in item:
|
|
entry.url = item["location"]
|
|
if "URLs" in secure:
|
|
for u in secure["URLs"]:
|
|
if not entry.url:
|
|
entry.url = u["url"]
|
|
url = urlparse(u["url"])
|
|
settings["Allow"].append(url.hostname)
|
|
applySettings = True
|
|
|
|
if applySettings:
|
|
settings["Allow"] = list(set(settings["Allow"]))
|
|
entry.set_custom_property("KeePassHttp Settings", json.dumps(settings))
|
|
|
|
|
|
# Dates
|
|
entry.ctime = datetime.datetime.fromtimestamp(item["createdAt"])
|
|
entry.mtime = datetime.datetime.fromtimestamp(item["updatedAt"])
|
|
|
|
kp.save()
|