diff --git a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs index b455a9003..ea889b8e6 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/EmailTests/EmailSettingsValidatorFixture.cs @@ -25,7 +25,6 @@ namespace NzbDrone.Core.Test.NotificationTests.EmailTests _emailSettings = Builder.CreateNew() .With(s => s.Server = "someserver") .With(s => s.Port = 567) - .With(s => s.Ssl = true) .With(s => s.From = "radarr@radarr.video") .With(s => s.To = new string[] { "radarr@radarr.video" }) .Build(); diff --git a/src/NzbDrone.Core/Notifications/Email/EmailService.cs b/src/NzbDrone.Core/Notifications/Email/EmailService.cs index 8a82cb79d..a7ee6e9ba 100644 --- a/src/NzbDrone.Core/Notifications/Email/EmailService.cs +++ b/src/NzbDrone.Core/Notifications/Email/EmailService.cs @@ -1,8 +1,9 @@ using System; using System.Linq; -using System.Net; -using System.Net.Mail; using FluentValidation.Results; +using MailKit.Net.Smtp; +using MailKit.Security; +using MimeKit; using NLog; namespace NzbDrone.Core.Notifications.Email @@ -24,27 +25,22 @@ namespace NzbDrone.Core.Notifications.Email public void SendEmail(EmailSettings settings, string subject, string body, bool htmlBody = false) { - var email = new MailMessage(); - email.From = new MailAddress(settings.From); + var email = new MimeMessage(); + email.From.Add(MailboxAddress.Parse(settings.From)); - settings.To.ToList().ForEach(x => email.To.Add(x)); - settings.CC.ToList().ForEach(x => email.CC.Add(x)); - settings.Bcc.ToList().ForEach(x => email.Bcc.Add(x)); + settings.To.ToList().ForEach(x => email.To.Add(MailboxAddress.Parse(x))); + settings.CC.ToList().ForEach(x => email.Cc.Add(MailboxAddress.Parse(x))); + settings.Bcc.ToList().ForEach(x => email.Bcc.Add(MailboxAddress.Parse(x))); email.Subject = subject; - email.Body = body; - email.IsBodyHtml = htmlBody; - - NetworkCredential credentials = null; - - if (!string.IsNullOrWhiteSpace(settings.Username)) + email.Body = new TextPart(htmlBody ? "html" : "plain") { - credentials = new NetworkCredential(settings.Username, settings.Password); - } + Text = body + }; try { - Send(email, settings.Server, settings.Port, settings.Ssl, credentials); + Send(email, settings); } catch (Exception ex) { @@ -54,13 +50,34 @@ namespace NzbDrone.Core.Notifications.Email } } - private void Send(MailMessage email, string server, int port, bool ssl, NetworkCredential credentials) + private void Send(MimeMessage email, EmailSettings settings) { - var smtp = new SmtpClient(server, port); - smtp.EnableSsl = ssl; - smtp.Credentials = credentials; + using (var client = new SmtpClient()) + { + var serverOption = SecureSocketOptions.Auto; - smtp.Send(email); + if (settings.RequireEncryption) + { + if (settings.Port == 465) + { + serverOption = SecureSocketOptions.SslOnConnect; + } + else + { + serverOption = SecureSocketOptions.StartTls; + } + } + + client.Connect(settings.Server, settings.Port, serverOption); + + if (!string.IsNullOrWhiteSpace(settings.Username)) + { + client.Authenticate(settings.Username, settings.Password); + } + + client.Send(email); + client.Disconnect(true); + } } public ValidationFailure Test(EmailSettings settings) diff --git a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs index 417d2341d..83a9a263e 100644 --- a/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs +++ b/src/NzbDrone.Core/Notifications/Email/EmailSettings.cs @@ -34,7 +34,6 @@ namespace NzbDrone.Core.Notifications.Email { Server = "smtp.gmail.com"; Port = 587; - Ssl = true; To = Array.Empty(); CC = Array.Empty(); @@ -47,8 +46,8 @@ namespace NzbDrone.Core.Notifications.Email [FieldDefinition(1, Label = "Port")] public int Port { get; set; } - [FieldDefinition(2, Label = "SSL", Type = FieldType.Checkbox)] - public bool Ssl { get; set; } + [FieldDefinition(2, Label = "Require Encryption", HelpText = "Require SSL (Port 465 only) or StartTLS (any other port)", Type = FieldType.Checkbox)] + public bool RequireEncryption { get; set; } [FieldDefinition(3, Label = "Username", Privacy = PrivacyLevel.UserName)] public string Username { get; set; } diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 6d9300396..f5a803a08 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -4,6 +4,7 @@ +