FluentFTP icon indicating copy to clipboard operation
FluentFTP copied to clipboard

FluentFtp connectsto an FTPserver using tls, can get the working directory, but times out trying to get a filelist

Open obrienj970 opened this issue 6 years ago • 4 comments

FTP OS: Unix (Unknown Linux)

FTP Server: Unknown server

Computer OS: Windows 10

I have a small piece of c# test code (4.7.2) using FluentFtp that connects to the Linux based server of unknown type on an unknown derivative of Linux.

I am developing on VS 2017.

I used NuGet to load FluentFTP.

And the .Net level for my test code is 4.7.2.

So far:

It connects.

I can get a working directory (GetWorkingDirectory()).

When I try to get the file list it gets "Timed out trying to connect!" on the FluentFtp GetListing.

I've looked at a number of SO posts and FluentFTP issues and tried several ideas. I have also tried both PASV and EPSV with the same result.

Since all of this FTP with "tls" is a bit confusing, if you have any thoughts I would certainly entertain them. I am in a bit of a time crunch.

Regards, Jim

The code is:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net;
    using System.Security.Authentication;
    using System.Diagnostics;

    using FluentFTP;

    namespace TryFLuentFTP {
    class Program {
    static void Main(string[] args) {

        FtpTrace.AddListener(new ConsoleTraceListener());

        FtpTrace.LogUserName = false;   // hide FTP user names
        FtpTrace.LogPassword = false;   // hide FTP passwords
        FtpTrace.LogIP = false;     // hide FTP server IP addresses

        try {
            FtpClient client = new FtpClient("ftp-host", "user", "******"); 
            client.EncryptionMode = FtpEncryptionMode.Explicit;
            client.SslProtocols = SslProtocols.Tls12;

            client.DataConnectionType = FtpDataConnectionType.EPSV;                            //PASV;

            client.DownloadDataType = FtpDataType.Binary;

            client.ValidateCertificate += (c, e) => { e.Accept = true; };
            client.Connect();

            Console.WriteLine("Connected!!!!");

            Console.WriteLine("The working directory is: " + client.GetWorkingDirectory());

            FtpListItem[] list = client.GetListing(client.GetWorkingDirectory());
            // FtpListOption.Modify | FtpListOption.Size);

            foreach(FtpListItem li in list) {
                Console.WriteLine(li.Type + " " + li.FullName);
            }

        } catch (Exception ex) {
            Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
        }

        Console.ReadLine();
    }
}

}

# Connect()
Status:   Connecting to ***:21
Response: 220 (vsFTPd 3.0.2)
Status:   Detected FTP server: VsFTPd
Command:  AUTH TLS
Response: 234 Proceed with negotiation.
Status:   FTPS Authentication Successful
Status:   Time to activate encryption: 0h 0m 0s.  Total Seconds: 0.1585755.
Command:  USER ***
Response: 331 Please specify the password.
Command:  PASS ***
Response: 230 Login successful.
Command:  PBSZ 0
Response: 200 PBSZ set to 0.
Command:  PROT P
Response: 200 PROT now Private.
Command:  FEAT
Response: 211 End
Response: 211-Features:
Response: AUTH TLS
Response: EPRT
Response: EPSV
Response: MDTM
Response: PASV
Response: PBSZ
Response: PROT
Response: REST STREAM
Response: SIZE
Response: TVFS
Response: UTF8
Status:   Text encoding: System.Text.UTF8Encoding
Command:  OPTS UTF8 ON
Response: 200 Always in UTF8 mode.
Command:  SYST
Response: 215 UNIX Type: L8
Status:   Auto-detected UNIX listing parser
Connected!!!!

# GetWorkingDirectory()
Command:  PWD
Response: 257 "/"
The working directory is: '/'
IsConnected - True

# GetListing("/", SizeModify)
Command:  TYPE I
Response: 200 Switching to Binary mode.

# OpenPassiveDataStream(PASV, "LIST /", 0)
Command:  PASV
Response: 227 Entering Passive Mode (192,168,6,90,120,121).
Status:   Connecting to ***:30841

NOTE: about a 5-10 second delay here

Status:   Disposing FtpSocketStream...
Timed out trying to connect!
   at FluentFTP.FtpSocketStream.Connect(String host, Int32 port, FtpIpVersion ipVersions)
   at FluentFTP.FtpClient.Connect(FtpSocketStream stream, String host, Int32 port, FtpIpVersion ipVersions)
   at FluentFTP.FtpClient.OpenPassiveDataStream(FtpDataConnectionType type, String command, Int64 restart)
   at FluentFTP.FtpClient.OpenDataStream(String command, Int64 restart)
   at FluentFTP.FtpClient.GetListing(String path, FtpListOption options)
   at TryFLuentFTP.Program.Main(String[] args) in C:\DiabesityInstituteProjects\Solutions\DiabesityLabResultProcessing\TryFLuentFTP\Program.cs:line 44

obrienj970 avatar Jul 03 '19 15:07 obrienj970

The Linix is Redhat and the FTP server is sftp. It is a new install but I don't know version level, release.

obrienj970 avatar Jul 03 '19 16:07 obrienj970

More info:

The server is vsftpd is version 3.0.2 and supports SSLv3 and TLS 1.2

obrienj970 avatar Jul 03 '19 18:07 obrienj970

I noticed something in the log, the line "Status: Connecting to ***:30841." when I try GetListing()

Why is it doing this when I am already connected to port 21?

I get something similar if I use EPSV.

Regardless of PASV or EPSV, the port is always different in that line.

Out of curiosity, is FluentFTP being maintained any more?

obrienj970 avatar Jul 03 '19 23:07 obrienj970

This works for me. I found that I sometimes have to retry and eventually it works.

using System;
using System.Security.Authentication;
using System.Diagnostics;

using FluentFTP;

namespace TryFluentFTP
{
    class Program
    {
        static void Main(string[] args)
        {
            int tryCount;

            FtpTrace.AddListener(new ConsoleTraceListener());

            FtpTrace.LogUserName = false;   // hide FTP user names
            FtpTrace.LogPassword = false;   // hide FTP passwords
            FtpTrace.LogIP = false;     // hide FTP server IP addresses

            try
            {
                FtpClient client = new FtpClient("ftp server", "username", "password");
                client.EncryptionMode = FtpEncryptionMode.Explicit;
                client.SslProtocols = SslProtocols.Tls12;

                client.DataConnectionType = FtpDataConnectionType.EPSV;                            //PASV;

                client.DownloadDataType = FtpDataType.Binary;

                client.ValidateCertificate += (c, e) => { e.Accept = true; };
                client.Connect();

                Console.WriteLine("Connected!!!!");

                Console.WriteLine("The working directory is: " + client.GetWorkingDirectory());

                tryCount = 0;
                do {
                    try
                    {
                        FtpListItem[] list = client.GetListing(client.GetWorkingDirectory());
                        // FtpListOption.Modify | FtpListOption.Size);
                        foreach (FtpListItem li in list)
                        {
                            Console.WriteLine(li.Type + " " + li.FullName);
                        }
                        tryCount = int.MaxValue;
                    }
                    catch (FtpException ex) {
                        string s;
                        if (ex.Message.Contains("InnerException"))
                        {
                            if (ex.InnerException is null)
                            {
                                s = ex.Message;
                            }
                            else
                            {
                                s = ex.InnerException.Message;
                            }
                        }
                        else
                        {
                            s = ex.Message;
                        }
                        Console.WriteLine(s);
                        tryCount += 1;
                    }
                    catch (System.IO.IOException ex)
                    {
                        Console.WriteLine(ex.Message);
                        tryCount += 1;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        tryCount = int.MaxValue;
                    }
                }  while ( tryCount < 8 );
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }

            Console.ReadLine();
        }
    }
}

mikemeinz avatar Jul 07 '19 19:07 mikemeinz

Is this issue still active?

# OpenPassiveDataStream(PASV, "LIST /", 0)
Command:  PASV
Response: 227 Entering Passive Mode (192,168,6,90,120,121).
Status:   Connecting to ***:30841

NOTE: about a 5-10 second delay here

Status:   Disposing FtpSocketStream...
Timed out trying to connect!

Connecting to the server by opening a data connection on the advertised port fails. Firewall? Routing?

FanDjango avatar Nov 04 '22 12:11 FanDjango