Я использую FileZilla в качестве сервера и службы DNS, поэтому мне не пришлось бы использовать IP-адрес моего локального компьютера (но я пробовал следующие методы на обоих).
Попробовав System.Net.FtpWebRequest для работы, я прочитал (включая несколько сообщений о SO) и обнаружил, что поддержка SSL не очень адекватна этой библиотеке. Он работал с обычным FTP, но когда я попытался принудительно использовать SSL, я получил сообщение об ошибке проверки сертификата: The remote certificate is invalid according to the validation procedure.
Итак, я немного поискал и нашел библиотеку Alex FTPS Client. Вот код, который я написал:
class FTPSWorker
{
public static void UploadFile(string sourceFile, string targetFile, string ftpIP, string ftpUser, string ftpPass)
{
try
{
using (FTPSClient client = new FTPSClient())
{
client.Connect(ftpIP, new NetworkCredential(ftpUser, ftpPass),
ESSLSupportMode.CredentialsRequired | ESSLSupportMode.DataChannelRequested);
client.SetTransferMode(ETransferMode.Binary);
client.PutFile(sourceFile, targetFile);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
К сожалению, я получал ту же самую ошибку сертификата. Однако я могу отлично получить доступ к FTP-серверу с помощью клиента FileZilla. Итак, я подумал, что должна быть проблема с сертификатом.
Я должен отметить, что мой сервер показывал следующие записи журнала:
Welcome Message
AUTH TLS
234 Using authentication type TLS
SSL connection established
disconnected
Пока клиент (приложение С# WPF) получал эту ошибку:
The remote certificate is invalid according to the validation procedure.
Это абсолютно такая же ошибка, если я использую библиотеку .NET и код MSDN.
Я провел больше исследований и нашел решения, подобные этим:
Удаленный сертификат недействителен в соответствии с процедурой проверки а>
Но они просто кажутся рискованными хаками ... И хотя они действительно работают, есть ли способ, чтобы информация о сертификации отображалась и, возможно, пользователь проверял ее / устанавливал ее помимо основного Да / Нет, который он использует в настоящее время?
Мой код прямо сейчас (я отказался от библиотеки Алекса и вернулся к .NET по умолчанию):
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(FTPWorker.ValidateServerCertificate);
public class FTPWorker
{
public static void UploadFile(string sourceFile, string targetFile, string ftpIP, string ftpUser, string ftpPass)
{
try
{
string filename = "ftp://" + ftpIP + "/test/" + targetFile;
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create(filename);
ftpReq.Method = WebRequestMethods.Ftp.UploadFile;
ftpReq.Credentials = new NetworkCredential(ftpUser, ftpPass);
ftpReq.UsePassive = true;
ftpReq.EnableSsl = true;
ftpReq.UseBinary = true;
ftpReq.KeepAlive = false;
byte[] b = File.ReadAllBytes(sourceFile);
ftpReq.ContentLength = b.Length;
using (Stream s = ftpReq.GetRequestStream())
{
s.Write(b, 0, b.Length);
}
FtpWebResponse ftpResp = (FtpWebResponse)ftpReq.GetResponse();
if (ftpResp != null)
{
MessageBox.Show(ftpResp.StatusDescription);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
else
{
if (System.Windows.Forms.MessageBox.Show("The server certificate is not valid.\nAccept?",
"Certificate Validation", System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
return true;
else
return false;
}
}
}