FTP через SSL для С#

Я использую приведенный ниже код (должен быть .Net 2.0) для подключения на сервере UAT к клиентскому FTP-серверу для загрузки/выгрузки файлов. Мне нужно подключиться через порт 990, используя предоставленный ими самоподписанный сертификат. Я изменил правила брандмауэра, чтобы разрешить подключение к URI через порт 990 с нашего сервера UAT.

Однако (! :)) я получаю тайм-аут на линии

 Stream requestStream = request.GetRequestStream();

Если я увеличиваю время ожидания, это не имеет значения.

Я посмотрел в Интернете, но не нашел ничего очевидного, что отсутствует в коде.

Если я использую CuteFTP для подключения к серверу UAT, то, естественно, он подключается нормально, и я могу вручную выполнять передачу файлов. Если я использую WireShark для просмотра сетевого трафика, он получает ответ от FTP-сервера, но никогда не выполняет рукопожатие для идентификатора пользователя и pwd (для кода), но через CuteFTP весь сетевой трафик в порядке.

Я принудительно возвращаю True, где он проверяет сертификат.


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; }

например FTPPath — ftp://111.222.333.444:990/UAT/testFile.zip; FtpUserName - ID пользователя; FtpPassword = пароль пользователя; LocalFilePath — c:\temp\testFile.zip

У кого-нибудь есть идеи? Поскольку у некоторых людей, похоже, работает приведенный выше код. ТИА.


person Neil Carey    schedule 31.08.2009    source источник


Ответы (5)


Находясь на порту 990, сервер, скорее всего, поддерживает неявный FTPS, а не более стандартный явный FTPS. Возможно, неявный FTPS не поддерживается в FtpWebRequest (я не знаю).

Если да, взгляните на edtFTPnet/PRO , который поддерживает как неявные, так и явный FTPS, а также SFTP.

person Bruce Blackshaw    schedule 07.09.2009
comment
Можем ли мы это проверить? Я думаю, что это может быть моя проблема. - person PeterX; 14.10.2013

Попробуйте библиотеку EnterpriseDT.

person tsilb    schedule 07.09.2009

Включите трассировку в .Net и воспроизведите проблему, затем опубликуйте полученный журнал, и я скажу вам, что происходит не так. Есть несколько известных проблем в FtpWebRequest в .Net 2.0, поэтому вы также можете столкнуться с одной из них, но это невозможно сказать только по коду, который вы показываете. Инструкции по включению отслеживания можно найти здесь: http://blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx

person Jeff Tucker    schedule 31.08.2009

Я тоже посмотрел на это изначально, но это не пролило на меня много света.

Я только что снова запустил трассировку и использовал настройки SSL system.diagnostics в сообщении Дургапрасада.

System.Net Verbose: 0 : [7016] WebRequest::Create(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Information: 0 : [7016] FtpWebRequest#48285313::.ctor(ftp://www.companyname.com:990/UAT/testFile.zip)
System.Net Verbose: 0 : [7016] Exiting WebRequest::Create()     -> FtpWebRequest#48285313
System.Net Verbose: 0 : [7016] FtpWebRequest#48285313::GetRequestStream()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::GetRequestStream(Method=STOR.)
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Socket(InterNetwork#2)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Socket() 
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Connect(131:990#-2083582714)
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Connect() 
System.Net Information: 0 : [7016] Associating FtpWebRequest#48285313 with FtpControlStream#18796293
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Receive()
System.Net.Sockets Error: 0 : [7016] Exception in the Socket#31914638::Receive - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
System.Net.Sockets Verbose: 0 : [7016] Exiting Socket#31914638::Receive()   -> 0#0
System.Net.Sockets Verbose: 0 : [7016] Socket#31914638::Dispose()
System.Net Information: 0 : [7016] FtpWebRequest#48285313::(Releasing FTP connection#18796293.)
System.Net Error: 0 : [7016] Exception in the FtpWebRequest#48285313::GetRequestStream - The operation has timed out.
System.Net Error: 0 : [7016]    at System.Net.FtpWebRequest.GetRequestStream()
System.Net Verbose: 0 : [7016] Exiting FtpWebRequest#48285313::GetRequestStream() 

Кроме того, (в предыдущий раз, когда я запускал это) я заставил сетевую команду запустить Netmon, и из нижеследующего они подразумевали, что это связано с кодом:


  TCP    kulccstgweb02:2673     companyname.com:microsoft -ds  ESTABLISHED
  TCP    kulccstgweb02:2678     companyname IP:ftps    ESTABLISHED
  TCP    kulccstgweb02:sms-chat  companyname IP:ftps    ESTABLISHED

Кстати, FTPPath — «ftp://111.222.333.444:990/UAT/testFile.zip" фактически является "ftp://www.companyname.com:990/UAT /testFile.zip" и затем преобразуется в IP-адрес. Но я не понимаю, как это может изменить ситуацию.

person Neil Carey    schedule 31.08.2009
comment
Если имя хоста 111.222.333.444 не является именем www.company.com, сопоставление имен сертификатов завершится ошибкой. Может это ваша проблема? - person Steve Gilham; 07.09.2009

При загрузке файла по FTP я обычно создаю объект FtpWebRequest следующим образом:

string address = "ftp://www.companyname.com/UAT/"
string fileName = "testFile.zip"
UriBuilder uriBuilder = new UriBuilder(address);
FtpWebRequest  request = (FtpWebRequest)WebRequest.Create(uriBuilder.ToString() + fileName);

Попробуйте и посмотрите, что произойдет, я знаю, что это работает с явным SSL и портом 990.

person Crackerjack    schedule 13.10.2009