SmtpClient with Gmail

81,140

Solution 1

Try running this:

mozroots --import --ask-remove

in your system (just in bash or from Mono Command Prompt if it is on Windows). And then run the code again.

EDIT:

I forgot you also should run

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

(and answer yes on questions). This works for me on Mono 2.10.8, Linux (with your example).

Solution 2

Gmail's SMTP server requires you to authenticate your request with a valid gmail email/password combination. You do need SSL enabled as well. Without actually being able to see a dump of all your variables being passed in the best guess I can make is that your Credentials are invalid, make sure you're using a valid GMAIL email/password combination.

You might want to read here for a working example.

EDIT: Okay here's something I wrote and tested just then and it worked fine for me:

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;
        }
    }
}

If you need any more info there's a similar SO article here

Solution 3

You need to enable 2-Step Verification in your gmail account and create an app password (https://support.google.com/accounts/answer/185833?hl=en). Once you replace your password with the new app password, it should work.

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

Solution 4

I think, you need to validate the server certificate that is used to establish the SSL connections.....

Use following code to send mail with validating server certificate.....

            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);
        }

Import System.Security.Cryptography.X509Certificates namespace to use ServicePointManager

Solution 5

This code works fine for me, try pasting this into LinqPad, edit the mail addresses and password and tell us what you see:

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);
}
Share:
81,140

Related videos on Youtube

simonbs
Author by

simonbs

Updated on July 09, 2022

Comments

  • simonbs
    simonbs almost 2 years

    I'm developing a mail client for a school project. I have managed to send e-mails using the SmtpClient in C#. This works perfectly with any server but it doesn't work with Gmail. I believe it's because of Google using TLS. I have tried setting EnableSsl to true on the SmtpClient but this doesn't make a difference.

    This is the code I am using to create the SmtpClient and send an e-mail.

    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);
    }
    

    This is the error I am getting when I try to send an e-mail.

    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 
    

    Does anyone have an idea why I might be getting this error?

    • Renatas M.
      Renatas M. about 12 years
      try to set client.UseDefaultCredentials = false; before setting credentials.
    • simonbs
      simonbs about 12 years
      @Reniuz That did not make a difference.
    • konrad.kruczynski
      konrad.kruczynski about 12 years
      Looks like the certificate problem - see my answer.
    • konrad.kruczynski
      konrad.kruczynski about 12 years
      I've edited my answer and am writing next comment to have you notified. Please see the edited answer.
    • simonbs
      simonbs about 12 years
      @konrad.kruczynski I'm not at my computer right now but I would definitely have a look at it as soon as possible. Thank you for your help.
  • simonbs
    simonbs about 12 years
    I'm sure that my credentials are write. I have tried copy/pasting them into the Gmail log in box and was able to log in. I have updated my question to show a simplified version of my code with the values of the variables hard coded.
  • psubsee2003
    psubsee2003 about 12 years
    @SimonBS are you using just your google username or the full email address for your Credentials? I believe logging in from a non-Google domain requires the full email address to log in
  • simonbs
    simonbs about 12 years
    I am using the entire email. E.g. [email protected].
  • psubsee2003
    psubsee2003 about 12 years
    @SimonBS and you have POP enabled in your gmail account?
  • Jason Larke
    Jason Larke about 12 years
    I am at work at the moment so I don't have C# right now to play around with. When I get home I'll have a look and see if I can write you a working example and edit my answer appropriately.
  • simonbs
    simonbs about 12 years
    @JasonLarke That sounds great! Thank you very much. I have been struggling with this for days.
  • simonbs
    simonbs about 12 years
    @psubsee2003 Yes, both POP and IMAP is activated but would that matter when I'm only using SMTP at the moment?
  • psubsee2003
    psubsee2003 about 12 years
    @SimonBS it probably shouldn't, but since I was able to make your code work without an exception, it seemed like a possibility
  • Admin
    Admin about 12 years
    Yeah, when I tried the code without validating X509Certificates,it worked fine for me too.....But sometime,when trying ssl connection, it need the validation of certificates.....
  • simonbs
    simonbs about 12 years
    I'm on a Mac and don't have LinqPad. All I use is MonoDevelop. Using the code above gives me the exact same.
  • psubsee2003
    psubsee2003 about 12 years
    @SimonBS you might want to retag the question with Mono. That could be part of the problem since it seems multiple people have managed to get the same code working in VS.
  • simonbs
    simonbs about 12 years
    @psubsee2003 You might be right. I didn't think of that. I'm still very new to C# and didn't think the IDE would matter. I have retagged it now.
  • psubsee2003
    psubsee2003 about 12 years
    @SimonBS I've never used done any work outside of VisualStudio, so I don't know if the fact that you are using MonoDevelop would matter, but given the facts, it seems like the next thing to check
  • simonbs
    simonbs about 12 years
    This adds 140 "new root certificates" to my "trust store" but it doesn't solve the issue but thanks for your answer.
  • simonbs
    simonbs about 12 years
    @JasonLarke Thank you, but sadly this gives me exactly the same.
  • simonbs
    simonbs about 12 years
    I'm sorry for the late response. This did the trick! Thank you very much. I just gotta make sure. If anyone runs my software, will they have to runs these commands to use the software? That's not really ideal. For a school project, it doesn't matter much, but I would like to know so that I can put it in my rapport :-)
  • konrad.kruczynski
    konrad.kruczynski about 12 years
    @SimonBS: They will have or not - that depends specifically on the OS/distribution used and their policy. Everything is quite well described (with reasons :)) here: mono-project.com/FAQ:_Security
  • simonbs
    simonbs about 12 years
    Thank you. I will take a look at that. Your help is really appreciated!
  • Tom Winans
    Tom Winans over 11 years
    Thanks, both, for this little tidbit ... very helpful and accurate on OSX and Ubuntu. Best to both ...
  • Steffen Winkler
    Steffen Winkler about 10 years
    colleague of mine just had trouble sending an e-mail from a Mono application on Android through our e-mail server. This fixed the problem. Awesome!
  • b.pell
    b.pell about 9 years
    This was the fix for me also. I could run my Mono app and send mail from the command prompt but once it went to cron it stopped working. The x509 line fixed that issue when running from cron.
  • netniV
    netniV about 9 years
    Whilst this would indeed get around the service issue and provide a method by which you would not have an interrupted service, it also removes all aspects of security by saying I don't care about the certificate. Thus, a MITM attack could quite easily listen in on your communication without additional checks in the callback to verify the "untrusted" certificate is definitely one you want to trust.
  • Tejasvi Hegde
    Tejasvi Hegde over 8 years
    Perfect answer. Works too.
  • Max Sorin
    Max Sorin almost 7 years
    For me, this was the actual solution, as Google Accounts, specifically, don't allow an application to log in on user's behalf to send an email. Thank you.