From 388a3b40108052159e98e45cb78b23b1ee4c3d90 Mon Sep 17 00:00:00 2001 From: chrisbednarski Date: Mon, 27 Nov 2023 04:12:11 +1100 Subject: [PATCH] fix openssl session resumption, add quiet shutdown option, support FTPS with hostname (#4103) --- Net/include/Poco/Net/FTPClientSession.h | 7 +++++++ NetSSL_OpenSSL/include/Poco/Net/Context.h | 15 ++++++++++++++ NetSSL_OpenSSL/src/Context.cpp | 20 +++++++++++++++++++ NetSSL_OpenSSL/src/FTPSClientSession.cpp | 4 ++-- NetSSL_OpenSSL/src/SSLManager.cpp | 1 + .../testsuite/src/TCPServerTest.cpp | 1 + 6 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Net/include/Poco/Net/FTPClientSession.h b/Net/include/Poco/Net/FTPClientSession.h index 7738a67cf..c2d79a24d 100644 --- a/Net/include/Poco/Net/FTPClientSession.h +++ b/Net/include/Poco/Net/FTPClientSession.h @@ -325,6 +325,9 @@ protected: DEFAULT_TIMEOUT = 30000000 // 30 seconds default timeout for socket operations }; + const std::string& getHost() const; + /// Returns the host name + static bool isPositivePreliminary(int status); static bool isPositiveCompletion(int status); static bool isPositiveIntermediate(int status); @@ -422,6 +425,10 @@ inline const std::string& FTPClientSession::welcomeMessage() return _welcomeMessage; } +inline const std::string& FTPClientSession::getHost() const +{ + return _host; +} } } // namespace Poco::Net diff --git a/NetSSL_OpenSSL/include/Poco/Net/Context.h b/NetSSL_OpenSSL/include/Poco/Net/Context.h index 67d697c99..52fb9cf4a 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/Context.h +++ b/NetSSL_OpenSSL/include/Poco/Net/Context.h @@ -439,6 +439,21 @@ public: void setSecurityLevel(SecurityLevel level); /// Sets the security level. + void ignoreUnexpectedEof(bool flag = true); + /// Enable or disable SSL/TLS SSL_OP_IGNORE_UNEXPECTED_EOF + /// + /// Some TLS implementations do not send the mandatory close_notify alert on shutdown. + /// If the application tries to wait for the close_notify alert + /// but the peer closes the connection without sending it, an error is generated. + /// When this option is enabled the peer does not need to send the close_notify alert + /// and a closed connection will be treated as if the close_notify alert was received. + + void setQuietShutdown(bool flag = true); + /// Normally, when an SSL connection is finished, the parties must send out close_notify alert messages for a clean shutdown. + /// When setting the "quiet shutdown" flag to true, the SecureSocketImpl::shutdown() will set the SSL shutdown flags, + /// but no close_notify alert is sent to the peer. This behaviour violates the TLS standard. + /// The default is a normal shutdown behaviour as described by the TLS standard. + private: void init(const Params& params); /// Initializes the Context with the given parameters. diff --git a/NetSSL_OpenSSL/src/Context.cpp b/NetSSL_OpenSSL/src/Context.cpp index 0f692b259..42c6b815e 100644 --- a/NetSSL_OpenSSL/src/Context.cpp +++ b/NetSSL_OpenSSL/src/Context.cpp @@ -229,6 +229,26 @@ void Context::setSecurityLevel(SecurityLevel level) #endif } +void Context::ignoreUnexpectedEof(bool flag) +{ + if (flag) + { +#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF) + SSL_CTX_set_options(_pSSLContext, SSL_OP_IGNORE_UNEXPECTED_EOF); +#endif + } + else + { +#if defined(SSL_OP_IGNORE_UNEXPECTED_EOF) + SSL_CTX_clear_options(_pSSLContext, SSL_OP_IGNORE_UNEXPECTED_EOF); +#endif + } +} + +void Context::setQuietShutdown(bool flag) +{ + SSL_CTX_set_quiet_shutdown(_pSSLContext, flag ? 1 : 0); +} void Context::useCertificate(const Poco::Crypto::X509Certificate& certificate) { diff --git a/NetSSL_OpenSSL/src/FTPSClientSession.cpp b/NetSSL_OpenSSL/src/FTPSClientSession.cpp index 059c94ebd..18c4984c0 100644 --- a/NetSSL_OpenSSL/src/FTPSClientSession.cpp +++ b/NetSSL_OpenSSL/src/FTPSClientSession.cpp @@ -96,7 +96,7 @@ void FTPSClientSession::afterCreateControlSocket() try { if (!_pContext) _pContext = Poco::Net::SSLManager::instance().defaultClientContext(); - Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(*_pControlSocket, _pContext)); + Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(*_pControlSocket, getHost(), _pContext)); *_pControlSocket = sss; } catch (Poco::Exception&) @@ -125,7 +125,7 @@ StreamSocket FTPSClientSession::establishDataConnection(const std::string& comma Poco::Net::SecureStreamSocketImpl* pSecure = dynamic_cast(_pControlSocket->impl()); if (pSecure != nullptr) { - Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(ss, pSecure->context(), pSecure->currentSession())); + Poco::Net::SecureStreamSocket sss(Poco::Net::SecureStreamSocket::attach(ss, getHost(), pSecure->context(), pSecure->currentSession())); ss = sss; if (_forceSessionReuse) { diff --git a/NetSSL_OpenSSL/src/SSLManager.cpp b/NetSSL_OpenSSL/src/SSLManager.cpp index 14048fa59..4ea45ab6e 100644 --- a/NetSSL_OpenSSL/src/SSLManager.cpp +++ b/NetSSL_OpenSSL/src/SSLManager.cpp @@ -103,6 +103,7 @@ void SSLManager::shutdown() ServerVerificationError.clear(); _ptrDefaultServerContext = 0; _ptrDefaultClientContext = 0; + _socketIndex = _contextIndex = -1; } diff --git a/NetSSL_OpenSSL/testsuite/src/TCPServerTest.cpp b/NetSSL_OpenSSL/testsuite/src/TCPServerTest.cpp index 0d4059981..af98055ea 100644 --- a/NetSSL_OpenSSL/testsuite/src/TCPServerTest.cpp +++ b/NetSSL_OpenSSL/testsuite/src/TCPServerTest.cpp @@ -324,6 +324,7 @@ void TCPServerTest::testReuseSession() 9, true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + pServerContext->disableProtocols(Context::PROTO_TLSV1_3); pServerContext->enableSessionCache(true, "TestSuite"); pServerContext->setSessionTimeout(10); pServerContext->setSessionCacheSize(1000);