FluentFtp connectsto an FTPserver using tls, can get the working directory, but times out trying to get a filelist
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
The Linix is Redhat and the FTP server is sftp. It is a new install but I don't know version level, release.
More info:
The server is vsftpd is version 3.0.2 and supports SSLv3 and TLS 1.2
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?
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();
}
}
}
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?