Como posso enviar e-mails através do SSL SMTP com o .NET Framework?

Existe uma maneira com o .NET Framework para enviar e-mails através de um servidor SMTP SSL na porta 465?

A maneira usual:

System.Net.Mail.SmtpClient _SmtpServer = new System.Net.Mail.SmtpClient("tempurl.org"); _SmtpServer.Port = 465; _SmtpServer.EnableSsl = true; _SmtpServer.Credentials = new System.Net.NetworkCredential("username", "password"); _SmtpServer.Timeout = 5000; _SmtpServer.UseDefaultCredentials = false; MailMessage mail = new MailMessage(); mail.From = new MailAddress(from); mail.To.Add(to); mail.CC.Add(cc); mail.Subject = subject; mail.Body = content; mail.IsBodyHtml = useHtml; _SmtpServer.Send(mail); 

o tempo acabou:

 System.Net Verbose: 0 : [1024] SmtpClient::.ctor(host=ssl0.ovh.net, port=465) System.Net Information: 0 : [1024] Associating SmtpClient#64923656 with SmtpTransport#44624228 System.Net Verbose: 0 : [1024] Exiting SmtpClient::.ctor() -> SmtpClient#64923656 System.Net Information: 0 : [1024] Associating MailMessage#17654054 with Message#52727599 System.Net Verbose: 0 : [1024] SmtpClient#64923656::Send(MailMessage#17654054) System.Net Information: 0 : [1024] SmtpClient#64923656::Send(DeliveryMethod=Network) System.Net Information: 0 : [1024] Associating SmtpClient#64923656 with MailMessage#17654054 System.Net Information: 0 : [1024] Associating SmtpTransport#44624228 with SmtpConnection#14347911 System.Net Information: 0 : [1024] Associating SmtpConnection#14347911 with ServicePoint#51393439 System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Socket(InterNetwork#2) System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Socket() System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Socket(InterNetworkV6#23) System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#23264094::Socket() System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Connect(20:465#337754884) System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Connect() System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Close() System.Net.Sockets Verbose: 0 : [1024] Socket#23264094::Dispose() System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#23264094::Close() System.Net Information: 0 : [1024] Associating SmtpConnection#14347911 with SmtpPooledStream#14303791 System.Net.Sockets Verbose: 0 : [1024] Socket#26756241::Receive() System.Net.Sockets Verbose: 0 : [2404] Socket#26756241::Dispose() System.Net.Sockets Error: 0 : [1024] Exception in the Socket#26756241::Receive - A blocking operation was interrupted by a call to WSACancelBlockingCall System.Net.Sockets Verbose: 0 : [1024] Exiting Socket#26756241::Receive() -> 0#0 System.Net Error: 0 : [1024] Exception in the SmtpClient#64923656::Send - Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall. System.Net Error: 0 : [1024] at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.Net.DelegatedStream.Read(Byte[] buffer, Int32 offset, Int32 count) at System.Net.BufferedReadStream.Read(Byte[] buffer, Int32 offset, Int32 count) at System.Net.Mail.SmtpReplyReaderFactory.ReadLines(SmtpReplyReader caller, Boolean oneLine) at System.Net.Mail.SmtpReplyReaderFactory.ReadLine(SmtpReplyReader caller) at System.Net.Mail.SmtpConnection.GetConnection(String host, Int32 port) at System.Net.Mail.SmtpTransport.GetConnection(String host, Int32 port) at System.Net.Mail.SmtpClient.GetConnection() at System.Net.Mail.SmtpClient.Send(MailMessage message) System.Net Verbose: 0 : [1024] Exiting SmtpClient#64923656::Send() System.Net Information: 0 : [1024] Associating MailMessage#49584532 with Message#19699911 

Eu pesquisei e descobri que System.Net.Mail suporta conexões na porta 587 (porta padrão para SSL explícito que começa descriptografada, emite um STARTDLS e alterna para uma conexão Criptografada: RFC 2228), mas não suporta SSL implícito (conexão inteira está envolto em uma camada SSL) …

Aqui está um exemplo de como enviar e-mail através do Gmail, que também usa SSL / 465. Pequenos ajustes no código abaixo devem funcionar!

 using System.Web.Mail; using System; public class MailSender { public static bool SendEmail( string pGmailEmail, string pGmailPassword, string pTo, string pSubject, string pBody, System.Web.Mail.MailFormat pFormat, string pAttachmentPath) { try { System.Web.Mail.MailMessage myMail = new System.Web.Mail.MailMessage(); myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/smtpserver", "smtp.gmail.com"); myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/smtpserverport", "465"); myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/sendusing", "2"); //sendusing: cdoSendUsingPort, value 2, for sending the message using //the network. //smtpauthenticate: Specifies the mechanism used when authenticating //to an SMTP //service over the network. Possible values are: //- cdoAnonymous, value 0. Do not authenticate. //- cdoBasic, value 1. Use basic clear-text authentication. //When using this option you have to provide the user name and password //through the sendusername and sendpassword fields. //- cdoNTLM, value 2. The current process security context is used to // authenticate with the service. myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate","1"); //Use 0 for anonymous myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/sendusername", pGmailEmail); myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/sendpassword", pGmailPassword); myMail.Fields.Add ("http://schemas.microsoft.com/cdo/configuration/smtpusessl", "true"); myMail.From = pGmailEmail; myMail.To = pTo; myMail.Subject = pSubject; myMail.BodyFormat = pFormat; myMail.Body = pBody; if (pAttachmentPath.Trim() != "") { MailAttachment MyAttachment = new MailAttachment(pAttachmentPath); myMail.Attachments.Add(MyAttachment); myMail.Priority = System.Web.Mail.MailPriority.High; } System.Web.Mail.SmtpMail.SmtpServer = "smtp.gmail.com:465"; System.Web.Mail.SmtpMail.Send(myMail); return true; } catch (Exception ex) { throw; } } } 

Estou atrasado para esta festa, mas vou oferecer minha abordagem para qualquer transeunte que possa estar interessado em uma alternativa.

Conforme observado nas respostas anteriores, a class System.Net.Mail SmtpClient não suporta o SSL implícito . Suporta SSL explícito , que requer uma conexão insegura ao servidor SMTP pela porta 25 para negociar o TLS (Transport Level Security). Eu escrevi sobre minhas dificuldades com esta sutileza aqui .

Em suma, o SMTP sobre a porta SSL implícita 465 exige que o TLS seja negociado antes de se conectar ao servidor SMTP. Em vez de escrever uma implementação .Net SMTPS, procurei um utilitário chamado Stunnel . É um pequeno serviço que permite redirect o tráfego em uma porta local para uma porta remota via SSL.

ISENÇÃO DE RESPONSABILIDADE: Stunnel usa partes da biblioteca OpenSSL, que recentemente teve uma exploração de alto perfil publicada em todas as principais mídias de notícias de tecnologia. Eu acredito que a versão mais recente usa o OpenSSL corrigido, mas por favor use a seu próprio risco.

Depois que o utilitário é instalado, uma pequena adição ao arquivo de configuração:

 ; Example SSL client mode services [my-smtps] client = yes accept = 127.0.0.1:465 connect = mymailserver.com:465 

… instrui o serviço Stunnel a redirect solicitações locais para a porta 465 para o meu servidor de e-mail na porta 465. Isso acontece em relação ao TLS, que satisfaz o servidor SMTP na outra extremidade.

Usando este utilitário, o seguinte código será transmitido com êxito pela porta 465:

 using System; using System.Net; using System.Net.Mail; namespace RSS.SmtpTest { class Program { static void Main( string[] args ) { try { using( SmtpClient smtpClient = new SmtpClient( "localhost", 465 ) ) { // < -- note the use of localhost NetworkCredential creds = new NetworkCredential( "username", "password" ); smtpClient.Credentials = creds; MailMessage msg = new MailMessage( "joe@schmoe.com", "jane@schmoe.com", "Test", "This is a test" ); smtpClient.Send( msg ); } } catch( Exception ex ) { Console.WriteLine( ex.Message ); } } } } 

Portanto, a vantagem aqui é que você pode usar o Implict SSL e a porta 465 como o protocolo de segurança, enquanto ainda usa os methods de envio de email embutidos na estrutura. A desvantagem é que ele requer o uso de um serviço de terceiros que pode não ser útil para nada além dessa function específica.

Ele funciona com System.Web.Mail (que está marcado como obsoleto):

 private const string SMTP_SERVER = "http://schemas.microsoft.com/cdo/configuration/smtpserver"; private const string SMTP_SERVER_PORT = "http://schemas.microsoft.com/cdo/configuration/smtpserverport"; private const string SEND_USING = "http://schemas.microsoft.com/cdo/configuration/sendusing"; private const string SMTP_USE_SSL = "http://schemas.microsoft.com/cdo/configuration/smtpusessl"; private const string SMTP_AUTHENTICATE = "http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"; private const string SEND_USERNAME = "http://schemas.microsoft.com/cdo/configuration/sendusername"; private const string SEND_PASSWORD = "http://schemas.microsoft.com/cdo/configuration/sendpassword"; System.Web.Mail.MailMessage mail = new System.Web.Mail.MailMessage(); mail.Fields[SMTP_SERVER] = "tempurl.org"; mail.Fields[SMTP_SERVER_PORT] = 465; mail.Fields[SEND_USING] = 2; mail.Fields[SMTP_USE_SSL] = true; mail.Fields[SMTP_AUTHENTICATE] = 1; mail.Fields[SEND_USERNAME] = "username"; mail.Fields[SEND_PASSWORD] = "password"; System.Web.Mail.SmtpMail.Send(mail); 

Qual é o seu ponto de vista sobre o uso de namespace obsoleto?

Tente verificar isso gratuitamente uma alternativa de código aberto https://www.nuget.org/packages/AIM É livre para usar e abrir o código-fonte e usa exatamente a mesma maneira que o System.Net.Mail está usando Para enviar e-mail para o SSL implícito portas você pode usar o seguinte código

 public static void SendMail() { var mailMessage = new MimeMailMessage(); mailMessage.Subject = "test mail"; mailMessage.Body = "hi dude!"; mailMessage.Sender = new MimeMailAddress("you@gmail.com", "your name"); mailMessage.To.Add(new MimeMailAddress("yourfriend@gmail.com", "your friendd's name")); // You can add CC and BCC list using the same way mailMessage.Attachments.Add(new MimeAttachment("your file address")); //Mail Sender (Smtp Client) var emailer = new SmtpSocketClient(); emailer.Host = "your mail server address"; emailer.Port = 465; emailer.SslType = SslMode.Ssl; emailer.User = "mail sever user name"; emailer.Password = "mail sever password" ; emailer.AuthenticationMode = AuthenticationType.Base64; // The authentication types depends on your server, it can be plain, base 64 or none. //if you do not need user name and password means you are using default credentials // In this case, your authentication type is none emailer.MailMessage = mailMessage; emailer.OnMailSent += new SendCompletedEventHandler(OnMailSent); emailer.SendMessageAsync(); } // A simple call back function: private void OnMailSent(object sender, AsyncCompletedEventArgs asynccompletedeventargs) { if (e.UserState!=null) Console.Out.WriteLine(e.UserState.ToString()); if (e.Error != null) { MessageBox.Show(e.Error.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } else if (!e.Cancelled) { MessageBox.Show("Send successfull!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } } 

Se for um SSL implícito, parece que não pode ser feito com o System.Net.Mail e ainda não é suportado.

http://blogs.msdn.com/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx

Para verificar se é um SSL implícito, tente isto.

Você também pode se conectar através da porta 465, mas devido a algumas limitações do namespace System.Net.Mail, você pode ter que alterar seu código. Isso ocorre porque o namespace não oferece a capacidade de fazer conexões SSL implícitas. Isso é discutido em http://blogs.msdn.com/b/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx .

É possível fazer conexões implícitas sem ter que usar o namespace System.Web.Mail agora obsoleto, mas é necessário acessar o Microsoft CDO (Collaborative Data Object). Eu forneci um exemplo de como usar o CDO em outra discussão ( GMail SMTP via c # .net erros em todas as portas ).

Espero que isto ajude!

Em VB.NET ao tentar me conectar à porta SSL da Rackspace em 465, encontrei o mesmo problema (requer SSL implícito). Eu usei o https://www.nuget.org/packages/MailKit/ para conectar com sucesso.

A seguir, um exemplo de uma mensagem de email em HTML.

 Imports MailKit.Net.Smtp Imports MailKit Imports MimeKit Sub somesub() Dim builder As New BodyBuilder() Dim mail As MimeMessage mail = New MimeMessage() mail.From.Add(New MailboxAddress("", c_MailUser)) mail.To.Add(New MailboxAddress("", c_ToUser)) mail.Subject = "Mail Subject" builder.HtmlBody = "Body Text" builder.HtmlBody += "" mail.Body = builder.ToMessageBody() Using client As New SmtpClient client.Connect(c_MailServer, 465, True) client.AuthenticationMechanisms.Remove("XOAUTH2") ' Do not use OAUTH2 client.Authenticate(c_MailUser, c_MailPassword) ' Use a username / password to authenticate. client.Send(mail) client.Disconnect(True) End Using End Sub 

Eu sei que estou me juntando tarde à discussão, mas acho que isso pode ser útil para os outros.

Eu queria evitar coisas obsoletas e depois de muito mexer, descobri uma maneira simples de enviar para servidores que exigem SSL implícito: use o NuGet e adicione o pacote MailKit ao projeto. (Eu usei o VS2017 visando o .NET 4.6.2, mas ele deve funcionar em versões mais baixas do .NET …)

Então você só precisa fazer algo assim:

 using MailKit.Net.Smtp; using MimeKit; var client = new SmtpClient(); client.Connect("server.name", 465, true); // Note: since we don't have an OAuth2 token, disable the XOAUTH2 authentication mechanism. client.AuthenticationMechanisms.Remove ("XOAUTH2"); if (needsUserAndPwd) { // Note: only needed if the SMTP server requires authentication client.Authenticate (user, pwd); } var msg = new MimeMessage(); msg.From.Add(new MailboxAddress("sender@ema.il")); msg.To .Add(new MailboxAddress("target@ema.il")); msg.Subject = "This is a test subject"; msg.Body = new TextPart("plain") { Text = "This is a sample message body" }; client.Send(msg); client.Disconnect(true); 

É claro que você também pode ajustá-lo para usar SSL explícito ou nenhuma segurança de transporte.

Para o gmail, essas configurações funcionaram para mim, a linha ServicePointManager.SecurityProtocol era necessária. Como eu configurei a verificação em duas etapas, eu precisava de uma senha de app do gerador de senhas do Google Apps. SmtpClient mailer = new SmtpClient(); mailer.Host = "smtp.gmail.com"; mailer.Port = 587; mailer.EnableSsl = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

Como afirmado em um comentário em

http://blogs.msdn.com/webdav_101/archive/2008/06/02/system-net-mail-with-ssl-to-authenticate-against-port-465.aspx

com System.Net.Mail, use a porta 25 em vez de 465:

Você deve definir SSL = true e Port = 25. O servidor responde à sua solicitação de 25 desprotegidos e, em seguida, lança conexão com o 465 protegido.

Se tiver alguma dúvida neste código, por favor, faça suas perguntas (Aqui para gmail, o número da porta é 587)

 // code to Send Mail // Add following Lines in your web.config file //  //  //  //  //  //  //  // Add below lines in your config file inside appsetting tag  //  //  //  // Namespace Used using System.Net.Mail; public static bool SendingMail(string subject, string content) { // getting the values from config file through c# string fromEmail = ConfigurationSettings.AppSettings["emailFromAddress"]; string mailid = ConfigurationSettings.AppSettings["emailToAddress"]; bool useSSL; if (ConfigurationSettings.AppSettings["EmailSsl"] == "true") { useSSL = true; } else { useSSL = false; } SmtpClient emailClient; MailMessage message; message = new MailMessage(); message.From = new MailAddress(fromEmail); message.ReplyTo = new MailAddress(fromEmail); if (SetMailAddressCollection(message.To, mailid)) { message.Subject = subject; message.Body = content; message.IsBodyHtml = true; emailClient = new SmtpClient(); emailClient.EnableSsl = useSSL; emailClient.Send(message); } return true; } // if you are sending mail in group private static bool SetMailAddressCollection(MailAddressCollection toAddresses, string mailId) { bool successfulAddressCreation = true; toAddresses.Add(new MailAddress(mailId)); return successfulAddressCreation; }