NBilov 0 Posted May 23, 2023 I have windows 7 . My program sended mail by smtp , with ssl encoding. It worked without any problems on Delphi 2010 , when the same code was compiled on Delphi 10.4.2 it started to raise error " SSL negotiation failed." I need to send from @yandex.ru mail where ssl encoding is obligatory. How can i make such sending on this operation system and compiled with this version of Delphi ? My code: procedure TfmMain.buSimpSendClick(Sender: TObject); var IdSMTP1: TIdSMTP; idMessage1: TIdMessage; idAttach: TidAttachment; idText1: TidText; msgParts: TidMessageParts; DT:TDateTime; IdSSLIOHandlerSocketOpenSSL1:TIdSSLIOHandlerSocketOpenSSL; MailHost,EmpPsw,EmpUser: string; EmPort: Integer; EmpEmail: string; EmpName: string; EmailTo: string; I: Integer; wassent: Boolean; ini: TIniFile; begin EmPort := 587; EmailTo := ''; ini := Tinifile.Create(ChangeFileExt(paramStr(0),'.ini')) ; try MailHost := ini.ReadString('C','MailHost',''); EmpPsw := ini.ReadString('C','EmpPsw',''); EmpUser := ini.ReadString( 'C','EmpUser',''); EmPort := ini.ReadInteger('C','EmPort',0); EmailTo := ini.ReadString('C','EmailTo',''); finally ini.Free; end; memo1.Text := ''; Edit1.Text := 'MailHost='+MailHost+','+'EmpPsw='+EmpPsw+','+'EmpUser='+EmpUser+','+'EmPort='+IntToStr(EmPort)+','+'EmailTo='+EmailTo ; EmpName := empemail;//(nil); wassent := True and false;//(nil); IdSMTP1 := TIdSMTP.Create(nil) ; try try IdSMTP1.Host:= MailHost; IdSMTP1.Password:= EmpPsw; IdSMTP1.Username:= EmpUser; IdSSLIOHandlerSocketOpenSSL1 := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP1); IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1; IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Mode := sslmUnassigned; IdSSLIOHandlerSocketOpenSSL1.SSLOptions.VerifyDepth := 0; IdSMTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1; if EmPort>0 then IdSMTP1.Port := EmPort else IdSMTP1.Port := 465; IdSMTP1.UseTLS := utUseExplicitTLS; idMessage1 := TIdMessage.Create(IdSMTP1); idMessage1.OnInitializeISO := TCL.LInitializeISO; idMessage1.From.Address := EmpEmail; idMessage1.From.Name := EmpName; idMessage1.Subject := 'EmSubject'+DateTimeToStr(now);//'Письмо с картинкой AComp'+FormatDateTime('dd.mm.yyyy hh:mm:ss',Now); idMessage1.CharSet := 'Windows-1251'; idMessage1.ContentTransferEncoding := '8bit'; msgParts := idMessage1.MessageParts; try // Load slBody with your HTML text... idText1 := TidText.Create(msgParts);//, slBody); idText1.ContentType := 'text/html'; idText1.CharSet := 'Windows-1251'; idText1.ContentTransfer := '8bit'; //if FileExists(EmBodyFileName) then idText1.Body.Text := ' (EmailBody)'+ParamStr(0); idMessage1.Recipients.EMailAddresses := EmailTo; idSMTP1.Connect; idSMTP1.Send(idMessage1); ShowMessage('Sent ok,''EmPort='+IntToStr(EmPort)); wassent := True; finally if idSMTP1.Connected then idSMTP1.Disconnect; end; except on E: Exception do Memo1.text := Memo1.text + #13#10 + 'EmPort='+IntToStr(EmPort)+#13#10+ E.Message; end; finally IdSMTP1.Free; self.caption := TimeToStr(now); end; end; Share this post Link to post
David Schwartz 426 Posted May 23, 2023 The first thing that comes to my mind is ... did you copy the proper / latest SSL lib DLLs onto your system? They are not distributed with Delphi. I've got 10.4.2 and I had problems with something that were solved by downloading the latest SSL DLLs. Share this post Link to post
DelphiUdIT 176 Posted May 23, 2023 (edited) Try the @David Schwartz suggestion (this is the official library of Indy: https://github.com/IndySockets/OpenSSL-Binaries) and also the following. You use port 465, (implicit TLS) so is better to put: IdSMTP1.UseTLS := utUseImplicitTLS; And I use that: IdSMTP1.Connect; IdSMTP1.Authenticate; if IdSMTP1.DidAuthenticate then begin IdSMTP1.Send(IdMessage1); end; Hope this help you. Bye Edited May 23, 2023 by DelphiUdIT Share this post Link to post
Remy Lebeau 1393 Posted May 23, 2023 55 minutes ago, NBilov said: IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1; Most servers are phasing out TLS 1.0, or already have, You should enable TLS 1.1 and TLS 1.2 as well: IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; 55 minutes ago, NBilov said: if EmPort>0 then IdSMTP1.Port := EmPort else If you allow the Port to be configurable, you should also allow the UseTLS value to be configurable as well. There is a functional difference between utUseImplicitTLS vs utUsseExplicitTLS, so you should let your config indicate which to use on a non-default Port. 55 minutes ago, NBilov said: IdSMTP1.Port := 465; IdSMTP1.UseTLS := utUseExplicitTLS; As mentioned earlier, this is wrong. You need to use utUseImplicitTLS on port 465. Use utUseExplicitTLS on port 587 instead. Share this post Link to post
NBilov 0 Posted May 25, 2023 Thanks a lot. I used this link https://github.com/IndySockets/OpenSSL-Binaries , actually this item Archive/Experimental/openssl-0.9.8o-i386-win32-fips-1.2.zip from its list and my program started to send letters on my windows 7 server when I put this two dll next to it. Share this post Link to post
Remy Lebeau 1393 Posted May 25, 2023 9 hours ago, NBilov said: Archive/Experimental/openssl-0.9.8o-i386-win32-fips-1.2.zip That is an extremely old version of OpenSSL. You should be using openssl-1.0.2u-i386-win32.zip instead. Or, you can use this SSLIOHandler (work in progress) and then you can use a newer OpenSSL 1.1.x version instead. 1 Share this post Link to post
NBilov 0 Posted May 29, 2023 On my that server almost everything is extremely old, but i will try this , thanks. Share this post Link to post
NBilov 0 Posted May 29, 2023 " IdSMTP1.Connect; IdSMTP1.Authenticate; if IdSMTP1.DidAuthenticate then begin IdSMTP1.Send(IdMessage1); end; " Is this better than my previous " idSMTP1.Connect; idSMTP1.Send(idMessage1);" With 587 port too ? Old variant was working being compiled on Delphi 2010 since 2016 with quite large volumes without much trouble. Share this post Link to post
DelphiUdIT 176 Posted May 29, 2023 4 hours ago, NBilov said: " IdSMTP1.Connect; IdSMTP1.Authenticate; if IdSMTP1.DidAuthenticate then begin IdSMTP1.Send(IdMessage1); end; " Is this better than my previous " idSMTP1.Connect; idSMTP1.Send(idMessage1);" With 587 port too ? Old variant was working being compiled on Delphi 2010 since 2016 with quite large volumes without much trouble. I always use port 465 (implicit TLS) and I must do IdSMTP1.Connect; IdSMTP1.Authenticate; if IdSMTP1.DidAuthenticate then begin IdSMTP1.Send(IdMessage1); end; to avoid any problem. If the simple and short way is working with port 587 there is not need to change. Bye Share this post Link to post
Remy Lebeau 1393 Posted May 29, 2023 TIdSMTP.Send() will call TIdSMTP.Authenticate() for you if authentication hasn't succeeded yet. If you try to send an email without being adequately authenticated, the server will report a failure, which TIdSMTP will raise as an exception. So really, there is little reason to check TIdSMTP.DidAuthenticate and call TIdSMTP.Authenticate() manually. Share this post Link to post