diff --git a/vault_from_gpg_agent.py b/vault_from_gpg_agent.py index 8627024..cbfe287 100755 --- a/vault_from_gpg_agent.py +++ b/vault_from_gpg_agent.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # # Store your Ansible vault password in gpg-agent. # @@ -31,6 +31,7 @@ import subprocess import sys import urllib +import urllib.parse import os.path import hashlib import base64 @@ -38,27 +39,32 @@ def get_passphrase(gpg_agent, my_path, cache_id): - description = urllib.quote( + description = urllib.parse.quote( "Please enter the ansible vault password for %s" % (my_path,)) command = "GET_PASSPHRASE %s X X %s\n" % (cache_id, description) - stdout = gpg_agent.communicate(command)[0] + # my_path might include the full character range thus hope that + # pinentry can handle it (no documentation found about the + # protocol encoding of pinentry) + stdout = gpg_agent.communicate(command.encode('utf-8'))[0] if gpg_agent.returncode != 0: raise Exception("gpg-connect-agent exited %r" % (gpg_agent.returncode,)) - elif not stdout.startswith("OK"): + elif not stdout.startswith("OK".encode('ascii')): raise Exception("gpg-agent says: %s" % (stdout.rstrip(),)) else: # You'll get an exception here if we get anything we didn't expect. - passphrase = stdout[3:-1].decode("hex") - print passphrase + passphrase = bytes.fromhex(stdout[3:-1].decode('ascii')).decode('utf-8') + print(passphrase) def clear_passphrase(gpg_agent, cache_id): - stdout = gpg_agent.communicate("CLEAR_PASSPHRASE %s\n" % (cache_id,))[0] + command = "CLEAR_PASSPHRASE %s\n" % (cache_id,) + # cache_id is a hash which is ascii only + stdout = gpg_agent.communicate(command.encode('ascii'))[0] if gpg_agent.returncode != 0: raise Exception("gpg-connect-agent exited %r" % (gpg_agent.returncode,)) - elif not stdout.startswith("OK"): + elif not stdout.startswith("OK".encode('ascii')): raise Exception("gog-agent says: %s" % (stdout.rstrip(),)) @@ -72,7 +78,7 @@ def main(): my_path = os.path.realpath(sys.argv[0]) # Per the source, cache-id is limited to 50 bytes, so we hash our # path and Base64 encode the path. - hashed_path = base64.b64encode(hashlib.sha1(my_path).digest()) + hashed_path = base64.b64encode(hashlib.sha1(my_path.encode('utf-8')).digest()) cache_id = "ansible-vault:%s" % (hashed_path,) if args.clear: clear_passphrase(gpg_agent, cache_id)