Skip to content

Commit 0afeb2f

Browse files
author
Matthew Borger
committed
Added option to save generated emails
to a given folder instead of sending via SMTP.
1 parent 62b4a59 commit 0afeb2f

File tree

3 files changed

+43
-28
lines changed

3 files changed

+43
-28
lines changed

doc/pius.1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ Hostname of SMTP server. [default: \fIlocalhost\fP]
4747
Use the pexpect module for signing and drop to the gpg shell for entering the passphrase. [default: false]
4848
.IP "\fB\-I\fP, \fB\-\-import\fP"
4949
Also import the unsigned keys from the keyring into the default keyring. Ignored if \fB\-r\fP is not specified, or if it's the same as the default keyring.
50+
.IP "\fB\-L\fP, \fB\-\-save\-to\-mail\-dir\fP"
51+
Instead of calling SMTP, save the email to this directory. Useful for signing from an air gapped machine. The saved email files can be sent using your own MTA such as sendmail or mailx.
5052
.IP "\fB\-m\fP \fIFROM\-EMAIL\fP, \fB\-\-mail=\fP\fIFROM\-EMAIL\fP"
5153
Email the encrypted, signed keys to the respective email addresses using \fIFROM\-EMAIL\fP as the sender. See also \fB\-H\fP and \fB\-P\fP.
5254
.IP "\fB\-M\fP \fIFILE\fP, \fB\-\-mail\-text=\fP\fIFILE\fP"

libpius/mailer.py

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import smtplib
55
import socket
6+
import os
67

78
from email import message, quoprimime
89
from email.utils import formatdate
@@ -21,7 +22,7 @@
2122

2223
class PiusMailer(object):
2324
def __init__(self, mail, host, port, user, tls, no_mime, override, msg_text,
24-
tmp_dir):
25+
tmp_dir, local_mail_dir):
2526
self.mail = mail
2627
self.host = host
2728
self.port = port
@@ -32,6 +33,7 @@ def __init__(self, mail, host, port, user, tls, no_mime, override, msg_text,
3233
self.address_override = override
3334
self.message_text = msg_text
3435
self.tmp_dir = tmp_dir
36+
self.local_mail_dir = local_mail_dir
3537

3638
@staticmethod
3739
def add_options(parser):
@@ -254,36 +256,42 @@ def _send_mail(self, to, msg):
254256
msg['From'] = self.mail
255257
if self.address_override:
256258
msg['To'] = self.address_override
259+
env_to = [msg['To']]
257260
else:
258261
msg['To'] = to
262+
env_to = [msg['To'], self.mail]
259263
msg['Date'] = formatdate(localtime=True)
260264

261-
try:
262-
smtp = smtplib.SMTP(self.host, self.port)
263-
if self.tls:
264-
# NOTE WELL: SECURITY IMPORTANT NOTE!
265-
# In python 2.6 if you attempt to starttls() and the server doesn't
266-
# understand an exception is raised. However before that, it just
267-
# carried on # and one could attempt to auth over a plain-text session.
268-
# This is BAD!
269-
#
270-
# So, in order be secure on older pythons we ehlo() and then check the
271-
# response before attempting startls.
272-
smtp.ehlo()
273-
if not smtp.has_extn('STARTTLS'):
274-
# Emulate 2.6 behavior
275-
raise smtplib.SMTPException('Server does not support STARTTLS')
276-
smtp.starttls()
277-
# must re-ehlo after STARTTLS
278-
smtp.ehlo()
279-
# Don't want to send auth information unless we're TLS'd
280-
if self.user:
281-
smtp.login(self.user, self.password)
282-
if self.address_override:
283-
env_to = self.address_override
284-
else:
285-
# BCC the user...
286-
env_to = [msg['To'], self.mail]
265+
if self.local_mail_dir:
266+
if not os.path.isdir(self.local_mail_dir):
267+
os.mkdir(self.local_mail_dir)
268+
if not self.address_ovrride:
269+
msg['Bcc'] = self.mail
270+
email = open(os.path.join(self.local_mail_dir, msg['To']), 'w')
271+
email.write(str(msg))
272+
email.close()
273+
else:
274+
try:
275+
smtp = smtplib.SMTP(self.host, self.port)
276+
if self.tls:
277+
# NOTE WELL: SECURITY IMPORTANT NOTE!
278+
# In python 2.6 if you attempt to starttls() and the server doesn't
279+
# understand an exception is raised. However before that, it just
280+
# carried on # and one could attempt to auth over a plain-text session.
281+
# This is BAD!
282+
#
283+
# So, in order be secure on older pythons we ehlo() and then check the
284+
# response before attempting startls.
285+
smtp.ehlo()
286+
if not smtp.has_extn('STARTTLS'):
287+
# Emulate 2.6 behavior
288+
raise smtplib.SMTPException('Server does not support STARTTLS')
289+
smtp.starttls()
290+
# must re-ehlo after STARTTLS
291+
smtp.ehlo()
292+
# Don't want to send auth information unless we're TLS'd
293+
if self.user:
294+
smtp.login(self.user, self.password)
287295

288296
smtp.sendmail(self.mail, env_to, msg.as_string())
289297
smtp.quit()

pius

100755100644
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ def main():
158158
' into the default keyring. Ignored if -r is not'
159159
' specified, or if it\'s the same as the default'
160160
' keyring.')
161+
parser.add_option('-L', '--save-to-mail-dir', dest='local_mail_dir',
162+
metavar='FILE',
163+
help='Instead of calling SMTP, save'
164+
' the email to this directory.')
161165
parser.add_option('-m', '--mail', dest='mail', metavar='EMAIL', nargs=1,
162166
type='email',
163167
help='Email the encrypted, signed keys to the'
@@ -238,7 +242,8 @@ def main():
238242
options.mail_no_pgp_mime,
239243
options.mail_override,
240244
options.mail_text,
241-
options.tmp_dir
245+
options.tmp_dir,
246+
options.local_mail_dir
242247
)
243248
else:
244249
mailer = None

0 commit comments

Comments
 (0)