TIdSMTP: Could Not Load SSL Library - delphi

Windows 7 64 bit
Delphi 5
Indy 10.6.2.5499
I know most of us have nervous ticking with this problem.
But in any case I lost some hours already without result to try different ssl dlls one by one.
In every case I get my favorite "Could Not Load SSL Library" exception.
I reinstalled Indy with previously deleted old Indy and so on.
I went this way more than 10 times in my life but here again...
Maybe you see some specific in my environment or so...
Code:
SSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
SSLHandler.SSLOptions.Method := sslvTLSv1;
FIdSMTP := TIdSMTP.Create(nil);
FIdSMTP.SASLMechanisms.Clear;
FIdSMTP.IOHandler := SSLHandler;
FIdSMTP.AuthType := satDefault;
FIdSMTP.UseTLS := utUseExplicitTLS;
FIdSMTP.Host := 'mx.freenet.de';
FIdSMTP.Port := 587;
FIdSMTP.Password := 'xxxxx';
FIdSMTP.Username := 'xxxxx';
FIdMessage := TIdMessage.Create(nil);
FIdMessage.CharSet := 'windows-1252';
FIdMessage.From.Address := 'xxxxx';
FIdMessage.ContentType := 'multipart/mixed';
FIdMessage.subject := subject;
FIdMessage.Recipients.EMailAddresses := email;
FHTML := TIdText.Create(FIdMessage.MessageParts, html);
FHTML.ContentType := 'text/html';
FIdSMTP.ConnectTimeout := 5000;
FIdSMTP.ReadTimeout := 5000;
try
FIdSMTP.Connect;
FIdSMTP.Send(FIdMessage);
FIdSMTP.Disconnect;
except
on e: Exception do
begin
ShowMessage(WhichFailedToLoad());
showmessage('Cannot send mail: ' + #13 + e.Message);
end;
end;
SSLHandler.Free;
FIdSMTP.Free;
FIdMessage.Free;
FHTML.Free;

Related

How to encode the response of an TIdHTTP call?

In a project I use TIdHTTP to call a webserver.
The webserver is an asp.net test application that returns the following json:
{
"message":"test ÀÈÉÌÒÙàèéìòù"
}
The response I get in Delphi is a kind of not encoded string:
{"message":"test ÃÃÃÃÃÃàèéìòù"}
this is how I use TIdHTTP:
Result := '';
IdHTTP := TIdHTTP.Create;
IdHTTP.Request.MethodOverride := 'ForwardCommand';
IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
IdSSLIOHandlerSocketOpenSSL.SSLOptions.Mode := sslmClient;
IdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions:= [sslvTLSv1_2];
IdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL;
IdHTTP.HandleRedirects := True;
IdHTTP.Response.ContentEncoding := 'UTF-8'; // I tried this but it seems not enough!
try
url := 'testappUrl';
try
IdHTTP.ConnectTimeout := 2000;
IdHTTP.ReadTimeout := 4000;
Response := IdHTTP.Get(url);
ShowMessage(response);
except
on E:Exception do
begin
response := StringReplace(E.Message,#10,' ',[rfReplaceAll]);
response := StringReplace(response,#13,' ',[rfReplaceAll]);
response := '{"errormessage": "'+response+'"}';
end;
end;
Result := response;
finally
IdHTTP.Free;
end;
please tell me how I can see the response correctly.
Is there a way to force encoding so that accented chars are read correctly?
Thanks.
Try to use a TStringStream forcing the encoding (UTF-8).
Test this code to get the response:
var
ts:TStringStream;
begin
...
ts := TStringStream.Create(string.Empty, TEncoding.UTF8);
IdHTTP1.Get('url', ts);
ShowMessage(ts.DataString);
or
ShowMessage(ts.ToString);
...

How to solve 'invalid address' using idSMTP

I've posted various questions trying to figure out all my issues with trying to send an email using TLS with Office365.
My last question here: How do I solve [EIdSMTPReplyError] Authentication unsuccessful?
Since I couldn't solve the latter I got credentials of one of our clients and try testing the sample with their office credentials which brought me one step closer. With my own office credentials I'm just unable to authenticate (see previous link). In PowerShell there is no issue and I can send an email with the same credentials but not programmatically.
I'm now trying to figure out why the server is returning "Invalid Address" using the client's credentials. Again, I'm able to use the exact same credentials in PowerShell and generate a sample email which works. But not with this component.
Slightly adjusted code from previous link:
procedure TForm28.SendEmail(poSMTP:TIdSMTP);
var
loSMTPMessage : TIdMessage;
begin
loSMTPMessage := TIdMessage.Create(nil);
with loSMTPMessage do
begin
Recipients.Add.Address := 'to address';
ReplyTo.Add.Text := edtUsername.Text;
From.Address := edtUsername.Text;
From.Name := 'xxx';
From.Text := 'Test';
Subject := 'Test';
end;
poSMTP.Send(loSMTPMessage);
loSMTPMessage.Free;
end;
procedure TForm28.Method2Click(Sender: TObject);
var
idSMTP1: TIdSMTP;
idSASLLogin: TIdSASLLogin;
idUserPassProvider: TIdUserPassProvider;
lp:PWideChar;
liSize:Cardinal;
begin
idSMTP1 := TIdSMTP.Create(nil);
idSMTP1.OnFailedRecipient := IdSMTP1FailedRecipient;
//have tried all these variations in trying to solve authentication issue
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNameNetBIOS);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNameDnsHostname);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNameDnsDomain);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNamePhysicalNetBIOS);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNamePhysicalDnsHostname);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNamePhysicalDnsDomain);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNamePhysicalDnsFullyQualified);
// IdSMTP1.HeloName := GetComputerNameExString(ComputerNameMax);
try
idSMTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idSMTP1);
idSMTP1.UseTLS := utUseExplicitTLS;
TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
idSMTP1.Host := edtSMTP.Text;
idSMTP1.Port := StrToInt(cbPort.Text);
idSASLLogin := TIdSASLLogin.Create(idSMTP1);
idUserPassProvider := TIdUserPassProvider.Create(idSASLLogin);
idSASLLogin.UserPassProvider := idUserPassProvider;
idUserPassProvider.Username := edtUsername.Text;
idUserPassProvider.Password := edtPassword.Text;
idSMTP1.AuthType := satSASL;
idSMTP1.SASLMechanisms.Add.SASL := idSASLLogin;
try
idSMTP1.Connect;
try
if idSMTP1.Authenticate then
SendEmail(idSMTP1);
finally
idSMTP1.Disconnect;
end;
ShowMessage('OK');
except
on E: Exception do
begin
ShowMessage(Format('Failed!'#13'[%s] %s', [E.ClassName, E.Message]));
raise;
end;
end;
finally
idSMTP1.Free;
end;
end;
This gives me an error: Project SMTP_SSL_Example.exe raised exception class EIdSMTPReplyError with message 'Invalid address
'.
Oh my gosh.
From.Text := 'Test';
called after
From.Address := edtUsername.Text
was changing my email address to 'test'.
Cannot believe I've wasted time with something stupid like this.

IdHttpServerexception:Error accepting connection with SSL. EOF was observed that violates the protocol;

I have a Delphi 2007 TIdHttpServer Web App (Version 10). My IdHTTPServer1.onexception handler is handling a lot of these exceptions:
Error accepting connection with SSL. EOF was observed that violates
the protocol
I also have the latest version of OpenSSL (1.0.2.4).
I know it is protocol to have a MCVE (Minimal, Complete, and Verifiable example). However I am not able to replicate this. These exceptions are occurring in production environment. All I have been able to do is log the ip address. And the IP Addresses are random. So it does not appear to be any single "spam bot" that could be doing this.
Do these exceptions mean something is making requests using a version of SSL that I am not supporting?
Is there something I can do to fix this?
Or is this something I should not worry about?
Below is my code for setting up the server:
ServerIOHandler := TIdServerIOHandlerSSLOpenSSL.Create(self);
ServerIOHandler.SSLOptions.CertFile := 'C:\xxxxx.crt';
ServerIOHandler.SSLOptions.KeyFile := 'C:\xxxxx.key';
ServerIOHandler.SSLOptions.RootCertFile := 'C:\yyyyyyy.crt';
ServerIOHandler.SSLOptions.Method := sslvSSLv23;
ServerIOHandler.SSLOptions.SSLVersions := [sslvSSLv23,sslvSSLv2, sslvSSLv3, sslvTLSv1,sslvTLSv1_1,sslvTLSv1_2];
ServerIOHandler.OnGetPassword := GetSSLPassword;
IdHTTPServer1 := TEAIdHTTPServer.Create;
IdHTTPServer1.MaxConnections := 1000;
IdHTTPServer1.AutoStartSession := True;
IdHTTPServer1.SessionState := True;
IdHTTPServer1.OnCommandGet := MainGet;
IdHTTPServer1.onexception := IdHttpServerexception;
IdHTTPServer1.onlistenexception := IdHttpServerlistenexception;
IdHTTPServer1.onconnect := IdHttpServerConnect;
IdHTTPServer1.ondisconnect := IdHttpServerDisconnect;
idHttpServer1.ParseParams := True;
idHttpServer1.OnQuerySSLPort := QuerySSLPort;
idHttpServer1.IOHandler := ServerIOHandler;
idHttpServer1.Bindings.Add.Port := 80;
idHttpServer1.Bindings.Add.Port := 443;
IdHTTPServer1.Active := True;
procedure TMyProject.QuerySSLPort(APort: TIdPort; var VUseSSL: Boolean);
begin
if APort=80 then begin
vUseSSL := False;
end else if APort=443 then begin
vUseSSL := True;
end else begin
vUseSSL := False;
end;
end;

Is Platform Assistant Server necessary to run fireDAC application to connect to Informix?

I am trying to connect my Delphi application to Informix database using fireDAC. I all the parameters supplied in connection editor. But I have to run PA Server to make it work.
So is it necessary to run the PA Server to connect to Informix db.
I am able to solve it using the following code to connect instead of dragging droping he controls:
procedure TForm1.FormCreate(Sender: TObject);
var
Params: TStringList;
begin
FDManager := TFDManager.Create(self);
FDconnection := TFDConnection.Create(self);
FDQuery := TFDQuery.Create(self);
FDataSOurce := TDataSource.Create(self);
Params := TStringList.create;
Params.Values['User_Name'] := paramstr(3);
Params.Values['Database'] := paramstr(2);
Params.Values['Password'] := paramstr(4);
Params.Values['DriverName'] := 'Informix';
Params.Values['HostName'] := paramstr(1);
Params.Values['RDBMS'] := 'OTHER';
Params.Values['DriverID'] := 'TDBX';
FDManager.AddConnectionDef('BOSSConnection', 'TDBX', Params);
FDConnection.DriverName := 'TDBX';
FDConnection.ConnectionDefName:='BOSSConnection';
FDConnection.Connected := True;
FDQuery.SQL.Add('select first 10 cust_code, bus_name, status from strcustr;');
FDQuery.Connection := FDConnection;
FDataSource.DataSet := FDQuery;
FDQuery.Active := True;
DBGrid1.DataSource := FDataSource;
FDConnection.LoginPrompt := False;
end;

Sending message to gmail fails with "Start SSL negotiation command failed." error

Tips i followed is found here.
I do have libeay32.dll and ssleay32.dll in win32 folder.
dfm file:
object tidSMTP: TIdSMTP
IOHandler = tidSMTP_SSL
SASLMechanisms = <>
UseTLS = utUseExplicitTLS
end
object tidSMTP_SSL: TIdSSLIOHandlerSocketOpenSSL
Destination = 'smtp.gmail.com:587'
Host = 'smtp.gmail.com'
MaxLineAction = maException
Port = 587
DefaultPort = 0
SSLOptions.Mode = sslmUnassigned
SSLOptions.VerifyMode = []
SSLOptions.VerifyDepth = 0
end
and Send button click event:
procedure TForm1.btnSendClick(Sender: TObject);
var
mes:TIdMessage;
fromAddress:TIdEmailAddressItem;
toAddress:TIdEMailAddressItem;
begin
tidSMTP.Username := txtUsername.Text;
tidSMTP.Password := txtPassword.Text;
tidSMTP.Host := txtSMTPserver.Text; //smtp.gmail.com
tidSMTP.Port := StrToInt(txtSMTPport.Text); //587
fromAddress := TIdEMailAddressItem.Create;
fromAddress.Address := txtUsername.Text;
toAddress := TIdEMailAddressItem.Create;
toAddress.Address := txtTo.Text;
mes := TIdMessage.Create;
mes.ContentType := 'text/plain';
mes.From := fromAddress;
mes.ReceiptRecipient := toAddress;
mes.Subject := txtSubject.Text;
mes.Body := memoText.Lines;
tidSMTP.Connect;
tidSMTP.Send(mes);
tidSMTP.Disconnect;
end;
Any help would be appreciated!
Set you SSL Method to SSL version 3 (tidSMTP_SSL.SSLOptions.Method). I think it defaults to SSL version 2, but GMail does not support that.
SSLOptions.Method := sslvSSLv3;
Edit:
You can log the SSL Status info by assigning an eventhandler to the OnStatusInfo event of your IOHandler:
tidSMTP_SSL.OnStatusInfo := DoOnStatusInfo;
proceudre TForm1.DoOnStatusInfo(Msg: string);
begin
// when running from IDE, message will appear in
// EventLog (Ctrl+Alt+V), otherwise,
// use DebugViewer.exe
OutputDebugString(PChar(Msg));
end;
Maybe this will give you a clue about the failing negotation.
PS: I'm on Indy 9.0.0.18, so things may have changed for you.
Edit2:
If above does not help, please check if there is not a firewall / antivirus that is blocking smtp.gmail.com or port 587
I successfully make it worked like this:
procedure TForm1.btn2Click(Sender: TObject);
var
email : TIdMessage;
idSMTPGMail: TIdSMTP;
idSSLGMail : TIdSSLIOHandlerSocketOpenSSL;
begin
idSSLGMail := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
idSSLGMail.SSLOptions.Method := sslvTLSv1;
idSSLGMail.SSLOptions.Mode := sslmUnassigned;
idSMTPGMail := TIdSMTP.Create(nil);
idSMTPGMail.IOHandler := idSSLGMail;
idSMTPGMail.UseTLS := utUseExplicitTLS;
email := TIdMessage.Create(nil);
email.From.Address := txtUsername.Text;
email.Recipients.EMailAddresses := txtTo.Text;
email.Subject := txtSubject.Text;
email.Body.Text := memoText.Text;
idSMTPGMail.Host := 'smtp.gmail.com';
idSMTPGMail.Port := 587;
idSMTPGMail.UserName := txtUsername.Text;
idSMTPGMail.Password := txtPassword.Text;
idSMTPGMail.Connect;
idSMTPGMail.Send(email);
idSMTPGMail.Disconnect;
email.Free;
idSSLGMail.Free;
idSMTPGMail.Free;
Beep;
end;
I use the same TEdit, TMemo, but dynamically create the Indy components...

Resources