Hi all, It would be nice to get any feedback on this. I'm fullquoting below so everyone gets the context.
Best wishes Michael On 08.04.19 13:55, Michael Kesper wrote: > Hi all, > > this was my first patch by email so I hope I didn't mess it up too much. :) > I could create a test keepass DB with attachments for testing purposes, if > that would make sense. > > Best wishes > Michael > > On 08.04.19 11:31, Michael Kesper wrote: >> >> In keepassx, it's possible to store one binary attachment per entry. >> In XML export, these are included as base64-encoded text. >> This patch will export these binaries as binary content into pass. >> Files will be saved as <path_to/entry>_<name of attachment>.gpg, e.g. >> for an attachment "order_2019-04-08.pdf" in entry "Orders/order001" it will >> be >> "Orders/order001_order_2019-04-08.pdf.gpg". >> The files can be decrypted directly with gpg --decrypt-files. >> --- >> contrib/importers/keepassx2pass.py | 35 ++++++++++++++++++++++++---->> 1 >> file changed, 28 insertions(+), 7 deletions(-) >> >> diff --git a/contrib/importers/keepassx2pass.py >> b/contrib/importers/keepassx2pass.py >> index 197375f..9daac91 100755 >> --- a/contrib/importers/keepassx2pass.py >> +++ b/contrib/importers/keepassx2pass.py >> @@ -1,10 +1,12 @@ >> #!/usr/bin/env python3 >> # >> # Copyright (C) 2012 Juhamatti Niemelä <[email protected]>. All Rights Reserved. >> +# Copyright © 2019 Michael Kesper <[email protected]>. >> # This file is licensed under the GPLv2+. Please see COPYING for more >> information. >> # >> # Usage ./keepassx2pass.py export.xml >> >> +import base64 >> import sys >> import re >> >> @@ -43,9 +45,11 @@ def path_for(element, path=''): >> >> def password_data(element): >> """ Return password data and additional info if available from >> - password entry element. """ >> + password entry element. >> + Extract any base64-encoded attachment. >> + """ >> passwd = element.find('password').text >> - ret = (passwd + "\n") if passwd else "\n" >> + ret = (passwd + "\n") if passwd is not None else "\n" >> for field in ['username', 'url', 'comment']: >> fel = element.find(field) >> children = [(e.text or '') + (e.tail or '') for e in list(fel)] >> @@ -54,17 +58,34 @@ def password_data(element): >> text = (fel.text or '') + "\n".join(children) >> if len(text) > 0: >> ret = "%s%s: %s\n" % (ret, fel.tag, text) >> - return ret >> + attachment = element.find('bin') >> + attachment_name = element.find('bindesc') >> + if attachment is not None: >> + attachment = base64.b64decode(attachment.text) >> + attachment_name = attachment_name.text >> + return ret, attachment_name, attachment >> + >> >> def import_entry(element, path=''): >> """ Import new password entry to password-store using pass insert >> - command """ >> - print("Importing " + path_for(element, path)) >> + command, exctract attachment if any. >> + """ >> + path_name = path_for(element, path) >> + print("Importing {}".format(path_name)) >> + pass_text, attachment_name, attachment = password_data(element) >> proc = Popen(['pass', 'insert', '--multiline', '--force', >> - path_for(element, path)], >> + path_name], >> stdin=PIPE, stdout=PIPE) >> - proc.communicate(password_data(element).encode()) >> + proc.communicate(pass_text.encode()) >> proc.wait() >> + if attachment is not None: >> + print("Extracting binary data: {}".format(attachment_name)) >> + proc = Popen(['pass', 'insert', '--multiline', '--force', >> + '{}_{}'.format(path_name, attachment_name)], >> + stdin=PIPE, stdout=PIPE) >> + proc.communicate(attachment) >> + proc.wait() >> + >> >> def import_group(element, path=''): >> """ Import all entries and sub-groups from given group """
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Password-Store mailing list [email protected] https://lists.zx2c4.com/mailman/listinfo/password-store
