Browse Source

Bug fix: Potential failure when opening unencrypted HTTP/WebDAV connection

Caused by Bug 2034

Source commit: b93f34c4e00ed58793e788815e55ddf0b07707f9
Martin Prikryl 2 years ago
parent
commit
9ffd61b6df
4 changed files with 27 additions and 22 deletions
  1. 1 5
      source/core/Http.cpp
  2. 22 9
      source/core/NeonIntf.cpp
  3. 3 0
      source/core/NeonIntf.h
  4. 1 8
      source/core/WebDAVFileSystem.cpp

+ 1 - 5
source/core/Http.cpp

@@ -73,11 +73,7 @@ void THttp::SendRequest(const char * Method, const UnicodeString & Request)
 
 
       if (IsTls)
       if (IsTls)
       {
       {
-        SetNeonTlsInit(NeonSession, InitSslSession);
-
-        ne_ssl_set_verify(NeonSession, NeonServerSSLCallback, this);
-
-        ne_ssl_trust_default_ca(NeonSession);
+        InitNeonTls(NeonSession, InitSslSession, NeonServerSSLCallback, this, NULL);
       }
       }
 
 
       ne_request_s * NeonRequest = ne_request_create(NeonSession, Method, StrToNeon(Uri));
       ne_request_s * NeonRequest = ne_request_create(NeonSession, Method, StrToNeon(Uri));

+ 22 - 9
source/core/NeonIntf.cpp

@@ -110,15 +110,6 @@ void InitNeonSession(ne_session * Session, TProxyMethod ProxyMethod, const Unico
 
 
   ne_redirect_register(Session);
   ne_redirect_register(Session);
   ne_set_useragent(Session, StrToNeon(FORMAT(L"%s/%s", (AppNameString(), Configuration->Version))));
   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));
-    if (Terminal != NULL)
-    {
-      Terminal->LogEvent(FORMAT(L"Using certificate store \"%s\"", (CertificateStorage)));
-    }
-  }
 
 
   if (Terminal != NULL)
   if (Terminal != NULL)
   {
   {
@@ -260,11 +251,33 @@ void ne_init_ssl_session(struct ssl_st * Ssl, ne_session * Session)
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 void SetNeonTlsInit(ne_session * Session, TNeonTlsInit OnNeonTlsInit)
 void SetNeonTlsInit(ne_session * Session, TNeonTlsInit OnNeonTlsInit)
 {
 {
+  // As the OnNeonTlsInit always only calls SetupSsl, we can simplify this with one shared implementation
   TMethod & Method = *(TMethod*)&OnNeonTlsInit;
   TMethod & Method = *(TMethod*)&OnNeonTlsInit;
   ne_set_session_private(Session, SESSION_TLS_INIT_KEY, Method.Code);
   ne_set_session_private(Session, SESSION_TLS_INIT_KEY, Method.Code);
   ne_set_session_private(Session, SESSION_TLS_INIT_DATA_KEY, Method.Data);
   ne_set_session_private(Session, SESSION_TLS_INIT_DATA_KEY, Method.Data);
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
+void InitNeonTls(
+  ne_session * Session, TNeonTlsInit OnNeonTlsInit, ne_ssl_verify_fn VerifyCallback, void * VerifyContext,
+  TTerminal * Terminal)
+{
+  UnicodeString CertificateStorage = Configuration->CertificateStorageExpanded;
+  if (!CertificateStorage.IsEmpty())
+  {
+    ne_ssl_set_certificates_storage(Session, StrToNeon(CertificateStorage));
+    if (Terminal != NULL)
+    {
+      Terminal->LogEvent(FORMAT(L"Using certificate store \"%s\"", (CertificateStorage)));
+    }
+  }
+
+  SetNeonTlsInit(Session, OnNeonTlsInit);
+
+  ne_ssl_set_verify(Session, VerifyCallback, VerifyContext);
+
+  ne_ssl_trust_default_ca(Session);
+}
+//---------------------------------------------------------------------------
 AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate)
 AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate)
 {
 {
   char * AsciiCert = ne_ssl_cert_export(Certificate);
   char * AsciiCert = ne_ssl_cert_export(Certificate);

+ 3 - 0
source/core/NeonIntf.h

@@ -38,6 +38,9 @@ UnicodeString GetNeonRedirectUrl(ne_session * Session);
 void CheckRedirectLoop(const UnicodeString & RedirectUrl, TStrings * AttemptedUrls);
 void CheckRedirectLoop(const UnicodeString & RedirectUrl, TStrings * AttemptedUrls);
 typedef void (__closure* TNeonTlsInit)(struct ssl_st * Ssl, ne_session * Session);
 typedef void (__closure* TNeonTlsInit)(struct ssl_st * Ssl, ne_session * Session);
 void SetNeonTlsInit(ne_session * Session, TNeonTlsInit OnNeonTlsInit);
 void SetNeonTlsInit(ne_session * Session, TNeonTlsInit OnNeonTlsInit);
+void InitNeonTls(
+  ne_session * Session, TNeonTlsInit OnNeonTlsInit, ne_ssl_verify_fn VerifyCallback, void * VerifyContext,
+  TTerminal * Terminal);
 AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate);
 AnsiString NeonExportCertificate(const ne_ssl_certificate * Certificate);
 bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert, UnicodeString & Error);
 bool NeonWindowsValidateCertificate(int & Failures, const AnsiString & AsciiCert, UnicodeString & Error);
 bool NeonWindowsValidateCertificateWithMessage(TNeonCertificateData & Data, UnicodeString & Message);
 bool NeonWindowsValidateCertificateWithMessage(TNeonCertificateData & Data, UnicodeString & Message);

+ 1 - 8
source/core/WebDAVFileSystem.cpp

@@ -306,15 +306,8 @@ void TWebDAVFileSystem::NeonClientOpenSessionInternal(UnicodeString & CorrectedU
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 void __fastcall TWebDAVFileSystem::SetSessionTls(TSessionContext * SessionContext, ne_session_s * Session, bool Aux)
 void __fastcall TWebDAVFileSystem::SetSessionTls(TSessionContext * SessionContext, ne_session_s * Session, bool Aux)
 {
 {
-  SetNeonTlsInit(Session, InitSslSession);
-
-  // When the CA certificate or server certificate has
-  // verification problems, neon will call our verify function before
-  // outright rejection of the connection.
   ne_ssl_verify_fn Callback = Aux ? NeonServerSSLCallbackAux : NeonServerSSLCallbackMain;
   ne_ssl_verify_fn Callback = Aux ? NeonServerSSLCallbackAux : NeonServerSSLCallbackMain;
-  ne_ssl_set_verify(Session, Callback, SessionContext);
-
-  ne_ssl_trust_default_ca(Session);
+  InitNeonTls(Session, InitSslSession, Callback, SessionContext, FTerminal);
 }
 }
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 void __fastcall TWebDAVFileSystem::InitSession(TSessionContext * SessionContext, ne_session_s * Session)
 void __fastcall TWebDAVFileSystem::InitSession(TSessionContext * SessionContext, ne_session_s * Session)