commit 23da552d5472d188ab925fef65dfb01a11ded1ff Author: askiiart Date: Tue Feb 27 19:37:34 2024 -0600 Initial commit - working diff --git a/README.md b/README.md new file mode 100644 index 0000000..734abc4 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# gpg-email-helper + +This is just a little script to automatically find and import the public key used to sign an email. It will first check if the email itself contains the public key, and if it does not, then it will attempting to get the key from many keyservers. + +## Usage + +Just run it with the email file, like this: + +```sh +python3 ./gpg-email-helper.py ~/Mail/inbox/10 +``` + +You can view the log at `$XDG_DATA_HOME/gpg-email-helper/log` or `~/.local/share/gpg-email-helper/log`. diff --git a/gpg-email-helper.py b/gpg-email-helper.py new file mode 100644 index 0000000..a2839b5 --- /dev/null +++ b/gpg-email-helper.py @@ -0,0 +1,94 @@ +import gpg +import hkp4py +import os +import sys + +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') + +with open(f'{XDG_DATA_HOME}/gpg-email-helper/log', 'a') as log: + log.write(f'\n\nRunning on {filename}\n') + + # Untested as I'm missing a real email with this done properly - is this even supported by anything? + 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] + log.write( + f'Attempted to import key from email: {gpg.Context(armor=True).key_import(public_key.encode())}\n') + + elif ( + email.rfind('-----BEGIN PGP SIGNATURE-----') != -1 + and email.rfind('-----END PGP SIGNATURE-----') != -1 + ): + signature = email[ + email.rfind('-----BEGIN PGP SIGNATURE-----'): email.rfind( + '-----END PGP SIGNATURE-----' + )+27 + ] + + 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', + # 'pgp.mit.edu' # still in operation but very unreliable + ] + + for server in keyservers: + log.write(f'{server}: ') + try: + pubkey = hkp4py.KeyServer( + # 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. + f'hkp://{server}').search(fingerprint) + if pubkey != None: + log.write(f'{pubkey}\n') + gpg.Context().key_import(pubkey) + break + else: + log.write('None\n') + except Exception as e: + log.write(f'[ERROR] {e}\n\n') + except Exception as e: + log.write(f'[ERROR] {e}\n\n') diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..924dd56 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +gpgme +hkp4py \ No newline at end of file