diff --git a/CHANGELOG b/CHANGELOG index 5aa033245..7b0b7c9ed 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -85,6 +85,9 @@ Release 1.3.6 (2009-11-xx) for how this is implemented. Contributed by Philippe Cuvillier. - fixed SF# 2897650: [branch 1.3.6] Net.SocketAddress won't compile for CYGWIN - fixed SF# 2896161: Building on Windows fails when basedir has space in it +- fixed SF# 2864380: Memory leak when using secure sockets +- NetSSL_OpenSSL: the SSL/TLS session cache is now disabled by default and + can be enabled per Context using Poco::Net::Context::enableSessionCache(). Release 1.3.5 (2009-05-11) @@ -1131,4 +1134,4 @@ building the libraries. -- -$Id: //poco/1.3/dist/CHANGELOG#59 $ +$Id: //poco/1.3/dist/CHANGELOG#60 $ diff --git a/Crypto/src/X509Certificate.cpp b/Crypto/src/X509Certificate.cpp index f9b6da551..9a7bdb978 100644 --- a/Crypto/src/X509Certificate.cpp +++ b/Crypto/src/X509Certificate.cpp @@ -1,7 +1,7 @@ // // X509Certificate.cpp // -// $Id: //poco/1.3/Crypto/src/X509Certificate.cpp#4 $ +// $Id: //poco/1.3/Crypto/src/X509Certificate.cpp#5 $ // // Library: Crypto // Package: Certificate @@ -67,8 +67,7 @@ X509Certificate::X509Certificate(X509* pCert): _pCert(pCert) { poco_check_ptr(_pCert); - - _pCert = X509_dup(_pCert); + init(); } diff --git a/NetSSL_OpenSSL/include/Poco/Net/Context.h b/NetSSL_OpenSSL/include/Poco/Net/Context.h index 6b07c1642..884191e86 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/Context.h +++ b/NetSSL_OpenSSL/include/Poco/Net/Context.h @@ -1,7 +1,7 @@ // // Context.h // -// $Id: //poco/1.3/NetSSL_OpenSSL/include/Poco/Net/Context.h#6 $ +// $Id: //poco/1.3/NetSSL_OpenSSL/include/Poco/Net/Context.h#7 $ // // Library: NetSSL_OpenSSL // Package: SSLCore @@ -140,6 +140,14 @@ public: Context::VerificationMode verificationMode() const; /// Returns the verification mode. + + void enableSessionCache(bool flag = true); + /// Enable or disable the SSL/TLS session cache for a server. + /// + /// The default is a disabled session cache. + + bool sessionCacheEnabled() const; + /// Returns true iff the session cache is enabled. private: Usage _usage; diff --git a/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h b/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h index 2d1cb541c..5572ceab8 100644 --- a/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h +++ b/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h @@ -1,7 +1,7 @@ // // SSLManager.h // -// $Id: //poco/1.3/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h#3 $ +// $Id: //poco/1.3/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h#4 $ // // Library: NetSSL_OpenSSL // Package: SSLCore @@ -48,6 +48,7 @@ #include "Poco/Net/InvalidCertificateHandler.h" #include "Poco/BasicEvent.h" #include "Poco/SharedPtr.h" +#include "Poco/Mutex.h" #include @@ -68,8 +69,8 @@ class NetSSL_API SSLManager /// or any of the passPhraseHandler methods (which tries to auto-initialize /// the context and passphrase handler based on an Poco::Util::Application configuration). /// - /// An exemplary documentation which sets either the server or client defaultcontext and creates a PrivateKeyPassphraseHandler - /// that reads the password from the XML file looks like this: + /// An exemplary documentation which sets either the server or client default context and creates + /// a PrivateKeyPassphraseHandler that reads the password from the XML file looks like this: /// /// /// @@ -92,6 +93,7 @@ class NetSSL_API SSLManager /// /// /// + /// true /// /// /// @@ -226,6 +228,7 @@ private: Context::Ptr _ptrDefaultClientContext; PrivateKeyPassphraseHandlerPtr _ptrClientPassPhraseHandler; InvalidCertificateHandlerPtr _ptrClientCertificateHandler; + Poco::FastMutex _mutex; static const std::string CFG_PRIV_KEY_FILE; static const std::string CFG_CERTIFICATE_FILE; @@ -242,6 +245,7 @@ private: static const std::string VAL_DELEGATE_HANDLER; static const std::string CFG_CERTIFICATE_HANDLER; static const std::string VAL_CERTIFICATE_HANDLER; + static const std::string CFG_CACHE_SESSIONS; friend class Poco::SingletonHolder; friend class Context; diff --git a/NetSSL_OpenSSL/src/Context.cpp b/NetSSL_OpenSSL/src/Context.cpp index 8f1a81744..bddf76be1 100644 --- a/NetSSL_OpenSSL/src/Context.cpp +++ b/NetSSL_OpenSSL/src/Context.cpp @@ -1,7 +1,7 @@ // // Context.cpp // -// $Id: //poco/1.3/NetSSL_OpenSSL/src/Context.cpp#7 $ +// $Id: //poco/1.3/NetSSL_OpenSSL/src/Context.cpp#8 $ // // Library: NetSSL_OpenSSL // Package: SSLCore @@ -71,6 +71,7 @@ Context::Context( } SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPasswdCallback); Utility::clearErrorStack(); + SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL); int errCode = 0; if (!caLocation.empty()) @@ -109,7 +110,7 @@ Context::Context( throw SSLContextException(std::string("Error loading private key from file ") + privateKeyFile, msg); } } - + if (!certificateFile.empty()) { errCode = SSL_CTX_use_certificate_chain_file(_pSSLContext, Poco::Path::transcode(certificateFile).c_str()); @@ -128,6 +129,7 @@ Context::Context( SSL_CTX_set_verify_depth(_pSSLContext, verificationDepth); SSL_CTX_set_mode(_pSSLContext, SSL_MODE_AUTO_RETRY); + SSL_CTX_set_session_cache_mode(_pSSLContext, SSL_SESS_CACHE_OFF); } @@ -137,4 +139,16 @@ Context::~Context() } +void Context::enableSessionCache(bool flag) +{ + SSL_CTX_set_session_cache_mode(_pSSLContext, flag ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_OFF); +} + + +bool Context::sessionCacheEnabled() const +{ + return SSL_CTX_get_session_cache_mode(_pSSLContext) != SSL_SESS_CACHE_OFF; +} + + } } // namespace Poco::Net diff --git a/NetSSL_OpenSSL/src/SSLManager.cpp b/NetSSL_OpenSSL/src/SSLManager.cpp index 575d94a4c..fe00fcf88 100644 --- a/NetSSL_OpenSSL/src/SSLManager.cpp +++ b/NetSSL_OpenSSL/src/SSLManager.cpp @@ -1,7 +1,7 @@ // // SSLManager.cpp // -// $Id: //poco/1.3/NetSSL_OpenSSL/src/SSLManager.cpp#5 $ +// $Id: //poco/1.3/NetSSL_OpenSSL/src/SSLManager.cpp#6 $ // // Library: NetSSL_OpenSSL // Package: SSLCore @@ -68,6 +68,7 @@ const std::string SSLManager::CFG_CERTIFICATE_HANDLER("invalidCertificateHandler const std::string SSLManager::VAL_CERTIFICATE_HANDLER("ConsoleCertificateHandler"); const std::string SSLManager::CFG_SERVER_PREFIX("openSSL.server."); const std::string SSLManager::CFG_CLIENT_PREFIX("openSSL.client."); +const std::string SSLManager::CFG_CACHE_SESSIONS("cacheSessions"); SSLManager::SSLManager() @@ -112,6 +113,8 @@ void SSLManager::initializeClient(PrivateKeyPassphraseHandlerPtr ptrPassPhraseHa Context::Ptr SSLManager::defaultServerContext() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrDefaultServerContext) initDefaultContext(true); @@ -121,6 +124,8 @@ Context::Ptr SSLManager::defaultServerContext() Context::Ptr SSLManager::defaultClientContext() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrDefaultClientContext) initDefaultContext(false); @@ -130,6 +135,8 @@ Context::Ptr SSLManager::defaultClientContext() SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::serverPassPhraseHandler() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrServerPassPhraseHandler) initPassPhraseHandler(true); @@ -139,6 +146,8 @@ SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::serverPassPhraseHandler() SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::clientPassPhraseHandler() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrClientPassPhraseHandler) initPassPhraseHandler(false); @@ -148,6 +157,8 @@ SSLManager::PrivateKeyPassphraseHandlerPtr SSLManager::clientPassPhraseHandler() SSLManager::InvalidCertificateHandlerPtr SSLManager::serverCertificateHandler() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrServerCertificateHandler) initCertificateHandler(true); @@ -157,6 +168,8 @@ SSLManager::InvalidCertificateHandlerPtr SSLManager::serverCertificateHandler() SSLManager::InvalidCertificateHandlerPtr SSLManager::clientCertificateHandler() { + Poco::FastMutex::ScopedLock lock(_mutex); + if (!_ptrClientCertificateHandler) initCertificateHandler(false); @@ -233,6 +246,12 @@ void SSLManager::initDefaultContext(bool server) _ptrDefaultServerContext = new Context(Context::SERVER_USE, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cypherList); else _ptrDefaultClientContext = new Context(Context::CLIENT_USE, privKeyFile, certFile, caLocation, verMode, verDepth, loadDefCA, cypherList); + + if (server) + { + bool cacheSessions = config.getBool(prefix + CFG_CACHE_SESSIONS, false); + _ptrDefaultServerContext->enableSessionCache(cacheSessions); + } }