SmtpClient не будет проходить аутентификацию через SSL / TLS (не указывая на gmail) - PullRequest
4 голосов
/ 16 августа 2011

У меня есть сервер ssl / tls (nodejs), который действует как прокси для postfix / sendmail, чтобы выполнить некоторую предварительную обработку / сбор данных на исходящей почте.

Из C # я могу вручную подключиться и аутентифицироваться с помощью следующего кода:

var sslStream = new SslStream(tcpClient.GetStream(), false,
                         new RemoteCertificateValidationCallback(CertificateValidation),
                         new LocalCertificateSelectionCallback(CertificateSelectionCallback));

                string fn = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "cert.pem");
                X509Certificate c = X509Certificate.CreateFromCertFile(fn);
                var certs = new X509CertificateCollection();
                certs.Add(c);
                sslStream.AuthenticateAsClient(System.Environment.MachineName, certs , SslProtocols.Default, false);

Однако я не могу подключить SmtpClient. Ошибка верхнего уровня - это тайм-аут, но я отлажен в SmtpClient / SmtpConnection, и основная ошибка заключается в том, что поток не читается, возможно потому, что он никогда не проходил аутентификацию (я не могу достичь точки останова на моем прокси-сервере ssl / tls с помощью Код SmtpClient, но приведенная выше инструкция sslConnection работает просто отлично.

Было бы замечательно, если бы существовал способ вручную передать базовый коммуникационный поток в SmtpClient, но я не могу найти способ сделать это.

Кто-нибудь имеет представление о том, почему код ниже не аутентифицируется?

Вот тестовое приложение, которое я использовал, чтобы безуспешно попытаться подключиться к SmtpClient:

    ServicePointManager.ServerCertificateValidationCallback = CertificateValidation;
    // Using Ssl3 rather than Tls here makes no difference
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
    var client = new SmtpClient {
                                  Timeout = 10000,
                                  DeliveryMethod = SmtpDeliveryMethod.Network,
                                  EnableSsl = true,
                                  UseDefaultCredentials = false,
                                  Host = "192.168.15.71",
                                  Port = 10126
                                };
    client.ClientCertificates.Add(c);
    client.Credentials = new NetworkCredential("username", "password");

    //times out here, except the real exception that doesn't bubble up is the stream
    //isnt readable because it never authenticated (when it trys to read the status
    //returned by the smtp server, eg: "220 smtp2.example.com ESMTP Postfix")
    client.send(email);

1 Ответ

6 голосов
/ 11 ноября 2011

Решил некоторое время назад, забыл опубликовать ответ.

SMTP-клиент .NET, наряду с большинством клиентских библиотек SMTP, не поддерживает инициацию связи через ssl / tls. Требуется, чтобы сервер smtp поддерживал инициирование незашифрованного обмена данными, а затем переход к зашифрованному соединению с помощью команды «upgrade» (это почти всегда выполняется за кулисами клиентской библиотекой SMTP).

В то время я подключался к полу настраиваемому серверу smtp, который проксировал postfix, и это пользовательское решение поддерживало подключение только через ssl / tls. С тех пор начал использовать Haraka для моего SMTP-сервера, который поддерживает все стандарты SMTP, а также предоставляет мне плагин, который мне нужен.

...