Using python to send email through TLS
<p>I am trying to automate sending email through a python script. I am presently using an expect script to use openssl s_client to connect to the server. Presently we only use a certificate file along with the username password and it allows me to send the email. I found another question in which it was mentioned that in python you either need a hack to or a wrapper around the smtp class to use only the CA cert file and not the key file(which i don't have). </p>

<pre><code>&gt;&gt;&gt; smtpobj = smtplib.SMTP("mymailserver.com",465)
Traceback (innermost last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "C:\Program Files (x86)\Python35-32\lib\smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
  File "C:\Program Files (x86)\Python35-32\lib\smtplib.py", line 337, in connect
(code, msg) = self.getreply()
  File "C:\Program Files (x86)\Python35-32\lib\smtplib.py", line 390, in getreply
+ str(e))
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [WinError 10054] An existing connection was forcibly closed by the remote host
</code></pre>

<p>The problem I am facing right now is that I am unable to connect to the server through python.</p>

<p>If I use the certificate file to connect through </p>

<pre><code>smtplib.SMTP_SSL(myserver, port, certfile="mycert.cert") 
</code></pre>

<p>then it throws the following error.</p>

<pre><code>ssl.SSLError: [Errno 336265225] _ssl.c:339: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
</code></pre>

<p>Please note, I am able to connect to the server using thunderbird, without a cert file. Any ideas, on how I can use python smtp(tls) to send the emails? </p>

<blockquote>
<pre><code>smtpobj = smtplib.SMTP("mymailserver.com",465)
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [WinError 10054] An existing connection was forcibly closed by the remote host
</code></pre>
</blockquote>

<p>This error has nothing to do with validation of the certificate. It is simply that you are using explicit TLS (i.e. STARTTLS command on plain connection) on a port which requires implicit TLS (TLS from start). Try this instead:</p>

<pre><code>smtpobj = smtplib.SMTP_SSL("mymailserver.com",465)
</code></pre>

<p>Apart from that:</p>

<blockquote>
  <p>... you either need a hack to or a wrapper around the smtp class to use only the CA cert file and not the key file(which i don't have).</p>
</blockquote>

<p>I think you mixing up some concepts:</p>

<ul>
<li>CA cert: this contains the trusted root which is needed to verify the certificate of the server. You don't have a key for this certificate and you don't need one.</li>
<li>local cert, local key: these are used if the server requires authentication with a client certificate. In this case both cert and key are needed</li>
</ul>

<p>What you probably want to specify is a CA cert in order to verify the servers certificate. Unfortunately smtplib does not give you a way to specify this CA certificate. You've tried certfile but this is used for specifying the local cert for client certificate authentication and it requires a key file.</p>

<p>The good news is: <strong>it works without specifying a CA cert</strong> because smtplib simply does not verify the servers certificate at all. The bad news is: because there is no verification of the server certificate <strong>a man in the middle attack against the encrypted connection is easy</strong>.</p>

python email ssl