From: Simon P <simon.git@le-huit.fr>
To: git@vger.kernel.org
Cc: mhagger@alum.mit.edu, matthieu.moy@grenoble-inp.fr
Subject: [git-multimail] smtplib, check certificate
Date: Thu, 21 Apr 2016 23:44:50 +0200 [thread overview]
Message-ID: <571949D2.10507@le-huit.fr> (raw)
[-- Attachment #1: Type: text/plain, Size: 653 bytes --]
Hi,
It seems that smtplib doesn't check if a certificate is valid (signed by
a trusted CA).
For my personal usage, I patched the starttls code in git-multimail:
only for starttls with smtplib.
This patch is inspired from
https://github.com/graingert/secure-smtplib/blob/master/src/secure_smtplib/__init__.py
It could be easy to add support cert check in for smtps (see
secure_smtplib).
This patch was tested only on git-multimail (v1.2)
It introduces two new options:
- multimailhook.smtpcheckcert (default false)
- multimailhook.smtpcacerts (default
/etc/ssl/certs/ca-certificates.crt)
Best regards,
Simon P.
[-- Attachment #2: git-multimail-secure-smtplib.patch --]
[-- Type: text/x-patch, Size: 4235 bytes --]
diff --git a/git-multimail/git_multimail.py b/git-multimail/git_multimail.py
index fae5c91..b49ed9d 100755
--- a/git-multimail/git_multimail.py
+++ b/git-multimail/git_multimail.py
@@ -57,6 +57,7 @@ import subprocess
import shlex
import optparse
import smtplib
+import ssl
import time
import cgi
@@ -1945,6 +1946,7 @@ class SMTPMailer(Mailer):
smtpservertimeout=10.0, smtpserverdebuglevel=0,
smtpencryption='none',
smtpuser='', smtppass='',
+ smtpcacerts='/etc/ssl/certs/ca-certificates.crt',smtpcheckcert=False
):
if not envelopesender:
sys.stderr.write(
@@ -1974,13 +1976,43 @@ class SMTPMailer(Mailer):
if self.security == 'none':
self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout)
elif self.security == 'ssl':
+ if smtpcheckcert:
+ msg = "Checking certificate is not supported for ssl, prefer starttls"
+ raise smtplib.SMTPException(msg)
self.smtp = call(smtplib.SMTP_SSL, self.smtpserver, timeout=self.smtpservertimeout)
elif self.security == 'tls':
if ':' not in self.smtpserver:
self.smtpserver += ':587' # default port for TLS
self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout)
- self.smtp.ehlo()
- self.smtp.starttls()
+ if smtpcheckcert:
+ # inspired form:
+ # https://github.com/graingert/secure-smtplib/blob/master/src/secure_smtplib/__init__.py
+ # but add the path to trusted ca, and force ceritficate verification.
+ self.smtp.ehlo_or_helo_if_needed()
+ if not self.smtp.has_extn("starttls"):
+ msg = "STARTTLS extension not supported by server"
+ raise smtplib.SMTPException(msg)
+ (resp, reply) = self.smtp.docmd("STARTTLS")
+ if resp == 220:
+ self.smtp.sock = ssl.wrap_socket(
+ self.smtp.sock,
+ ca_certs=smtpcacerts,
+ cert_reqs=ssl.CERT_REQUIRED
+ )
+ if not hasattr(self.smtp.sock, "read"):
+ # using httplib.FakeSocket with Python 2.5.x or earlier
+ self.smtp.sock.read = self.smtp.sock.recv
+ self.smtp.file = smtplib.SSLFakeFile(self.smtp.sock)
+ self.smtp.helo_resp = None
+ self.smtp.ehlo_resp = None
+ self.smtp.esmtp_features = {}
+ self.smtp.does_esmtp = 0
+ else:
+ msg = "Wrong answer to the STARTTLS command"
+ raise smtplib.SMTPException(msg)
+ else:
+ self.smtp.ehlo()
+ self.smtp.starttls()
self.smtp.ehlo()
else:
sys.stdout.write('*** Error: Control reached an invalid option. ***')
@@ -3500,6 +3532,8 @@ def choose_mailer(config, environment):
smtpencryption = config.get('smtpencryption', default='none')
smtpuser = config.get('smtpuser', default='')
smtppass = config.get('smtppass', default='')
+ smtpcacerts = config.get('smtpcacerts', default='/etc/ssl/certs/ca-certificates.crt')
+ smtpcheckcert = config.get_bool('smtpcheckcert', default='false')
mailer = SMTPMailer(
envelopesender=(environment.get_sender() or environment.get_fromaddr()),
smtpserver=smtpserver, smtpservertimeout=smtpservertimeout,
@@ -3507,6 +3541,8 @@ def choose_mailer(config, environment):
smtpencryption=smtpencryption,
smtpuser=smtpuser,
smtppass=smtppass,
+ smtpcacerts=smtpcacerts,
+ smtpcheckcert=smtpcheckcert
)
elif mailer == 'sendmail':
command = config.get('sendmailcommand')
next reply other threads:[~2016-04-21 21:53 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-21 21:44 Simon P [this message]
2016-04-22 6:05 ` [git-multimail] smtplib, check certificate Matthieu Moy
2016-04-22 6:41 ` Michael Haggerty
2016-04-24 19:14 ` Simon Pontié
2016-04-24 18:20 ` Simon Pontié
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=571949D2.10507@le-huit.fr \
--to=simon.git@le-huit.fr \
--cc=git@vger.kernel.org \
--cc=matthieu.moy@grenoble-inp.fr \
--cc=mhagger@alum.mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).