Skip to content

Instantly share code, notes, and snippets.

@ewjoachim
Created September 18, 2022 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ewjoachim/fcaf3cb2ed1316724e14ed63d9cc5045 to your computer and use it in GitHub Desktop.
Save ewjoachim/fcaf3cb2ed1316724e14ed63d9cc5045 to your computer and use it in GitHub Desktop.
Pinentry wrapper for MacGPG2 that lets you save the yubikey PIN to the Mac Keychain
#!/usr/bin/env python3
import pathlib
import re
import subprocess
import sys
import threading
import traceback
skip_next = []
prog = list(sys.argv[1:]) or ["/usr/local/bin/pinentry-mac"]
logfile = pathlib.Path("/Users/joachim/.gnupg/mypinentry-logs")
logfile.write_text("")
lock = threading.Lock()
def log(text):
with lock, logfile.open("a") as f:
f.write(text)
def stdin(process):
for line in sys.stdin:
log(f"stdin: {line}")
process.stdin.write(line)
process.stdin.flush()
match = re.match(r"SETDESC Please unlock the card%0A%0ANumber: ([\d ]+)", line)
if match:
skip_next.append(True)
id = match.group(1).replace(" ", "")
keyinfo_line = f"SETKEYINFO x/card-pin-{id}\n"
process.stdin.write(keyinfo_line)
process.stdin.flush()
log(f"added stdin: {keyinfo_line}")
def stdout(process):
for line in process.stdout:
try:
skip_next.pop()
except IndexError:
pass
else:
log(f"ignored stdout: {line}")
continue
log(f"stdout: {line}")
sys.stdout.write(line)
sys.stdout.flush()
def main():
process = subprocess.Popen(prog, stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, bufsize=0)
stdin_thread = threading.Thread(target=stdin, args=(process,))
stdout_thread = threading.Thread(target=stdout, args=(process,))
stdin_thread.start()
stdout_thread.start()
stdin_thread.join()
process.wait()
stdout_thread.join()
if __name__ == "__main__":
try:
main()
except BaseException:
log(traceback.format_exc())
default-cache-ttl 60
max-cache-ttl 720
# pinentry-program /usr/local/bin/pinentry-mac
pinentry-program /Users/joachim/.gnupg/card-id-cache
enable-ssh-support
default-cache-ttl-ssh 60
max-cache-ttl-ssh 720
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment