Indy10 + OpenSSL: send email code stopped working on Windows 8

折月煮酒 提交于 2019-12-10 19:12:40

问题


Code stopped working on Windows 8. It works fine on Windows7, Windows XP... I found a workaround for this issue: start application in Windows compatibility mode: Windows XP (Service Pack 3) - code working. Code not working if Windows compatibility mode is Windows 7. I run application as Administrator. Have already tried to switch off antivirus and firewall. I can send email with the same parameters using another smtp client, e.g. .Net SmtpClient. The problem is reproduced on different Windows 8 computers(home, office). I created simple test application. Code is written on Delphi XE, Indy 10.5.7, OpenSSL 1.0.1.3 dlls are placed in test.exe folder.

Any ideas?

Code:

SSLHandler.MaxLineAction := maException;
SSLHandler.SSLOptions.Method := sslvTLSv1;
SSLHandler.SSLOptions.Mode := sslmUnassigned;
SSLHandler.SSLOptions.VerifyMode := [];
SSLHandler.SSLOptions.VerifyDepth := 0;
SSLHandler.OnStatusInfo := IdSSLIOHandlerSocketOpenSSL1StatusInfo;

SMTP.IOHandler := SSLHandler;
SMTP.Host := 'smtp.gmail.com';
SMTP.Port := 587;
SMTP.UseTLS := utUseExplicitTLS;
SMTP.Username := FromAddress;
SMTP.Password := AuthPassword;

Email.From.Address := FromAddress;
Email.Recipients.EmailAddresses := ToAddress;
Email.Subject := Subject;
Email.Body.Text := Body;

SMTP.Connect;
SMTP.Send(Email);
SMTP.Disconnect;

Output:

SSL status: "before/connect initialization"

SSL status: "before/connect initialization"

SSL status: "SSLv3 write client hello A"

SSL status: "SSLv3 read server hello A"

EIdSocketError with message 'Socket Error # 10060 Connection timed out.'


回答1:


It is IdHTTP's ReadTimeout. By default it is -1 and doesn't work with Windows 8. Set it to anything positive like 15000ms or 30000 will fix the problem.

Note that you need to set the numerical value programmatically on the IdHTTP object. Do not try to set the binded IoHandler via the object inspector because it won't work in that way.

Example:

  IdHTTP1.ReadTimeout := 30000;

One tells Indy to use an infinite timeout on its socket operations. However, to work around a deadlock in OpenSSL on Vista+ when a connection is dropped, TIdSSLIOHandlerSocketOpenSSL forces a 30 second timeout at the lower socket layer if the ReadTimeout is <= 0.}

A solution Bob Daneshfar posted on this forum.




回答2:


Finally I found that it is Indy related issue. Upgrade to Indy 10.5.8 or 10.5.9 fixes the problem.

Thanks all for advices.




回答3:


Since you can successfully send email using the .NET SmtpClient class, I suggest you use a packet sniffer, such as Wireshark, to view SmtpClient's network traffic and compare it to Indy/OpenSSL's network traffic and see exactly what the differences are. Something is happening during OpenSSL's TLSv1 handshake that is not happening to SmtpClient, so go see what their handshakes actually look like.




回答4:


Are you sure you've distributed the OpenSSL libraries with you're application (like 'libeay32.dll' and 'ssleay32.dll')?

When you forget those, you get timeouts too, because the error of the OpenSSL library is not correctly transferred to the outer IO object (like TIdSMTP or TIdHTTP).

To check whether OpenSLL for Indy can load I use the following code (which raises an erre when SSL is not available) - uses unit 'IdSSLOpenSSL'

TIdSSLContext.Create.Free; // Raises an error, when unable to load SSL lib and such

You can also plug into the OpenSSL headers unit 'IdSSLOpenSSLHeader' and try to load the library manually and check whether it can:

if not IdSSLOpenSSLHeaders.Load then ; // Raises no error, but return 'true' when it can load


来源:https://stackoverflow.com/questions/14756882/indy10-openssl-send-email-code-stopped-working-on-windows-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!