我正在使用mailkit来访问pop3clients的列表。为了测试的目的,我有一个客户端,将不认证和我写了一个if语句的认证真做一些任务。但它并没有移动到另一个客户端,而是抛出一个异常,并停止了这个过程.我应该在我的代码中实现或添加什么,以便在没有连接或验证的情况下能够移动到另一个客户端。
public void connect(){
try
{
foreach (ObjectDeserializer obj in mailDeserialization.ListOfObjects())
{
Console.WriteLine(obj.toString());
if (obj.port == 995)
{
using (Pop3Client client = new Pop3Client())
{
client.CheckCertificateRevocation = false;
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(obj.server, obj.port, SecureSocketOptions.Auto);
client.Authenticate(obj.user, obj.password);
if (client.IsAuthenticated == true)
{
for (int i = 0; i < client.Count; i++)
{
var message = client.GetMessage(i);
Console.WriteLine(message.From.ToString());
}
}
}
}
else
{
using (Pop3Client clientNoSSL = new Pop3Client(new ProtocolLogger("pop3.log")))
{
clientNoSSL.Connect(obj.server, obj.port, SecureSocketOptions.Auto);
Console.WriteLine(clientNoSSL.IsConnected.ToString());
clientNoSSL.Authenticate(obj.user, obj.password);
if (clientNoSSL.IsAuthenticated == true)
{
for (int i = 0; i < clientNoSSL.Count; i++)
{
var message = clientNoSSL.GetMessage(i);
Console.WriteLine(message.From.ToString());
}
}
else
{
Console.WriteLine("No");
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
正如@jdweng在评论中提到的,你需要做的是这样。
public void connect()
{
foreach (ObjectDeserializer obj in mailDeserialization.ListOfObjects())
{
Console.WriteLine(obj.toString());
using (var client = new Pop3Client ())
{
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.CheckCertificateRevocation = false;
try {
client.Connect(obj.server, obj.port, SecureSocketOptions.Auto);
client.Authenticate(obj.user, obj.password);
for (int i = 0; i < client.Count; i++)
{
var message = client.GetMessage(i);
Console.WriteLine(message.From.ToString());
}
client.Disconnect (true);
} catch (Exception ex) {
Console.WriteLine (ex);
if (client.IsConnected)
client.Disconnect (false);
}
}
}
}
我也冒昧地简化了你的代码,去掉了你的ifelse逻辑,检查端口,原因有二:
Auto
的SSL模式,这意味着如果服务器支持SSL模式,那么MailKit在连接到纯文本端口后会尝试升级到SSLTLS连接。STARTTLS
(或 STLS
在POP3的情况下)命令,这意味着验证回调和证书撤销的属性。可能 是需要的。我也许应该提醒一下,使用 client.ServerCertificateValidationCallback = (s, c, h, e) => true;
是不安全的,会允许MITM攻击。我曾经在我的README中设置了这个黑客,因为例如在Linux上Mono上运行代码的开发者,经常会在他们的SSL证书数据库中没有任何Root CA证书,所以他们所做的每一个SSL连接都会因为无法验证任何SSL证书而失败。另一个原因是由于自签名的SSL证书在家庭邮件服务器上非常普遍。
从MailKit 2.6.0开始,MailKit有一个默认的ServerCertificateValidationCallback实现,它已经知道了最常见的IMAP、SMTP和POP3邮件服务器的指纹和其他识别信息,所以在大多数情况下不再需要黑客。