summaryrefslogtreecommitdiff
path: root/src/mongo/transport
diff options
context:
space:
mode:
authorGabriel Marks <gabriel.marks@mongodb.com>2020-07-15 21:23:18 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-27 18:08:33 +0000
commiteeb2dfac9a55dd495c9c1a85a3096b9f4fad9e4b (patch)
tree60b89bd8e93eb82a94117e9cc6b42f747aa44b48 /src/mongo/transport
parentc1f940d3d2d65fabfb1a4b536aeaff58d6e0ec53 (diff)
downloadmongo-eeb2dfac9a55dd495c9c1a85a3096b9f4fad9e4b.tar.gz
SERVER-49134 Implement rotate for Windows
Diffstat (limited to 'src/mongo/transport')
-rw-r--r--src/mongo/transport/session_asio.h19
-rw-r--r--src/mongo/transport/transport_layer.h5
-rw-r--r--src/mongo/transport/transport_layer_asio.cpp85
-rw-r--r--src/mongo/transport/transport_layer_asio.h13
-rw-r--r--src/mongo/transport/transport_layer_manager.cpp13
-rw-r--r--src/mongo/transport/transport_layer_manager.h4
-rw-r--r--src/mongo/transport/transport_layer_mock.h7
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;