2024-02-27 19:37:34 -06:00
|
|
|
import gpg
|
|
|
|
import hkp4py
|
|
|
|
import os
|
|
|
|
import sys
|
2024-02-28 22:55:01 -06:00
|
|
|
import asyncio
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
async def get_pubkey(server, fingerprint, log):
|
|
|
|
# This isn't perfect, it's a loose search
|
|
|
|
# for example searching for 7C79FCBB8372E5DE5B17E09A90D4B9641E092971 on keyserver.ubuntu.com returns the wrong key. But it works 99% of the time.
|
|
|
|
#return hkp4py.KeyServer(f'hkp://{server}').search(f'0x{fingerprint}')
|
|
|
|
results = await subprocess.getstatusoutput(f'gpg --keyserver {server} --recv-key {fingerprint}')
|
|
|
|
log.write(f'{server}: {results}\n')
|
|
|
|
print(f'{server}: {results}')
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
def get_first_real_result(results):
|
|
|
|
for s in results:
|
|
|
|
s = list(s)
|
|
|
|
for task in s:
|
|
|
|
try:
|
|
|
|
return task.result()
|
|
|
|
except asyncio.exceptions.InvalidStateError:
|
|
|
|
pass
|
|
|
|
return None
|
|
|
|
|
2024-02-27 19:37:34 -06:00
|
|
|
|
|
|
|
XDG_DATA_HOME = os.getenv('XDG_DATA_HOME')
|
|
|
|
HOME = os.path.expanduser('~')
|
|
|
|
if XDG_DATA_HOME == None:
|
|
|
|
XDG_DATA_HOME = f'{HOME}/.local/share'
|
|
|
|
|
|
|
|
filename = sys.argv[-1]
|
|
|
|
email = ''.join(open(filename, 'rt').readlines())
|
|
|
|
|
|
|
|
if 'gpg-email-helper' not in os.listdir(f'{XDG_DATA_HOME}'):
|
|
|
|
os.mkdir(f'{XDG_DATA_HOME}/gpg-email-helper')
|
|
|
|
|
2024-02-28 22:55:01 -06:00
|
|
|
|
|
|
|
async def main(log):
|
2024-02-27 19:37:34 -06:00
|
|
|
log.write(f'\n\nRunning on {filename}\n')
|
|
|
|
|
2024-02-28 14:13:22 -06:00
|
|
|
if (
|
|
|
|
email.rfind('-----BEGIN PGP PUBLIC KEY BLOCK-----') != -1
|
|
|
|
and email.rfind('-----END PGP PUBLIC KEY BLOCK-----') != -1
|
|
|
|
):
|
|
|
|
public_key = email[
|
|
|
|
email.rfind('-----BEGIN PGP PUBLIC KEY BLOCK-----') : email.rfind(
|
|
|
|
'-----END PGP PUBLIC KEY BLOCK-----'
|
|
|
|
)
|
|
|
|
+ 35
|
|
|
|
]
|
2024-02-28 10:11:43 -06:00
|
|
|
# quoted-printable attachments have the equals sign escaped as =3D apparently
|
|
|
|
public_key = public_key.replace('=3D', '=')
|
2024-02-27 19:37:34 -06:00
|
|
|
log.write(
|
2024-02-28 14:13:22 -06:00
|
|
|
f'Attempted to import key from email: {gpg.Context(armor=True).key_import(public_key.encode())}\n'
|
|
|
|
)
|
2024-02-27 19:37:34 -06:00
|
|
|
|
|
|
|
elif (
|
|
|
|
email.rfind('-----BEGIN PGP SIGNATURE-----') != -1
|
|
|
|
and email.rfind('-----END PGP SIGNATURE-----') != -1
|
|
|
|
):
|
|
|
|
signature = email[
|
2024-02-28 14:13:22 -06:00
|
|
|
email.rfind('-----BEGIN PGP SIGNATURE-----') : email.rfind(
|
2024-02-27 19:37:34 -06:00
|
|
|
'-----END PGP SIGNATURE-----'
|
2024-02-28 14:13:22 -06:00
|
|
|
)
|
|
|
|
+ 27
|
2024-02-27 19:37:34 -06:00
|
|
|
]
|
2024-02-28 14:13:22 -06:00
|
|
|
signature.replace('=3D', '=')
|
2024-02-27 19:37:34 -06:00
|
|
|
|
|
|
|
try:
|
|
|
|
# Needed to skip geting the key if it already exists.
|
|
|
|
gpg.Context().verify(signature.encode())
|
|
|
|
except gpg.errors.BadSignatures as e:
|
|
|
|
if 'No public key' in str(e):
|
|
|
|
fingerprint = str(e)[: str(e).find(':')]
|
|
|
|
log.write(
|
|
|
|
f'{fingerprint} not found, gonna try to find it on a keyserver...\n'
|
|
|
|
)
|
|
|
|
keyservers = [
|
|
|
|
'keyserver.ubuntu.com',
|
|
|
|
'pgpkeys.eu',
|
|
|
|
'pgp.cyberbits.eu',
|
|
|
|
'pgp.flexyz.com',
|
|
|
|
'sks.pgpkeys.eu',
|
|
|
|
'fi.pgpkeys.eu',
|
|
|
|
'keys.nicemail.eu',
|
|
|
|
'pubkeys.intevation.de',
|
|
|
|
'pgp.surf.nl',
|
|
|
|
'sks.pod03.togsvcs.com',
|
|
|
|
'sks.ewr1.newconews.org',
|
|
|
|
'sks.pod02.fleetstreetops.com',
|
|
|
|
'sks.pod01.fleetstreetops.com',
|
|
|
|
'pgp.net.nz',
|
|
|
|
'zuul.rediris.es',
|
|
|
|
'pgp.gnd.pw',
|
|
|
|
'openpgp.circl.lu',
|
|
|
|
'keywin.trifence.ch',
|
|
|
|
'data.pgp.gnd.pw',
|
|
|
|
'sks.infcs.de',
|
|
|
|
'keyserver.escomposlinux.org',
|
|
|
|
'keyserver.cert.or.id',
|
|
|
|
'keyserver1.computer42.org',
|
|
|
|
'keyserver2.computer42.org',
|
|
|
|
'keyserver.spline.inf.fu-berlin.de',
|
|
|
|
'key-server.org',
|
|
|
|
'pgp.id',
|
|
|
|
'sks.ygrek.org',
|
2024-02-28 22:55:01 -06:00
|
|
|
#'pgp.mit.edu' # still in operation but very unreliable
|
2024-02-27 19:37:34 -06:00
|
|
|
]
|
|
|
|
|
2024-02-28 22:55:01 -06:00
|
|
|
tasks = [
|
|
|
|
asyncio.create_task(get_pubkey(server, fingerprint, log))
|
|
|
|
for server in keyservers
|
|
|
|
]
|
|
|
|
#tasks = set(tasks)
|
|
|
|
results = await asyncio.gather(tasks)
|
|
|
|
print(1)
|
|
|
|
print(get_first_real_result(results))
|
|
|
|
print(3)
|
|
|
|
print(get_first_real_result(results))
|
|
|
|
|
2024-02-27 19:37:34 -06:00
|
|
|
except Exception as e:
|
|
|
|
log.write(f'[ERROR] {e}\n\n')
|
2024-02-28 22:55:01 -06:00
|
|
|
|
|
|
|
|
|
|
|
with open(f'{XDG_DATA_HOME}/gpg-email-helper/log', 'a') as log:
|
|
|
|
asyncio.run(main(log))
|