Using FtpWebRequest to do FTP over SSL

Published 22 April 05 02:27 PM | adarshk 

Last few weeks we were busy to get Whidbey Beta-2 bits ready for release.

If you are looking for some API where your application could talk to a FTP server, which supports SSL. FtpWebRequest under System.Net namespace is your solution. Here I will just point to SSL specific features of the class

Enabling FtpWebrequest to use Ssl is pretty simple, you just need to set EnableSsl flag before calling GetResponse() or GetRequestStream() on the FtpWebRequest object. 

FtpWebRequest request = WebRequest.Create(ftp://myftpserver/dir/filename);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.EnableSsl = true; // Here you enabled request to use ssl instead of clear text
WebResponse response = request.GetResponse();

Some people asked me why FtpWebRequest support "ftps:" protocol based uri similar to "https:", the reason is there is no standard "ftps" scheme specified (yet) and ftp-over-ssl mechanism actually does not demand dedicated port for ssl, you could do it on the same server port on which you are doing regular clear text ftp. It depends on server configuration choice to force the SSL or allow both.

Once you start doing Ftp over SSL there are two important things you will need to know

Validating Server Certificate

If you were old WebRequest user, you might already know about using ServicePointManager.CertificatePolicy for https server certificate validation. In whidbey you will notice the compiler warning saying ServicePointManager.CertificatePolicy is obsolete and replaced with ServicePointManager.ServerCertificateValidationCallback which is delegate of type RemoteCertificateValidationDelegate. New delegate provide better programming model with all certificate errors reported in a single callback and you will also get instance of X509Chain object, which allow you to make decision on certificate chain. 

     ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(myCertificateValidation);

Actual method will look as below
  public bool myCertificateValidation(Object sender,
      X509Certificate cert,
      X509Chain chain,
      SslPolicyErrors Errors)
{ return (certificate.GetName() == "my_trusted_name"); }; //Just an example, not real world scenaio

:) Another additional advantage you can take with delegate is from anonymous method support of C# 2.0, especially if you have very simple 1-2 line certificateplicy to implement, see follwing example.

ServicePointManager.ServerCertificateValidationCallback = delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 
                                                                                             { return (certificate.GetName() == "my_trusted_name"); }; //Just an example, not real world scenaio

Using Client Certificate

Using Client certificate based authentication when connecting to FTP-SSL is no different then existing HttpWebRequest. You just need to assign appropriate X509Certificate instance to the request object before making GetResponse() or GetRequestStream() call.

 

This posting is provided "AS IS" with no warranties, and confers no rights

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Cindy Ferguson said on January 23, 2006 3:20 PM:
When I turn on EnableSSL = true I get the following exception:

ex.InnerException.Message = "The message or signature supplied for verification has been altered"

Here is my code:

FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(myUrl);
ftpRequest.Credentials = myCredentials;
ftpRequest.EnableSsl = true;

ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;

using (FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse())

It throws the exception on the final line of code. If comment out the ftpRequest.EnableSSL = true;, I do not get the error.

# Hari said on June 23, 2006 4:19 AM:
while using SSL(request.EnableSsl = True), the following error occurs: The remote server returned an error: (530) Not logged in
# LastHope said on September 12, 2006 6:39 AM:
Hi,
I'd like an information: enabling the EnableSsl, it'll make work the FTP connection as a SFTP connection
http://en.wikipedia.org/wiki/SSH_file_transfer_protocol
or not?
If the answer is no, have you got some reference on how I might do it? ;)
# adarshk said on September 15, 2006 7:35 PM:
Actually current SSL support on ftp does not include SSH FTP. Currently it is based on ftps mentioned in http://en.wikipedia.org/wiki/FTPS, which is basically FTP over SSL/TLS. Future versions of FtpWebRequest may support SSH/FTP.
# Lucky said on September 16, 2006 2:11 AM:
I have looked at your sample code how do you implent this in a solution
# Navneet said on October 10, 2006 12:48 PM:

What other options available to to SFTP using .Net?

Thanks,

Navneet

# adarshk said on October 25, 2006 9:55 PM:

Until .net frameworks 3.0, there is no API available in .net frameworks. There may be some third party options available. (Ex. one I came across is http://www.jscape.com/articles/sftp_using_csharp.html). I could not get chance to try any of them, so can not recommend any from my side.

# Squish said on November 8, 2006 7:29 PM:

Hi,

I'm using exactly the same code, but when I send a RETR to the FTP server the FTP server thinks its a GET instead.

I've check the FTPWebRequest method and it thinks it's a RETR because of the URI.

I've tried it with other ftp servers and still nothing.

Help..please

Squish

# Milan Petrovic said on March 23, 2007 11:11 AM:

Can I see the code to implement SSL connection to a server? I have tried this:

FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);

request.Credentials = new NetworkCredential("username", "password");

request.Method = WebRequestMethods.Ftp.ListDirectory;

request.UsePassive = true;

request.EnableSsl = true;

FtpWebResponse response = (FtpWebResponse)request.GetResponse();

And I get following error: The remote certificate is invalid according to the validation procedure.

Server I am trying to connect is FileZilla Server. How to validate this for connection? FileZilla Client works without any problem.

# Tom said on April 24, 2007 1:40 AM:

I am very confused as to the purpose of ClientCertificates on FtpWebRequest.  I need to authenticate to the FTP server using ONLY an X.509 certificate, no username or password.  It does not appear that there is any way to do this without going to a third-party component.

# Bob said on July 19, 2007 10:25 AM:

I am trying to call a web service over https that has an invalid ssl cert. The .Net 2.0 framework throws an "unable to connect to remote host" error every time I try to call a method on the web service. How do I override this. Here is my code:

ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;

        hew.apshealthcare.healtheweb_test.HealthEWebService webservice = new hew.apshealthcare.healtheweb_test.HealthEWebService();

        DataSet ds = webservice.GetEligibleFamilyMembers(this.tbMemberId.Text);

        this.GridView1.DataSource = ds;

        this.GridView1.DataBind();

   }

   public static bool ValidateServerCertificate(

     object sender,

     X509Certificate certificate,

     X509Chain chain,

     SslPolicyErrors sslPolicyErrors)

   {

       return true;

   }

# Amit said on August 21, 2007 7:48 AM:

after enabling Enablessl property it gives an exception on  

   request.GetResponse();

error(500): unrecognized command.

# Smoother said on September 20, 2007 5:26 AM:

I am also getting the exception (500) unrecognized command. I just remove the line enableSsl = true; and it works flawless. Is this bug or i am mising something?

# ftp server said on November 2, 2007 11:06 PM:

Does anyone know if this works with RaidenFTPD ftp server ssl connection?

# Sid said on January 2, 2008 11:21 AM:

I would like to know is there any way we can implement FTPS in implicit mode.

# Fx said on February 21, 2008 2:51 PM:

Hi,

Does anybody have sample that works ?

# Sam said on March 7, 2008 6:12 AM:

If u don't want to answer why u create this blog

# Shashikant Patil said on April 24, 2008 6:47 AM:

Perhaps you are trying to connect FTP port. FTPS port is different. Try putting correct SSL FTP port.

# artcoding said on May 6, 2008 4:40 AM:

The C# ftp SSL works in combination with FileZilla.

Configure Filezilla:

Server options: "SSL/TLS settings"

- check "Enable SSL/TLS Support"

- "Generate new certificate", file path should appear in "Private key file" and in "Certificate file"

- check "Allow esplicit SSL/TLS on normal connections" and optionally recommanded "Force explicit SSL/TLS"

Users:

- "Add" user

- set the password

- check "Force SSL for user login"

- at "Shared folders", "Add" only one without alias and "Set as the home dir"

In C#:

request.EnableSsl = true;

ServicePointManager.ServerCertificateValidationCallback = ... return true;}

# Network Class Library Team (System.Net) said on July 25, 2008 9:23 PM:

This is a current compile of the team's existing blogs on FtpWebRequest. I am going to update it periodically

# Guest said on August 29, 2008 2:28 AM:

This is an error when I call function reqFTP.GetRequestStream()

"A call to SSPI failed, see inner exception."

and this is innner exception message "The message received was unexpected or badly formatted"

# varun said on September 4, 2008 6:30 AM:

 try this .. ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

                                    {

               FtpWebResponse response =

               (FtpWebResponse)reqFTP.GetResponse();

}

# varun said on September 4, 2008 6:30 AM:

 try this ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

                                    {

               FtpWebResponse response =

               (FtpWebResponse)reqFTP.GetResponse();

}

# Fatou said on November 18, 2008 6:14 PM:

Thanks for the post. It helped me a lot!

# chaminda said on November 25, 2008 7:39 AM:

hey I had the same issue, but i was able to get this solved using the content in following posting

http://www.codeguru.com/csharp/.net/net_security/authentication/article.php/c15051

# chaminda said on November 25, 2008 7:43 AM:

hey I had the same issue, but i was able to get this solved using the content in following posting

http://www.codeguru.com/csharp/.net/net_security/authentication/article.php/c15051

# chaminda said on November 25, 2008 7:43 AM:

http://www.codeguru.com/csharp/.net/net_security/authentication/article.php/c15051

# Chri said on January 4, 2009 7:43 PM:

Hm. im scratching my hair off. Why wont FtpWebRequest.EnableSsl=true; work? Anyone got some ideas why it wont work? It seems like its a big problem noone can sove.

Regards

# reg SSL | keyongtech said on January 22, 2009 1:31 AM:

PingBack from http://www.keyongtech.com/679888-reg-ssl

# Giri said on March 26, 2009 10:36 AM:

I tried this and it worked, but the enablessl flag must be set to true right after you create the ftpwebrequest and before sending the network credential.

# Adarsh s blog Using FtpWebRequest to do FTP over SSL | Hair Growth Products said on June 13, 2009 8:50 AM:

PingBack from http://hairgrowthproducts.info/story.php?id=2245

Leave a Comment

(required) 
(optional)
(required) 

Search

Go

This Blog

Syndication

Page view tracker