Recent

Author Topic: How to solve this synapse ftp(s) error? [SOLVED]  (Read 1056 times)

rvk

  • Hero Member
  • *****
  • Posts: 4937
Re: How to solve this synapse ftps error?
« Reply #15 on: August 12, 2022, 12:56:52 am »
Ok, passivemode probably needs to be true.

Quote
FTP sessions work in active or passive modes:
Active mode. After a client initiates a session via a command channel request, the server creates a data connection back to the client and begins transferring data.
Passive mode. The server uses the command channel to send the client the information it needs to open a data channel. Because passive mode has the client initiating all connections, it works well across firewalls and network address translation gateways.

You might want to implement the OnStatus event to see the communication on the command port. There you can see what ports are too be used for the actual data. Maybe something goes wrong there.

With PASV mode the server will respond with a port and ip for the client to connect to (other than the default command port). Maybe the ip the client gets from the server is the wrong (internal) one. You should be able to see that in the OnStatus (although it's strange that this does work in Windows).

(Btw. That second data port which the server transmits with passivemode also needs to be open in the firewall on the server side.)

Could you show more complete code which works under Windows and not under Linux for plain FTP? And show what the OnStatus gives you.

« Last Edit: August 12, 2022, 01:20:41 am by rvk »

Hartmut

  • Hero Member
  • *****
  • Posts: 550
Re: How to solve this synapse ftps error?
« Reply #16 on: August 12, 2022, 12:15:59 pm »
You found the problem rvk! It works now! Thank you so much. I will report the details later, must go outside now. But I wanted to announce this good news early so that nobody else continues working on that problem.

Hartmut

  • Hero Member
  • *****
  • Posts: 550
Re: How to solve this synapse ftps error?
« Reply #17 on: August 12, 2022, 02:01:44 pm »
Here comes the details how the information from rvk leaded to the solution:

With PASV mode the server will respond with a port and ip for the client to connect to (other than the default command port). Maybe the ip the client gets from the server is the wrong (internal) one.

With Linux console command pftp (passive ftp client) I got the following output:
Code: Text  [Select][+][-]
  1. hg6@i3300:~$ pftp hostname 45032
  2. Connected to xxxxx.
  3. 220 HelmiNAS FTP server ready.
  4. Name (xxxxx:hg6): xxxxx
  5. 331 Password required for xxxxx.
  6. Password:
  7. 230 User xxxxx logged in.
  8. Remote system type is UNIX.
  9. Using binary mode to transfer files.
  10. ftp> dir
  11. 227 Entering Passive Mode (192,168,178,21,217,88)
  12.    <here was a timeout of 130 seconds>
  13. ftp: connect: Connection timed out

Now I understood the meaning of line
   227 Entering Passive Mode (192,168,178,21,217,88)
and saw that this was an internal IP adress!

I contacted the friend who had configured the server and with this info he could find and enable something like "Report external adress in Passive Mode". After this it worked :-))

Interesting is that TotalCommander (a wellknown filemanger for Windows which supports FTP and FTPS and most of it runs on Linux via WINE) is able to automatically redirect this internal IP to the correct external IP. Extract from the TotalCommander FTP logfile:
Code: Text  [Select][+][-]
  1. ...
  2. Connect ok!
  3. PWD
  4. 257 "/" is current directory.
  5. Verzeichnis einlesen
  6. TYPE A
  7. 200 Type set to A.
  8. PASV
  9. 227 Entering Passive Mode (192,168,178,21,217,88)
  10. Server reports local IP -> Redirect to: 95.xxx.xxx.xxx
  11. Connected to PASV port

That means, it is technically possible to detect the internal IP and redirect it to the correct external IP! Seems that synapse can do this on Windows (because my code worked on Windows), but not on Linux (because the same code got a 130 sec timeout there).

Can anyone explain this difference in synapse?

Again thank you very much to rvk that you pointed me to the problem.

rvk

  • Hero Member
  • *****
  • Posts: 4937
Re: How to solve this synapse ftps error?
« Reply #18 on: August 12, 2022, 02:12:38 pm »
I contacted the friend who had configured the server and with this info he could find and enable something like "Report external adress in Passive Mode". After this it worked :-))
Yes, that was what I expected.

That means, it is technically possible to detect the internal IP and redirect it to the correct external IP! Seems that synapse can do this on Windows (because my code worked on Windows), but not on Linux (because the same code got a 130 sec timeout there).
An 192.168.x.x is always a local IP. The FTP client could just ignore that and try the external IP on which the connection was initiated.
That's what TotalCommander seems to do.

I'm not aware Synapse does this. And if it does, it should also work under Linux.

If you implement the OnStatus for your program you'll see those messages there too (on Windows and Linux) and you'll know which commands are sent.

One possibility... When TotalCommander detects a local IP (like 192.168.x.x) this could also be a local adres within your network.
If Windows is on 10.0.0.x for example and the FTP server reports 192.168.x.x, you know it's a remote location.
If Linux is on 192.168.x.x and the FTP server reports 192.168.x.x, this could also be a local network adres.
How would TotalCommander see the difference?

You ran TotalCommander on Windows. But your program also worked under Windows. So maybe your Windows is on a different subnet from your Linux machine?

Hartmut

  • Hero Member
  • *****
  • Posts: 550
Re: How to solve this synapse ftps error?
« Reply #19 on: August 12, 2022, 05:44:19 pm »
You ran TotalCommander on Windows.
No, I ran TotalCommander on Linux via WINE (some kind of "emulator"). The logfile extract which I showed in reply #17 was created on Linux, not on Windows.

Quote
But your program also worked under Windows. So maybe your Windows is on a different subnet from your Linux machine?
I don't have a Windows which is able to access the Internet. So I sent a Windows version of my program to a friend an he ran it on a pure Windows 10 (no Virtual Machine), where it worked. This computer has local IP adress 192.168.178.20.

My Linux computer has local IP 10.13.x.x. So it should be easy for synapse to detect, that 192.168.x.x must be a remote location. I don't know which local IP adress TotalCommander sees on Linux via WINE.

Quote
If you implement the OnStatus for your program you'll see those messages there too (on Windows and Linux) and you'll know which commands are sent.
This sounds interesting. I have found this Event and saw that it needs a class to work. It will take some work for me to implement this, because I'm not too familiar with that stuff. I want to do this just for curiosity after my project is finished.

rvk

  • Hero Member
  • *****
  • Posts: 4937
Re: How to solve this synapse ftps error?
« Reply #20 on: August 12, 2022, 06:04:17 pm »
I don't have a Windows which is able to access the Internet. So I sent a Windows version of my program to a friend an he ran it on a pure Windows 10 (no Virtual Machine), where it worked. This computer has local IP adress 192.168.178.20.
That's not the same friend which has the FTP server by any chance?
Because then it's obvious that it worked.
It just connected internally  :D

My Linux computer has local IP 10.13.x.x. So it should be easy for synapse to detect, that 192.168.x.x must be a remote location. I don't know which local IP adress TotalCommander sees on Linux via WINE.
Yes. But I'm not aware Synapse does this (like TC).
You might be able to force the IP of the server yourself (haven't look yet).
But you'll need to implement the OnStatus to detect the PASV command.

Quote
If you implement the OnStatus for your program you'll see those messages there too (on Windows and Linux) and you'll know which commands are sent.
This sounds interesting. I have found this Event and saw that it needs a class to work. It will take some work for me to implement this, because I'm not too familiar with that stuff. I want to do this just for curiosity after my project is finished.
You can create a dummy class with an event and assign that event to your OnStatus.
If you make it a class function you don't even need to create an insurance for that class.
When you are at that point I can show an example.

It would just be something like (I'm on mobile so forgive any typos)

Code: Pascal  [Select][+][-]
  1. Type
  2.   TMyDummyClass = class(TObject)
  3.   public
  4.     class procedure OnStatus(etc. Etc cant look up the def now);
  5.   end;
  6. //...
  7. class procedure TMyDummyClass.OnStatus(etc. Etc cant look up the def now);
  8. begin
  9.   Writeln(logline);
  10. end;
  11. //...
  12.   fTX.OnStatus := @TMyDummyClass.OnStatus;


Hartmut

  • Hero Member
  • *****
  • Posts: 550
Re: How to solve this synapse ftp(s) error? [SOLVED]
« Reply #21 on: August 13, 2022, 10:55:33 am »
I don't have a Windows which is able to access the Internet. So I sent a Windows version of my program to a friend an he ran it on a pure Windows 10 (no Virtual Machine), where it worked. This computer has local IP adress 192.168.178.20.
That's not the same friend which has the FTP server by any chance?
Because then it's obvious that it worked.
It just connected internally
It was the same friend, so this test was useless.

Quote
Code: Pascal  [Select][+][-]
  1. Type
  2.   TMyDummyClass = class(TObject)
  3.   public
  4.     class procedure OnStatus(etc. Etc cant look up the def now);
  5.   end;
  6. //...
  7. class procedure TMyDummyClass.OnStatus(etc. Etc cant look up the def now);
  8. begin
  9.   Writeln(logline);
  10. end;
  11. //...
  12.   fTX.OnStatus := @TMyDummyClass.OnStatus;
Thank you for that draft, it will help me.

rvk

  • Hero Member
  • *****
  • Posts: 4937
Re: How to solve this synapse ftp(s) error? [SOLVED]
« Reply #22 on: August 15, 2022, 12:27:33 pm »
For completeness sake, I made a little example for detecting wrong remote IP with PASV for Synapse.
You will need to override the ParseRemote() of TFTPSend to get to the point where you can change the FDataIP (the IP address over which the data is send). This is reported by PASV and is parsed in ParseRemote().

In that same class you can put your own OnStatus te assign the your FTX.

This will detect (in ParseRemote) if the reported dataIP (in PASV) is the same as the hostIP (which is Self.Sock.GetRemoteSinIP). If not, then we probably have an internal IP and can override the FDataIP with Self.Sock.GetRemoteSinIP.

(BTW. My FTP server reports an internal IP when using PASV for internal connections but an external IP for external connections. So this wrong reporting of IP only happens with wrongly configured FTP servers. But apparently it happens often enough for TotalCommander to build in the check   ;))

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses
  4.   FTPSend, blcksock;
  5.  
  6. type
  7.   TMyFTPSend = class(TFTPSend)
  8.   public
  9.     procedure ParseRemote(Value: string); override;
  10.     class procedure OnMyStatus(Sender: TObject; Response: boolean; const Value: string);
  11.   end;
  12.  
  13.   class procedure TMyFTPSend.OnMyStatus(Sender: TObject; Response: boolean; const Value: string);
  14.   begin
  15.     Writeln(Value);
  16.   end;
  17.  
  18.   procedure TMyFTPSend.ParseRemote(Value: string);
  19.   begin
  20.     inherited;
  21.     Writeln('--> PASV reports data channel: ' + FDataIP + ' on ' + FDataPort);
  22.     Writeln('--> Server is on ' + Self.Sock.GetRemoteSinIP);
  23.  
  24.     // Check here if FDataIP the same as IP of control channel
  25.     // if not, we probably have a internal ip
  26.  
  27.     if (FDataIP <> Self.Sock.GetRemoteSinIP) then
  28.     begin
  29.       Writeln('--> So PASV is probably reporting an internal IP');
  30.       Writeln('--> Redirecting to server IP: ' + Self.Sock.GetRemoteSinIP);
  31.       FDataIP := Self.Sock.GetRemoteSinIP; // we keep FDataPort the same
  32.     end;
  33.  
  34.   end;
  35.  
  36. var
  37.   FTX: TFTPSend;
  38.   Ok: boolean;
  39. begin
  40.   FTX := TMyFTPSend.Create; // Note TMyFTPSend, not the default TFTPSend
  41.   FTX.TargetHost := 'ftp.mydomain.com';
  42.   FTX.TargetPort := '21';
  43.   FTX.Username := 'user';
  44.   FTX.Password := 'password';
  45.   FTX.OnStatus := @TMyFTPSend.OnMyStatus;
  46.   Ok := FTX.Login;
  47.   if Ok then Writeln('Login ok')
  48.   else
  49.     Writeln('Error loging in ' + FTX.Sock.GetErrorDescEx);
  50.   FTX.List('/', True); // reading of data channel not implemented here
  51.  
  52.   Readln; // wait for enter to end console app
  53.  
  54. end.
« Last Edit: August 15, 2022, 12:30:24 pm by rvk »

 

TinyPortal © 2005-2018