浏览代码

Bug 2034: Custom certificate store file

https://winscp.net/tracker/2034
(cherry picked from commit e70fd8fa510de97f6741ad2ac428fdb3899ddae7)

Source commit: 95c530928c9871191cf4f67478bf35b171e94643
Martin Prikryl 4 年之前
父节点
当前提交
81337cdcc5

+ 21 - 0
source/core/Configuration.cpp

@@ -116,6 +116,7 @@ void __fastcall TConfiguration::Default()
   FTryFtpWhenSshFails = true;
   FParallelDurationThreshold = 10;
   FMimeTypes = UnicodeString();
+  FCertificateStorage = EmptyStr;
   FDontReloadMoreThanSessions = 1000;
   FScriptProgressFileNameLimit = 25;
   FKeyVersion = 0;
@@ -256,6 +257,7 @@ UnicodeString __fastcall TConfiguration::PropertyToKey(const UnicodeString & Pro
     KEY(Integer,  ScriptProgressFileNameLimit); \
     KEY(Integer,  KeyVersion); \
     KEY(Bool,     CollectUsage); \
+    KEY(String,   CertificateStorage); \
   ); \
   BLOCK(L"Logging", CANCREATE, \
     KEYEX(Bool,  PermanentLogging, L"Logging"); \
@@ -1664,6 +1666,25 @@ void __fastcall TConfiguration::SetMimeTypes(UnicodeString value)
   SET_CONFIG_PROPERTY(MimeTypes);
 }
 //---------------------------------------------------------------------
+void TConfiguration::SetCertificateStorage(const UnicodeString & value)
+{
+  SET_CONFIG_PROPERTY(CertificateStorage);
+}
+//---------------------------------------------------------------------
+UnicodeString TConfiguration::GetCertificateStorageExpanded()
+{
+  UnicodeString Result = FCertificateStorage;
+  if (Result.IsEmpty())
+  {
+    UnicodeString DefaultCertificateStorage = TPath::Combine(ExtractFilePath(ModuleFileName()), L"cacert.pem");
+    if (FileExists(DefaultCertificateStorage))
+    {
+      Result = DefaultCertificateStorage;
+    }
+  }
+  return Result;
+}
+//---------------------------------------------------------------------
 void __fastcall TConfiguration::SetTryFtpWhenSshFails(bool value)
 {
   SET_CONFIG_PROPERTY(TryFtpWhenSshFails);

+ 5 - 0
source/core/Configuration.h

@@ -80,6 +80,7 @@ private:
   int FDontReloadMoreThanSessions;
   int FScriptProgressFileNameLimit;
   int FKeyVersion;
+  UnicodeString FCertificateStorage;
 
   bool FDisablePasswordStoring;
   bool FForceBanners;
@@ -145,6 +146,8 @@ private:
   void __fastcall SetTryFtpWhenSshFails(bool value);
   void __fastcall SetParallelDurationThreshold(int value);
   void __fastcall SetMimeTypes(UnicodeString value);
+  void SetCertificateStorage(const UnicodeString & value);
+  UnicodeString GetCertificateStorageExpanded();
   bool __fastcall GetCollectUsage();
   void __fastcall SetCollectUsage(bool value);
   bool __fastcall GetIsUnofficial();
@@ -326,6 +329,8 @@ public:
   __property int CacheDirectoryChangesMaxSize = { read = FCacheDirectoryChangesMaxSize, write = SetCacheDirectoryChangesMaxSize };
   __property bool ShowFtpWelcomeMessage = { read = FShowFtpWelcomeMessage, write = SetShowFtpWelcomeMessage };
   __property UnicodeString ExternalIpAddress = { read = FExternalIpAddress, write = SetExternalIpAddress };
+  __property UnicodeString CertificateStorage = { read = FCertificateStorage, write = SetCertificateStorage };
+  __property UnicodeString CertificateStorageExpanded = { read = GetCertificateStorageExpanded };
   __property int LocalPortNumberMin = { read = FLocalPortNumberMin, write = SetLocalPortNumberMin };
   __property int LocalPortNumberMax = { read = FLocalPortNumberMax, write = SetLocalPortNumberMax };
   __property bool TryFtpWhenSshFails = { read = FTryFtpWhenSshFails, write = SetTryFtpWhenSshFails };

+ 4 - 0
source/core/FtpFileSystem.cpp

@@ -2685,6 +2685,10 @@ const wchar_t * __fastcall TFTPFileSystem::GetOption(int OptionID) const
       FOptionScratch = L"";
       break;
 
+    case OPTION_MPEXT_CERT_STORAGE:
+      FOptionScratch = FTerminal->Configuration->CertificateStorageExpanded;
+      break;
+
     default:
       DebugFail();
       FOptionScratch = L"";

+ 5 - 0
source/core/NeonIntf.cpp

@@ -110,6 +110,11 @@ void InitNeonSession(ne_session * Session, TProxyMethod ProxyMethod, const Unico
 
   ne_redirect_register(Session);
   ne_set_useragent(Session, StrToNeon(FORMAT(L"%s/%s", (AppNameString(), Configuration->Version))));
+  UnicodeString CertificateStorage = Configuration->CertificateStorageExpanded;
+  if (!CertificateStorage.IsEmpty())
+  {
+    ne_ssl_set_certificates_storage(Session, StrToNeon(CertificateStorage));
+  }
 
   UnicodeString CertificateStorage = IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + L"cacert.pem";
   if (FileExists(CertificateStorage))

+ 2 - 1
source/filezilla/AsyncSslSocketLayer.cpp

@@ -762,7 +762,8 @@ int CAsyncSslSocketLayer::InitSSLConnection(bool clientMode,
       SSL_CTX_set_session_cache_mode(m_ssl_ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE | SSL_SESS_CACHE_NO_AUTO_CLEAR);
       SSL_CTX_sess_set_new_cb(m_ssl_ctx, NewSessionCallback);
       CFileStatus Dummy;
-      if (CFile::GetStatus((LPCTSTR)m_CertStorage, Dummy))
+      if (!m_CertStorage.IsEmpty() &&
+          CFile::GetStatus((LPCTSTR)m_CertStorage, Dummy))
       {
         SSL_CTX_load_verify_locations(m_ssl_ctx, T2CA(m_CertStorage), 0);
       }

+ 1 - 0
source/filezilla/FileZillaOpt.h

@@ -51,5 +51,6 @@
 #define OPTION_MPEXT_NODELAY 1010
 #define OPTION_MPEXT_NOLIST 1011
 #define OPTION_MPEXT_COMPLETE_TLS_SHUTDOWN 1012
+#define OPTION_MPEXT_CERT_STORAGE 1013
 //---------------------------------------------------------------------------
 #endif // FileZillaOptH

+ 1 - 11
source/filezilla/FtpControlSocket.cpp

@@ -384,17 +384,7 @@ bool CFtpControlSocket::InitConnect()
 
     m_pSslLayer->SetClientCertificate(m_CurrentServer.Certificate, m_CurrentServer.PrivateKey);
 
-    TCHAR buffer[1000];
-    GetModuleFileName(NULL, buffer, 1000);
-    CString filename = buffer;
-    int pos = filename.ReverseFind(L'\\');
-    if (pos != -1)
-    {
-      filename = filename.Left(pos + 1);
-      filename += L"cacert.pem";
-    }
-    else
-      filename = L"cacert.pem";
+    CString filename = GetOption(OPTION_MPEXT_CERT_STORAGE);
     m_pSslLayer->SetCertStorage(filename);
   }