Загрузить файлы на сервер 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);
}
}
2 ответа
Я бы порекомендовал взглянуть на эту статью
Судя по тому, как это звучит, проблема в том, что FTP-сервер проверяет сертификат вашего приложения, а не принимает его. Как объясняется в статье, есть плагины, которые позволяют вам получить / сделать сертификат для вашего приложения, соответствующего вашему FTP-серверу.
Я не вижу ничего, что указывает на проблему с сертификатом клиента. Вы уверены, что сертификат на сервере соответствует используемому вами 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;
}