<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://illuminatedcomputing.com/">
  <id>https://illuminatedcomputing.com/</id>
  <title>Illuminated Computing</title>
  <updated>2013-07-15T00:00:00Z</updated>
  <link rel="alternate" href="https://illuminatedcomputing.com/" type="text/html"/>
  <link rel="self" href="https://illuminatedcomputing.com/tags/smtp/atom.xml" type="application/atom+xml"/>
  <author>
    <name>Paul A. Jungwirth</name>
    <uri>https://illuminatedcommputing.com/</uri>
  </author>
  <entry>
    <id>tag:illuminatedcomputing.com,2013-07-15:/posts/2013/07/public-keys-via-smtp/</id>
    <title type="html">Why not distribute public keys via SMTP?</title>
    <published>2013-07-15T00:00:00Z</published>
    <updated>2013-07-15T00:00:00Z</updated>
    <link rel="alternate" href="https://illuminatedcomputing.com/posts/2013/07/public-keys-via-smtp/" type="text/html"/>
    <content type="html">
&lt;p&gt;One of the hurdles to end-to-end email encryption is key distribution. Doing this manually ensures that only technical people will bother, so why not automate it via some protocol? A natural method would be to extend SMTP so the sender can ask if a user’s key exists, and if so then use that to send the message, e.g. like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HELO relay.example.org
250
MAIL FROM:&amp;lt;bob@example.org&amp;gt;
250
KEY FOR:&amp;lt;alice@example.com&amp;gt;
250
--- BEGIN PGP PUBLIC KEY BLOCK ---
...
--- END PGP PUBLIC KEY BLOCK ---
RCPT TO:&amp;lt;alice@example.com&amp;gt;
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;KEY FOR&lt;/code&gt; capability could also be discoverable via the common &lt;a href="http://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol#Optional_extensions"&gt;&lt;code&gt;EHLO&lt;/code&gt; command&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;EHLO relay.example.org
250-smtp.example.org 
250-KEYS    
...&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why hasn’t this been suggested before? Googling I found only &lt;a href="http://kenta.blogspot.com/2010/04/xtkofktg-public-key-distribution.html"&gt;one link&lt;/a&gt;. Is there some flaw with it?&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:illuminatedcomputing.com,2011-03-25:/posts/2011/03/starttls-problems-with-ruby/</id>
    <title type="html">STARTTLS Problems with Ruby</title>
    <published>2011-03-25T00:00:00Z</published>
    <updated>2011-03-25T00:00:00Z</updated>
    <link rel="alternate" href="https://illuminatedcomputing.com/posts/2011/03/starttls-problems-with-ruby/" type="text/html"/>
    <content type="html">
&lt;p&gt;If you want to send email from a Ruby program, one approach is to hit an SMTP server where you have an account, and ask it to send the email in your name. This is nice, because you ensure your &lt;code&gt;From:&lt;/code&gt; and &lt;code&gt;Sender:&lt;/code&gt; fields contain real addresses. There are lots of sites out there that describe how to do this with Gmail. The best library to use seems to be Pony. From a Ruby 1.8.7 script, you can say this:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;span class="doctype"&gt;#!/usr/bin/env ruby&lt;/span&gt;

require &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;rubygems&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;
require &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;pony&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;

from = &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;example@gmail.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;
to = &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;someone@example.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;
subject = &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;testing&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;
msg = &lt;span class="string"&gt;&lt;span class="delimiter"&gt;&amp;lt;&amp;lt;EOM&lt;/span&gt;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="content"&gt;
Hello, this is a test!&lt;/span&gt;&lt;span class="delimiter"&gt;
EOM&lt;/span&gt;&lt;/span&gt;

&lt;span class="constant"&gt;Pony&lt;/span&gt;.mail(&lt;span class="symbol"&gt;:to&lt;/span&gt; =&amp;gt; to,
          &lt;span class="symbol"&gt;:from&lt;/span&gt; =&amp;gt; from,
          &lt;span class="symbol"&gt;:subject&lt;/span&gt; =&amp;gt; subject,
          &lt;span class="symbol"&gt;:body&lt;/span&gt; =&amp;gt; msg,
          &lt;span class="symbol"&gt;:via&lt;/span&gt; =&amp;gt; &lt;span class="symbol"&gt;:smtp&lt;/span&gt;,
          &lt;span class="symbol"&gt;:via_options&lt;/span&gt; =&amp;gt; {
            &lt;span class="symbol"&gt;:address&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;smtp.gmail.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:port&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;587&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:enable_starttls_auto&lt;/span&gt; =&amp;gt; &lt;span class="predefined-constant"&gt;true&lt;/span&gt;,
            &lt;span class="symbol"&gt;:user_name&lt;/span&gt; =&amp;gt; from,
            &lt;span class="symbol"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;OMITTED&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:authentication&lt;/span&gt; =&amp;gt; &lt;span class="symbol"&gt;:plain&lt;/span&gt;,
          }
         )&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;:enable_starttls_auto&lt;/code&gt; line is actually optional, because it defaults to true. Unless you tell it otherwise, Ruby’s SMTP library will negotiate with the server for TLS. This is an SSL-like encryption scheme which you initiate from a regular SMTP session by sending the STARTTLS command. Without TLS, the whole SMTP conversation is in plaintext, including the email body and your account password. So in general, Ruby’s approach is a good thing. The trouble I encountered is that I didn’t want my emails to come from a Gmail account. I wanted them to come from illuminatedcomputing.com. And while my webhost does let me send emails via its SMTP server, its SSL certificate is a little wanting: the domain name on it is &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Strictly speaking, this means a client should reject the certificate, because it doesn’t match the domain you think you’re connecting to. This is what Ruby does, which means Pony was failing with this error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/lib/ruby/1.8/openssl/ssl.rb:124:in `post_connection_check':
hostname was not match with the server certificate (OpenSSL::SSL::SSLError)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(I guess this is the kind of error message you get when you use a language from Japan. :-)&lt;/p&gt;

&lt;p&gt;I couldn’t find any obvious way around this. You can tell Ruby’s SSLContext to ignore a mismatched domain name, but how can you tell Pony to pass this setting on to Mail, which should pass it on to SMTP, which should set it on the SSLContext? It seemed hopeless. My first attempt was rather heavy-handed, just overriding the default SSLContext:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;span class="keyword"&gt;class&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="class"&gt;Net::SMTP&lt;/span&gt;
  remove_method &lt;span class="symbol"&gt;:default_ssl_context&lt;/span&gt; &lt;span class="comment"&gt;# if defined?(Net::SMTP.default_ssl_context)&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;module&lt;/span&gt; &lt;span class="class"&gt;Net&lt;/span&gt;
    &lt;span class="keyword"&gt;class&lt;/span&gt; &lt;span class="class"&gt;SMTP&lt;/span&gt;
        &lt;span class="keyword"&gt;def&lt;/span&gt; &lt;span class="constant"&gt;SMTP&lt;/span&gt;.&lt;span class="function"&gt;default_ssl_context&lt;/span&gt;
            ctx = &lt;span class="constant"&gt;OpenSSL&lt;/span&gt;::&lt;span class="constant"&gt;SSL&lt;/span&gt;::&lt;span class="constant"&gt;SSLContext&lt;/span&gt;.new
            ctx.verify_mode = &lt;span class="constant"&gt;OpenSSL&lt;/span&gt;::&lt;span class="constant"&gt;SSL&lt;/span&gt;::&lt;span class="constant"&gt;VERIFY_NONE&lt;/span&gt;
            ctx
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This works, but it affects too much: probably all the SSL connections you make throughout your application.&lt;/p&gt;

&lt;p&gt;With some more digging, I noticed that Mail::SMTP accepted an option called &lt;code&gt;:openssl_verify_mode&lt;/code&gt;, which could be set to the constant &lt;code&gt;OpenSSL::SSL::VERIFY_NONE&lt;/code&gt;. If I passed this to Pony in the &lt;code&gt;:via_options&lt;/code&gt; hash, would it pass it along? There was no documentation suggesting it would, but I tried it anyway, and guess what? It worked! So this code is a way to get around a no-domain SSL certificate without wrecking SSL for your whole application:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;code class="language-ruby"&gt;&lt;span class="constant"&gt;Pony&lt;/span&gt;.mail(&lt;span class="symbol"&gt;:to&lt;/span&gt; =&amp;gt; to,
          &lt;span class="symbol"&gt;:from&lt;/span&gt; =&amp;gt; from,
          &lt;span class="symbol"&gt;:subject&lt;/span&gt; =&amp;gt; subject,
          &lt;span class="symbol"&gt;:body&lt;/span&gt; =&amp;gt; msg,
          &lt;span class="symbol"&gt;:via&lt;/span&gt; =&amp;gt; &lt;span class="symbol"&gt;:smtp&lt;/span&gt;,
          &lt;span class="symbol"&gt;:via_options&lt;/span&gt; =&amp;gt; {
            &lt;span class="symbol"&gt;:address&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;smtp.mydomain.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:port&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;25&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:enable_starttls_auto&lt;/span&gt; =&amp;gt; &lt;span class="predefined-constant"&gt;true&lt;/span&gt;,
            &lt;span class="symbol"&gt;:user_name&lt;/span&gt; =&amp;gt; from,
            &lt;span class="symbol"&gt;:password&lt;/span&gt; =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;OMITTED&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
            &lt;span class="symbol"&gt;:authentication&lt;/span&gt; =&amp;gt; &lt;span class="symbol"&gt;:plain&lt;/span&gt;,
            &lt;span class="symbol"&gt;:openssl_verify_mode&lt;/span&gt; =&amp;gt; &lt;span class="constant"&gt;OpenSSL&lt;/span&gt;::&lt;span class="constant"&gt;SSL&lt;/span&gt;::&lt;span class="constant"&gt;VERIFY_NONE&lt;/span&gt;,
          }
         )&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m very impressed that Pony lets you get away with this.&lt;/p&gt;

&lt;p&gt;Please note that this approach is not entirely secure! The reason an SSL certificate contains a domain name is to prove you’re talking to the real owner of the domain. So the code above is not ideal. Please use it at your own risk, and don’t blame me if anything goes wrong. In my case, I’m not too surprised that my hosting provider doesn’t pay for a separate SSL certificate for every single customer, and I’m willing to risk a DNS spoofing attack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; The same parameter works with ActionMailer, so you can say this (Rails 3):&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;div class="code"&gt;&lt;pre&gt;&lt;code class="language-ruby"&gt;config.action_mailer.smtp_settings = {
      &lt;span class="symbol"&gt;:address&lt;/span&gt;              =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;smtp.mydomain.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:port&lt;/span&gt;                 =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;25&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:domain&lt;/span&gt;               =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;mydomain.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:user_name&lt;/span&gt;            =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;example@mydomain.com&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:password&lt;/span&gt;             =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;OMITTED&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:authentication&lt;/span&gt;       =&amp;gt; &lt;span class="string"&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;span class="content"&gt;plain&lt;/span&gt;&lt;span class="delimiter"&gt;'&lt;/span&gt;&lt;/span&gt;,
      &lt;span class="symbol"&gt;:enable_starttls_auto&lt;/span&gt; =&amp;gt; &lt;span class="predefined-constant"&gt;true&lt;/span&gt;,
      &lt;span class="symbol"&gt;:openssl_verify_mode&lt;/span&gt;  =&amp;gt; &lt;span class="constant"&gt;OpenSSL&lt;/span&gt;::&lt;span class="constant"&gt;SSL&lt;/span&gt;::&lt;span class="constant"&gt;VERIFY_NONE&lt;/span&gt;,
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
  </entry>
</feed>

