83 lines
1.9 KiB
Text
83 lines
1.9 KiB
Text
|
#!/usr/bin/env python3
|
||
|
|
||
|
"""
|
||
|
Parses the output of gpg into a list suitable for the poezio
|
||
|
GPG plugin. Double-check the output and use at your own risk.
|
||
|
"""
|
||
|
|
||
|
import subprocess
|
||
|
import pprint
|
||
|
import re
|
||
|
import os
|
||
|
|
||
|
addr_re = re.compile(r'^uid\s+\[\s+full\s+\]\s.*<(.*@.*)>$')
|
||
|
id_re = re.compile(r'^pub\s+.*/(........) .*')
|
||
|
|
||
|
def extract_block(total):
|
||
|
"""
|
||
|
GPG output blocks are separated by newlines
|
||
|
"""
|
||
|
if '' in total:
|
||
|
index = total.index('')
|
||
|
else:
|
||
|
index = len(total)
|
||
|
block = total[:index]
|
||
|
total = total[index+1:]
|
||
|
return (block, total)
|
||
|
|
||
|
def parse_block(blocks, block):
|
||
|
"""
|
||
|
Keep the blocks with trusted keys
|
||
|
and extract addresses and UIDs
|
||
|
"""
|
||
|
|
||
|
uid = ''
|
||
|
addrs = []
|
||
|
blocksize = len(block)
|
||
|
|
||
|
for i, line in enumerate(reversed(block)):
|
||
|
if line.startswith('uid'):
|
||
|
match = addr_re.match(line)
|
||
|
if match:
|
||
|
addr = match.groups()[0]
|
||
|
if addr not in addrs:
|
||
|
addrs.append(addr)
|
||
|
else:
|
||
|
del block[blocksize-1-i]
|
||
|
elif line.startswith('pub'):
|
||
|
uid = id_re.match(line).groups()[0]
|
||
|
|
||
|
if addrs:
|
||
|
blocks[uid] = addrs
|
||
|
|
||
|
def output(blocks):
|
||
|
print('[keys]')
|
||
|
for uid in blocks:
|
||
|
for addr in blocks[uid]:
|
||
|
print('%s = %s' % (addr, uid))
|
||
|
|
||
|
def main():
|
||
|
|
||
|
os.putenv('LANG', 'en_US.UTF-8')
|
||
|
|
||
|
gpg_proc = subprocess.Popen(
|
||
|
[
|
||
|
"/usr/bin/gpg",
|
||
|
"--list-keys",
|
||
|
"--list-options",
|
||
|
"show-uid-validity"
|
||
|
],
|
||
|
stdout=subprocess.PIPE)
|
||
|
|
||
|
result, _ = gpg_proc.communicate()
|
||
|
result = result.decode().strip().splitlines()[2:]
|
||
|
blocks = {}
|
||
|
|
||
|
while result:
|
||
|
block, result = extract_block(result)
|
||
|
parse_block(blocks, block)
|
||
|
output(blocks)
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|