Troubleshooting “The server committed a protocol violation” when sending mail with SmtpClient

梦想的初衷 提交于 2019-12-07 02:21:38

问题


I want to send a mail message with the SmtpClient class.

Here's the code I use:

SmtpClient smtpClient = new SmtpClient("Host",25);
NetworkCredential basicCredential =
new NetworkCredential("UserName", "Password");
MailMessage message = new MailMessage();
MailAddress fromAddress = new MailAddress("me@domain.com");
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = basicCredential;
message.From = fromAddress;
message.Subject = "test send";
message.IsBodyHtml = true;
message.Body = "<h1>hello</h1>";
message.To.Add("mail@domain.com");
smtpClient.Send(message);

But it always throws an exception:

The server committed a protocol violation The server response was: UGFzc3dvcmQ6

I can't find the reason for that. Please, if anyone has faced something like this, tell me what to do.


回答1:


This looks to me like SmtpClient authentication is somehow getting out of step.

Some authentication mechanisms are "Client: request auth with username and password, Server: success/fail" others are "Client: request auth with username, Server: request password, Client: reply with password, Server: success/fail".

It looks like SmtpClient is expecting the former, while your server is expecting the latter.

As dave wenta suggested, a log of a session would tell you what auth mechanism SmtpClient is trying to use, but it will also say what auth mechanisms the server supports.

What normally happens is that the server offers a number of authetication options, and the client choses which one it is going to use. The behaviour from there should be determined by the protocol chosen. I would hope that the SmtpClient class took care of that for you though, but I'm afraid I've never used that particular class.

Also remember - If you are going to post a log here, change to a throwaway password before you log the session, as a base64 encoded plain text password can be trivially changed back to human readable plain text password.




回答2:


I had the same problem, for my case it was for setting user@domain instead of user, I mean

Old code

new NetworkCredential("UserName@domain.com", "Password");

New code

new NetworkCredential("UserName", "Password");



回答3:


UGFzc3dvcmQ6 is "Password:" base 64 encoded (without quotes), meaning the password is probably wrong or not send encoded. Try base 64 encoding the password:

string password = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("Password));



回答4:


Enable logging for System.Net.Mail. Then view the log file. This will show you exactly what is happening during the SMTP layer.

Here is a link with more info:

http://systemnetmail.com/faq/4.10.aspx




回答5:


thousand of hit on google for UGFzc3dvcmQ6

it seem the server expect encrypted(with base64) username/password




回答6:


Had the same problem. Solved it in the following steps: 1) find out, what the server offers for SMTP Authentication by connecting to the SMTP Server using Telnet or putty or any other terminal:

telnet xxx.yyy.zzz.aaa 587 

(xxx.yyy.zzz.aaa = IP address of the SMTP Server, 587 = port number)

< Server answers with "220 protocol + version + time"

ehlo testing

< Server displays list of capabilities e.g.

250-AUTH NTLM CRAM-MD5 LOGIN

The SMTP client tries to take the most secure protocol first. In my case:

1. System.Net.Mail.SmtpNegotiateAuthenticationModule
2. System.Net.Mail.SmtpNtlmAuthenticationModule
3. System.Net.Mail.SmtpDigestAuthenticationModule
4. System.Net.Mail.SmtpLoginAuthenticationModule

It looks as if the SMTP client tries NTLM while the server tries to run LOGIN.

With a hack (cf. https://blogs.msdn.microsoft.com/knom/2008/04/16/hacking-system-net-mail-smtpclient/), all protocols can be turned of except for the one the server assumes (LOGIN in this case):

FieldInfo transport = smtpClient.GetType().GetField("transport", BindingFlags.NonPublic | BindingFlags.Instance);

FieldInfo authModules = transport.GetValue(smtpClient).GetType().GetField("authenticationModules",BindingFlags.NonPublic | BindingFlags.Instance);

Array modulesArray = authModules.GetValue(transport.GetValue(smtpClient)) as Array;
foreach (var module in modulesArray)
{
    Console.WriteLine(module.ToString());
}
// System.Net.Mail.SmtpNegotiateAuthenticationModule
// System.Net.Mail.SmtpNtlmAuthenticationModule
// System.Net.Mail.SmtpDigestAuthenticationModule
// System.Net.Mail.SmtpLoginAuthenticationModule

// overwrite the protocols that you don't want
modulesArray.SetValue(modulesArray.GetValue(3), 0);
modulesArray.SetValue(modulesArray.GetValue(3), 1);
modulesArray.SetValue(modulesArray.GetValue(3), 2);



回答7:


This can also happen when you simply don't provide the password. In my case I was using credentials from a web.config smtp block and on my deployment server (using octopus deploy) had forgotten to populate the password attribute.




回答8:


For anyone else coming across this on google.. I fixed this by supplying my username in the "username" format instead of "DOMAIN\username"

$Credential = Get-Credential

Send-MailMessage -SmtpServer exchange.contoso.com -Credential $Credential -From 'user@contoso.com' -To 'recipient@domain.com' -Subject 'Test email' -Port 587 -UseSsl


来源:https://stackoverflow.com/questions/2380531/troubleshooting-the-server-committed-a-protocol-violation-when-sending-mail-wi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!