FNCCloudServices stopped working

Hi, we were using FNCCloudServices in an application with OneDrive, GDrive and Dropbox. We are now unable to connect new accounts.
The callback to localhost:8888 (for example) no longer works. We have checked firewall, etc and tried it on multiple machines that were working in the past.
We have tried upgrading to the latest FNC core, components but the problem persists.
We have tried removing the security - so using http instead of https but the problem persists.
It's as if the component doesn't start listening for the oauth to come back.
Are you aware of any changes or issues that might cause this to happen? We only noticed last week, but this may have been the case for a while.
If a service is connected, you can still connect to it - ie GDrive, but trying to do the oauth pathway for onedrive fails when calling back.

1 Like

Hi,

We are not aware of any issues with the TTMSFNCCloudStorageServices component.
We also haven't received any similar reports from other users.

Please provide the following information so I can further investigate this.

  • Which version of Delphi are you using?
  • Are you using a VCL or FMX application?
  • Please explain exactly what happens when the callback to localhost fails.
    If there are error messages, please provide screenshots.
  • Does the issue only happen with OneDrive or also with Google Drive and/or DropBox?
  • Are there any other services running on the PC that use localhost on port 8888?
  • Does the issue only happen in your own application or also with the CloudStorageServices demo?

Hi Bart,
In answer to your questions, this was working and now is not.

  • Delphi 10.3
  • VCL
  • You go through the OAuth process and on coming back to the local address the browser reports - "This site can’t be reached xxxxx took too long to respond."
  • It happens with all cloud services
  • There is nothing else using port 8888
  • Also with the demo

I've managed with a restart of the server (and also closing all instances of the application) to initiate a connection the first time. But subsequent times fail. This is true when changing the connection type - onedrive, google drive etc and clicking connect as well as closing just the form and reopening. It's almost as if the cloudservices doesn't reinitialise the listener on 8888 on subsequent calls to Connect. Is there a way to force this? I can't see a Disconnect method, only Connect. which i thought might reset things.

Can you please make sure you are using the latest version of TMS FNC Core and TMS FNC Cloud Pack?
Have you tried changing the port number (for example to 8889)?

Hi Bart
Yes I upgraded to the latest to see if there had been any fixes. But the same behaviour.
I've now tried with port 8889 (and opened that port in the firewall) and that is doing the same. When it comes back to localhost:8889 the browser says 'page did not respond'.
Almost as if the listener is not listening.
Thanks

Hi,

I'm not sure what is going wrong on your side.
Can you please provide a screenshot of the error message (make sure to include the browser's address bar in the image as well)?

Hi Bart this is the screen it comes back to. I've also put on the firewall rules I have locally. As I say its almost as if the CloudServices component is not listening.

I get the same screen, albeit with a different port in the address bar when I use port 8889.

Thanks for your help

Hi,

I notice you are using an HTTPS localhost callback. Are you sure that the callback set in the component is the same as you use in the service? Did you try with HTTP instead of HTTPS?

Hi Pieter yes we've tried using http and https. Yes this was working, but now is not.

That's very strange, we are still not able to reproduce this here... For some reason, it's like the HTTP server included in TMS FNC Cloud Pack Authentication didn't start. Could you try to debug and see if the code breaks on line 764 in the unit FMX.TMSFNCCloudOAuth.pas and the code is executed properly.

image

Stepping through VCL.TMSFNCCloudOAuth.pas helped. This might explain why it works the first time but not subsequently. This error was raised on line 770 ConfigureSSL.

We have the option to change service and then connect is called again. However it is still connected to the previous service, there is no call to disconnect so perhaps this is why as the library is still in use from the previous connection?

Previously although I had changed the address to use to http I'd left in the call to CloudStorageServices.Storage.OnConfigureHTTPServer := DoConfigureHTTPServer; so it may have been hitting this problem for both http and https

When changing a service dynamically while the HTTP server process is still running could indeed be the reason for the issue. Then it starts the http-server twice on the same port, which is not possible. This indeed is not related to HTTP or HTTPS specifically, it's an issue related to the configuration of a running HTTP server. What you can try is the following code:

TMSFNCCloudStorageServices1.Storage.DestroyHTTPServer;

Which needs to come before changing the service.

Thanks Pieter, in addition with destroying the SSLHandler seemed to have resolved it but the issue persists. This is the code we have. Many thanks for your help


    if (Assigned(SSLHandler)) then
    begin
      SSLHandler.Free;
      SSLHandler := nil
    end;
    CloudStorageServices.Storage.DestroyHTTPServer;//clear connection

    SelectService;

    CloudStorageServices.Storage.OnConfigureHTTPServer := DoConfigureHTTPServer;//handle ssl

    CloudStorageServices.Connect;
  end;
end;

procedure TCloudServicefm.CertPW(var pw: string);
begin
  pw := 'xxxx';
end;

function TCloudServicefm.VerifyPeer(Certificate: TIdX509; AOk: Boolean; ADepth: Integer; AError: Integer): Boolean;
begin
  Result := True;
end;

procedure TCloudServicefm.DoHTTPServerConnect(AContext: TIdContext);
begin
  AContext.Connection.Socket.ReadTimeout := 60000;
end;

procedure TCloudServicefm.DoConfigureHTTPServer(Sender: TObject; const AHTTPServer: THTTPServer);
begin
  AHTTPServer.OnConnect := DoHTTPServerConnect;

  SSLHandler := TIdServerIOHandlerSSLOpenSSL.Create(nil);
  SSLHandler.SSLOptions.CertFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'xxxx.pfx');
  SSLHandler.SSLOptions.KeyFile := TPath.Combine(ExtractFilePath(ParamStr(0)), 'xxxx.pfx');
  SSLHandler.SSLOptions.RootCertFile := '';

  SSLHandler.SSLOptions.Mode := sslmServer;
  SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

  SSLHandler.OnGetPassword := CertPW;
  SSLHandler.OnVerifyPeer := VerifyPeer;
  AHTTPServer.IOHandler := SSLHandler;
end;

Thanks for the feedback!

Can you try with our own built-in SSL certificate handling and see if that allows to connect? You will need to accept the certificate before getting the authentication succes screen, but as soon as that has happened, you should be able to connect. If that works, then I suppose it's something missing in the SSL override configuration you added or maybe an issue in the handshake.

Hi Pieter that has the same issue. It seems to come down to ln 463 in VCL.TMSFNCCloudOAuth.pas specifically
lib.SaveToFile(pthOpenSSL + 'libeay32.dll');
The files there cannot be removed, they are in use and locked. They are removed when the application closes but not before. So once they are instantiated it is not possible to create a new oauth connection. However if you go through the oauth process each run of the application. You are then able to connect to and switch between these two services.
Is there a way to release and remove these dlls?

I've modified the .pas to be

if (not TFile.Exists(pthOpenSSL + 'libeay32.dll')) then
`lib.SaveToFile(pthOpenSSL + 'libeay32.dll');`

and i think that has resolved the issue for me

Thanks for the reply, as this makes sense, I'll add this fix to our sources.