FluentFTP: Authentication failed because the remote party has closed the transport stream

1.5k Views Asked by At

I am using a C# console app to repro the issue. It's a .NET Framework 4.7 app. The FluentFTP version is 24.0.0, installed as a Nuget package.

This is my code:

using FluentFTP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace FTP_Test
{
    class Program
    {
        private static string host = "<my host>";
        private static string username = "<my username>";
        private static string pass = "<my pass>";
        private static int port = 990;

        static void Main(string[] args)
        {
            FtpClient ftpClient = new FtpClient(host, port, username, pass);

            ftpClient.DataConnectionType = FtpDataConnectionType.EPSV;
            ftpClient.EncryptionMode = FtpEncryptionMode.Implicit;

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

                        ftpClient.DataConnectionEncryption = true;
            ftpClient.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
            var cer = new System.Security.Cryptography.X509Certificates.X509Certificate2();
            ftpClient.ClientCertificates.Add(cer);
            ServicePointManager.ServerCertificateValidationCallback = ServerCertificateValidationCallback;

            ftpClient.Connect();
        }

        private static void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
        {
            // add logic to test if certificate is valid here
            e.Accept = true;
        }
        private static bool ServerCertificateValidationCallback(object sender,
                                                System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                                                System.Security.Cryptography.X509Certificates.X509Chain chain,
                                                System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}

The error (and the stacktrace) I'm getting in the console:

Unhandled Exception: System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at FluentFTP.FtpSocketStream.ActivateEncryption(String targethost, X509CertificateCollection clientCerts, SslProtocols sslProtocols)
   at FluentFTP.FtpClient.Connect()
   at FTP_Test.Program.Main(String[] args) in C:\Users\Nemanja\source\repos\FTP Test\Program.cs:line 35

What am I missing here?

I am able to connect through Filezilla, using the same set of host/user/pass. In Filezilla, I have to set the following:

  • Ecryption: Require implicit FTP over TLS (in the "General" tab)
  • Transfer mode: Passive (in the "Transfer Settings" tab)

When I run the app in debug mode and set breakpoints inside functions OnValidateCertificate and ServerCertificateValidationCallback, those breakpoints are not hit.

2

There are 2 best solutions below

0
lukin155 On BEST ANSWER

Turns out FluentFTP doesn't support Implicit SSL, so I had to switch to Chilkat.

example-code.com has good examples for this library and here is the link to the example for Implicit SSL: https://www.example-code.com/csharp/ftp_implicitSSL.asp

Copying the example (from the link above) here in case the link stops working.

// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.

Chilkat.Ftp2 ftp = new Chilkat.Ftp2();

// If this example does not work, try using passive mode
// by setting this to true.
ftp.Passive = false;
ftp.Hostname = "ftp.something.com";
ftp.Username = "test";
ftp.Password = "test";
ftp.Port = 990;

// We don't want AUTH SSL:
ftp.AuthTls = false;

// We want Implicit SSL:
ftp.Ssl = true;

// Connect and login to the FTP server.
bool success = ftp.Connect();
if (success != true) {
    Debug.WriteLine(ftp.LastErrorText);
    return;
}
else {
    // LastErrorText contains information even when
    // successful. This allows you to visually verify
    // that the secure connection actually occurred.
    Debug.WriteLine(ftp.LastErrorText);
}

Debug.WriteLine("FTPS Channel Established!");

// Do whatever you're doing to do ...
// upload files, download files, etc...

success = ftp.Disconnect();
0
Kellyc On

If you are using .NETFramework 4.5, FluentFTP does support Implicit Tls up to Tls1.2. FluentFTP at the time of this comment does NOT support .NETFramework above 4.5. This works for me:

Uri uri = new Uri(FTP_URL);
using (var conn = new FtpClient(uri.Host, FTP_Username, FTP_Password))
{
    conn.EncryptionMode = FtpEncryptionMode.Implicit;
    conn.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
    conn.ValidateAnyCertificate = true;
    conn.Connect();
    conn.UploadFile(file, FileName, FtpRemoteExists.Overwrite, false, FtpVerify.Retry);
    conn.Disconnect();
}