Upload file to implicit FTPS server in C# with TLS session reuse - c#

I'm trying to upload file to FileZilla server through ftps by protocol TLS. On the server port 20 and 21 is closed. The only way how I managed to connect to server is by using FluentFTP but I couldn't upload file because of some FileZilla server bug.
https://github.com/robinrodricks/FluentFTP/issues/335
https://forum.filezilla-project.org/viewtopic.php?t=51601
public static void UploadTest(
string pathUploadFile, string addressIP, int port, string location,
string userName, string password)
{
FtpClient ftp;
Console.WriteLine("Configuring FTP to Connect to {0}", addressIP);
ftp = new FtpClient(addressIP, port, new NetworkCredential(userName, password));
ftp.ConnectTimeout = 600000;
ftp.ReadTimeout = 60000;
ftp.EncryptionMode = FtpEncryptionMode.Implicit;
ftp.SslProtocols = SslProtocols.Default | SslProtocols.Tls11 | SslProtocols.Tls12;
ftp.ValidateCertificate += new FtpSslValidation(OnValidateCertificate);
ftp.Connect();
// upload a file
ftp.UploadFile(pathUploadFile, location);
Console.WriteLine("Connected to {0}", addressIP);
ftp.Disconnect();
void OnValidateCertificate(FtpClient control, FtpSslValidationEventArgs e)
{
// add logic to test if certificate is valid here
e.Accept = true;
}
}
Is there any way around without a violating security level? If not is there any other free library which support uploading files with TLS/SSL? I also tried this but it didn't work.
https://learn.microsoft.com/en-us/dotnet/api/system.net.ftpwebrequest.enablessl
Thanks.

You can use WinSCP .NET assembly.
It supports implicit TLS (port 990). And uses OpenSSL TLS implementation (not .NET Framework), so it should not have the problem that FluentFTP has. It definitely works for me against FileZilla FTP server, even with session resumption requirement turned on.
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "username",
Password = "password",
FtpSecure = FtpSecure.Implicit,
TlsHostCertificateFingerprint = "xx:xx:xx:...",
};
using (Session session = new Session())
{
session.Open(sessionOptions);
session.PutFiles(localPath, remotePath).Check();
}
(I'm the author of WinSCP)
For more references about the problem, see also Can connect to FTP using FileZilla or WinSCP, but not with FtpWebRequest or FluentFTP.

Related

In C# how to upload file on FTPS server Encryption Type 'Required Explicit FTP over TLS'

I need the expert help. I have written the C# console base application. In which I have to upload the zip file to FTPS server. Every time I am getting the connection refuse error. But when I connect by the FileZilla its connected and working fine.
I am using FTP Protocol and Encryption type is "Required Explicit FTP over TLS" logon type normal (see the below screen shots).
The exception message as below :
"Connection failed.\r\nTLS connect: error in error\r\nCan't establish TLS connection\r\nDisconnected from server\r\nConnection failed"
Please provide any sample code or help me to correct this code.
My sample C# sample code as below :
using System;
using System.Collections.Generic;
using System.IO;
using WinSCP;
namespace FTPS
{
class Program
{
static void Main(string[] args)
{
try
{
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "CIR-SVN34",
UserName = "buildmachine",
Password = "Password",
FtpSecure = FtpSecure.Implicit,
PortNumber = 990
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Upload files
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
TransferOperationResult transferResult;
transferResult =
session.PutFiles(#"C:\BuildProcess\Testing.zip", #"/Apps-Panel Dev Daily Build/", false, transferOptions);
// Throw on any error
transferResult.Check();
// Print results
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Working only with FileZilla client
If your FileZilla configuration is working, then your server is strangely configured. It listens on implicit TLS port 990 for explicit TLS connection.
This should work:
FtpSecure = FtpSecure.Explicit,
PortNumber = 990,
Explicit TLS normally works on the standard FTP port 21.

Certificate Issues while connecting to Amazon S3

My C# code is trying to pull some files from an Amazon S3 bucket. This code works fine on my development as well as on UAT server. However, when I run this on my production server, I get a certificate error.
One difference between the UAT and Production servers is that on UAT there is no restriction on outbound internet access. On Production servers free outbound internet access is not allowed. we open only selective URLs as per requirements.
We have already opened access to s3.amazonaws.com. We have also ensured that this access works fine using WinSCP tool. However, when my code tries to do the same, I get the following error:
WinSCP.SessionRemoteException: Server Certificate Verification Failed: Issuer is not trusted.
The source code is attached below:
s3HostName = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["s3HostName"]);
s3UserName = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["s3UserName"]);
s3Password = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["s3Password"]);
LocalFilePath = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["LocalFilePath"]);
s3Folder = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["s3Folder"]);
LocalFileFolder = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["LocalFileFolder"]);
LocalFolder = LocalFilePath + yesterday + "\\";
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.S3,
HostName = s3HostName,
UserName = s3UserName,
Password = s3Password,
};
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = WinSCP.TransferMode.Automatic;
transferOptions.FilePermissions = null;
transferOptions.PreserveTimestamp = false;
using (Session session = new Session())
{
log.Debug("Open session for s3");
session.Open(sessionOptions);
if (!Directory.Exists(LocalFolder))
{
Directory.CreateDirectory(LocalFolder);
}
//to download files
session.GetFiles(s3Folder + "*" + yesterday + ".csv", LocalFolder);
session.Close();
log.Debug("Closed session for s3");
return "Success";
}
Resolved the issue using the oldest trick in the book. Reinstalled WinSCP. Its all working fine now.

How to use SFTP connection with key file using C# and .NET

I have a C# .NET project, where am trying to open an SFTP connection to a server and put a file to the server.
I have SFTP hostname, username and key file (.pem file).
I do not have a password here.
Please help me with something to use SFTP in C# and .Net.
Probably every SFTP/SSH library supports public key authentication.
For example:
SSH.NET (NuGet package):
var privateKey = new PrivateKeyFile(#"C:\some\path\key.pem");
var client = new SftpClient("example.com", "username", new[] { privateKey });
client.Connect();
If the private key is encrypted:
var privateKey = new PrivateKeyFile(#"C:\some\path\key.pem", "passphrase");
WinSCP .NET assembly (NuGet package):
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "example.com",
UserName = "username",
SshHostKeyFingerprint = "ssh-rsa 2048 ...=",
SshPrivateKeyPath = #"C:\some\path\key.ppk",
};
using (Session session = new Session())
{
session.Open(sessionOptions);
// Your code
}
WinSCP needs the key converted to PPK format (You can use WinSCP GUI for that, or PuTTYgen). Also note that WinSCP verifies the SSH host key (SshHostKeyFingerprint). SSH.NET fails to do that by default, what is a security flaw.
If the private key is encrypted, add PrivateKeyPassphrase or SecurePrivateKeyPassphrase.
WinSCP GUI can generate a code template for you.
(I'm the author of the library)
I ran into this same issue. The code provided by Martin certainly helped me but, it was missing a couple settings for my needs.
I needed to add a Port Number and a Pass Phrase to fully automate my solution. So code ends up like:
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
PortNumber = port,
HostName = host,
UserName = username,
PrivateKeyPassphrase = passphrase,
SshHostKeyFingerprint = fingerprint,
SshPrivateKeyPath = privatekeyfile
};

How to download files from FTPS in C#

Our IT department gave me credentials for an FTPS, which I can access using FileZilla
But I also need to access the FTPS using an application I am working on to automate the process. The information provided to me was,
That this is an FTP over TLS/SSL
IP: xxx.xxx.xx.xx
Port: 990 <-- suggesting its an implicit encryption
UserName: username.ftp
Password: password123
After reading some posts on WinSCP on stack and their documentation, I still can't access the ftps using my application. My code so far..
SessionOptions sessionOp = new SessionOptions()
{
FtpSecure = FtpSecure.Implicit,
Protocol = Protocol.Ftp,
HostName = IP,
UserName = userName,
Password = password,
};
sessionOp.AddRawSettings("ProxyMethod", "3");
sessionOp.AddRawSettings("ProxyPort", "990");
using (Session session = new Session())
{
session.Open(sessionOp);
var list = session.ListDirectory(dir);
Console.WriteLine(list);
}
The error I get is, "Failed to Connect" from WinSCP
How can I access this FTPS?
What you did is configuring the HTTP Proxy port to 990. Instead you should configure the FTPS port.
SessionOptions sessionOp = new SessionOptions()
{
FtpSecure = FtpSecure.Implicit,
Protocol = Protocol.Ftp,
HostName = IP,
UserName = userName,
Password = password,
PortNumber = 990
};
and remove the lines
sessionOp.AddRawSettings("ProxyMethod", "3");
sessionOp.AddRawSettings("ProxyPort", "990");
Also, I suggest using the WinSCP GUI to try this instead of FileZilla, considering that the library is related to the GUI.

Files not getting transferred from Windows to Linux remote server

I am trying to use WinSCP in visual studio. I downloaded and installed WinSCP using the Managed NuGet package. I have used the below code in a web application to transfer one of the files to a remote Linux server. The code executes fine without any error, but the file is not transferred. I logged in using PuTTY to verify if the file has actually transferred, but could not locate the file. Below is the code used
public int Upload(String HostName, String UserName, String Password, String remotePath, String localFilePath)
{
int result = 0;
Session session = null;
try
{
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = HostName,
UserName = UserName,
Password = Password,
Timeout = TimeSpan.FromDays(1),
};
using (session = new Session())
{
// Connect
session.Open(sessionOptions);
// upload files
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Ascii;
TransferOperationResult transferResult = null;
transferResult = session.PutFiles(localFilePath, remotePath, false, transferOptions);
// Throw on any error
transferResult.Check();
// Print results
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
}
session.GetFiles(#"\\remoteserver\folder1\folder_backups\test_files\test1.txt", #"d:\folder3\").Check();
}
result = 0;
}
catch (Exception e)
{
Console.WriteLine("Error: {0}", e);
result = 1;
}
finally
{
if (session != null)
{
session.Dispose();
}
}
return result;
}
The arguments are passed as below:
project1.Upload("remote host server", "username", "password", #"\\remote host server\folder1\folder_backups\test_files\", Fileupload1.PostedFile.FileName);
The code executes without any error, but no file is uploaded nor downloaded. How to fix this?
Thanks
After the login happens in GUI - it points to /home/UserId . But the folder which i want to move the files exist in /folder1
If remote path you want to use is /folder1/, use that for remotePath argument of your Upload method, instead of obviously wrong value #"\\remote host server\folder1\folder_backups\test_files\".
project1.Upload("host", "user", "password", "/folder1/", Fileupload1.PostedFile.FileName);
Not entirely sure but looks like you've set the protocol to FTP which may not be supported by the server. If you're able to login via putty then that means SSH connection is possible. Try setting the protocol to SFTP.

Categories