Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is it necessary to enable SSL on MailKit

Tags:

c#

mailkit

I read on the Microsoft website that the SmtpClient was obsolete and they recommended using the MailKit for it's replacement.

I'm in the process of writing an application to make use of the MailKit.

This is what I have so far:

    // *************** SEND EMAIL *******************
    using (var client = new MailKit.Net.Smtp.SmtpClient())
    {
      //accept all SSL certificates
      client.ServerCertificateValidationCallback = (s, c, h, e) => true;

      client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.IsSslEnabled);

      if (emailSettings.IsAuthenticationRequired)
      {
        // Note: only needed if the SMTP server requires authentication
        client.Authenticate(emailSettings.SmtpUsername, emailSettings.SmtpPassword);
      }

      // timeout = 20 seconds
      client.Timeout = 20000;

      client.Send(message);
      client.Disconnect(true);
    }

When I set this part:

client.Connect(emailSettings.SmtpServer, emailSettings.SmtpPort, emailSettings.IsSslEnabled);

the last parameter is bool useSSL, which I set to true. My email server is hosted by Rackspace so I know that it uses SSL. When I set this option to true, it fails to send but if I set this option to false, it sends fine.

Shouldn't this line catch the certificate type:

client.ServerCertificateValidationCallback

If so, why wouldn't useSSL on the connect not work? Do I need to set the useSSL to false? I'm confused on how the useSSL works when I have the line above.

like image 786
TechGuy Avatar asked Jul 12 '19 13:07

TechGuy


1 Answers

Mail protocols (SMTP, IMAP, and POP3) all have 2 different ways of doing SSL.

System.Net.Mail.SmtpClient only implemented support for the STARTTLS way of doing SSL whereas MailKit does both.

When you specify useSsl as true in MailKit's Connect method, it assumes that you meant to use an SSL-wrapped connection (which is different from STARTTLS).

To make this less confusing, MailKit has a Connect method that takes a SecureSocketOptions argument instead of a bool.

The options are as follows:

  • None: Don't use any form of SSL (or TLS).
  • Auto: Automatically decides which type of SSL mode to use based on the specified port. Note: This only works reliable when the port is a standard defined port (e.g. 25, 587 or 465 for SMTP).
  • SslOnConnect: This specifies that MailKit should connect via an SSL-wrapped connection.
  • StartTls: Use the STARTTLS method for SSL/TLS encryption. If the server doesn't support the STARTTLS command, abort the connection.
  • StartTlsWhenAvailable: Use the STARTTLS method for SSL/TLS encryption if the server supports it, otherwise continue using an unencrypted channel.

Since you are using SMTP, you might find this useful:

Port 25 was the original port used for SMTP and it originally only supported unencrypted communications.

Later, administrators and users demanded SSL encryption so admins and mail clients started supporting SSL-wrapped connections on port 465 because this was very easy to do for admins (no server software needed to be upgraded and clients that didn't support SSL-wrapped connections could continue connecting on port 25).

After a few years of this, mail protocol authors introduced the STARTTLS command extension for IMAP, SMTP and POP3 (well, for POP3, the command is STLS but it is otherwise the same thing) that clients could optionally use if they supported it. This extension only made sense on the original (non-SSL-wrapped) ports.

These days STARTTLS is the preferred method for encrypting communications between a client and a mail server, but SSL-wrapped ports are still in wide use as well.

MailKit treats port 587 the same as it treats 25. In other words, it treats port 25 and 587 as a plain-text connection port but will switch to SSL/TLS if requested to do so via STARTTLS.

like image 60
jstedfast Avatar answered Oct 21 '22 21:10

jstedfast