#delphi #delphi-xe #indy10
#delphi #delphi-xe #indy10
Вопрос:
У меня возникла проблема с использованием TIdSMTP, когда TIdSSLIOHandlerSocketOpenSSL получает «Ошибку сокета» просто при подключении к серверу.
Вот код компонента формы
object IdSMTP: TIdSMTP
IOHandler = IdSSLIOHandlerSSL
Port = 465
SASLMechanisms = <>
UseTLS = utUseImplicitTLS
Left = 93
Top = 49
end
object IdSSLIOHandlerSSL: TIdSSLIOHandlerSocketOpenSSL
OnStatus = IdSSLIOHandlerSSLStatus
Destination = ':465'
MaxLineAction = maException
Port = 465
DefaultPort = 0
SSLOptions.Mode = sslmUnassigned
SSLOptions.VerifyMode = []
SSLOptions.VerifyDepth = 0
OnStatusInfo = IdSSLIOHandlerSSLStatusInfo
Left = 88
Top = 112
end
и код Delphi
IdSMTP.Username := 'username';
IdSMTP.Password := 'password';
IdSMTP.Host := 'domain';
IdSMTP.Port := 465;
IdSMTP.UseTLS := utUseImplicitTLS;
try
IdSMTP.Connect;
except
on E:Exception do
// Socket Error, Connection Timeout is thrown.
Memo1.Lines.Add(E.Message);
end;
Я зарегистрировал статус ввода-вывода SSL и получил это:
Resolving hostname {domain}.
Connecting to {ip}.
SSL status: "before/connect initialization"
SSL status: "before/connect initialization"
SSL status: "SSLv3 write client hello A"
SSL status: "SSLv3 read server hello A"
Socket Error # 10060
Connection timed out.
Кстати, наш почтовый сервер использует самозаверяющий сертификат.
Что я делаю не так?
TIA
ОБНОВЛЕНИЕ: 07-02-2014
Пытался отправлять почту в Gmail с помощью подсказки Indy, но я получаю, что соединение закрыто корректно, отправляя электронное письмо также после того, как SSLv3 прочитал сервер hello A.
Resolving hostname smtp.gmail.com.
Connecting to 74.125.25.108.
Connected.
Sending Email..
SSL status: "before/connect initialization"
SSL status: "before/connect initialization"
SSL status: "SSLv3 write client hello A"
SSL status: "SSLv3 read server hello A"
Disconnected.
Connection Closed Gracefully.
Вот новый код:
IdSMTP.Username := 'username';
IdSMTP.Password := 'password';
IdSMTP.Host := 'smtp.gmail.com';
IdSMTP.UseTLS := utUseExplicitTLS;
IdSMTP.Port := 587;
try
// Can connect successfully
IdSMTP.Connect;
// This part throws the exception
IdSMTP.Send(IdMessage);
except
on E:Exception do
// Disconnected, connection closed gracefully
Memo1.Lines.Add(E.Message);
end;
Обновить:
Пробовал отправлять электронную почту с помощью Thunderbird, подключаясь к тому же домену.
Thunderbird:
Indy:
В моей программе не произошло «обмена ключами клиента, …«.
РЕШАЕМАЯ
Эта проблема была решена путем ручной настройки connectiontimeout
Ответ №1:
Вы используете неявный SSL. Это означает, что SSL-квитирование инициируется, как только сокет подключен к серверу, до обмена любыми данными приложения (командами / ответами SMTP). На сервер отправляется клиентское приветствие, а затем наступает тайм-аут в ожидании, пока сервер отправит ответное приветствие. Это означает, что сервер НЕ использует SSL на порту, к которому вы подключаетесь.
Что следует иметь в виду — установка UseTLS
свойства может изменить Port
свойство, поэтому убедитесь, что Port
это действительно то, что вы ожидаете при Connect()
вызове. Чтобы убедиться, попробуйте установить Port
после установки UseTLS
, а не до.
Комментарии:
1. ошибка тайм-аута / сокета возникает сразу после приветствия сервера, без дополнительной задержки. соединение внезапно прерывается.
2. порт использует SSL, потому что мы можем отправлять электронную почту с помощью других почтовых клиентов, таких как Thunderbird. Назначение порта после установки UseTLS также приводит к тому же результату.
3. Немедленное отключение, вероятно, означает, что Gmail отклоняет рукопожатие. Вы пробовали использовать анализатор пакетов для просмотра сообщений о квитировании? Кроме того, при подключении к Gmail вы установили
SSLVersion
значение TLSv1? Не используйте SSLv3.4. я использую только v1. Прослушал с помощью wireshark и обнаружил, что обмен ключами клиента не происходит при использовании Indy (мы используем самозаверяющий сертификат). Я посмотрю, как я могу обмениваться ключами с нашим сервером.
5. Ваш клиент закрывает сокет (отправляя
FIN
TCP-пакет) после получения приветствия сервера. Либо OpenSSL отклоняет сертификат сервера, либо возникает исключение, или тому подобное.
Ответ №2:
Пожалуйста, убедитесь, что ваш брандмауэр временно отключен. Я попал на эту страницу, потому что у меня была та же проблема — немедленное отключение с надписью «Соединение закрыто корректно» при выполнении SMTP с SSL. Затем я отключил свой Avast! брандмауэр, и все было в порядке.