使用Delphi XE2,随附的Indy 10和OpenSSL dll的1.0.1c版本。
我们正处于将Delphi 6项目转换为Delphi XE2的最后阶段。
到目前为止,我们已经解决了每个节目限制器,但我遇到了一个尝试连接到Gmail smtp服务器的插件。
我们的Delphi 6应用程序可以正常使用SSL v2.3和SSL v3以及连接到端口465的Indy 9组件(根据Google自己的文档)。 Google Support
我们的Delphi XE2应用根本没有连接。对连接的调用进入以太,并且在7分钟内没有任何反应,直到我感到无聊等待事情超时并将其终止。我实际上跟踪程序执行一直到IdWinsock2函数:
function Stub_select(nfds: Integer; readfds, writefds, exceptfds: PFDSet; timeout: PTimeVal): Integer; stdcall;
begin
@select := FixupStub(hWinSockDll, 'select'); {Do not Localize}
Result := select(nfds, readfds, writefds, exceptfds, timeout);//<-this line never returns and timeout is always nil
end;
我需要为现有用户维护旧的SSL连接&#39;配置。
新用户将能够使用TLS(到端口587)进行连接,并且可以正常工作!?!?
我不知道为什么非TLS SSL选项不起作用,并且不报告任何错误,也没有超时但只是去永不落地。请帮忙!
TJ
以下是代码:
SMTPClient.Host := trim(EditSMTPServer.Text);
SMTPClient.Port := EditSMTPServerPort.AsInteger;//<- value from custom edit box
SMTPClient.Username := trim(EditSMTPLogon.Text);
SMTPClient.Password := trim(EditSMTPPassword.Text);
SMTPClient.AuthType := satDefault;
if CheckBoxUseSSL.Checked then begin
SMTPClient.IOHandler := IdSSLIOHandlerSocket1;
IdSSLIOHandlerSocket1.ReadTimeout := 30000;//30 second timeout which does not appear to work
case ComboBoxSSLMode.ItemIndex of
0 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv2;
1 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
2 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv3;
3 : begin
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLsv1;
SMTPClient.UseTLS := utUseImplicitTLS;
end;
end;//case
IdSSLIOHandlerSocket2.SSLOptions.Method := IdSSLIOHandlerSocket1.SSLOptions.Method;
IdSSLIOHandlerSocket2.PassThrough := False;
end
else begin
SMTPClient.IOHandler := nil;
end;
try
SMTPClient.Connect;
if SMTPClient.Connected then begin
if SMTPClient.Authenticate then begin
... do some work ...
end;
end;
except
on e:Exception do begin
showmessage(e.message);
end;
end;
编辑:
像往常一样,在我发布问题之后,我偶然发现了一种解决方法。
如果我将UsetTLS属性设置为utUseImplicitTLS用于所有NON-SSL事务并将其设置为utUseExplicitTLS用于TLS事务,则我的连接似乎及时工作。
希望这可以帮助别人。
更新代码:
if CheckBoxUseSSL.Checked then begin
SMTPClient.IOHandler := IdSSLIOHandlerSocket1;
SMTPClient.UseTLS := utUseImplicitTLS;
case ComboBoxSSLMode.ItemIndex of
0 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv2;
1 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23;
2 : IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv3;
3 : begin
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLsv1;
SMTPClient.UseTLS := utUseExplicitTLS;
end;
end;//case
IdSSLIOHandlerSocket2.SSLOptions.Method := IdSSLIOHandlerSocket1.SSLOptions.Method;
IdSSLIOHandlerSocket2.PassThrough := False;
end
else begin
SMTPClient.UseTLS := utNoTLSSupport;//reset TLS support flag
SMTPClient.IOHandler := nil;
end;
答案 0 :(得分:3)
你发现的是你应该做的事情。 SSL和TLS具有不同的语义,因此您必须相应地设置UseTLS
。
对于端口465上的SSL,服务器希望您的客户端在连接后立即启动SSL握手,然后服务器发送加密的问候语。 UseTLS=utUseImplicitTLS
会这样做,但UseTLS=utUseExplicitTLS
没有。当UseTLS=utUseExplicitTLS
,TIdSMTP
期望服务器立即发送未加密的问候语,这可以解释select()
中的挂起 - 服务器没有发送任何数据!
对于端口587上的TLS,服务器期望客户端最初未加密连接,然后在准备好启动加密时发送显式STARTTLS
命令。 UseTLS=utUseExplicitTLS
会这样做,但UseTLS=utUseImplicitTLS
没有。