I am sending emails via an external SMTP server. Sending the email is handled with this code:
try
{
System.Net.Mail.MailMessage mail = new System.Net.Mail.MailMessage();
mail.From = new MailAddress(froma);
mail.To.Add(toc);
mail.Subject = subject;
mail.IsBodyHtml = true;
mail.Body = body;
SmtpClient smtp = new SmtpClient(ClientServer);
DataSet ds = new DataSet();
int retCode = Email.getSmtp(ref ds, DatabaseName);
string User="";
string Password="";
if (ds.Tables["Value"].Rows.Count > 0)
{
User = ds.Tables["Value"].Rows[0]["UserName"].ToString();
Password = ds.Tables["Value"].Rows[0]["PasswordName"].ToString();
}
else
{
MessageBox.Show("Invalid SMTP settings!");
return;
}
smtp.UseDefaultCredentials = false;
smtp.Credentials = new System.Net.NetworkCredential(User, Password);
smtp.EnableSsl = false;
smtp.Send(mail);
}
catch (System.Web.HttpException exHttp)
{
System.Console.WriteLine("Exception occurred:" + exHttp.Message);
}
Testing this code on my server, with my own SMTP server on the same network, this returns all my emails. However, using an external SMTP server causes the error:
Mailbox unavailable. The server response was: relay not permitted.
I have read around and it appears that the admin for SMTP must allow relays for my server. However, using the authentication credentials provided, I can't seem to connect, and am still receiving the relay error.
Yes, it sounds like the external server that you are using is not allow relay. Even if you have the proper authentication credentials, you will not be able to send the email because the relay function is still disabled. Are you the admin of this external server? If you are then you can enable it. This LINK HERE explains how to set up SMTP and the relay. If you are not the admin of this external server, then you will have to contact who is so they can enable the SMTP and relay for you.
It sounds like the server on your network has SMTP installed and the relay is set up properly since you are able to send. I had to install SMTP and configure the relay on all three of servers here (development box, staging box, and production box) to send emails. I hope this information helps.
I had the same error and commented out :
//smtp.UseDefaultCredentials = true;
And the email was sent successfully.
Related
I'm trying to set up some code to send email via Office 365's authenticated SMTP service:
var _mailServer = new SmtpClient();
_mailServer.UseDefaultCredentials = false;
_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password");
_mailServer.Host = "smtp.office365.com";
_mailServer.TargetName = "STARTTLS/smtp.office365.com"; // same behaviour if this lien is removed
_mailServer.Port = 587;
_mailServer.EnableSsl = true;
var eml = new MailMessage();
eml.Sender = new MailAddress("test.user#mydomain.com");
eml.From = eml.Sender;
eml.to = new MailAddress("test.recipient#anotherdomain.com");
eml.Subject = "Test message";
eml.Body = "Test message body";
_mailServer.Send(eml);
This doesn't appear to be working, and I'm seeing an exception:
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, String from)
at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
at System.Net.Mail.SmtpClient.Send(MailMessage message)
I've tried enabling network tracing and it appears that secure communications are established (for example, I see a line in the log for the "STARTTLS" command, and later there's a line in the log "Remote certificate was verified as valid by the user.", and the following Send() and Receive() data is not readable as plain text, and doesn't appear to contain any TLS/SSH panics)
I can use the very same email address and password to log on to http://portal.office.com/ and use the Outlook email web mail to send and read email, so what might be causing the authentication to fail when sending email programmatically?
Is there any way to additionally debug the encrypted stream?
In my case after I tried all this suggestion without luck, I contacted Microsoft support, and their suggestion was to simply change the password.
This fixed my issue.
Note that the password wasn't expired, because I logged on office365 with success, however the reset solved the issue.
Lesson learned: don't trust the Office 365 password expiration date, in my case the password would be expired after 1-2 months, but it wasn't working.
This leaded me to investigate in my code and only after a lot of time I realized that the problem was in the Office365 password that was "corrupted" or "prematurely expired".
Don't forget every 3 months to "refresh" the password.
To aid in debugging, try temporarily switching to MailKit and using a code snippet such as the following:
using System;
using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MimeKit;
namespace TestClient {
class Program
{
public static void Main (string[] args)
{
var message = new MimeMessage ();
message.From.Add (new MailboxAddress ("", "test.user#mydomain.com"));
message.To.Add (new MailboxAddress ("", "test.recipient#anotherdomain.com"));
message.Subject = "Test message";
message.Body = new TextPart ("plain") { Text = "This is the message body." };
using (var client = new SmtpClient (new ProtocolLogger ("smtp.log"))) {
client.Connect ("smtp.office365.com", 587, SecureSocketOptions.StartTls);
client.Authenticate ("test.user#mydomain.com", "password");
client.Send (message);
client.Disconnect (true);
}
}
}
}
This will log the entire transaction to a file called "smtp.log" which you can then read through and see where things might be going wrong.
Note that smtp.log will likely contain an AUTH LOGIN command followed by a few commands that are base64 encoded (these are your user/pass), so if you share the log, be sure to scrub those lines.
I would expect this to have the same error as you are seeing with System.Net.Mail, but it will help you see what is going on.
Assuming it fails (and I expect it will), try changing to SecureSocketOptions.None and/or try commenting out the Authenticate().
See how that changes the error you are seeing.
Be sure you're using the actual office365 email address for the account. You can find it by clicking on the profile button in Outlook365. I wrestled with authentication until I realized the email address I was trying to use for authentication wasn't the actual mailbox email account. The actual account email may have the form of: account#company.onmicrosoft.com.
We got ours working by converting the mailboxes (from address) from "shared" to "regular". Before this change, my application quit sending email when we migrated from Gmail to Office 365. No other code changes were required, besides setting the host to smtp.office365.com.
Please check below code I have tested to send email using Exchange Online:
MailMessage msg = new MailMessage();
msg.To.Add(new MailAddress("YourEmail#hotmail.com", "XXXX"));
msg.From = new MailAddress("XXX#msdnofficedev.onmicrosoft.com", "XXX");
msg.Subject = "This is a Test Mail";
msg.Body = "This is a test message using Exchange OnLine";
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("XXX#msdnofficedev.onmicrosoft.com", "YourPassword");
client.Port = 587; // You can use Port 25 if 587 is blocked
client.Host = "smtp.office365.com";
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = true;
try
{
client.Send(msg);
}
catch (Exception ex)
{
}
Port (587) was defined for message submission. Although port 587 doesn't mandate requiring STARTTLS, the use of port 587 became popular around the same time as the realisation that SSL/TLS encryption of communications between clients and servers was an important security and privacy issue.
In my case my problem was not related to the code but something to do with the Exchange mailbox. Not sure why but this solved my problem:
Go to the exchange settings for that user's mailbox and access Mail Delegation
Under Send As, remove NT AUTHORITY\SELF and then add the user's account.
This gives permissions to the user to send emails on behalf of himself. In theory NT AUTHORITY\SELF should be doing the same thing but for some reason that did not work.
Source: http://edudotnet.blogspot.com.mt/2014/02/smtp-microsoft-office-365-net-smtp.html
I got this same error while testing, using my own domain email account during development. The issue for me seemed related to the MFA (Multi Factor Authentication) that's enabled on my account. Switching to an account without MFA resolved the issue.
I had this issue since someone had enabled Security defaults in Azure.
This disables SMTP/Basic authentication. It's clearly stated in the documentation, but it's not evident by the error message, and you have to have access to the account to find out.
https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults
It's possible to enable it per account.
https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission
You need change the credentials function. Here is the substitution you need to make:
change
-*_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password");*
for this
-*_mailServer.Credentials = new NetworkCredential("test.user#mydomain.com", "password", "domain");*
In my case, password was expired.I just reset password and its started working again
I used following code to send E-Mail using exchange server in a win form-application(.net 4 client profile):
public void SendEmail(string From,
string To,
string Subject,
string Body,
string AttachmentFile)
{
try
{
SmtpClient sMail = new SmtpClient("xs1.iasc.net");//exchange or smtp server goes here.
var SMTPUserInfo = new System.Net.NetworkCredential("user", "pass");
sMail.UseDefaultCredentials = false;
sMail.Credentials = SMTPUserInfo;
sMail.DeliveryMethod = SmtpDeliveryMethod.Network;
var msg = new MailMessage();
msg.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
msg.IsBodyHtml = true;
msg.From = new MailAddress(From);
msg.To.Add(To);
msg.Subject = Subject;
msg.Body = Body;
sMail.Send(msg);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
It works correctly in windows XP but when I run it on Windows 7, I get following error:
Client does not have permission to submit mail to this server. The server response was: 5.7.3 Client does not have permission to submit mail to this server.
Any Idea?
The IP address of your windows 7 client is probably blocked in your Exchange - either in the receive connector or in the antispam IP blocklist.
Check the configuration of the Exchange "receive connector" in
Exchange management console > server configuration > hub transport >
properties of the (default) receive connector. On the "network" tab
check that the IP address of your windows 7 client is included in
one the IP ranges for "remote addresses" down at the bottom of the
tab.
Remove the IP of the Win 7 computer from the IP block list under Exchange management console > server configuration > hub transport > Antispam (next to "receive connector tab" on the bottom half) > IP block list. You might want to add it to the IP allow list to be sure for the future.
By setting Local Security Setting to Send LM & NTLM -use NTLMv2 session security if negotiated. my problem solved:
Control Panel>All Control Panel Items>Administrative Tools>Local Security Policy>Security Settings>Local Policies>Security Options>Network Security : LAN Manager Authentication Level
SmptClient can be used to send an email via relay server. But is SmtpClient also able to send email directly to the receiver and not via relay server?
EDIT
Any ideas how SmtpCLient needs to be configured to be able to send emails directly to the receiver?
I tried with the following code but I got "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required."
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
// var credentialUserName = "myAccount#gmail.com";
var sentFrom = "myAccount#gmail.com";
// var pwd = "myPwd";
System.Net.Mail.SmtpClient client =
new System.Net.Mail.SmtpClient("smtp.gmail.com");
client.Port = 587;
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
/* System.Net.NetworkCredential credentials =
new System.Net.NetworkCredential(credentialUserName, pwd);
*/
client.EnableSsl = true;
// client.Credentials = credentials;
var mail =
new System.Net.Mail.MailMessage(sentFrom, message.Destination);
mail.Subject = message.Subject;
mail.Body = message.Body;
return client.SendMailAsync(mail);
}
}
SECOND EDIT:
Thanx, it works now. App sent email directly ( and not via myAccount#gmail.com ) to otherAccount#gmail.com. Here's the code:
public class EmailService : IIdentityMessageService
{
public Task SendAsync(IdentityMessage message)
{
var sentFrom = "myAccount#gmail.com";
System.Net.Mail.SmtpClient client =
new System.Net.Mail.SmtpClient("gmail-smtp-in.l.google.com");
client.Port = 25;
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
var mail =
new System.Net.Mail.MailMessage(sentFrom, message.Destination);
mail.Subject = message.Subject;
mail.Body = message.Body;
return client.SendMailAsync(mail);
}
}
Thank you
Short answer: yes!
A relay server is just a server that is configured to accept all your emails and pass them on to the right destination. You can equally well contact the right destination server directly and delivery the email there.
This, of course, provided there is no firewall issues preventing you from contacting the destination server directly.
EDIT
The server smtp.gmail.com is for gmail users to send (outgoing) emails, i.e. you must authenticate with your gmail username and password in order to be allowed to send an email that way, but if you do that you can send to any recipient, i.e. also non-gmail addresses.
I understood your original question to mean you would like to send emails to (in this case) a gmail-address without using a proxy. In that case your client should behave as any arbitrary email server that is trying to send to a gmail-address, i.e. it should connect to one of official incoming SMTP servers for the domain as given by MX-records in the DNS. E.g. one of gmail's MX-records points to gmail-smtp-in.l.google.com, and if you connect to port 25 of that server you can submit an email to a gmail-address (and you can also completely spoof the sending address, but then spam-filtering might cause your email to not be delivered).
My caveat about firewall issues is to interpreted as this: most ISPs disallow outgoing TCP connections to port 25 to other hosts than their own servers. This is just because of the above mentioned spoofing possibility, i.e. if your ISP allows you to make TCP connections to port 25 of other email servers, you can use that to send spam. Therefore your ISP might not allow you to do that, and instead you should relay your emails via your ISP so they can take appropriate measures if you try to spam people.
I am trying to send email using Amazon SES.
I am able to send email by using our local SMTPserver and also able to send email by using sample provided at amazon website.
I need to send send From Address & To Address names with the email. I can not do this with SendEmailRequest class provided in the Amazon SDK, because there is no such overload for WithSource(toaddress), WithDestination(destinationaddress) & WithReplyToAddresses(replytoaddress) methods so i can't pass names form sender 7 receiver here, so that I am using regular method of sending mail using Amazon configurations.
I tried both way pass credentials by the hard coding through code as well as by puyting configuration by file but still I am getting same error for both ways above this error when using port 587,
"The SMTP server requires a secure connection or the client was not authenticated. The server response was: Authentication required"
when tried with 465 port getting this error,
"Failure Sending Email"
When tried putting IP address instead of host address of amazon server got this error.
"The remote certificate is invalid according to the validation procedure."
Please suggest me what I am missing here,
Here is my code,
MailMessage mail = new MailMessage();
mail.From = new System.Net.Mail.MailAddress(FromEmail, FromName);
SmtpClient smtp = new SmtpClient("email-smtp.us-east-1.amazonaws.com", 587);
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials = false;
smtp.EnableSsl = true;
smtp.Credentials = new NetworkCredential(AWSAccessKey, AWSSecretKey);
//recipient address
mail.To.Add(new MailAddress(ToEmail, ToName));
//Formatted mail body
mail.IsBodyHtml = true;
mail.Body = strBody;
smtp.Send(mail);
Thanks in Advance..!!!
I solved this problem by passing email with email user name in the following in the format
User Name< example#domain.com >
Sample from Amazon site is already working for me,
here is my working code,
AWSCredentials objAWSCredentials = new BasicAWSCredentials(AWSAccessKey, AWSSecretKey);
Destination destination = new Destination().WithToAddresses(new List<string>() { TO });
// Create the subject and body of the message.
Content subject = new Content().WithData(SUBJECT);
Content textBody = new Content().WithData(BODY);
Body body = new Body().WithHtml(textBody);
//Body body = new Body().WithText(textBody);
// Create a message with the specified subject and body.
Message message = new Message().WithSubject(subject).WithBody(body);
// Assemble the email.
SendEmailRequest request = new SendEmailRequest().WithSource(FROM).WithDestination(destination).WithMessage(message).WithReplyToAddresses(REPLYTO);
// Instantiate an Amazon SES client, which will make the service call. Since we are instantiating an
// AmazonSimpleEmailServiceClient object with no parameters, the constructor looks in App.config for
// your AWS credentials by default. When you created your new AWS project in Visual Studio, the AWS
// credentials you entered were added to App.config.
AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient(objAWSCredentials);
// Send the email.
Console.WriteLine("Attempting to send an email through Amazon SES by using the AWS SDK for .NET...");
client.SendEmail(request);
here I've passed FROM, TO & ReplyToAddress in this format,
User Name< example#domain.com >
I am trying to send an email through an SMTP server but it fails giving me the following error:
MailBox name not allowed. The server response was Senders must have
valid reverse DNS
Unfortunately I could not find meaningfull information to solve the problem
Here is my method:
public void SendSmtp()
{
try
{
using (MailMessage message = new MailMessage())
{
message.From = new MailAddress("some#email.com");
message.To.Add(new MailAddress("other#email.com"));
message.Subject = "subject";
message.Body = "body";
message.IsBodyHtml = true;
// NetworkCredential basicCredential = new NetworkCredential("test#test.com", "password");
try
{
using (SmtpClient client = new SmtpClient())
{
client.Host = "mail.host.com";
client.Port = 25;
client.UseDefaultCredentials = true;
// client.Credentials = basicCredential;
client.Send(message);
MessageBox.Show("Success!!");
}
}
finally
{
//dispose the client
message.Dispose();
}
}
}
catch (SmtpFailedRecipientsException ex)
{
for (int i = 0; i < ex.InnerExceptions.Length; i++)
{
SmtpStatusCode status = ex.InnerExceptions[i].StatusCode;
if (status == SmtpStatusCode.MailboxBusy ||
status == SmtpStatusCode.MailboxUnavailable)
{
Console.WriteLine("Delivery failed - retrying in 5 seconds.");
System.Threading.Thread.Sleep(5000);
//client.Send(message);
}
else
{
Console.WriteLine("Failed to deliver message to {0}",
ex.InnerExceptions[i].FailedRecipient);
}
}
}
}
This works well when I try it on a different server or my local machine not sure why.
I set up my SMTP grant access to my server.
Please advice.
The error's a direct response from the SMTP server that your code is attempting to connect to. Your client machine does not have a valid reverse DNS mapping (e.g. 127.0.0.1 -> localhost), so the SMTP server is rejecting the connection.
It could be something as simple as your client identifying itself as example.com, but when the SMTP server does a reverse lookup, the server's IP comes back as system-1-2-3.4.hostingprovider.com or similar.
Looking back at my question, I can tell you that if you face this issue, It is not an issue in the code really it is more of a network issue.
A quick way to test this is to do run your code in a less locked down environment. I was getting this error only on my production server. It worked fine in development.
So this means you need to close visual studio and investigate. The error could be misleading so don't rely on it 100% instead use tools to debug your issue. I used wireshark to examine the packets and I noticed an IP that being denied on my SMTP server.
I didn't realize because my server had multiple network cards in my case. Something that I could not easily guessed. So my advise is to use tools to watch traffic network and you will find the reason.
Don't guess, use tools* to give you the answers.
*tools: in addition to wireshark, sites like mxtoolbox could be very helpful
Old thread, but if anybody else has this issue, for me the issue was related to the "FROM" attribute. On the smtp server there is allowed "from" address which you have to request to your email server admins.