diff options
author | Adam Cooper <adam.cooper@mongodb.com> | 2020-11-16 17:33:06 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-03-15 16:10:09 +0000 |
commit | c70cdd4dab05881bec7fa150c96d1a9034e3ad50 (patch) | |
tree | 3da0ada5b1790b32ea1ea59e9d939bcbd37a617e | |
parent | 5913bb654dfebaff81c19c775dda88fedbba3ee9 (diff) | |
download | mongo-c70cdd4dab05881bec7fa150c96d1a9034e3ad50.tar.gz |
SERVER-52648 Refactor kms_aws.cpp into kms_aws.cpp and kms_network.cpp
This commit fixes the build failure on Windows which was introduced by the original commit on November 13th, 2020.
(cherry picked from commit 96ced1dddcb87b0bc7bafc40094d9014c04edd98)
-rw-r--r-- | src/mongo/shell/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/shell/kms_aws.cpp | 108 | ||||
-rw-r--r-- | src/mongo/shell/kms_network.cpp | 116 | ||||
-rw-r--r-- | src/mongo/shell/kms_network.h | 68 |
4 files changed, 189 insertions, 104 deletions
diff --git a/src/mongo/shell/SConscript b/src/mongo/shell/SConscript index 317b146e0c6..ad982a415b4 100644 --- a/src/mongo/shell/SConscript +++ b/src/mongo/shell/SConscript @@ -142,6 +142,7 @@ kmsEnv.Library( "kms.cpp", "kms_aws.cpp", "kms_local.cpp", + "kms_network.cpp", "kms.idl", ], LIBDEPS=[ diff --git a/src/mongo/shell/kms_aws.cpp b/src/mongo/shell/kms_aws.cpp index 120613d7538..629adc247dc 100644 --- a/src/mongo/shell/kms_aws.cpp +++ b/src/mongo/shell/kms_aws.cpp @@ -38,13 +38,12 @@ #include "mongo/base/secure_allocator.h" #include "mongo/base/status_with.h" #include "mongo/bson/json.h" -#include "mongo/db/commands/test_commands_enabled.h" #include "mongo/shell/kms.h" #include "mongo/shell/kms_gen.h" +#include "mongo/shell/kms_network.h" #include "mongo/util/base64.h" #include "mongo/util/kms_message_support.h" #include "mongo/util/net/hostandport.h" -#include "mongo/util/net/sock.h" #include "mongo/util/net/ssl_manager.h" #include "mongo/util/net/ssl_options.h" #include "mongo/util/text.h" @@ -54,31 +53,6 @@ namespace mongo { namespace { /** - * Make a request to a AWS HTTP endpoint. - * - * Does not maintain a persistent HTTP connection. - */ -class AWSConnection { -public: - AWSConnection(SSLManagerInterface* ssl) - : _sslManager(ssl), _socket(std::make_unique<Socket>(10, logv2::LogSeverity::Info())) {} - - UniqueKmsResponse makeOneRequest(const HostAndPort& host, ConstDataRange request); - -private: - UniqueKmsResponse sendRequest(ConstDataRange request); - - void connect(const HostAndPort& host); - -private: - // SSL Manager for connections - SSLManagerInterface* _sslManager; - - // Synchronous socket - std::unique_ptr<Socket> _socket; -}; - -/** * AWS configuration settings */ struct AWSConfig { @@ -208,7 +182,7 @@ std::vector<uint8_t> AWSKMSService::encrypt(ConstDataRange cdr, StringData kmsKe auto buffer = UniqueKmsCharBuffer(kms_request_get_signed(request.get())); auto buffer_len = strlen(buffer.get()); - AWSConnection connection(_sslManager.get()); + KMSNetworkConnection connection(_sslManager.get()); auto response = connection.makeOneRequest(_server, ConstDataRange(buffer.get(), buffer_len)); auto body = kms_response_get_body(response.get(), nullptr); @@ -268,7 +242,7 @@ SecureVector<uint8_t> AWSKMSService::decrypt(ConstDataRange cdr, BSONObj masterK auto buffer = UniqueKmsCharBuffer(kms_request_get_signed(request.get())); auto buffer_len = strlen(buffer.get()); - AWSConnection connection(_sslManager.get()); + KMSNetworkConnection connection(_sslManager.get()); auto response = connection.makeOneRequest(_server, ConstDataRange(buffer.get(), buffer_len)); auto body = kms_response_get_body(response.get(), nullptr); @@ -299,64 +273,6 @@ SecureVector<uint8_t> AWSKMSService::decrypt(ConstDataRange cdr, BSONObj masterK return toSecureVector(blobStr); } -void AWSConnection::connect(const HostAndPort& host) { - SockAddr server(host.host().c_str(), host.port(), AF_UNSPEC); - - uassert(51136, - str::stream() << "AWS KMS server address " << host.host() << " is invalid.", - server.isValid()); - - int attempt = 0; - bool connected = false; - while ((connected == false) && (attempt < 20)) { - connected = _socket->connect(server); - attempt++; - } - uassert(51137, - str::stream() << "Could not connect to AWS KMS server " << server.toString(), - connected); - - uassert(51138, - str::stream() << "Failed to perform SSL handshake with the AWS KMS server " - << host.toString(), - _socket->secure(_sslManager, host.host())); -} - -// Sends a request message to the AWS KMS server and creates a KMS Response. -UniqueKmsResponse AWSConnection::sendRequest(ConstDataRange request) { - std::array<char, 512> resp; - - _socket->send( - reinterpret_cast<const char*>(request.data()), request.length(), "AWS KMS request"); - - auto parser = UniqueKmsResponseParser(kms_response_parser_new()); - int bytes_to_read = 0; - - while ((bytes_to_read = kms_response_parser_wants_bytes(parser.get(), resp.size())) > 0) { - bytes_to_read = std::min(bytes_to_read, static_cast<int>(resp.size())); - bytes_to_read = _socket->unsafe_recv(resp.data(), bytes_to_read); - - uassert(51139, - "kms_response_parser_feed failed", - kms_response_parser_feed( - parser.get(), reinterpret_cast<uint8_t*>(resp.data()), bytes_to_read)); - } - - auto response = UniqueKmsResponse(kms_response_parser_get_response(parser.get())); - - return response; -} - -UniqueKmsResponse AWSConnection::makeOneRequest(const HostAndPort& host, ConstDataRange request) { - connect(host); - - auto resp = sendRequest(request); - - _socket->close(); - - return resp; -} - boost::optional<std::string> toString(boost::optional<StringData> str) { if (str) { return {str.get().toString()}; @@ -368,23 +284,7 @@ std::unique_ptr<KMSService> AWSKMSService::create(const AwsKMS& config) { auto awsKMS = std::make_unique<AWSKMSService>(); SSLParams params; - params.sslPEMKeyFile = ""; - params.sslPEMKeyPassword = ""; - params.sslClusterFile = ""; - params.sslClusterPassword = ""; - params.sslCAFile = ""; - - params.sslCRLFile = ""; - - // Copy the rest from the global SSL manager options. - params.sslFIPSMode = sslGlobalParams.sslFIPSMode; - - // KMS servers never should have invalid certificates - params.sslAllowInvalidCertificates = false; - params.sslAllowInvalidHostnames = false; - - params.sslDisabledProtocols = - std::vector({SSLParams::Protocols::TLS1_0, SSLParams::Protocols::TLS1_1}); + getSSLParamsForNetworkKMS(¶ms); // Leave the CA file empty so we default to system CA but for local testing allow it to inherit // the CA file. diff --git a/src/mongo/shell/kms_network.cpp b/src/mongo/shell/kms_network.cpp new file mode 100644 index 00000000000..b68a32af112 --- /dev/null +++ b/src/mongo/shell/kms_network.cpp @@ -0,0 +1,116 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kControl + +#include "mongo/platform/basic.h" + +#include "mongo/shell/kms_network.h" + +namespace mongo { + +void KMSNetworkConnection::connect(const HostAndPort& host) { + SockAddr server(host.host().c_str(), host.port(), AF_UNSPEC); + + uassert(51136, + str::stream() << "KMS server address " << host.host() << " is invalid.", + server.isValid()); + + int attempt = 0; + bool connected = false; + while (!connected && attempt < 20) { + connected = _socket->connect(server); + attempt++; + } + uassert( + 51137, str::stream() << "Could not connect to KMS server " << server.toString(), connected); + + uassert(51138, + str::stream() << "Failed to perform SSL handshake with the KMS server " + << host.toString(), + _socket->secure(_sslManager, host.host())); +} + +// Sends a request message to the KMS server and creates a KMS Response. +UniqueKmsResponse KMSNetworkConnection::sendRequest(ConstDataRange request) { + std::array<char, 512> resp; + + _socket->send(reinterpret_cast<const char*>(request.data()), request.length(), "KMS request"); + + auto parser = UniqueKmsResponseParser(kms_response_parser_new()); + int bytes_to_read = 0; + + while ((bytes_to_read = kms_response_parser_wants_bytes(parser.get(), resp.size())) > 0) { + bytes_to_read = std::min(bytes_to_read, static_cast<int>(resp.size())); + bytes_to_read = _socket->unsafe_recv(resp.data(), bytes_to_read); + + uassert(51139, + "kms_response_parser_feed failed", + kms_response_parser_feed( + parser.get(), reinterpret_cast<uint8_t*>(resp.data()), bytes_to_read)); + } + + auto response = UniqueKmsResponse(kms_response_parser_get_response(parser.get())); + + return response; +} + +UniqueKmsResponse KMSNetworkConnection::makeOneRequest(const HostAndPort& host, + ConstDataRange request) { + connect(host); + + auto resp = sendRequest(request); + + _socket->close(); + + return resp; +} + +void getSSLParamsForNetworkKMS(SSLParams* params) { + params->sslPEMKeyFile = ""; + params->sslPEMKeyPassword = ""; + params->sslClusterFile = ""; + params->sslClusterPassword = ""; + params->sslCAFile = ""; + + params->sslCRLFile = ""; + + // Copy the rest from the global SSL manager options. + params->sslFIPSMode = sslGlobalParams.sslFIPSMode; + + // KMS servers never should have invalid certificates + params->sslAllowInvalidCertificates = false; + params->sslAllowInvalidHostnames = false; + + params->sslDisabledProtocols = + std::vector({SSLParams::Protocols::TLS1_0, SSLParams::Protocols::TLS1_1}); +} + + +} // namespace mongo
\ No newline at end of file diff --git a/src/mongo/shell/kms_network.h b/src/mongo/shell/kms_network.h new file mode 100644 index 00000000000..43e08fc9789 --- /dev/null +++ b/src/mongo/shell/kms_network.h @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2020-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#include "mongo/util/kms_message_support.h" +#include "mongo/util/net/hostandport.h" +#include "mongo/util/net/sock.h" +#include "mongo/util/net/ssl_manager.h" +#include "mongo/util/net/ssl_options.h" + +namespace mongo { + +/** + * Make a request to an HTTP endpoint. + * + * Does not maintain a persistent HTTP connection. + */ +class KMSNetworkConnection { +public: + KMSNetworkConnection(SSLManagerInterface* ssl) + : _sslManager(ssl), _socket(std::make_unique<Socket>(10, logv2::LogSeverity::Info())) {} + + UniqueKmsResponse makeOneRequest(const HostAndPort& host, ConstDataRange request); + +private: + UniqueKmsResponse sendRequest(ConstDataRange request); + + void connect(const HostAndPort& host); + +private: + // SSL Manager for connections + SSLManagerInterface* _sslManager; + + // Synchronous socket + std::unique_ptr<Socket> _socket; +}; + +/** + * Creates an initial SSLParams object for KMS over the network. + */ +void getSSLParamsForNetworkKMS(SSLParams*); + +} // namespace mongo |