загружать файлы на FTPS-сервер

Я пытаюсь загрузить файлы на FTP-сервер (FTPS). Выполнение следующего кода приводит к исключению:

Удаленный сертификат недействителен в соответствии с процедурой проверки.

Код:

static void Main(string[] args)
{
    FTPFactory ftp = new FTPFactory();

    ftp.setDebug(true);
    ftp.setRemoteHost("ftps.host");
    //Connect to SSL Port (5920)
    ftp.setRemotePort(5920);
    ftp.loginWithoutUser();

    string cmd = "AUTH SSL";
    ftp.sendCommand(cmd);

    //Create SSL Stream
        ftp.getSslStream();
        ftp.setUseStream(true);
    //Login  FTP Secure
    //     ftp.setRemoteUser(Settings.Default.TargetFtpSecureUser);
    ftp.setRemoteUser("user");
    //  ftp.setRemotePass(Settings.Default.TargetFtpSecurePass);
    ftp.setRemotePass("pass");
    ftp.login();

    //Set ASCII Mode
    ftp.setBinaryMode(false);


    //Upload file

    // Send Argument if you want
    // cmd = "site arg1 arg2";
    // ftp.sendCommand(cmd);

    ftp.upload("", false);
    ftp.uploadSecure(@"Filepath", false);

    ftp.close();
}
catch (Exception e)
{
    Console.WriteLine("Caught Error :" + e.Message);
}
}

это класс FTPFactory:

using System;
using System.Net.Sockets;

namespace FTP_DLL
{
    public class FTPFactory
    {
        public FTPFactory();

        public void chdir(string dirName);
        public void close();
        public Socket createDataSocket();
        public void deleteRemoteFile(string fileName);
        public void download(string remFileName);
        public void download(string remFileName, bool resume);
        public void download(string remFileName, string locFileName);
        public void download(string remFileName, string locFileName, bool resume);
        public string[] getFileList(string mask);
        public long getFileSize(string fileName);
        public string getRemoteHost();
        public string getRemotePath();
        public int getRemotePort();
        public void getSslStream();
        public void getSslStream(Socket Csocket);
        public void login();
        public void loginWithoutUser();
        public void mkdir(string dirName);
        public void renameRemoteFile(string oldFileName, string newFileName);
        public void rmdir(string dirName);
        public void sendCommand(string command);
        public void setBinaryMode(bool mode);
        public void setDebug(bool debug);
        public void setRemoteHost(string remoteHost);
        public void setRemotePass(string remotePass);
        public void setRemotePath(string remotePath);
        public void setRemotePort(int remotePort);
        public void setRemoteUser(string remoteUser);
        public void setUseStream(bool value);
        public void upload(string fileName, bool resume);
        public void uploadSecure(string fileName, bool resume);
    }
}

person David Munsa    schedule 30.04.2014    source источник


Ответы (2)


Я бы рекомендовал взглянуть на эта статья

Судя по всему, проблема в том, что FTP-сервер просматривает сертификат вашего приложения и не принимает его. Как объясняется в статье, существуют плагины, которые позволяют вам получить/создать сертификат для вашего приложения, соответствующий вашему FTP-серверу.

person Dylan Corriveau    schedule 30.04.2014
comment
теперь есть способ обойти это? - person David Munsa; 30.04.2014
comment
В сертификатах не было бы особого смысла, если бы вы могли обойти проверку. - person djdanlib; 30.04.2014

Я не вижу ничего, что указывало бы на проблему с сертификатом клиента. Вы уверены, что сертификат на сервере соответствует DNS-имени или IP-адресу, который вы используете, и срок его действия не истек?

Я не знаком с используемым вами классом FTPFactory. Вы должны включить ссылку на веб-сайт для него.

Однако, если базовый класс, используемый для выполнения соединения SSL, является частью .NET Framework, вы, вероятно, можете изменить поведение проверки сертификата, установив ServicePointManager.ServerCertificateValidationCallback делегату, как показано ниже. В других библиотеках также может быть механизм переопределения поведения проверки сертификата.

Хотя это подходит для тестирования, я не рекомендую обходить проверку сертификата в производственном коде. Вместо этого следует исправить сертификат, представляемый сервером.

    public static bool ServicePointManager_ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        bool allowCertificate = true;

        if (sslPolicyErrors != SslPolicyErrors.None)
        {
            Console.WriteLine("Accepting the certificate with errors:");
            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
            {
                Console.WriteLine("\tThe certificate subject {0} does not match.", certificate.Subject);
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
            {
                Console.WriteLine("\tThe certificate chain has the following errors:");
                foreach (X509ChainStatus chainStatus in chain.ChainStatus)
                {
                    Console.WriteLine("\t\t{0}", chainStatus.StatusInformation);

                    if (chainStatus.Status == X509ChainStatusFlags.Revoked)
                    {
                        allowCertificate = false;
                    }
                }
            }

            if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
            {
                Console.WriteLine("No certificate available.");
                allowCertificate = false;
            }

            Console.WriteLine();
        }

        return allowCertificate;
    }
person JamieSee    schedule 19.01.2016