Skip to content

Commit

Permalink
Add support for SMTP SSL port (465) (jaymzh#140)
Browse files Browse the repository at this point in the history
Adds an option (--ssl) to use SSL instead of STARTTLS to gain support of
mail servers supporting only this auth method.

According to [RFC8314](https://datatracker.ietf.org/doc/html/rfc8314)
implicit SSL is recommended over STARTTLS for mail submission now.
  • Loading branch information
felixonmars authored Jan 31, 2023
1 parent ab5339a commit 9dc205a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ There are a variety of other options that you may want:
* customize mail hostname and port (-H and -P respectively)
* customize the email message (-M)
* don't use PGP/Mime in the email (-O, implies -e)
* specify a SMTPAUTH or STARTTLS for SMTP (-u and -S)
* specify SMTPAUTH (-u) and either STARTTLS (-S) or SSL (--ssl) for SMTP

And more! See the '-h' option for more.

Expand Down
74 changes: 46 additions & 28 deletions libpius/mailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def __init__(
port,
user,
tls,
ssl,
no_mime,
override,
msg_text,
Expand All @@ -43,6 +44,7 @@ def __init__(
self.user = user
self.password = ""
self.tls = tls
self.ssl = ssl
self.no_pgp_mime = no_mime
self.address_override = override
self.message_text = msg_text
Expand Down Expand Up @@ -77,6 +79,7 @@ def add_options(parser, group=None):
mail_host=DEFAULT_MAIL_HOST,
mail_port=DEFAULT_MAIL_PORT,
mail_tls=True,
mail_ssl=False,
)
group.add_option(
"-D",
Expand All @@ -103,6 +106,12 @@ def add_options(parser, group=None):
dest="mail_tls",
help="Do not use STARTTLS when talking to the SMTP" " server.",
)
group.add_option(
"--ssl",
action="store_true",
dest="mail_ssl",
help="Use SSL when talking to the SMTP server.",
)
group.add_option(
"-P",
"--mail-port",
Expand Down Expand Up @@ -175,7 +184,10 @@ def get_pass(self):
def verify_pass(self):
"""Verify the password we got works for SMTPAUTH."""
try:
smtp = smtplib.SMTP(self.host, self.port)
if self.ssl:
smtp = smtplib.SMTP_SSL(self.host, self.port)
else:
smtp = smtplib.SMTP(self.host, self.port)
except socket.error as msg:
raise MailSendError(msg)

Expand All @@ -188,13 +200,14 @@ def verify_pass(self):
# So, in order be secure on older pythons we ehlo() and then check the
# response before attempting startls.
try:
smtp.ehlo()
if not smtp.has_extn("STARTTLS"):
# Emulate 2.6 behavior
raise smtplib.SMTPException("Server does not support STARTTLS")
smtp.starttls()
# must ehlo after startls
smtp.ehlo()
if not self.ssl:
smtp.ehlo()
if not smtp.has_extn("STARTTLS"):
# Emulate 2.6 behavior
raise smtplib.SMTPException("Server does not support STARTTLS")
smtp.starttls()
# must ehlo after startls
smtp.ehlo()
smtp.login(self.user, self.password)
except smtplib.SMTPAuthenticationError:
return False
Expand Down Expand Up @@ -374,27 +387,32 @@ def _send_mail(self, to, msg):
msg["Date"] = formatdate(localtime=True)

try:
smtp = smtplib.SMTP(self.host, self.port)
if self.ssl:
smtp = smtplib.SMTP_SSL(self.host, self.port)
else:
smtp = smtplib.SMTP(self.host, self.port)
if self.tls:
# NOTE WELL: SECURITY IMPORTANT NOTE!
#
# In python 2.6 if you attempt to starttls() and the server
# doesn't understand an exception is raised. However before
# that, it just carried on and one could attempt to auth over a
# plain-text session. This is BAD!
#
# So, in order be secure on older pythons we ehlo() and then
# check the response before attempting startls.
smtp.ehlo()
if not smtp.has_extn("STARTTLS"):
# Emulate 2.6 behavior
raise smtplib.SMTPException(
"Server does not support STARTTLS"
)
smtp.starttls()
# must re-ehlo after STARTTLS
smtp.ehlo()
# Don't want to send auth information unless we're TLS'd
if not self.ssl:
# NOTE WELL: SECURITY IMPORTANT NOTE!
#
# In python 2.6 if you attempt to starttls() and the server
# doesn't understand an exception is raised. However before
# that, it just carried on and one could attempt to auth over a
# plain-text session. This is BAD!
#
# So, in order be secure on older pythons we ehlo() and then
# check the response before attempting startls.
smtp.ehlo()
if not smtp.has_extn("STARTTLS"):
# Emulate 2.6 behavior
raise smtplib.SMTPException(
"Server does not support STARTTLS"
)
smtp.starttls()
# must re-ehlo after STARTTLS
smtp.ehlo()

# Don't want to send auth information unless we're TLS'd
if self.user:
smtp.login(self.user, self.password)
if self.address_override:
Expand Down
8 changes: 6 additions & 2 deletions pius
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ def check_options(parser, options, args):
print("NOTE: -O and -m are present, turning on -e")
options.encrypt_outfiles = True

if options.mail_user and not options.mail_tls:
print("NOTE: -u is present, turning off -S.")
if options.mail_user and not (options.mail_tls or options.mail_ssl):
print("NOTE: -u (SMTPAUTH) is present, enabling TLS. Either TLS or SSL is required with SMTPAUTH")
options.mail_tls = True

if options.mail_tls and options.mail_ssl:
parser.error("ERROR: TLS and SSL cannot be used at the same time.")

if options.mail_text and not options.mail:
parser.error("ERROR: -M requires -m")

Expand Down Expand Up @@ -300,6 +303,7 @@ def main():
options.mail_port,
options.mail_user,
options.mail_tls,
options.mail_ssl,
options.mail_no_pgp_mime,
options.mail_override,
options.mail_text,
Expand Down
1 change: 1 addition & 0 deletions pius-keyring-mgr
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ There are no options"""
options.mail_port,
options.mail_user,
options.mail_tls,
options.mail_ssl,
options.mail_no_pgp_mime,
options.mail_override,
options.mail_text,
Expand Down
1 change: 1 addition & 0 deletions pius-report
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ def main():
options.mail_port,
options.mail_user,
options.mail_tls,
options.mail_ssl,
options.mail_no_pgp_mime,
options.mail_override,
options.mail_text,
Expand Down

0 comments on commit 9dc205a

Please sign in to comment.