Search code examples
c#tls1.2ftpswinscp-netfluentftp

FluentFTP and TLS connection to IIS fails with error 534


We currently use WinSCP C# library to connect to an FTP site using TLS. It works perfectly, but we are moving to Linux containers and WinSCP won't work. I've been trying to replicate the functionality using FluentFTP but with out success so far, the only response I ever seem to get from FluentFTP is

534 Local policy on server does not allow TLS secure connections.

Here is the WinSCP setup:

options = new SessionOptions
{
    FtpSecure = FtpSecure.Explicit,

    HostName = hostName, 
    PortNumber = 21,
    Protocol = Protocol.Ftp,
    TlsClientCertificatePath = certificatePath, 
    UserName = "anonymous",
    PrivateKeyPassphrase = certificatePassword,
    TimeoutInMilliseconds = 6000

};
options.AddRawSettings("FtpHost", "0");
options.AddRawSettings("PostLoginCommands", "FEAT");

Here is the FluentFTP set up (with possibly a few extra bits I've tried):

using(FtpClient client = new FtpClient(_config.CmosFtpUrl))
{
    FtpTrace.EnableTracing = true; 
    FtpTrace.LogToFile ="log_file.txt";
    FtpTrace.LogUserName = false;   // hide FTP user names
    FtpTrace.LogPassword = false;   // hide FTP passwords
    FtpTrace.LogIP = false;     // hide FTP server IP addresses
    client.Credentials = new System.Net.NetworkCredential("anonymous", "");
    client.ClientCertificates.Add(cert);
    client.Port = 21;
    //client.PlainTextEncryption = true;
    client.EncryptionMode = FtpEncryptionMode.Explicit;
    client.SocketKeepAlive = false;
    client.DataConnectionType = FtpDataConnectionType.PASV;
    client.DataConnectionEncryption = true;
    client.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 | SslProtocols.Tls11 | SslProtocols.Tls;
    client.ValidateCertificate += Client_ValidateCertificate;
    client.Host = _config.CmosFtpUrl;
    // client.SslProtocols = System.Security.Authentication.SslProtocols.None;
    client.ValidateAnyCertificate = true;
    await client.AutoConnectAsync();
    await client.ExecuteAsync("FEAT", default);

    var directory = await client.GetWorkingDirectoryAsync();
    logger.LogInformation(directory);
}

Here is the log from WinSCP:

. 2020-01-14 13:45:56.838 Session name: [email protected] (Ad-Hoc site)
. 2020-01-14 13:45:56.838 Host name: automated.cmosservice.co.uk (Port: 21)
. 2020-01-14 13:45:56.838 User name: anonymous (Password: No, Key file: No, Passphrase: Yes)
. 2020-01-14 13:45:56.838 Transfer Protocol: FTP
. 2020-01-14 13:45:56.838 Ping type: Dummy, Ping interval: 30 sec; Timeout: 6 sec
. 2020-01-14 13:45:56.838 Disable Nagle: No
. 2020-01-14 13:45:56.838 Proxy: None
. 2020-01-14 13:45:56.838 Send buffer: 262144
. 2020-01-14 13:45:56.838 UTF: Auto
. 2020-01-14 13:45:56.838 FTPS: Explicit TLS/SSL [Client certificate: Yes]
. 2020-01-14 13:45:56.838 FTP: Passive: Yes [Force IP: Auto]; MLSD: Auto [List all: Auto]; HOST: On
. 2020-01-14 13:45:56.838 Session reuse: Yes
. 2020-01-14 13:45:56.839 TLS/SSL versions: TLSv1.0-TLSv1.2
. 2020-01-14 13:45:56.839 Local directory: default, Remote directory: home, Update: Yes, Cache: Yes
. 2020-01-14 13:45:56.839 Cache directory changes: Yes, Permanent: Yes
. 2020-01-14 13:45:56.839 Recycle bin: Delete to: No, Overwritten to: No, Bin path: 
. 2020-01-14 13:45:56.839 Timezone offset: 0h 0m
. 2020-01-14 13:45:56.839 --------------------------------------------------------------------------
. 2020-01-14 13:45:56.856 Connecting to xxxxx ...
. 2020-01-14 13:45:56.885 Connected with xxxx, negotiating TLS connection...
< 2020-01-14 13:45:56.904 220 Microsoft FTP Service
> 2020-01-14 13:45:56.904 HOST automated.cmosservice.co.uk
< 2020-01-14 13:45:56.922 220 Host accepted.
> 2020-01-14 13:45:56.922 AUTH TLS
< 2020-01-14 13:45:56.940 234 AUTH command ok. Expecting TLS Negotiation.
. 2020-01-14 13:45:57.175 Server asks for authentication with a client certificate.
. 2020-01-14 13:45:57.283 Verifying certificate for "xxxx" with fingerprint 59:51:8b:ec:8e:49:54:7b:24:08:00:47:81:41:4d:20:5f:60:98:24 and 20 failures
. 2020-01-14 13:45:57.284 Certificate subject alternative name "xxxx" matches hostname
. 2020-01-14 13:45:57.345 Certificate verified against Windows certificate store
. 2020-01-14 13:45:57.345 Using TLSv1.2, cipher TLSv1/SSLv3: ECDHE-RSA-AES256-SHA384, 2048 bit RSA, ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
. 2020-01-14 13:45:57.346 TLS connection established. Waiting for welcome message...
> 2020-01-14 13:45:57.346 USER anonymous
< 2020-01-14 13:45:57.363 331 Anonymous access allowed, send identity (e-mail name) as password.
. 2020-01-14 13:45:57.364 Server asked for password, but we are using certificate, and no password was specified upfront, using fake password
> 2020-01-14 13:45:57.364 PASS *********
< 2020-01-14 13:45:57.383 230 User logged in.
> 2020-01-14 13:45:57.383 SYST
. 2020-01-14 13:45:57.402 The server is probably running Windows, assuming that directory listing timestamps are affected by DST.
< 2020-01-14 13:45:57.402 215 Windows_NT
> 2020-01-14 13:45:57.402 FEAT
< 2020-01-14 13:45:57.421 211-Extended features supported:
< 2020-01-14 13:45:57.421  LANG EN*
< 2020-01-14 13:45:57.421  UTF8
< 2020-01-14 13:45:57.422  AUTH TLS;TLS-C;SSL;TLS-P;
< 2020-01-14 13:45:57.422  PBSZ
< 2020-01-14 13:45:57.422  PROT C;P;
< 2020-01-14 13:45:57.422  CCC
< 2020-01-14 13:45:57.424  HOST
< 2020-01-14 13:45:57.424  SIZE
< 2020-01-14 13:45:57.424  MDTM
< 2020-01-14 13:45:57.424  REST STREAM
< 2020-01-14 13:45:57.424 211 END
> 2020-01-14 13:45:57.424 OPTS UTF8 ON
< 2020-01-14 13:45:57.444 200 OPTS UTF8 command successful - UTF8 encoding now ON.
> 2020-01-14 13:45:57.444 PBSZ 0
< 2020-01-14 13:45:57.465 200 PBSZ command successful.
> 2020-01-14 13:45:57.465 PROT P
< 2020-01-14 13:45:57.485 200 PROT command successful.
. 2020-01-14 13:45:57.487 Connected
. 2020-01-14 13:45:57.487 --------------------------------------------------------------------------
. 2020-01-14 13:45:57.487 Using FTP protocol.

And the FluentFTP log is this:

# ConnectAsync()
Status:   Connecting to ***:21
Response: 220 Microsoft FTP Service
Status:   Detected FTP server: WindowsServerIIS
Command:  AUTH TLS
Response: 534 Local policy on server does not allow TLS secure connections.

# Dispose()
Status:   Disposing FtpClient object...
Command:  QUIT
Response: 221 Goodbye.
Status:   Disposing FtpSocketStream...
Status:   Disposing FtpSocketStream...

I'm not sure why winSCP can connect and the FluentFTP one gets the 534 error. I'm running these under IIS Express locally to test.


Solution

  • The difference is most probably caused by the HOST command, which is sent by WinSCP.

    2020-01-14 13:45:56.904 HOST automated.cmosservice.co.uk  
    2020-01-14 13:45:56.922 220 Host accepted.
    

    It does not look like the FluentFTP does support it.

    It might help, if you enable TLS server-wide on IIS. You probably have it enabled per-site only. But that's not a programming question.