diff --git a/system/security/securesocket/securesocket.cpp b/system/security/securesocket/securesocket.cpp index 9f445e0cc5e..465184a41ef 100644 --- a/system/security/securesocket/securesocket.cpp +++ b/system/security/securesocket/securesocket.cpp @@ -1271,6 +1271,7 @@ static bool setVerifyCertsPEMBuffer(SSL_CTX *ctx, const char *caCertBuf, int caC class CSecureSocketContext : public CInterfaceOf { private: + SecureSocketType sockettype; OwnedSSLCTX m_ctx; #if (OPENSSL_VERSION_NUMBER > 0x00909000L) const SSL_METHOD* m_meth = nullptr; @@ -1282,6 +1283,9 @@ class CSecureSocketContext : public CInterfaceOf bool m_address_match = false; Owned m_peers; StringAttr password; + CriticalSection cs; + Owned syncedConfig; + unsigned configVersion = 0; void setSessionIdContext() { @@ -1352,8 +1356,7 @@ class CSecureSocketContext : public CInterfaceOf throw makeStringExceptionV(-1, "Error loading CA certificates from %s", caCertsPathOrBuf); } -public: - CSecureSocketContext(const IPropertyTree* config, SecureSocketType sockettype) + void createNewContext(const IPropertyTree* config) { initContext(sockettype); @@ -1444,13 +1447,49 @@ class CSecureSocketContext : public CInterfaceOf SSL_CTX_set_mode(m_ctx, SSL_CTX_get_mode(m_ctx) | SSL_MODE_AUTO_RETRY); } + void checkForUpdatedContext() + { + //Check if a new context should be created - it must be called within a critical section + if (syncedConfig) + { + unsigned activeVersion = syncedConfig->getVersion(); + if (activeVersion != configVersion) + { + configVersion = activeVersion; + Owned config = syncedConfig->getTree(); + createNewContext(config); + } + } + } + +public: + CSecureSocketContext(const IPropertyTree* config, SecureSocketType _sockettype) : sockettype(_sockettype) + { + createNewContext(config); + } + + CSecureSocketContext(const ISyncedPropertyTree* _syncedConfig, SecureSocketType _sockettype) : syncedConfig(_syncedConfig), sockettype(_sockettype) + { + Owned config; + if (syncedConfig) + { + configVersion = syncedConfig->getVersion(); + config.setown(syncedConfig->getTree()); + } + createNewContext(config); + } + ISecureSocket* createSecureSocket(ISocket* sock, int loglevel, const char *fqdn) { + CriticalBlock block(cs); + checkForUpdatedContext(); return new CSecureSocket(sock, m_ctx, m_verify, m_address_match, m_peers, loglevel, fqdn); } ISecureSocket* createSecureSocket(int sockfd, int loglevel, const char *fqdn) { + CriticalBlock block(cs); + checkForUpdatedContext(); return new CSecureSocket(sockfd, m_ctx, m_verify, m_address_match, m_peers, loglevel, fqdn); } }; @@ -1939,14 +1978,12 @@ extern "C" { SECURESOCKET_API ISecureSocketContext* createSecureSocketContext(SecureSocketType sockettype) { - return new securesocket::CSecureSocketContext(nullptr, sockettype); + return new securesocket::CSecureSocketContext((ISyncedPropertyTree *)nullptr, sockettype); } SECURESOCKET_API ISecureSocketContext* createSecureSocketContextSynced(const ISyncedPropertyTree * config, SecureSocketType sockettype) { - //Temporary workaround - change the implementation of CSecureSocketContext to only take an ISyncedPropertyTree instead - Owned configTree(config ? config->getTree() : nullptr); - return new securesocket::CSecureSocketContext(configTree, sockettype); + return new securesocket::CSecureSocketContext(config, sockettype); }