Einzelnen Beitrag anzeigen

AWeber

Registriert seit: 12. Feb 2013
19 Beiträge
 
#41

AW: Indy & OpenSSL 1.1.1 & TLS 1.3

  Alt 25. Aug 2021, 12:32
Hallo,
zunächst möchte ich mich bedanken für die hier geleistete Arbeit

Aber auch gleich mit einem kleinen Problem um die Ecke kommen. Die Reaktion denn die OpenSSL DLL's nicht vorhanden sind - ist nicht so schön bei mir kommt es dann immer zu einer Schutzverletzung - im destructor der Klasse TIdOpenSSLContextClient Soweit ich durchdebuggt habe - ist die Aufrufkette folgende:
Delphi-Quellcode:
TIdTCPClientCustom.Connect( ) --> IOHandler := nil; (bedingt durch Exception) --> TIdTCPConnection.SetIOHandler --> IdDisposeAndNil(LIOHandler);
--> TIdOpenSSLIOHandlerClient.Destroy --> TIdOpenSSLContextClient.Destroy
Delphi-Quellcode:
TIdTCPClientCustom.Connect( )
  try
    IOHandler.Open; --> Exception weil DLL's nicht verfügbar
except
if IOHandler <> nil then begin
IOHandler.Close;
if ManagedIOHandler then begin
// Mein IOHandler ist ManagedIOHandler = true! (bedingt durch anderen Code zuvor)
IOHandler := nil; // RLebeau - SetIOHandler() will free the IOHandler
end;
end;
raise;
end;
Das Set IOhandler = nil führt dann zu:

Delphi-Quellcode:
 procedure TIdTCPConnection.SetIOHandler(AValue: TIdIOHandler);
    if ManagedIOHandler then begin
      if Assigned(LIOHandler) then begin
        FIOHandler := nil;
        -- Zugriffsfehler im Destructor des IOHandlers
        IdDisposeAndNil(LIOHandler);
      end;
      ManagedIOHandler := False;
    end;
Delphi-Quellcode:
destructor TIdOpenSSLIOHandlerClient.Destroy;
  FContext.Free(); --> Zugriffsfehler
Delphi-Quellcode:
destructor TIdOpenSSLContextClient.Destroy;
  OpenSSLContext ist hier noch nil
  und die Methoden / Funktionszeiger
  -> SSL_CTX_sess_set_remove_cb
  -> SSL_CTX_sess_set_new_cb ebenso... da DLL ja nicht gefunden wurde
Meine Lösung sieht jetzt so aus ich ändere die Routine:

Delphi-Quellcode:
procedure TIdOpenSSLIOHandlerClient.EnsureContext;
begin
  // schlägt das Laden der DLL fehl ist FContext noch <nil> und der Aufruf des TIdOpenSSLContextClient.Destroy entfällt.
  EnsureOpenSSLLoaded();

  if not Assigned(FContext) then
     FContext := TIdOpenSSLContextClient.Create();
  
  // EnsureOpenSSLLoaded(); --> führt ggf. zu Exception, wo FContext welches nicht komplett initialsiert ist abgeräumt wird
  try
    BeforeInitContext(FContext);
    TIdOpenSSLContextClient(FContext).Init(FOptions);
    AfterInitContext(FContext);
  except
    on E: EExternalException do
    begin
      try
        FreeAndNil(FContext);
      except
        on E: EExternalException do ; // Nothing
      end;
      raise EIdOpenSSLLoadError.Create('Failed to load OpenSSL');
    end;
  end;
end;
ist das so der richtige Weg?

Nachtrag:

in der Funktion TOpenSSLLoader.Load steckt leider auch ein Bug, auch wenn diese Funktion beim ersten Versuch sauber false liefert wenn die DLL's nicht geladen werden konnten, liefert einer 2. Aufruf true - auch wenn die DLL's immer noch nicht da sind... daher habe ich folgende geändert:

if not Result then
begin
// bei weiterem Aufruf nochmal versuchen die DLL's zu laden...
FLoadCount.Decrement();
Exit;
end;




André

Geändert von AWeber (25. Aug 2021 um 13:02 Uhr)
  Mit Zitat antworten Zitat