1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
#!/usr/bin/env python3
# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# put pinentry-tty through its paces on an otherwise clean
# pseudoterminal.
import posix
import subprocess
import codecs
import time
# block on pinentry verification:
def isok(pinentry):
l = pinentry.stdout.readline()
if not l.startswith('OK'):
raise Exception("notok: " + l if l else '<None>')
(master, pty) = posix.openpty()
# depends on /proc!
ptyname = posix.readlink("/proc/self/fd/%d"%(pty))
p = subprocess.Popen(['pinentry-tty'],
shell=False,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
universal_newlines=True,
bufsize=1)
isok(p)
p.stdin.write("option ttyname %s\n"%(ptyname))
isok(p)
p.stdin.write("setprompt foo bar\n")
isok(p)
p.stdin.write("getpin\n")
p.stdin.flush()
# avoid failures on laggy build daemons
time.sleep(2.0)
prompt = codecs.decode(posix.read(master, 1000))
print("---begin pinentry prompt---")
print(prompt)
print("---end pinentry prompt---")
posix.write(master, codecs.encode("abc123\n"))
answer = p.stdout.readline()
if answer.strip() != "D abc123":
raise Exception("wrongpass" + answer)
isok(p)
p.stdin.write("bye\n")
isok(p)
ret = p.wait()
if ret:
raise Exception("pinentry terminated wrong: %d!"%(ret))
posix.close(pty)
posix.close(master)
|