Procházet zdrojové kódy

Limiting scope of Bug 2030 (Timeout while uploading files to some FTP servers using TLS 1.3) to affected servers only

https://winscp.net/tracker/2030

Source commit: 83123c9e8d158ae74d541b5b07c88303c5ec7fe6
Martin Prikryl před 4 roky
rodič
revize
12a3508797

+ 16 - 7
source/core/FtpFileSystem.cpp

@@ -375,6 +375,7 @@ void __fastcall TFTPFileSystem::Open()
   FWindowsServer = false;
   FMVS = false;
   FVMS = false;
+  FFileZilla = false;
   FTransferActiveImmediately = (Data->FtpTransferActiveImmediately == asOn);
   FVMSAllRevisions = Data->VMSAllRevisions;
 
@@ -637,13 +638,7 @@ void __fastcall TFTPFileSystem::CollectUsage()
     FTerminal->CollectTlsUsage(TlsVersionStr);
   }
 
-  // 220-FileZilla Server version 0.9.43 beta
-  // 220-written by Tim Kosse ([email protected])
-  // 220 Please visit http://sourceforge.net/projects/filezilla/
-  // SYST
-  // 215 UNIX emulated by FileZilla
-  // (Welcome message is configurable)
-  if (ContainsText(FSystem, L"FileZilla"))
+  if (FFileZilla)
   {
     FTerminal->Configuration->Usage->Inc(L"OpenedSessionsFTPFileZilla");
   }
@@ -2840,6 +2835,10 @@ int __fastcall TFTPFileSystem::GetOptionVal(int OptionID) const
       Result = FFileTransferNoList ? TRUE : FALSE;
       break;
 
+    case OPTION_MPEXT_COMPLETE_TLS_SHUTDOWN:
+      Result = FFileZilla ? FALSE : TRUE;
+      break;
+
     default:
       DebugFail();
       Result = FALSE;
@@ -3493,6 +3492,16 @@ void __fastcall TFTPFileSystem::HandleReplyStatus(UnicodeString Response)
           FTerminal->LogEvent(L"Server is known to require use of relative paths");
           FWorkFromCwd = asOn;
         }
+        // 220-FileZilla Server 1.0.1
+        // 220 Please visit https://filezilla-project.org/
+        // SYST
+        // 215 UNIX emulated by FileZilla
+        // (Welcome message is configurable)
+        if (ContainsText(FSystem, L"FileZilla"))
+        {
+          FTerminal->LogEvent(L"FileZilla server detected.");
+          FFileZilla = true;
+        }
       }
       else
       {

+ 1 - 0
source/core/FtpFileSystem.h

@@ -297,6 +297,7 @@ private:
   bool FBytesAvailableSupported;
   bool FMVS;
   bool FVMS;
+  bool FFileZilla;
   bool FFileTransferAny;
   bool FLoggedIn;
   bool FVMSAllRevisions;

+ 1 - 0
source/filezilla/AsyncSocketEx.h

@@ -283,6 +283,7 @@ protected:
 
   virtual void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg) {};
   virtual bool LoggingSocketMessage(int nMessageType) { return true; };
+  virtual int GetSocketOptionVal(int OptionID) const { DebugFail(); return 0; };
   virtual void ConfigureSocket() {};
 };
 //---------------------------------------------------------------------------

+ 8 - 0
source/filezilla/AsyncSocketExLayer.cpp

@@ -980,3 +980,11 @@ bool CAsyncSocketExLayer::LoggingSocketMessage(int nMessageType)
   else
     return m_pOwnerSocket->LoggingSocketMessage(nMessageType);
 }
+
+int CAsyncSocketExLayer::GetSocketOptionVal(int OptionID) const
+{
+  if (m_pPrevLayer)
+    return m_pPrevLayer->GetSocketOptionVal(OptionID);
+  else
+    return m_pOwnerSocket->GetSocketOptionVal(OptionID);
+}

+ 1 - 0
source/filezilla/AsyncSocketExLayer.h

@@ -136,6 +136,7 @@ protected:
 
   void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);
   bool LoggingSocketMessage(int nMessageType);
+  int GetSocketOptionVal(int OptionID) const;
 
 private:
   // Layer state can't be set directly from derived classes

+ 9 - 2
source/filezilla/AsyncSslSocketLayer.cpp

@@ -1015,8 +1015,15 @@ BOOL CAsyncSslSocketLayer::ShutDown(int nHow /*=sends*/)
     int res = SSL_shutdown(m_ssl);
     if (res == 0)
     {
-      // maybe we do not need to call this at all (as neon does)
-      SSL_shutdown(m_ssl);
+      // Without bi-directional shutdown, file uploads are incomplete on some servers
+      res = SSL_shutdown(m_ssl);
+
+      if ((SSL_version(m_ssl) <= TLS1_2_VERSION) ||
+          !GetSocketOptionVal(OPTION_MPEXT_COMPLETE_TLS_SHUTDOWN))
+      {
+        LogSocketMessageRaw(FZ_LOG_INFO, L"Not waiting for complete TLS shutdown");
+        res = 0;
+      }
     }
     if (res >= 0)
     {

+ 1 - 0
source/filezilla/FileZillaOpt.h

@@ -50,5 +50,6 @@
 #define OPTION_MPEXT_HOST 1009
 #define OPTION_MPEXT_NODELAY 1010
 #define OPTION_MPEXT_NOLIST 1011
+#define OPTION_MPEXT_COMPLETE_TLS_SHUTDOWN 1012
 //---------------------------------------------------------------------------
 #endif // FileZillaOptH

+ 5 - 0
source/filezilla/FtpControlSocket.cpp

@@ -6035,6 +6035,11 @@ bool CFtpControlSocket::LoggingSocketMessage(int nMessageType)
   return LoggingMessageType(nMessageType);
 }
 
+int CFtpControlSocket::GetSocketOptionVal(int OptionID) const
+{
+  return GetOptionVal(OptionID);
+}
+
 BOOL CFtpControlSocket::ParsePwdReply(CString& rawpwd)
 {
   CServerPath realPath;

+ 1 - 0
source/filezilla/FtpControlSocket.h

@@ -144,6 +144,7 @@ protected:
 
   virtual void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);
   virtual bool LoggingSocketMessage(int nMessageType);
+  virtual int GetSocketOptionVal(int OptionID) const;
 
   void ShowStatus(UINT nID, int type) const;
   void ShowStatus(CString status,int type) const;

+ 5 - 0
source/filezilla/TransferSocket.cpp

@@ -1135,6 +1135,11 @@ void CTransferSocket::LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg)
   LogMessageRaw(nMessageType, pMsg);
 }
 
+int CTransferSocket::GetSocketOptionVal(int OptionID) const
+{
+  return GetOptionVal(OptionID);
+}
+
 void CTransferSocket::EnsureSendClose(int Mode)
 {
   if (!m_bSentClose)

+ 1 - 0
source/filezilla/TransferSocket.h

@@ -56,6 +56,7 @@ protected:
   virtual int OnLayerCallback(std::list<t_callbackMsg> & callbacks);
   int ReadDataFromFile(char * buffer, int len);
   virtual void LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg);
+  virtual int GetSocketOptionVal(int OptionID) const;
   virtual void ConfigureSocket();
   bool Activate();
   void Start();