我正在尝试使用kazakov.nickolay在this post中建议的方法验证smtp用户。
首先,我尝试使用VRFY
命令,它给出了错误响应
"命令无效"。
接下来,我直接尝试使用AUTH
命令,在这种情况下,我得到了错误响应 -
"首先发出starttls命令。"
当我首先尝试STARTTLS
命令然后AUTH
时,线程进入无限循环。这可能发生,因为socket.Available
计数为零,之后我无法做任何事情。
以下是示例代码 -
public bool ValidateUser()
{
bool isValid = true;
string useremail = "user@mail.com";
string password = "userPassword";
string smtpserver = "smtp.server.name"
int port = 587;
try
{
const string EOF = "\r\n";
IPHostEntry hostEntry = Dns.GetHostEntry(smtpserver);
IPEndPoint endPoint = new IPEndPoint(hostEntry.AddressList[0], port);
using (Socket tcpSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
try
{
tcpSocket.Connect(endPoint);
if (!CheckResponse(tcpSocket, 220))
isValid = false;
SendBytes(tcpSocket, $"EHLO {Dns.GetHostName()}{EOF}");
if (!CheckResponse(tcpSocket, 250))
isValid = false;
//SendBytes(tcpSocket, $"VRFY {useremail} {EOF}");
//if (!CheckResponse(tcpSocket, 250) || !CheckResponse(tcpSocket, 251))
// isValid = false;
//SendBytes(tcpSocket, $"STARTTLS{EOF}");
//if (!CheckResponse(tcpSocket, 220))
// isValid = false;
SendBytes(tcpSocket, $"AUTH {useremail} {EOF}");
if (!CheckResponse(tcpSocket, 334))
isValid = false;
SendBytes(tcpSocket, Convert.ToBase64String(Encoding.UTF8.GetBytes($"{useremail}")) + EOF);
if (!CheckResponse(tcpSocket, 334))
{
return false;
}
SendBytes(tcpSocket, Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")) + EOF);
if (!CheckResponse(tcpSocket, 235))
{
return false;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
tcpSocket.Dispose();
}
}
}
catch (Exception)
{
throw;
}
return isValid;
}
private bool CheckResponse(Socket socket, int expectedCode)
{
bool isResponse = true;
try
{
if (socket == null)
return false;
while (socket.Available == 0)
{
System.Threading.Thread.Sleep(100);
}
byte[] responseArray = new byte[1024];
socket.Receive(responseArray, 0, socket.Available, SocketFlags.None);
string responseData = Encoding.ASCII.GetString(responseArray);
int responseCode = Convert.ToInt32(responseData.Substring(0, 3));
if (responseCode != expectedCode)
{
isResponse = false;
}
}
catch (Exception ex) { throw ex; }
return isResponse;
}
private void SendBytes(Socket socket, string data)
{
if (socket == null)
return;
byte[] bytes = Encoding.UTF8.GetBytes(data);
socket.Send(bytes, 0, bytes.Length, SocketFlags.None);
}
我还尝试了另一种启用SSL的方法。
在以下代码行_sslStream.AuthenticateAsClient(smtpserver);
上,我得到了异常 -
"由于意外的数据包格式,握手失败。"
在调用发送方法之前,有人可以建议我验证用户的正确步骤吗?
请注意 - 如果用户不是有效用户,我不想调用send方法。此外,我不想发送虚拟邮件来检查相同的内容。