c# mono gmail monodevelop smtpclient

c# - SmtpClient con Gmail



mono monodevelop (6)

Comencé a recibir esto con GMail en mayo de 2013 después de trabajar para 6 meses. El documento de Uso de las Raíces Confiables del Proyecto Mono Respetuosamente proporcionó orientación sobre cómo trabajar. Elegí la opción # 1:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Es demasiado perturbador que el correo electrónico de mi servicio deje de funcionar sin previo aviso.

Actualización del 26 de agosto de 2016: el usuario Chico sugirió la siguiente implementación completa de la devolución de llamada ServerCertificateValidationCallback. No he probado.

ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback; bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { bool isOk = true; // If there are errors in the certificate chain, look at each error to determine the cause. if (sslPolicyErrors != SslPolicyErrors.None) { for (int i=0; i<chain.ChainStatus.Length; i++) { if (chain.ChainStatus [i].Status != X509ChainStatusFlags.RevocationStatusUnknown) { chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0); chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; bool chainIsValid = chain.Build ((X509Certificate2)certificate); if (!chainIsValid) { isOk = false; } } } } return isOk; }

Estoy desarrollando un cliente de correo para un proyecto escolar. He logrado enviar correos electrónicos usando el SmtpClient en C #. Esto funciona perfectamente con cualquier servidor, pero no funciona con Gmail. Creo que es debido a Google utilizando TLS. He intentado establecer EnableSsl en true en el SmtpClient pero esto no hace una diferencia.

Este es el código que estoy usando para crear el SmtpClient y enviar un correo electrónico.

this.client = new SmtpClient("smtp.gmail.com", 587); this.client.EnableSsl = true; this.client.UseDefaultCredentials = false; this.client.Credentials = new NetworkCredential("username", "password"); try { // Create instance of message MailMessage message = new MailMessage(); // Add receiver message.To.Add("[email protected]"); // Set sender // In this case the same as the username message.From = new MailAddress("[email protected]"); // Set subject message.Subject = "Test"; // Set body of message message.Body = "En test besked"; // Send the message this.client.Send(message); // Clean up message = null; } catch (Exception e) { Console.WriteLine("Could not send e-mail. Exception caught: " + e); }

Este es el error que recibo cuando intento enviar un correo electrónico.

Could not send e-mail. Exception caught: System.Net.Mail.SmtpException: Message could not be sent. ---> System.IO.IOException: The authentication or decryption has failed. ---> System.InvalidOperationException: SSL authentication error: RemoteCertificateNotAvailable, RemoteCertificateChainErrors at System.Net.Mail.SmtpClient.<callback>m__4 (System.Object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) [0x00000] in <filename unknown>:0 at System.Net.Security.SslStream+<BeginAuthenticateAsClient>c__AnonStorey7.<>m__A (System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Int32[] certErrors) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslClientStream.OnRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslStreamBase.RaiseRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.SslClientStream.RaiseServerCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] certificateErrors) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0 at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process () at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at System.Net.Mail.SmtpClient.Send (System.Net.Mail.MailMessage message) [0x00000] in <filename unknown>:0 at P2Mailclient.SMTPClient.send (P2Mailclient.Email email) [0x00089] in /path/to/my/project/SMTPClient.cs:57

¿Alguien tiene una idea de por qué podría estar recibiendo este error?


Creo que es necesario validar el certificado del servidor que se utiliza para establecer las conexiones SSL ...

Utilice el siguiente código para enviar correo con el certificado del servidor de validación ...

this.client = new SmtpClient(_account.SmtpHost, _account.SmtpPort); this.client.EnableSsl = _account.SmtpUseSSL; this.client.Credentials = new NetworkCredential(_account.Username, _account.Password); try { // Create instance of message MailMessage message = new MailMessage(); // Add receivers for (int i = 0; i < email.Receivers.Count; i++) message.To.Add(email.Receivers[i]); // Set sender message.From = new MailAddress(email.Sender); // Set subject message.Subject = email.Subject; // Send e-mail in HTML message.IsBodyHtml = email.IsBodyHtml; // Set body of message message.Body = email.Message; //validate the certificate ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; // Send the message this.client.Send(message); // Clean up message = null; } catch (Exception e) { Console.WriteLine("Could not send e-mail. Exception caught: " + e); }

Importe el espacio de nombres de System.Security.Cryptography.X509Certificates para usar ServicePointManager


Debe habilitar la verificación de 2 pasos en su cuenta de gmail y crear una contraseña de aplicación ( https://support.google.com/accounts/answer/185833?hl=en ). Una vez que reemplace su contraseña con la nueva contraseña de la aplicación, debería funcionar.

Credentials = new System.Net.NetworkCredential("your email address", "your app password");


El servidor SMTP de Gmail requiere que autentique su solicitud con una combinación válida de correo electrónico / contraseña de Gmail. Usted necesita SSL habilitado también. Sin ser capaz de ver cómo se transfieren todas sus variables en la mejor conjetura que puedo hacer es que sus credenciales no son válidas, asegúrese de estar usando una combinación válida de correo electrónico y contraseña de GMAIL .

Es posible que desee leer here para un ejemplo de trabajo.

EDIT: Bueno, aquí hay algo que escribí y probé en ese momento y funcionó bien para mí:

public static bool SendGmail(string subject, string content, string[] recipients, string from) { if (recipients == null || recipients.Length == 0) throw new ArgumentException("recipients"); var gmailClient = new System.Net.Mail.SmtpClient { Host = "smtp.gmail.com", Port = 587, EnableSsl = true, UseDefaultCredentials = false, Credentials = new System.Net.NetworkCredential("******", "*****") }; using (var msg = new System.Net.Mail.MailMessage(from, recipients[0], subject, content)) { for (int i = 1; i < recipients.Length; i++) msg.To.Add(recipients[i]); try { gmailClient.Send(msg); return true; } catch (Exception) { // TODO: Handle the exception return false; } } }

Si necesitas más información, hay un artículo SO similar here


Este código funciona bien para mí, intente pegarlo en LinqPad, edite las direcciones de correo y la contraseña y díganos lo que ve:

var client = new System.Net.Mail.SmtpClient("smtp.gmail.com", 587); client.EnableSsl = true; client.UseDefaultCredentials = false; client.Credentials = new System.Net.NetworkCredential("[email protected]", "xxxxxxx"); try { // Create instance of message System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(); // Add receiver message.To.Add("[email protected]"); // Set sender // In this case the same as the username message.From = new System.Net.Mail.MailAddress("[email protected]"); // Set subject message.Subject = "Test"; // Set body of message message.Body = "En test besked"; // Send the message client.Send(message); // Clean up message = null; } catch (Exception e) { Console.WriteLine("Could not send e-mail. Exception caught: " + e); }


Intenta ejecutar esto:

mozroots --import --ask-remove

en su sistema (solo en bash o desde la solicitud de comando Mono si está en Windows). Y luego ejecute el código de nuevo.

EDITAR:

Olvidé que tú también deberías correr

certmgr -ssl smtps://smtp.gmail.com:465

(y responda sí a las preguntas). Esto me funciona en Mono 2.10.8, Linux (con su ejemplo).