diff options
author | Gabriel Marks <gabriel.marks@mongodb.com> | 2020-07-15 21:23:18 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-07-27 18:08:33 +0000 |
commit | eeb2dfac9a55dd495c9c1a85a3096b9f4fad9e4b (patch) | |
tree | 60b89bd8e93eb82a94117e9cc6b42f747aa44b48 /src/mongo/transport | |
parent | c1f940d3d2d65fabfb1a4b536aeaff58d6e0ec53 (diff) | |
download | mongo-eeb2dfac9a55dd495c9c1a85a3096b9f4fad9e4b.tar.gz |
SERVER-49134 Implement rotate for Windows
Diffstat (limited to 'src/mongo/transport')
-rw-r--r-- | src/mongo/transport/session_asio.h | 19 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer.h | 5 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.cpp | 85 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_asio.h | 13 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_manager.cpp | 13 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_manager.h | 4 | ||||
-rw-r--r-- | src/mongo/transport/transport_layer_mock.h | 7 |
7 files changed, 91 insertions, 55 deletions
diff --git a/src/mongo/transport/session_asio.h b/src/mongo/transport/session_asio.h index e2590153b9f..315cef28975 100644 --- a/src/mongo/transport/session_asio.h +++ b/src/mongo/transport/session_asio.h @@ -110,7 +110,7 @@ public: _local = HostAndPort(_localAddr.toString(true)); _remote = HostAndPort(_remoteAddr.toString(true)); #ifdef MONGO_CONFIG_SSL - _sslManager = tl->getSSLManager(); + _sslContext = *tl->_sslContext; #endif } catch (const DBException&) { throw; @@ -246,14 +246,14 @@ public: #ifdef MONGO_CONFIG_SSL const SSLConfiguration* getSSLConfiguration() const override { - if (_sslManager) { - return &_sslManager->getSSLConfiguration(); + if (_sslContext->manager) { + return &_sslContext->manager->getSSLConfiguration(); } return nullptr; } const std::shared_ptr<SSLManagerInterface> getSSLManager() const override { - return _sslManager; + return _sslContext->manager; } #endif @@ -267,13 +267,12 @@ protected: Future<void> handshakeSSLForEgressWithLock(stdx::unique_lock<Latch> lk, const HostAndPort& target, const ReactorHandle& reactor) { - if (!_tl->_egressSSLContext) { + if (!_sslContext->egress) { return Future<void>::makeReady(Status(ErrorCodes::SSLHandshakeFailed, "SSL requested but SSL support is disabled")); } - _sslSocket.emplace( - std::move(_socket), *_tl->_egressSSLContext, removeFQDNRoot(target.host())); + _sslSocket.emplace(std::move(_socket), *_sslContext->egress, removeFQDNRoot(target.host())); lk.unlock(); auto doHandshake = [&] { @@ -677,7 +676,7 @@ private: // protocol message needs to be 0 or -1. Otherwise the connection is either sending // garbage or a TLS Hello packet which will be caught by the TLS handshake. if (responseTo != 0 && responseTo != -1) { - if (!_tl->_ingressSSLContext) { + if (!_sslContext->ingress) { return Future<bool>::makeReady( Status(ErrorCodes::SSLHandshakeFailed, "SSL handshake received but server is started without SSL support")); @@ -694,7 +693,7 @@ private: }); } - _sslSocket.emplace(std::move(_socket), *_tl->_ingressSSLContext, ""); + _sslSocket.emplace(std::move(_socket), *_sslContext->ingress, ""); auto doHandshake = [&] { if (_blockingMode == Sync) { std::error_code ec; @@ -799,7 +798,7 @@ private: #ifdef MONGO_CONFIG_SSL boost::optional<asio::ssl::stream<decltype(_socket)>> _sslSocket; bool _ranHandshake = false; - std::shared_ptr<SSLManagerInterface> _sslManager; + std::shared_ptr<TransportLayerASIO::SSLConnectionContext> _sslContext; #endif TransportLayerASIO* const _tl; diff --git a/src/mongo/transport/transport_layer.h b/src/mongo/transport/transport_layer.h index 26c60be4905..cd171156ea2 100644 --- a/src/mongo/transport/transport_layer.h +++ b/src/mongo/transport/transport_layer.h @@ -119,6 +119,11 @@ public: return opCtx->getServiceContext()->makeBaton(opCtx); } +#ifdef MONGO_CONFIG_SSL + /** Rotate the in-use certificates for new connections. */ + virtual Status rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) = 0; +#endif + protected: TransportLayer() = default; }; diff --git a/src/mongo/transport/transport_layer_asio.cpp b/src/mongo/transport/transport_layer_asio.cpp index 5439c9c2d12..698125c111d 100644 --- a/src/mongo/transport/transport_layer_asio.cpp +++ b/src/mongo/transport/transport_layer_asio.cpp @@ -262,13 +262,8 @@ TransportLayerASIO::TransportLayerASIO(const TransportLayerASIO::Options& opts, : _ingressReactor(std::make_shared<ASIOReactor>()), _egressReactor(std::make_shared<ASIOReactor>()), _acceptorReactor(std::make_shared<ASIOReactor>()), -#ifdef MONGO_CONFIG_SSL - _ingressSSLContext(nullptr), - _egressSSLContext(nullptr), -#endif _sep(sep), - _listenerOptions(opts) { -} + _listenerOptions(opts) {} TransportLayerASIO::~TransportLayerASIO() = default; @@ -858,11 +853,6 @@ Status validateFastOpenOnce() noexcept { } // namespace Status TransportLayerASIO::setup() { -#ifdef MONGO_CONFIG_SSL - if (SSLManagerCoordinator::get()) { - _sslManager = SSLManagerCoordinator::get()->getSSLManager(); - } -#endif std::vector<std::string> listenAddrs; if (_listenerOptions.ipList.empty() && _listenerOptions.isIngress()) { listenAddrs = {"127.0.0.1"}; @@ -1008,37 +998,11 @@ Status TransportLayerASIO::setup() { } #ifdef MONGO_CONFIG_SSL - const auto& sslParams = getSSLGlobalParams(); - - if (_sslMode() != SSLParams::SSLMode_disabled && _listenerOptions.isIngress()) { - _ingressSSLContext = std::make_unique<asio::ssl::context>(asio::ssl::context::sslv23); - - Status status = - _sslManager->initSSLContext(_ingressSSLContext->native_handle(), - sslParams, - SSLManagerInterface::ConnectionDirection::kIncoming); - if (!status.isOK()) { - return status; - } - - auto resp = _sslManager->stapleOCSPResponse(_ingressSSLContext->native_handle()); - if (!resp.isOK()) { - return Status(ErrorCodes::InvalidSSLConfiguration, - str::stream() - << "Can not staple OCSP Response. Reason: " << resp.reason()); - } - } - - if (_listenerOptions.isEgress() && _sslManager) { - _egressSSLContext = std::make_unique<asio::ssl::context>(asio::ssl::context::sslv23); - Status status = - _sslManager->initSSLContext(_egressSSLContext->native_handle(), - sslParams, - SSLManagerInterface::ConnectionDirection::kOutgoing); - if (!status.isOK()) { - return status; - } + std::shared_ptr<SSLManagerInterface> manager = nullptr; + if (SSLManagerCoordinator::get()) { + manager = SSLManagerCoordinator::get()->getSSLManager(); } + return rotateCertificates(manager); #endif return Status::OK(); @@ -1215,6 +1179,45 @@ void TransportLayerASIO::_acceptConnection(GenericAcceptor& acceptor) { SSLParams::SSLModes TransportLayerASIO::_sslMode() const { return static_cast<SSLParams::SSLModes>(getSSLGlobalParams().sslMode.load()); } + +Status TransportLayerASIO::rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) { + auto newSSLContext = std::make_shared<SSLConnectionContext>(); + newSSLContext->manager = manager; + const auto& sslParams = getSSLGlobalParams(); + + if (_sslMode() != SSLParams::SSLMode_disabled && _listenerOptions.isIngress()) { + newSSLContext->ingress = std::make_unique<asio::ssl::context>(asio::ssl::context::sslv23); + + Status status = newSSLContext->manager->initSSLContext( + newSSLContext->ingress->native_handle(), + sslParams, + SSLManagerInterface::ConnectionDirection::kIncoming); + if (!status.isOK()) { + return status; + } + + auto resp = + newSSLContext->manager->stapleOCSPResponse(newSSLContext->ingress->native_handle()); + if (!resp.isOK()) { + return Status(ErrorCodes::InvalidSSLConfiguration, + str::stream() + << "Can not staple OCSP Response. Reason: " << resp.reason()); + } + } + + if (_listenerOptions.isEgress() && newSSLContext->manager) { + newSSLContext->egress = std::make_unique<asio::ssl::context>(asio::ssl::context::sslv23); + Status status = newSSLContext->manager->initSSLContext( + newSSLContext->egress->native_handle(), + sslParams, + SSLManagerInterface::ConnectionDirection::kOutgoing); + if (!status.isOK()) { + return status; + } + } + _sslContext = std::move(newSSLContext); + return Status::OK(); +} #endif #ifdef __linux__ diff --git a/src/mongo/transport/transport_layer_asio.h b/src/mongo/transport/transport_layer_asio.h index d23c5b89483..ddbc6b2d5f5 100644 --- a/src/mongo/transport/transport_layer_asio.h +++ b/src/mongo/transport/transport_layer_asio.h @@ -144,8 +144,10 @@ public: #endif #ifdef MONGO_CONFIG_SSL + Status rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) override; + std::shared_ptr<SSLManagerInterface> getSSLManager() { - return _sslManager; + return _sslContext.get()->manager; } #endif @@ -200,9 +202,12 @@ private: std::shared_ptr<ASIOReactor> _acceptorReactor; #ifdef MONGO_CONFIG_SSL - std::unique_ptr<asio::ssl::context> _ingressSSLContext; - std::unique_ptr<asio::ssl::context> _egressSSLContext; - std::shared_ptr<SSLManagerInterface> _sslManager; + struct SSLConnectionContext { + std::unique_ptr<asio::ssl::context> ingress; + std::unique_ptr<asio::ssl::context> egress; + std::shared_ptr<SSLManagerInterface> manager; + }; + synchronized_value<std::shared_ptr<SSLConnectionContext>> _sslContext; #endif std::vector<std::pair<SockAddr, GenericAcceptor>> _acceptors; diff --git a/src/mongo/transport/transport_layer_manager.cpp b/src/mongo/transport/transport_layer_manager.cpp index 2f7508e5c1a..3db4912e2df 100644 --- a/src/mongo/transport/transport_layer_manager.cpp +++ b/src/mongo/transport/transport_layer_manager.cpp @@ -38,6 +38,7 @@ #include <memory> #include "mongo/base/status.h" +#include "mongo/config.h" #include "mongo/db/server_options.h" #include "mongo/db/service_context.h" #include "mongo/logv2/log.h" @@ -144,5 +145,17 @@ std::unique_ptr<TransportLayer> TransportLayerManager::createWithConfig( return std::make_unique<TransportLayerManager>(std::move(retVector)); } +#ifdef MONGO_CONFIG_SSL +Status TransportLayerManager::rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) { + for (auto&& tl : _tls) { + auto status = tl->rotateCertificates(manager); + if (!status.isOK()) { + return status; + } + } + return Status::OK(); +} +#endif + } // namespace transport } // namespace mongo diff --git a/src/mongo/transport/transport_layer_manager.h b/src/mongo/transport/transport_layer_manager.h index 8da53951276..0bce30d46f2 100644 --- a/src/mongo/transport/transport_layer_manager.h +++ b/src/mongo/transport/transport_layer_manager.h @@ -32,6 +32,7 @@ #include <vector> #include "mongo/base/status.h" +#include "mongo/config.h" #include "mongo/platform/mutex.h" #include "mongo/transport/session.h" #include "mongo/transport/transport_layer.h" @@ -98,6 +99,9 @@ public: return _tls[0]->makeBaton(opCtx); } +#ifdef MONGO_CONFIG_SSL + Status rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) override; +#endif private: template <typename Callable> void _foreach(Callable&& cb) const; diff --git a/src/mongo/transport/transport_layer_mock.h b/src/mongo/transport/transport_layer_mock.h index 8d38a4c4ef5..4f234f9734a 100644 --- a/src/mongo/transport/transport_layer_mock.h +++ b/src/mongo/transport/transport_layer_mock.h @@ -30,6 +30,7 @@ #pragma once #include "mongo/base/status.h" +#include "mongo/config.h" #include "mongo/stdx/unordered_map.h" #include "mongo/transport/session.h" #include "mongo/transport/transport_layer.h" @@ -74,6 +75,12 @@ public: // Set to a factory function to use your own session type. std::function<SessionHandle(TransportLayer*)> createSessionHook; +#ifdef MONGO_CONFIG_SSL + Status rotateCertificates(std::shared_ptr<SSLManagerInterface> manager) override { + return Status::OK(); + } +#endif + private: friend class MockSession; |