Question

I was trying to use SSL in ftpwebrequest like below

  FileStream outputStream = new FileStream(fileName, FileMode.Append);
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + ftpserverIp + "/" + file));
           reqFTP.EnableSsl = true;
            reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
            reqFTP.UseBinary = true;
            reqFTP.KeepAlive = false;
            reqFTP.Timeout = -1;
            reqFTP.UsePassive = true;
            reqFTP.Credentials = new NetworkCredential("sh", "SE");
            FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
            Stream ftpStream = response.GetResponseStream();
            long cl = response.ContentLength;
            // reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
            int bufferSize = 4096;
            int readCount;
            byte[] buffer = new byte[bufferSize];
            readCount = ftpStream.Read(buffer, 0, bufferSize);
            Console.WriteLine("Connected: Downloading File");
            while (readCount > 0)
            {
                outputStream.Write(buffer, 0, readCount);
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                //Console.WriteLine(readCount.ToString());
            }

            ftpStream.Close();
            outputStream.Close();
            response.Close();

I got this below exception:

The remote certificate is invalid according to the validation procedure.

Based on my google remove the private key part in the certificate and start processing now it throws

431 could not initialize ssl connection

I tried googling but no result so far,any idea guys.

Am trying to connect FileZilla.

Was it helpful?

Solution

The answer is simple that FtpWebRequest does not even support FTPS good enough.

Quoted from http://ftps.codeplex.com/

The System.Net.FTPWebRequest class provided by the .Net Framework, is perfect for simple tasks (e.g. downloading or uploading a file or getting a directory list) and supports also SSL via the EnableSsl property See: http://blogs.msdn.com/adarshk/archive/2005/04/22/410925.aspx . So why a new class for that?

The point is that SSL support in FTP is more that an on/off switch (as in HTTP/HTTPS). FTP requires two separate connections: one for the commands (the control connection) and one for the data (the data connection), for downloads, uploads and directory listings. FTPWebRequest.EnableSsl simply forces the use of SSL on both of them. The problem is that this is not always suitable.

Microsoft only starts to support FTPS on server side when they provide FTP 7.5 for Windows Server 2008 and above. Up to now, they don't even support FTPS in Internet Explorer nor Windows Explorer. No wonder .NET Framework BCL lacks FTPS support.

OTHER TIPS

In this segment of code: new Uri("ftp://" + ftpserverIp + "/" + file) you're attempting to connect to a non-SSL ftp server, which is denoted with "ftp". Changing "ftp://" to "ftps://" should help (assuming the server supports SSL.)

The step you're missing is establishing a policy for certificate validation.

This is done with the following code:

public static bool ValidateCertificate(object sender,
                       X509Certificate certificate, X509Chain chain,
                       SslPolicyErrors sslPolicyErrors) {
   /**
    * validation steps for the certificate go here
    * if you want them, but it may be expedient to 
    * just accept whatever the FTP server gave you.
    * The channel will be encrypted regardless of
    * how trusted the certificate is.
    */
    return true;
}

and then setting the above method to be hit when you get a certificate check:

ServicePointManager.ServerCertificateValidationCallback = 
    new RemoteCertificateValidationCallback(ValidateCertificate);

The given example works in .NET 3.5 meaning at the time of the currently accepted answer, the statement that this setup was impossible was already wrong.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top