I just saw the other response and guess I never wrote up the solution I actually implemented. It turns out that python imaplib is straightforward and I wrote a very quick script. Barring a few changes (e.g., anonymizing my various USERNAMEs, EMAILPASSWORD, WORKDOMAINNAME, MYGPGKEYID). I also don't just send encrypted it; but prepend the subject with the username of the sender and put some of the header stuff before the GPG (in case I'm reading it on my phone and can't decrypt).
#!/usr/bin/python
import imaplib
import email
from datetime import datetime,timedelta
import shelve
from subprocess import Popen, PIPE
def piped_call(command1, arg1_list, command2, arg2_list):
"""
if arg1_tuple = (a10, a11, a12); arg2_tuple is (a20, a21)
This executes "command1 a10 a11 a12 | command2 a20 a21 a22"
"""
if type(arg1_list) not in (list, tuple):
arg1_list = [arg1_list,]
if type(arg2_list) not in (list, tuple):
arg2_list = [arg2_list,]
p1 = Popen([command1,]+list(arg1_list), stdout=PIPE)
p2 = Popen([command2,]+list(arg2_list), stdin=p1.stdout, stdout=PIPE)
p1.stdout.close()
return p2.communicate()[0]
shlf = shelve.open('/home/USERNAME/mail/mail.shlf')
# This shelf (a persistent python dictionary written to file) has as its key
# the IMAP message ids of all emails that have been processed by this script.
# Every time the script runs, I fetch all emails from the current day
# (except from midnight to 1am, where I fetch all emails since yesterday)
# and then send all emails that haven't been sent previously
# by checking message ids against the python shelf.
M = imaplib.IMAP4_SSL(host='imap.WORKDOMAINNAME.com', port=993)
M.login('EMAILUSERNAME', 'EMAILPASSWORD')
M.select()
dt = datetime.now() - timedelta(0,5*60*60)
# Only search for messages since the day of an hour earlier.
# This way messages from yesterday don't get lost at midnight; as well as limiting the number of messages to process through to just todays.
typ, uid_data = M.uid('search', None, '(SINCE %s)' % dt.strftime('%d-%b-%Y'))
for num in uid_data[0].split():
typ, data = M.uid('fetch', num, '(RFC822)')
e = email.message_from_string(data[0][1])
print 'Message %s\n%s\n' % (num, e['subject'])
if num not in shlf:
sender_email = e['return-path']
for s in ('<', '>', '@WORKDOMAINNAME.com'):
sender_email = sender_email.replace(s,'')
subject = "%s: %s" % (sender_email, e['Subject'])
body = ("From: %s\n"
"To: %s\n"
"Cc: %s\n"
"Subject: %s\n\n" % (e['From'], e['To'], e['Cc'], e['subject']))
payload = e.get_payload()
if type(payload) in (list, tuple):
payload = str(payload[0])
else:
payload = str(payload)
encrypted_payload = piped_call('echo', (payload,),
'gpg', ('-e', '-a', '-r', 'MYGPGKEYID'))
body += encrypted_payload
piped_call('echo', (body,),
'mail', ['USERNAME@gmail.com', '-s', subject])
shlf[num] = datetime.now()
M.close()
M.logout()
I then added the following lines to my crontab (the script above is named mail.py inside a directory called mail), so it will run every 5 minutes during the normal hours on weekdays (M-F 8-7pm) and less frequently at other hours. (crontab -e)
# Every 5 minutes, M-F from 8am - 7pm.
*/5 8-19 * * 1-5 cd /home/USERNAME/mail && ./mail.py >> /home/USERNAME/mail/mail.log 2>&1
# Every 30 minutes, Sat&Sun from 8am-7pm
0,30 8-19 * * 6,7 cd /home/USERNAME/mail && ./mail.py >> /home/USERNAME/mail/mail.log 2>&1
# Every 30 minutes, M-F 8pm-2am; (no emails 2am-8am)
0,30 0-2,20-23 * * 1-5 cd /home/USERNAME/mail && ./mail.py >> /home/USERNAME/mail/mail.log 2>&1
# Every 60 minutes, Sat&Sun hours 8pm-2am; (no emails 2am-8am)
0 0-2,20-23 * * 6-7 cd /home/USERNAME/mail && ./mail.py >> /home/USERNAME/mail/mail.log 2>&1
In muttrc, use
set crypt_opportunistic_encrypt = yes
From $ man 5 muttrc
crypt_opportunistic_encrypt
Type: boolean
Default: no
Setting this variable will cause Mutt to automatically enable
and disable encryption, based on whether all message recipient
keys can be located by mutt.
When this option is enabled, mutt will determine the encryption
setting each time the TO, CC, and BCC lists are edited. If
$edit_headers is set, mutt will also do so each time the
message is edited.
While this is set, encryption settings can't be manually
changed. The pgp or smime menus provide an option to disable
the option for a particular message.
If $crypt_autoencrypt or $crypt_replyencrypt enable encryption
for a message, this option will be disabled for the message. It
can be manually re-enabled in the pgp or smime menus. (Crypto
only)
This also inspects cc:ed addresses for validity. Unfortunately, as per the second-last paragraph, this overrides many useful settings. For example, I have set pgp_autoinline = yes
, which is deprecated, but necessary for sending to older clients1, which don't support PGP/MIME.
1 For example, Android's K-9 + APG. AFAIK this is the only FOSS Android email client that reads PGP-encrypted email at all, but only in a limited fashion. (EDIT: K-9 + openkeychain now supports PGP/MIME.)
Best Answer
Update as of 2018/03/18: This feature was merged upstream, and released in notmuch 0.26.
Please note:
See the comments below this answer how to make use of this feature.
--
This is in the works upstream, as of today, 2016/02/09. Quoting the linked mail: