title: FTP over SSL for C#
body: <p>I'm using the code below (needs to be .Net 2.0) to connect on a UAT server to a customer FTP server to up/down load files. I need to connect over port 990, using a self signed certificate supplied by them. I've got the firewall rules amended to allow connection to the URI on port 990 from our UAT server.</p>
  
  <p>However (! :) ) I get a timeout on the line <pre><code> Stream requestStream = request.GetRequestStream();</code></pre></p>
  
  <p>If I increase the timeout time it makes no difference.</p>
  
  <p>I've had a look around on the web but found nothing obvious that is missing in the code. </p>
  
  <p>If I use CuteFTP to connect on the UAT server then, naturally, it connect fine and I can manually do the file transfers. If I use WireShark to look at the network traffic it gets a responce from the FTP server but never does the handshake for the userid and pwd (for the code), but via CuteFTP all the network traffic is fine.</p>
  
  <p>I force the return of True where it checks the certificate.</p>
  
  <pre><code>
  private void button4_Click(object sender, EventArgs e)
          {
              try
              {
                  string completeFTPPath = ConfigurationManager.AppSettings["FTPPath"];
                  // get the object used to communicate with the server.
                  FtpWebRequest request = (FtpWebRequest)WebRequest.Create(completeFTPPath);
                  request.EnableSsl = true;
                  request.Credentials = new NetworkCredential(ConfigurationManager.AppSettings["FtpUserName"], ConfigurationManager.AppSettings["FtpPassword"]);
                  request.Method = WebRequestMethods.Ftp.UploadFile;                
  
                  ServicePointManager.ServerCertificateValidationCallback = AcceptAllCertifications;
  
                  // read file into byte array
                  StreamReader sourceStream = new StreamReader(ConfigurationManager.AppSettings["LocalFilePath"]);
                  byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
                  sourceStream.Close();
                  request.ContentLength = fileContents.Length;
  
                  // send bytes to server
                  MessageBox.Show("GetRequestStream() start");
                  Stream requestStream = request.GetRequestStream();
                  requestStream.Write(fileContents, 0, fileContents.Length);
                  requestStream.Close();
                  MessageBox.Show("GetRequestStream() end");
  
                  FtpWebResponse response = (FtpWebResponse)request.GetResponse();
                  MessageBox.Show("Response status: " + response.StatusDescription);
              }
              catch (WebException we)
              {
                  MessageBox.Show(we.Message);
              }
              catch (Exception exc)
              {
                  MessageBox.Show(exc.Message);
              }
  
          }
  
    public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
          { return true; }
  
  </code></pre>
  
  <p>e.g.
  FTPPath - <a href="ftp://111.222.333.444:990/UAT/testFile.zip" rel="nofollow noreferrer">ftp://111.222.333.444:990/UAT/testFile.zip</a>; 
  FtpUserName - userID; 
  FtpPassword = userPwd; 
  LocalFilePath - c:\temp\testFile.zip</p>
  
  <p>Anyone any ideas? As some people seem to have the above code working. TIA.</p>