diff options
author | Daniel Kahn Gillmor <dkg@fifthhorseman.net> | 2019-11-09 16:48:14 -0500 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2019-11-10 00:59:28 -0700 |
commit | e910230a9fb8a5151bede6d043679ec50570290f (patch) | |
tree | c96bfbda91a332944ed4ece13ab0aba20a9d2903 /email-print-mime-structure | |
parent | bc35cd2bd19d4e29c46289c831170327f5c8e161 (diff) | |
download | mailscripts-e910230a9fb8a5151bede6d043679ec50570290f.tar.gz |
email-print-mime-structure: Add --use-gpg-agent for decryption
In some cases, the user may want to try to use their own GnuPG secret
keys to decrypt encrypted parts of the message.
By default it is disabled so that we aren't accidentally triggering
the use of user secret key material.
Note that gpg(1) says:
It is highly recommended to use [--batch] along with the options
--status-fd and --with-colons for any unattended use of gpg.
I am deliberately choosing to not use either --status-fd or
--with-colons for email-print-mime-structure.
I'm not using --with-colons because there is no output from GnuPG that
we expect to be machine-readable -- we're just looking for the cleartext
of whatever ciphertext is in the message part.
I'm not using --status-fd because there is nothing actionable we can do
with GnuPG status messages, and asking for them would require switching
from subprocess.run to subprocess.Popen to take advantage of the
pass_fds argument, which in turn would make the script only work in a
POSIX environment (I believe, but have not tested, that the script can
currently be used on Windows).
Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Diffstat (limited to 'email-print-mime-structure')
-rwxr-xr-x | email-print-mime-structure | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/email-print-mime-structure b/email-print-mime-structure index c22d556..5497597 100755 --- a/email-print-mime-structure +++ b/email-print-mime-structure @@ -29,9 +29,11 @@ Example: If you want to number the parts, i suggest piping the output through something like "cat -n" ''' +import os import sys import email import logging +import subprocess from argparse import ArgumentParser, Namespace from typing import Optional, Union, List, Tuple, Any @@ -70,7 +72,7 @@ class MimePrinter(object): nbytes = len(payload) print(f'{prefix}{z.get_content_type()}{cset}{disposition}{fname} {nbytes:d} bytes') - try_decrypt:bool = True if self.args.pgpkey else False + try_decrypt:bool = self.args.pgpkey or self.args.use_gpg_agent if try_decrypt and \ (parent is not None) and \ @@ -84,6 +86,8 @@ class MimePrinter(object): return if self.args.pgpkey: cryptopayload = self.pgpy_decrypt(self.args.pgpkey, ciphertext) + if cryptopayload is None and self.args.use_gpg_agent: + cryptopayload = self.gpg_decrypt(ciphertext) if cryptopayload is None: logging.warning(f'Unable to decrypt') return @@ -108,6 +112,19 @@ class MimePrinter(object): pass return None + def gpg_decrypt(self, ciphertext:str) -> Optional[Message]: + inp:int + outp:int + inp, outp = os.pipe() + with open(outp, 'w') as outf: + outf.write(ciphertext) + out:subprocess.CompletedProcess[bytes] = subprocess.run(['gpg', '--batch', '--decrypt'], + stdin=inp, + capture_output=True) + if out.returncode == 0: + return email.message_from_bytes(out.stdout) + return None + def print_tree(self, z:Message, prefix:str, parent:Optional[Message], num:int) -> None: if (z.is_multipart()): self.print_part(z, prefix+'┬╴', parent, num) @@ -132,6 +149,9 @@ def main() -> None: epilog="Example: email-print-mime-structure <message.eml") parser.add_argument('--pgpkey', metavar='KEYFILE', action='append', help='OpenPGP Transferable Secret Key for decrypting') + parser.add_argument('--use-gpg-agent', metavar='true|false', type=bool, + default=False, + help='Ask local GnuPG installation for decryption') args:Namespace = parser.parse_args() msg:Union[Message, str, int, Any] = email.message_from_file(sys.stdin) |