Search code examples
oauth-2.0google-oauthmailkitgoogle-oauth-.net-client

Error trying to Connect to GMail with MailKit


I've got the following code...

var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets
{
    ClientId = "<< MY CLIENT ID>>",
    ClientSecret = "<<MY CLIENT SECRET>>"
},
                new[] { "https://www.googleapis.com/auth/gmail.readonly" },
                "<<EMAIL ADDRESS>>",
                CancellationToken.None,
                new FileDataStore("Mail2.Auth.Store")).Result;

using (var client = new ImapClient())
{
    // THE CODE FAILS ON THIS NEXT LINE
    client.Connect("imap.gmail.com", 993, SecureSocketOptions.SslOnConnect);
    client.Authenticate("<<EMAIL ADDRESS>>", credential.Token.AccessToken);
}

When run, the code fails on the indicated like with AuthenticationException: The remote certificate is invalid according to the validation procedure.

I initially thought that is was 'cos the account had 2-step authentication on. So, I set up another account ensuring it just used the regular authentication settings and I got the same error.

I have found a number of posts, here and elsewhere, that deal with this exception but they seem to deal with the issue of working with the SmtpClient() and here, as you can see from the code, I'm getting the error with the ImapClient().

Can anyone suggest what it is that may be the cause of the error? Is it GMail? MailKit? .NET? All of the above?


Solution

  • The problem is that your system does not accept the GMail's SSL certificate.

    You can override client.ServerCertificateValidationCallback.

    A very simple example of a solution might look like this:

    client.ServerCertificateValidationCallback = () => true;
    

    Obviously that means that if anyone ever spoofed imap.gmail.com, your software would get caught in a MITM attack, so that's not ideal.

    You'll likely want to match the certificate's thumbprint against a known thumbprint or else add the certificate to your local certificate store and assign a trust level to it.