Created
August 5, 2019 20:27
-
-
Save CookedApps/b5be361088b9b850739abde440101c10 to your computer and use it in GitHub Desktop.
Python script for importing a SafeInCloud XML export to pass (the unix password manager)
This file contains hidden or 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
| """ | |
| Import a SafeInCloud XML export to pass. | |
| Created by Sandro Wahl on 05.08.2019 | |
| """ | |
| import sys | |
| import re | |
| from subprocess import Popen, PIPE | |
| from xml.etree import ElementTree | |
| TYPES = ["login", "password", "email", "pin", "text"] | |
| def insert_data(path, text): | |
| """ | |
| Insert data into the password store. | |
| (1) ensures text ends with a new line and encodes in UTF-8 | |
| (2) inserts | |
| """ | |
| if not text.endswith('\n'): | |
| text = text + '\n' | |
| text = text.encode('utf8') | |
| print("Inserting {}".format(path)) | |
| proc = Popen(['pass', 'insert', '--multiline', '--force', path], stdin=PIPE, stdout=PIPE) | |
| proc.communicate(text) | |
| proc.wait() | |
| def clean_string(value): | |
| """ | |
| Make the string more commandline friendly. | |
| """ | |
| value = value.strip() | |
| value = '_'.join(value.split()) | |
| value = re.sub("(\\|\||\(|\)|/|\"|')", "", value) | |
| value = re.sub("\@", "At", value) | |
| value = re.sub("-", "_", value) | |
| value = '_'.join(value.split('_')) | |
| return value | |
| def parse_database(element): | |
| cards = 0 | |
| for card in element.findall("card"): | |
| if is_not(card, "deleted") and is_not(card, "template"): | |
| parse_card(card) | |
| cards += 1 | |
| print("Imported {} cards".format(cards)) | |
| def is_not(element, attrib): | |
| return (attrib not in element.attrib) or (attrib in element.attrib and element.attrib[attrib] == "false") | |
| def parse_card(element): | |
| path = clean_string(element.attrib["title"]) | |
| for field in element.findall("field"): | |
| parse_field(field, path) | |
| def parse_field(element, path): | |
| if element.attrib["type"] in TYPES: | |
| path += "/" | |
| path += clean_string(element.attrib["name"]) | |
| insert_data(path, element.text) | |
| def main(xml_file): | |
| """ Parse XML entries from a SafeInCloud """ | |
| element = ElementTree.parse(xml_file).getroot() | |
| assert element.tag == 'database' | |
| parse_database(element) | |
| if __name__ == '__main__': | |
| main(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment