Indy "Could not load SSL library" Delphi XE2 IW14 - delphi

I know this question has been asked before but none of the answers seem to be appropriate for this situation.
I'm using a TIdHttp component with an SSL handler. My code is as follows:
idHTTPClient := TIdHTTP.Create(nil);
ioHnd := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
ioHnd.DefaultPort := iSSL_PORT;
ioHnd.SSLOptions.Mode := sslmClient;
idHTTPClient.IOHandler := ioHnd;
idHTTPClient.Request.AcceptEncoding := 'gzip,deflate,identity';
idHTTPClient.Request.BasicAuthentication := False;
try
idHTTPClient.Post(FFQDN, stmRequest, stmResponse);
except
on E:Exception do
begin
if IdSSLOpenSSLHeaders.WhichFailedToLoad <> '' then
begin
AddMsg('Failed to load file ' + IdSSLOpenSSLHeaders.WhichFailedToLoad + '. ' + E.Message);
end;
end;
end;
There are three versions of the ssleay32 and libeay32.dll files on the machine. One set is in the same folder as my executable (V1.0.0.5). One set is in the Apache bin folder (V0.9.8.20) and one set is in C:\Windows\SysWOW64 (no version but dated 2003).
When the app starts it runs fine. But after a few days the Post call starts to fail with "Could not load SSL library". The files which fail to load are:
SSL_SESSION_get_id,SSL_COMP_get_compression_methods
Once this problem starts to happen it won't go away until the app is restarted. Then it works fine again for another few days.
It would seem to me that for some reason the dlls being loaded change after a few days. How could this happen and what could I do to ensure the correct files are loaded every time?

Ideally, delete all the other versions of OpenSSL DLLs on your machine to ensure that your app always finds the correct DLL. Its the multiple versions and processes (Apache) loading these different versions that is causing the conflict.

Related

Could not load SSL library - dll not found

In my Delphi (10.3 community edition) program, I try to use Indy with the OpenSSL library, but I receive an error
Could not load SSL library
My OpenSSL library is version 1.0.2u and I put the libeay32.dll and ssleay32.dll files in my program EXE directory, and in Windows\SYSWOW64 and Windows\System32.
I have installed the Embarcadero Delphi Patch RS1033_Indy_SSL_Patch.
After the exception, I call WhichFailedToLoad() and the result is
Failed to load libeay32.dll
This is a simple program that raises the exception:
url := 'https://www.google.it';
try
Web := TIdHTTP.Create(nil);
hIOHand := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
hIOHand.SSLOptions.SSLVersions := [sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2,sslvSSLv23];
Web.IOHandler := hIOHand;
Web.Request.UserAgent := INET_USERAGENT; //Custom user agent string
Web.RedirectMaximum := INET_REDIRECT_MAX; //Maximum redirects
Web.HandleRedirects := INET_REDIRECT_MAX <> 0; //Handle redirects
Web.ReadTimeOut := INET_TIMEOUT_SECS * 1000; //Read timeout msec
try
Sito := Web.Get(Url);
Sito := DateToStr(Web.Response.LastModified) + Sito;
except
on e : exception do
stg := WhichFailedToLoad();
end;
finally
Web.Free;
end;
Can you help me to solve the problem?
I put the libeay32.dll and ssleay32.dll files in my program EXE directory
That is fine. That is the 1st place the OS will look for them.
and in Windows\SYSWOW64 and in Windows\System32
Don't do that! Non-system files do not belong there. ESPECIALLY if you are putting the same files in both folders, since Windows\SYSWOW64 is meant only for 32bit files and Windows\System32 is meant only for 64bit files.
Failed to load libeay32.dll
That means Windows could not load that DLL into memory at all. Probably because it couldn't find the dependent ssleay32.dll file, but more likely because you mixed up the 32bit and 64bit versions of the DLLs. If your app is compiled as a 32bit EXE, you must use the 32bit version of both DLLs. If your app is compiled as a 64bit EXE, you must use the 64bit version of both DLLs.

Why does a simple Delphi FTP upload of a zip file produce a corrupted file? [duplicate]

I'm having a problem downloading a file using the TidFTP component in Delphi XE2. I am able to get a connection to the FTP site, get a list of files and perform the get command. However, when I try to download a file using the get command the file always downloads larger than the source file. Then the subsequent file is corrupt.
Additionally, if I try to download multiple files, the first file downloads (larger than the source) and the remaining files are skipped. No error is thrown from the get command, it just quits. I tried to hook into some of the events on the TidFTP control like AfterGet and OnStatus but everything appears normal.
I tried using a 3rd party FTP client to access the file and download it just to make sure it was not a problem with our FTP server and that download worked as expected. So I'm thinking it might be related to the TidFTP control or perhaps I'm doing something incorrectly.
Here is the routine I'm using to download the file:
var
ftp: TIdFTP;
strDirectory: string;
begin
ftp := TIdFTP.Create(nil);
try
ftp.Host := 'ftp.myftpserver.com'
ftp.Passive := false;
ftp.Username := 'TestUser';
ftp.Password := 'TestPassword';
ftp.ConnectTimeout := 1000;
ftp.Connect();
ftp.BeginWork(wmRead);
ftp.ChangeDir('/TestArea/');
strDirectory := 'c:\test\';
if not DirectoryExists(strDirectory) then
CreateDir(strDirectory);
ftp.Get('Test.zip', strDirectory + '\' + 'Test.zip', true, false);
ftp.Disconnect();
except
on e: exception do
showMessage(e.message);
end;
end;
You need to set the TIdFTP.TransferType. Its default value is Id_TIdFTP_TransferType, which is ftASCII. You need to use ftBinary instead, and set it before executing the Get:
ftp.Connect();
...
ftp.TransferType := ftBinary;
ftp.Get('Test.zip', strDirectory + '\' + 'Test.zip', true, false);
ftp.Disconnect();
The documentation for TIdFTP.TransferType says in one place that it's automatically set to ftBinary when Login is executed or when Connect is called when AutoLogin is set to true, but you're not executing Login in your code and haven't set AutoLogin. The paragraph immediately following the above statement says:
According to #RemyLebeau in the comments below, the documentation quoted is in error, and TransferType was never set to ftBinary in Login. Leaving the stricken content for future reference.
According to the documentation:
The default value for TransferType is Id_TIdFTP_TransferType, as assigned during initialization of the component.

Downloading list of files from remote FTP

I'm getting a problem using the TidFTP component.
I'm able to connect with the server using a code like this
vFileList := TStringList.Create;
oClientFTP := TidFTP.Create(nil);
oClientFTP.Port := PortFTP;
oClientFTP.Host := IPHost;
oClientFTP.UserName := UserFTP;
oClientFTP.Password := PasswordFTP;
After getting several files from the StringList (this one has exactly 778 elements) when the element no. 137 is retrieved the exception EIdAcceptTimeout is raised with "Accept timed out." message.
The code that I run is like this (runs in a Thread by the way)
procedure TDownloadFTP.Get;
begin
try
for I := 0 to vFileList .Count - 1 do
begin
sFileName:= vFileList [I];
posPoint := LastDelimiter('.', sFileName);
if posPoint = 0 then
ForceDirectories(ExtractFilePath(Application.ExeName) + '/BackUp/' + sFileName)
else
try
oClienteFTP.Get(sFileName,IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName) + '/BackUp/') + sFileName, True);
except
on E: EIdReplyRFCError do
begin
end;
on E: Exception do
exceptionList.Add(sFileName);
end;
end;
After the exception, the file is downloaded correctly but the process needs like 25 seconds per file (I'm downloading 2KB png images).
Any idea of the meaning of this Exception?
Thanks
Googling for EIdAcceptTimeout leads to this discussion in the Indy forum:
UseHOST in TIdFTP (client) => EIdAcceptTimeout
Where Remy Lebeau states:
The only time that exception can occur during a data transfer is if
you have the TIdFTP.Passive property set to False, which tells the FTP
server to make an inbound connection to TIdFTP. Those connections are
usually blocked by firewalls/routers that are not FTP-aware. You
usually have to set TIdFTP.Passive=True when you are behind a
firewall/router.
So, the solution could be for you to add a line
oClientFTP.Passive := True;
Btw. In your code snippets you have both oClientFTP and oClienteFTP. Adjust my suggestion if needed.
I would have written this as comments, rather than an answer, but comments are too limited. Please let me know and excuse me if I misbehave.
Looking at your code a second time raises a few questions. I see that the StringList can have both files (posPoint <> 0) and presumably directories (posPoint = 0). Is element 137 a file or directory and if a file, is it the first file after a new directory?
Do the entries in the StringList include the path they ought to have after '\backup\?
Assuming your application is a Windows application (since you don't say otherwise), When you create new paths, why do you use forward slashes (/) instead of backslashes () which is the path delimiter on Windows? Does your code even create subdirectories on Windows? Well, maybe crossplatform Delphi adjusts according to OS.
In the oClienteFTP.Get statement you say IncludeTrailingPathDelimiter even if you already have a slash as the trailing delimiter in '/backup/'.
You should never anymore use 'ExtractFilePath(Application.ExeName)' and subdirectories, as storage for data files.

Delphi with indy

I just started using indy10 (today) in Delphi 2010, after reading everywere i managed to make it work, i can send emails using gmail, it works fine on my computer, but when i install the application on my laptop (for tests), it doesnt send the email and my app stops working, do i have to install something else on my laptop or how can i make it to work on every computer i install my program, so far i have to install it on 6 different computers, some use windows XP and some Windows 7, i hope there is a way to make it multiplatform or something.
This is my code:
procedure SendIndyMail;
begin
Form_final.IdSMTP1 .IOHandler := Form_final.IdSSLIOHandlerSocketOpenSSL1;
Form_final.IdSMTP1.Host:= 'smtp.gmail.com';
Form_final.IdSMTP1.Password:= 'xxxxxx';
Form_final.IdSMTP1.Port := 587;
Form_final.IdSMTP1.UseTLS := utUseExplicitTLS;
Form_final.IdSMTP1.Username := 'xxxxxx';
Form_final.IdSSLIOHandlerSocketOpenSSL1.Destination := 'smtp.gmail.com:587';
Form_final.IdSSLIOHandlerSocketOpenSSL1.Host := 'smtp.gmail.com';
Form_final.IdSSLIOHandlerSocketOpenSSL1.Port := 587;
Form_final.IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1;
Form_final.IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode := sslmUnassigned;
Form_final.IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyMode := [];
Form_final.IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 0;
Form_final.IdMessage1.Subject:=conect.Q_selec_info_generalDescripcion.Text+' '+DateToStr(Date);
Form_final.IdMessage1.Recipients.EMailAddresses:=conect.Q_config_seleccorreo.Text;
TIdAttachmentFile.Create(Form_final.IdMessage1.MessageParts, conect.Q_config_selecfolder.Text+'\reporte_'+FormatDateTime('dddd d of mmmm yyyy', Date)+' Inventario '+Form_inventario.Edit_id_inventario.Text+'.pdf');
Form_final.IdSMTP1.Connect;
Form_final.IdSMTP1.Send(Form_final.IdMessage1);
Form_final.IdSMTP1.Disconnect;
end;
I ran the proyect on my laptop and it says:
Could not load SSL Library, now, i did many things to make it work, downloaded many things and tried many other, now i dont know where those libraries are and how to retrieve them, and i would like to know of a way to load them with the installation so my installer goes with everything needed.
Thanks in advance.
Make sure you have the OpenSSL DLLs on your target machines, preferrably in your app's installation folder. If you still get the error, Indy's WhichFailedToLoad() function in the IdSSLOpenSSLHeaders unit can tell you why it could not load the OpenSSL DLLs. As for the DLLs themselves, you can download Indy-compatible copies from Indy's Fulgan mirror.
On a side note, you do not need to set the IOHandler's Destination, Host, or Port properties. The Connect() method will handle that internally for you.

INDY 10.1.5 - Which SSL dlls work with Delphi 2006?

I'm trying to connect to google documents (following Marco Cantu's excellent REST example) but I am getting the following SSL errors:
1) If I use the SSL dlls from openssl-0.9.8i-i386-win32.zip I get the error:
"Could not load SSL library"
2) If I use the SSL dlls from indy_OpenSSL096m.zip I get the error:
"Error connecting with SSL"
3) If I use the SSL dlls from openssl-0.9.8h-i386-win32-Indy-IntraWebEdition.zip I get the error:
"Could not load SSl Library"
Now I've researched this and there are a lot of recommendations with dead links to dlls about, including links on stack overflow. I suspect I need to find the SSL dlls that are compatible with the version of INDY I am using.
My question is, does anyone know exactly which SSL dlls are compatible with Delphi 2006 & INDY 10.1.5?
I had the same problem even after I upgrading to INDY 10.2.3 and I tryed every different version of the “libeay32.dll” and “ssleay32.dll” files I could find ... Like Matt I always got one of the two errors: "Could not load SSL library" or the "Error connecting with SSL" with something like "error:00000006:lib(0):func(0):EVP lib" ...
I was very happy when I change the TidSSLioHandlerSocketOpenSSL.SSLOptions.Method to sslvSSLv23 and everything started working.
A bit more research and I quickly understood anytime I got the error "Could not load SSL library" I was using the wrong version of the DLL files and anytime I got the "Error connecting with SSL" with something like "error:00000006:lib(0):func(0):EVP lib" I was using the wrong SSLOptions.Method value.
Other Info: I'm using Delphi 2006, INDY 10.2.3 and I'm runnin on WinXP Pro
This caused me so much pain, I hope this post will save someone some time.
You could resort to some trial and error using downloads from the Fulgan site.
You might want to think about updating your copy of Indy and using the most recent OpenSSL DLLs.
FWIW, since I have spent a lot of time getting this https thing to work, here are the results of my successful efforts.
1- Delphi 7
2- indy9.0.19_d7.exe
3- IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLSv1; or,
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLSv23; or,
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLSv3;
I tried indy10.0.76_d7.exe and indy10.1.5_d7.exe under Delphi 7 and I cannot get them to install properly, let alone get HTTPS to work. I get the infamous message "Unit IdSysWin32 was compiled with a different version of IdException.EIdException." I searched for a solution to that problem on the web and couldn't find one - loads of others had the same message.
A useful site for testing https is https://msp.f-secure.com/web-test/common/test.html
Here is my source:
procedure TForm1.ButtonHTTPSClick(Sender: TObject);
var
IdHTTP1: TIdHTTP;
ParamStringList: TStringList;
s1: String;
MemoryStream1: TMemoryStream;
IdSSLIOHandlerSocket1: TIdSSLIOHandlerSocket;
begin // ssl works fine must have Indy version indy9.0.19_d7.exe and must use option sslvSSLv23
Screen.Cursor := crHourGlass;
IdHTTP1 := TIdHTTP.Create(nil);
IdSSLIOHandlerSocket1 := TIdSSLIOHandlerSocket.Create(nil);
IdHTTP1.IOHandler := IdSSLIOHandlerSocket1;
// IdSSLIOHandlerSocket1.SSLOptions.Method := sslvTLSv1; // sslvSSLv1 works fine
IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv3; // sslvSSLv3 works fine
// IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv23; // sslvSSLv23 works fine
// IdSSLIOHandlerSocket1.SSLOptions.Method := sslvSSLv2; sslvSSLv2 does not work
IdSSLIOHandlerSocket1.SSLOptions.Mode := sslmUnassigned;
IdSSLIOHandlerSocket1.SSLOptions.VerifyMode := [];
IdSSLIOHandlerSocket1.SSLOptions.VerifyDepth := 0;
ParamStringList := TStringList.Create;
MemoryStream1 := TMemoryStream.Create;
s1 := IdHTTP1.Post('https://msp.f-secure.com/web-test/common/test.html', ParamStringList);
MemoryStream1.Write(s1[1], Length(s1));
MemoryStream1.Position := 0;
MemoryStream1.SaveToFile('c:\temp\MemoryStream1.txt');
Memo1.Lines.Clear;
Memo1.Lines.LoadFromFile('c:\temp\MemoryStream1.txt');
MemoryStream1.Free;
ParamStringList.Free;
IdSSLIOHandlerSocket1.Free;
IdHTTP1.Free;
Screen.Cursor := crDefault;
end;
As far as I am aware the more recent versions of Indy work with standard OpenSSL binaries.
Download from here. We produced a Delphi FTP client app a while ago using Indy with SSL connections and I'm sure we just shipped the current OpenSSL dlls.
Edit: Just checked the app directory and the DLLs we used are OpenSSL 0.9.8.2 (3-Aug-06). (It's an old app)
Edit 2: And I've just copied the more recent 0.9.8k dlls over and they work fine too.
Find the Indy version you are using.Copy the Indy dlls i.e libeay32.dll,libssl32.dll and
ssleay32.dll into the Windows/System 32 Folder.It will resolve the error "Could not Load SSL Library"

Resources