Created
June 27, 2017 17:21
-
-
Save simsor/747e1065d051ce6d7417439110637aaa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Convert your pass(1) password database to a Keepass 2 (.kdbx) database. | |
# Change the PASS_DIR, KP_FILE and PASSPHRASE variables | |
# Create the kdbx file beforehand. The script assumes the passphrase of your GPG key and the database password are the same. | |
# You'll need the pykeepass libraries (install with pip3) and gpg installed on your computer | |
# Make sure your pass key is in your GPG keyring, there's absolutely no checks whatsoever | |
# I've only tested this with the WSL on Windows 10, so yeah, YMMV | |
from pykeepass import PyKeePass | |
import subprocess | |
import os | |
import sys | |
PASS_DIR = "/mnt/c/Users/Simon/AppData/Roaming/password-store" | |
KP_FILE = "./database.kdbx" | |
PASSPHRASE = "" | |
contents = {} | |
kp = PyKeePass(KP_FILE, password=PASSPHRASE) | |
def gpg_decrypt(file, passphrase): | |
p = subprocess.Popen(["gpg", "--passphrase", passphrase, "--decrypt", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
(out, _) = p.communicate() | |
return out | |
def unpass(dir, c): | |
for entry in os.listdir(dir): | |
if entry[0] == ".": | |
continue | |
fullpath = os.path.join(dir, entry) | |
if os.path.isdir(fullpath): | |
c[entry] = {} | |
unpass(fullpath, c[entry]) | |
else: | |
if entry[-4:] == ".gpg": | |
entry = entry[:-4] | |
c[entry] = {} | |
c[entry]["ENTRYTYPE"] = "file" | |
decrypted = gpg_decrypt(fullpath, PASSPHRASE).decode("UTF-8") | |
parts = decrypted.split("\n") | |
c[entry]["password"] = parts[0] | |
c[entry]["username"] = "" | |
c[entry]["notes"] = "" | |
c[entry]["url"] = "" | |
for part_idx in range(1, len(parts)): | |
if not parts[part_idx]: | |
continue | |
label = parts[part_idx].split(":")[0] | |
info = ":".join(parts[part_idx].split(":")[1:]) | |
info = info.lstrip(" ") | |
if label.lower() == "username": | |
c[entry]["username"] = info | |
elif label.lower() == "url": | |
c[entry]["url"] = info | |
else: | |
c[entry]["notes"] += label + ": " + info + "\n" | |
def tokeepass(curgroup, c): | |
for (k, v) in c.items(): | |
if "ENTRYTYPE" in v and v["ENTRYTYPE"] == "file": | |
kp.add_entry(curgroup, k, v["username"], v["password"], url=v["url"], notes=v["notes"]) | |
else: | |
g = kp.add_group(curgroup, k) | |
tokeepass(g, v) | |
def main(): | |
pass_key = open(os.path.join(PASS_DIR, ".gpg-id")).read().strip() | |
print("Pass key:", pass_key) | |
print("====") | |
unpass(PASS_DIR, contents) | |
# Create base groups | |
for (k, v) in contents.items(): | |
if "ENTRYTYPE" in v and v["ENTRYTYPE"] == "file": | |
continue | |
g = kp.add_group(kp.root_group, k) | |
tokeepass(g, v) | |
kp.save() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment