19

I am trying to connect to iCloud via SmtpClient

The settings I am using are as follows:

Server name: smtp.mail.me.com
SSL Required: Yes
If you see an error message when using SSL, try using TLS or STARTTLS instead.
Port: 587
SMTP Authentication Required: Yes - with relevant username and password

If I use SSL I get "Handshake failed due to unexpected packet format"

If I don't use SSL visual studio debugger hangs on connect.

I think the problem is I am not telling the SmtpClient to use tls but I cant find documentation on how to do this.

The code is as follows:

using (var client = new SmtpClient()) {
    client.Timeout = 1000 * 20;
    //client.Capabilities.
    client.AuthenticationMechanisms.Remove ("XOAUTH2");

    client.Connect("SMTP.mail.me.com", 587, false); //dies here
    //client.Connect(servername, port, useSsl);
    //can I set tls or starttls here??
    client.Authenticate(username, password);
    client.Send(FormatOptions.Default, message);
}

Am I able to set TLS or StartTLS manually. One thing I did try is the following but it did not seem to work

client.Connect(new Uri("smtp://" + servername + ":" + port + "/?starttls=true"));

Thanks for any help with this.

knocte
  • 16,941
  • 11
  • 79
  • 125
Jaybeecave
  • 827
  • 2
  • 8
  • 17
  • Why are you passing `false` for the `useSSL` flag if you're saying you require `SSL`? – Rob Jul 22 '15 at 01:49
  • @Rob I've tried with true and I get a Handshake failed due to unexpected packet format. iCloud suggests this: "If you see an error message when using SSL, try using TLS or STARTTLS instead." – Jaybeecave Jul 22 '15 at 02:25

5 Answers5

32

The Connect() method that you are using only allows enabling/disabling SSL-wrapped connections which is not the same thing as StartTLS.

Due to the confusion, I've implemented a separate Connect() method that makes this more obvious what is going on:

using (var client = new SmtpClient()) {
    // Note: don't set a timeout unless you REALLY know what you are doing.
    //client.Timeout = 1000 * 20;

    client.Connect ("smtp.mail.me.com", 587, SecureSocketOptions.StartTls);
    client.Authenticate (username, password);
    client.Send (message);
}

Try that.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • @jstedfast imap client hangs on connect sometimes. until the windows service is forced to restart. is there a way to time it out so that it restarts on its own – coder771 Oct 12 '18 at 09:34
  • Depends on where it is hanging. If it is in the socket.Connect() call, then no. If it is in the code that reads the greeting, etc after the socket.Connect(), then yes - set the `client.Timeout` value. – jstedfast Oct 12 '18 at 12:46
5

You can set your options to "SecureSocketOptions.Auto" something like this

await client.ConnectAsync(mailService.Host, mailService.Port,   SecureSocketOptions.Auto);

MailKit will automatically decide to use SSL or TLS.

error505
  • 1,126
  • 1
  • 17
  • 29
  • What does it use to decide? The port number? – Paul Knopf Aug 21 '16 at 23:15
  • Port number you must set in your model. It is just port number from google mail or what ever. So I just call my model and ask for port and host from my DB.... But what is important here is "SecureSocketOptions.Auto" – error505 Aug 22 '16 at 14:10
  • 1
    @PaulKnopf Yes, MailKit uses the port to decide. It's not the best system in the world, but it works 99% of the time. – jstedfast Mar 09 '17 at 20:16
2

According to MailKit Doc

Connect(string host,int port,bool useSsl,CancellationToken cancellationToken = null)

The useSsl argument only controls whether or not the client makes an SSL-wrapped connection. In other words, even if the useSsl parameter is false, SSL/TLS may still be used if the mail server supports the STARTTLS extension.

Michael Freidgeim
  • 26,542
  • 16
  • 152
  • 170
0

This worked for me over the SecureSocketOptions.Auto option mentioned previously:

    client.Connect(host, port, SecureSocketOptions.None);
0

For anyone using the samples from the FluentEmail documentation, to use "StartTLS" with FluentEmail and MailKit, I ended up with this in my program.cs:

var smtpClientOptions =  new SmtpClientOptions
{
    Server = "myserver.blah.com",
    Port = 587,
    Password = "supersecure",
    UseSsl = true,
    User = "blah@blah.com",
    SocketOptions = SecureSocketOptions.StartTls
};

builder.Services.AddFluentEmail("blah@blah.com")
        .AddMailKitSender(smtpClientOptions);
        
Email.DefaultSender = new MailKitSender(smtpClientOptions);

And just send email like this:

var email = await Email
            .From("blah@blah.com")
            .To("you@blah.com", "You")
            .Subject("You know exactly what this is")
            .Body("Yep, this is an email example I am sending.")
            .SendAsync();
flashsplat
  • 433
  • 3
  • 13