Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Achieving FTP/SFTP without 3rd party dll with FtpWebRequest if possible in C#

Tags:

c#

.net

winforms

I am trying to achieve the ftp/sftp through FtpWebRequest class in C# but not succeeded till now.

I dont want to use any 3rd party free or paid dll.

credentials are like

  1. hostname = sftp.xyz.com
  2. userid = abc
  3. password = 123

I am able to achieve the ftp with Ip address but unable to acheive sftp for above hostname with credentials.

For sftp I have enabled the EnableSsl property of FtpWebRequest class to true but getting error unable to connect to remote server.

I am able to connect with Filezilla with the same credentials and hostname but not through code.

I observed filezilla, it changes the host name from sftp.xyz.com to sftp://sftp.xyz.com in textbox and in command line it changes the userid to [email protected]

I have done the same in code but not succeeded for sftp.

Please need urgent help on this. Thanks in advance.

Below is my code so far:

private static void ProcessSFTPFile()
{
    try
    {
        string[] fileList = null;
        StringBuilder result = new StringBuilder();

        string uri = "ftp://sftp.xyz.com";

        FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(new Uri(uri));
        ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
        ftpRequest.EnableSsl = true;
        ftpRequest.Credentials = new NetworkCredential("[email protected]", "123");
        ftpRequest.UsePassive = true;
        ftpRequest.Timeout = System.Threading.Timeout.Infinite;

        //ftpRequest.AuthenticationLevel = Security.AuthenticationLevel.MutualAuthRequested;
        //ftpRequest.Proxy = null;
        ftpRequest.KeepAlive = true;
        ftpRequest.UseBinary = true;

        //Hook a callback to verify the remote certificate 
        ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
        //ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);

        FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
        StreamReader reader = new StreamReader(response.GetResponseStream());
        string line = reader.ReadLine();
        while (line != null)
        {
            result.Append("ftp://sftp.xyz.com" + line);
            result.Append("\n");
            line = reader.ReadLine();
        }

        if (result.Length != 0)
        {
            // to remove the trailing '\n'
            result.Remove(result.ToString().LastIndexOf('\n'), 1);

            // extracting the array of all ftp file paths
            fileList = result.ToString().Split('\n');
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message.ToString());
        Console.ReadLine();
    }
}

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (certificate.Subject.Contains("CN=sftp.xyz.com"))
    {
        return true;
    }
    else
    {
        return false;
    }
}
like image 808
pan4321 Avatar asked May 18 '12 17:05

pan4321


1 Answers

UPDATE:

If using BizTalk, you can work with the SFTP Adapter, using the ESB Toolkit. It has been supported since 2010. One wonders why it didn't make it to the .Net Framework

  1. BizTalk Server 2013: Creating Custom Adapter Provider in ESB Toolkit SFTP As an Example
  2. BizTalk Server 2013: How to use SFTP Adapter
  3. MSDN Docs

--

Unfortunately, it still requires alot of work to do with just the Framework currently. Placing the sftp protocol prefix isnt enough to make-it-work Still no built-in, .Net Framework support today, maybe in the future.

---------------------------------------------------------

1) A good library to try out is SSHNet.

---------------------------------------------------------

It has:

  1. a lot more features, including built-in streaming support.
  2. an API document
  3. a simpler API to code against

Example code from documentation:

List directory

/// <summary>
/// This sample will list the contents of the current directory.
/// </summary>
public void ListDirectory()
{
    string host            = "";
    string username        = "";
    string password        = "";
    string remoteDirectory = "."; // . always refers to the current directory.

    using (var sftp = new SftpClient(host, username, password))
    {
        sftp.Connect();

        var files = sftp.ListDirectory(remoteDirectory);
        foreach (var file in files)
        {
            Console.WriteLine(file.FullName);
        }
    }
}

Upload File

/// <summary>
/// This sample will upload a file on your local machine to the remote system.
/// </summary>
public void UploadFile()
{
    string host           = "";
    string username       = "";
    string password       = "";
    string localFileName  = "";
    string remoteFileName = System.IO.Path.GetFileName(localFile);

    using (var sftp = new SftpClient(host, username, password))
    {
        sftp.Connect();

        using (var file = File.OpenRead(localFileName))
        {
            sftp.UploadFile(remoteFileName, file);
        }

        sftp.Disconnect();
    }
}

Download File

/// <summary>
/// This sample will download a file on the remote system to your local machine.
/// </summary>
public void DownloadFile()
{
    string host           = "";
    string username       = "";
    string password       = "";
    string localFileName  = System.IO.Path.GetFileName(localFile);
    string remoteFileName = "";

    using (var sftp = new SftpClient(host, username, password))
    {
        sftp.Connect();

        using (var file = File.OpenWrite(localFileName))
        {
            sftp.DownloadFile(remoteFileName, file);
        }

        sftp.Disconnect();
    }
}

---------------------------------------------------------

2) Another alternative library is WinSCP

---------------------------------------------------------

With the follwing example:

using System;
using WinSCP;

class Example
{
    public static int Main()
    {
        try
        {
            // Setup session options
            SessionOptions sessionOptions = new SessionOptions
            {
                Protocol = Protocol.Sftp,
                HostName = "example.com",
                UserName = "user",
                Password = "mypassword",
                SshHostKeyFingerprint = "ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
            };

            using (Session session = new Session())
            {
                // Connect
                session.Open(sessionOptions);

                // Upload files
                TransferOptions transferOptions = new TransferOptions();
                transferOptions.TransferMode = TransferMode.Binary;

                TransferOperationResult transferResult;
                transferResult = session.PutFiles(@"d:\toupload\*", "/home/user/", false, transferOptions);

                // Throw on any error
                transferResult.Check();

                // Print results
                foreach (TransferEventArgs transfer in transferResult.Transfers)
                {
                    Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
                }
            }

            return 0;
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}", e);
            return 1;
        }
    }
}

Found here and with more here.

like image 62
user919426 Avatar answered Sep 22 '22 19:09

user919426