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.

Signed-off-by: Daniel Kahn Gillmor <d...@fifthhorseman.net>
---
 debian/control                   |  2 ++
 email-print-mime-structure       | 18 +++++++++++++++++-
 email-print-mime-structure.1.pod | 21 +++++++++++++++++----
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/debian/control b/debian/control
index fc2bccc..4c3b956 100644
--- a/debian/control
+++ b/debian/control
@@ -38,6 +38,8 @@ Depends:
 Recommends:
  devscripts,
  git,
+ gpg,
+ gpg-agent,
  notmuch,
  python3-pgpy,
 Architecture: all
diff --git a/email-print-mime-structure b/email-print-mime-structure
index 6507436..2270506 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 = True if (self.args.pgpkey or 
self.args.use_gpg_agent) else False
 
         if try_decrypt and \
            (parent is not None) and \
@@ -97,6 +99,17 @@ class MimePrinter(object):
                             break
                         except:
                             pass
+            if cryptopayload is None and self.args.use_gpg_agent:
+                inp:int
+                outp:int
+                inp, outp = os.pipe()
+                with open(outp, 'w') as outf:
+                    outf.write(ciphertext)
+                out:subprocess.CompletedProcess[bytes] = 
subprocess.run(['gpg', '--decrypt'],
+                                                                        
stdin=inp,
+                                                                        
capture_output=True)
+                if out.returncode == 0:
+                    cryptopayload = email.message_from_bytes(out.stdout)
             if cryptopayload is None:
                 logging.warning(f'Unable to decrypt')
             else:
@@ -128,6 +141,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)
 
diff --git a/email-print-mime-structure.1.pod b/email-print-mime-structure.1.pod
index b846d87..cfdeb20 100644
--- a/email-print-mime-structure.1.pod
+++ b/email-print-mime-structure.1.pod
@@ -29,6 +29,16 @@ standard input, this key will be tried for decryption.  May 
be used
 multiple times if you want to try decrypting with more than one secret
 key.
 
+OpenPGP secret keys listed in B<--pgpkey=> are used ephemerally, and
+do not interact with any local GnuPG keyring.
+
+=item B<--use-gpg-agent=>I<true>|I<false>
+
+If I<true>, and B<email-print-mime-structure> encounters a
+PGP/MIME-encrypted part, it will try to decrypt the part using the
+secret keys found in the local installation of GnuPG. (default:
+I<false>)
+
 =item B<--help>, B<-h>
 
 Show usage instructions.
@@ -49,10 +59,13 @@ Show usage instructions.
 
 =head1 LIMITATIONS
 
-B<email-print-mime-structure> only decrypts encrypted e-mails using
-raw, non-password-protected OpenPGP secret keys (see B<--pgpkey>,
-above).  If it is unable to decrypt an encrypted part with the
-supplied keys, it will warn on stderr.
+When using B<--pgpkey>, B<email-print-mime-structure> only decrypts
+encrypted e-mails using raw, non-password-protected OpenPGP secret
+keys.
+
+If B<email-print-mime-structure> has been asked to decrypt parts with
+either B<--pgpkey> or with B<--use-gpg-agent=true>, and it is unable
+to decrypt an encrypted part, it will emit a warning to stderr.
 
 B<email-print-mime-structure>'s output is not stable, and is not
 intended to be interpreted by machines, so please do not depend on it
-- 
2.24.0.rc1

Reply via email to