I'm trying to access gmail emails using imap and the code is failing at the ssl handshake without showing me any errors. Really appreciate if anyone could please help with this. I've built this using xunit, .NET Core 2.1. I'm using MailKit Nuget
public GMailHandler(string mailServer, int port, bool ssl, string login, string password)
//mailServer = imap.gmail.com
//port = 993
//ssl = true
{
if (ssl)
Client.Connect(mailServer, port);
else
Client.Connect(mailServer, port);
Client.Authenticate(login, password);
Client.Inbox.Open(FolderAccess.ReadOnly);
}
Here's a copy & paste from the MailKit FAQ:
"MailKit.Security.SslHandshakeException: An error occurred while attempting to establish an SSL or TLS connection."
when I try to Connect?When you get an exception with that error message, it usually means that you are encountering one of the following scenarios:
There are 2 different ways to use SSL/TLS encryption with mail servers.
The first way is to enable SSL/TLS encryption immediately upon connecting to the SMTP, POP3 or IMAP server. This method requires an "SSL port" because the standard port defined for the protocol is meant for plain-text communication.
The second way is via a STARTTLS
command (aka STLS
for POP3) that is optionally
supported by the server.
Below is a table of the protocols supported by MailKit and the standard plain-text ports
(which either do not support any SSL/TLS encryption at all or only via the STARTTLS
command extension) and the SSL ports which require SSL/TLS encryption immediately upon a
successful connection to the remote host.
|Protocol|Standard Port|SSL Port|
|:------:|:-----------:|:------:|
| SMTP | 25 or 587 | 465 |
| POP3 | 110 | 995 |
| IMAP | 143 | 993 |
It is important to use the correct SecureSocketOptions
for the port that you are connecting to.
If you are connecting to one of the standard ports above, you will need to use SecureSocketOptions.None
,
SecureSocketOptions.StartTls
or SecureSocketOptions.StartTlsWhenAvailable
.
If you are connecting to one of the SSL ports, you will need to use SecureSocketOptions.SslOnConnect
.
You could also try using SecureSocketOptions.Auto
which works by choosing the appropriate option to use
by comparing the specified port to the ports in the above table.
Often times, mail servers will use self-signed certificates instead of using a certificate that has been signed by a trusted Certificate Authority. Another potential pitfall is when locally installed anti-virus software replaces the certificate in order to scan web traffic for viruses.
When your system is unable to validate the mail server's certificate because it is not signed by a known and trusted Certificate Authority, the above error will occur.
You can work around this problem by supplying a custom RemoteCertificateValidationCallback and setting it on the client's ServerCertificateValidationCallback property.
In the simplest example, you could do something like this (although I would strongly recommend against it in production use):
using (var client = new SmtpClient ()) {
client.ServerCertificateValidationCallback = (s,c,h,e) => true;
client.Connect (hostName, port, SecureSocketOptions.Auto);
// ...
}
Most likely you'll want to instead compare the certificate's Thumbprint property to a known value that you have verified at a prior date.
You could also use this callback to prompt the user (much like you have probably seen web browsers do) as to whether or not the certificate should be trusted.
Most Certificate Authorities are probably pretty good at keeping their CRL and/or OCSP servers up 24/7, but occasionally they do go down or are otherwise unreachable due to other network problems between you and the server. When this happens, it becomes impossible to check the revocation status of one or more of the certificates in the chain.
To ignore revocation checks, you can set the
CheckCertificateRevocation
property of the IMAP, POP3 or SMTP client to false
before you connect:
using (var client = new SmtpClient ()) {
client.CheckCertificateRevocation = false;
client.Connect (hostName, port, SecureSocketOptions.Auto);
// ...
}
MailKit attempts to keep up with the latest security recommendations and so is continuously removing older SSL and TLS protocols that are no longer considered secure from the default configuration. This often means that MailKit's SMTP, POP3 and IMAP clients will fail to connect to servers that are still using older SSL and TLS protocols. Currently, the SSL and TLS protocols that are not supported by default are: SSL v2.0, SSL v3.0, and TLS v1.0.
You can override MailKit's default set of supported SSL and TLS protocols by setting the value of the SslProtocols property on your SMTP, POP3 or IMAP client.
For example:
using (var client = new SmtpClient ()) {
// Allow SSLv3.0 and all versions of TLS
client.SslProtocols = SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
client.Connect ("smtp.gmail.com", 465, true);
// ...
}