Перейдите к другому клиенту, если нет соединения / аутентификации MailKit - PullRequest
0 голосов
/ 28 апреля 2020

Я использую mailkit для доступа к списку pop3clients. Для целей тестирования у меня есть клиент, который не будет аутентифицироваться, и я написал оператор if для аутентификации true, чтобы выполнить какую-то задачу. Но вместо того, чтобы перейти к другому клиенту, он генерирует исключение и останавливает процесс. Что я должен реализовать или добавить в свой код, чтобы можно было перейти к другому клиенту в случае отсутствия соединения или аутентификации.

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

1 Ответ

0 голосов
/ 01 мая 2020

Как отметил @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);
            }
        }
    }
}

Я также позволил себе немного упростить ваш код, избавившись от необходимости использовать if / иначе logi c проверки портов по 2 причинам:

  1. Поскольку вы используете Auto для режима SSL, это означает, что MailKit будет пытаться обновить соединение SSL / TLS после подключения к обычному текстовому порту, если сервер поддерживает команду STARTTLS (или STLS в случае POP3), что означает, что могут потребоваться свойства обратного вызова проверки и отзыва сертификата .
  2. Даже если они не нужны, он не разорвет соединение только для простого текста, потому что эти свойства не будут использоваться.

Вероятно, я должен предупредить, что использование client.ServerCertificateValidationCallback = (s, c, h, e) => true; небезопасно и позволит MITM-атак. Я имел обыкновение иметь этот взлом в моем README, потому что разработчики, выполняющие свой код на Mono на Linux, например, часто не имели бы никаких сертификатов Root CA в своей базе данных SSL-сертификатов, и поэтому каждое SSL-соединение, которое они установили, было бы неудачным из-за невозможность проверить любой сертификат SSL. Другая причина заключалась в том, что самозаверяющие SSL-сертификаты так распространены на домашних почтовых серверах.

Начиная с MailKit 2.6.0, MailKit имеет стандартную реализацию ServerCertificateValidationCallback, которая уже знает отпечаток пальца и другую идентификационную информацию для наиболее распространенного IMAP , Почтовые серверы SMTP и POP3 и, таким образом, взлом в большинстве случаев больше не требуется.

...