From a22e3f375bf3059387a83c28d9ce153c283d04ae Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 22 Apr 2025 21:46:31 +0200 Subject: [PATCH] Make FTP opt-in, increase timeout, protect wpa_supplicant better (#879) * Increase timeout * Protect wpa_supplicant more effectively * Make FTP opt-in with NetworkFTPEnabled --- src/config.cpp | 6 ++++++ src/config.h | 2 ++ src/minidexed.cpp | 25 +++++++++++++++---------- src/minidexed.ini | 1 + src/net/ftpworker.cpp | 18 ++++++++++++------ 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 00d4d2d..65cd68c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -211,6 +211,7 @@ void CConfig::Load (void) m_INetworkDefaultGateway = m_Properties.GetIPAddress("NetworkDefaultGateway") != 0; m_bSyslogEnabled = m_Properties.GetNumber ("NetworkSyslogEnabled", 0) != 0; m_INetworkDNSServer = m_Properties.GetIPAddress("NetworkDNSServer") != 0; + m_bNetworkFTPEnabled = m_Properties.GetNumber("NetworkFTPEnabled", 0) != 0; const u8 *pSyslogServerIP = m_Properties.GetIPAddress ("NetworkSyslogServerIPAddress"); if (pSyslogServerIP) @@ -792,3 +793,8 @@ CIPAddress CConfig::GetNetworkSyslogServerIPAddress (void) const { return m_INetworkSyslogServerIPAddress; } + +bool CConfig::GetNetworkFTPEnabled (void) const +{ + return m_bNetworkFTPEnabled; +} diff --git a/src/config.h b/src/config.h index fcb8cca..aaf2476 100644 --- a/src/config.h +++ b/src/config.h @@ -253,6 +253,7 @@ public: CIPAddress GetNetworkDNSServer (void) const; bool GetSyslogEnabled (void) const; CIPAddress GetNetworkSyslogServerIPAddress (void) const; + bool GetNetworkFTPEnabled (void) const; private: CPropertiesFatFsFile m_Properties; @@ -382,6 +383,7 @@ private: CIPAddress m_INetworkDNSServer; bool m_bSyslogEnabled; CIPAddress m_INetworkSyslogServerIPAddress; + bool m_bNetworkFTPEnabled; }; #endif diff --git a/src/minidexed.cpp b/src/minidexed.cpp index 0063b11..134d241 100644 --- a/src/minidexed.cpp +++ b/src/minidexed.cpp @@ -2305,18 +2305,23 @@ void CMiniDexed::UpdateNetwork() m_UDPMIDI->Initialize(); } - m_pFTPDaemon = new CFTPDaemon(FTPUSERNAME, FTPPASSWORD); + if (m_pConfig->GetNetworkFTPEnabled()) { + m_pFTPDaemon = new CFTPDaemon(FTPUSERNAME, FTPPASSWORD); - if (!m_pFTPDaemon->Initialize()) - { - LOGERR("Failed to init FTP daemon"); - delete m_pFTPDaemon; - m_pFTPDaemon = nullptr; - } - else - { - LOGNOTE("FTP daemon initialized"); + if (!m_pFTPDaemon->Initialize()) + { + LOGERR("Failed to init FTP daemon"); + delete m_pFTPDaemon; + m_pFTPDaemon = nullptr; + } + else + { + LOGNOTE("FTP daemon initialized"); + } + } else { + LOGNOTE("FTP daemon not started (NetworkFTPEnabled=0)"); } + m_UI.DisplayWrite (IPString, "", "TG1", 0, 1); m_pmDNSPublisher = new CmDNSPublisher (m_pNet); diff --git a/src/minidexed.ini b/src/minidexed.ini index 7d0fd31..c176e85 100644 --- a/src/minidexed.ini +++ b/src/minidexed.ini @@ -161,6 +161,7 @@ NetworkIPAddress=0 NetworkSubnetMask=0 NetworkDefaultGateway=0 NetworkDNSServer=0 +NetworkFTPEnabled=0 NetworkSyslogEnabled=0 NetworkSyslogServerIPAddress=0 diff --git a/src/net/ftpworker.cpp b/src/net/ftpworker.cpp index 6f19f8a..28415e2 100644 --- a/src/net/ftpworker.cpp +++ b/src/net/ftpworker.cpp @@ -40,7 +40,7 @@ constexpr u16 PassivePortBase = 9000; constexpr size_t TextBufferSize = 512; -constexpr unsigned int SocketTimeout = 20; +constexpr unsigned int SocketTimeout = 60; constexpr unsigned int NumRetries = 3; #ifndef MT32_PI_VERSION @@ -48,7 +48,7 @@ constexpr unsigned int NumRetries = 3; #endif const char MOTDBanner[] = "Welcome to the MiniDexed " MT32_PI_VERSION " embedded FTP server!"; -const char* exclude_filename = "SD:/wpa_supplicant.conf"; +const char* exclude_filename = "wpa_supplicant.conf"; enum class TDirectoryListEntryType { @@ -616,10 +616,16 @@ bool CFTPWorker::Retrieve(const char* pArgs) FIL File; CString Path = RealPath(pArgs); - typedef const char* LPCTSTR; - //printf("%s\n", (LPCTSTR)Path); - //printf("%s\n", exclude_filename ); - if (strcmp((LPCTSTR)Path, exclude_filename) == 0) + + // Disallow any file named wpa_supplicant.conf (case-insensitive) in any directory + const char* pathStr = Path; + const char* lastSep = nullptr; + for (const char* p = pathStr; *p; ++p) { + if (*p == '/' || *p == ':') lastSep = p; + } + const char* filename = lastSep ? lastSep + 1 : pathStr; + // Case-insensitive compare using strcasecmp if available + if (strcasecmp(filename, "wpa_supplicant.conf") == 0) { SendStatus(TFTPStatus::FileNameNotAllowed, "Reading this file is not allowed"); return false;