diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2018-09-17 18:31:30 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-12-10 19:19:41 -0500 |
commit | 6e6ee2948919f59d27fa9aec46cbc3294c700991 (patch) | |
tree | c0cac60e40917e6a9fad594f22f7c3ccce7b9a42 | |
parent | e3e09931fe23c694f220df3f60a75d28ed549530 (diff) | |
download | mongo-6e6ee2948919f59d27fa9aec46cbc3294c700991.tar.gz |
SERVER-36250 Add support for optionally logging specific negotiated TLS versions
(cherry picked from commit 573f92bd3567a70f2b6bdc8295a9d230dec1cf04)
-rw-r--r-- | jstests/ssl/ssl_count_protocols.js | 22 | ||||
-rw-r--r-- | src/mongo/executor/async_secure_stream.cpp | 11 | ||||
-rw-r--r-- | src/mongo/executor/async_secure_stream.h | 3 | ||||
-rw-r--r-- | src/mongo/util/net/SConscript | 14 | ||||
-rw-r--r-- | src/mongo/util/net/asio_message_port.cpp | 8 | ||||
-rw-r--r-- | src/mongo/util/net/sock.cpp | 5 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 82 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.h | 30 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.cpp | 42 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.h | 1 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options_test.cpp | 272 |
11 files changed, 456 insertions, 34 deletions
diff --git a/jstests/ssl/ssl_count_protocols.js b/jstests/ssl/ssl_count_protocols.js index b19268a01ba..6ecc01bb1b6 100644 --- a/jstests/ssl/ssl_count_protocols.js +++ b/jstests/ssl/ssl_count_protocols.js @@ -22,6 +22,8 @@ sslMode: 'allowSSL', sslPEMKeyFile: SERVER_CERT, sslDisabledProtocols: 'none', + useLogFiles: true, + tlsLogVersions: "TLS1_0,TLS1_1,TLS1_2", }); print(disabledProtocols); @@ -50,6 +52,26 @@ assert.eq(0, exitStatus, ""); + print(`Checking ${conn.fullOptions.logFile} for TLS version message`); + const log = cat(conn.fullOptions.logFile); + + // Find the last line in the log file and verify it has the right version + let re = /Accepted connection with TLS Version (1\.\d) from connection 127.0.0.1:\d+/g; + let result = re.exec(log); + let lastResult = null; + while (result !== null) { + lastResult = result; + result = re.exec(log); + } + + assert(lastResult !== null, + "'Accepted connection with TLS Version' log line missing in log file!\n" + + "Log file contents: " + conn.fullOptions.logFile + + "\n************************************************************\n" + log + + "\n************************************************************"); + + assert.eq(lastResult['1'], version_number); + MongoRunner.stopMongod(conn); } diff --git a/src/mongo/executor/async_secure_stream.cpp b/src/mongo/executor/async_secure_stream.cpp index a7c051bc34b..95f90469cfa 100644 --- a/src/mongo/executor/async_secure_stream.cpp +++ b/src/mongo/executor/async_secure_stream.cpp @@ -98,13 +98,16 @@ void AsyncSecureStream::_handleConnect(asio::ip::tcp::resolver::iterator iter) { if (ec) { return _userHandler(ec); } - return _handleHandshake(ec, iter->host_name()); + return _handleHandshake(ec, *iter); })); } -void AsyncSecureStream::_handleHandshake(std::error_code ec, const std::string& hostName) { - auto certStatus = - getSSLManager()->parseAndValidatePeerCertificate(_stream.native_handle(), hostName); +void AsyncSecureStream::_handleHandshake( + std::error_code ec, const asio::ip::basic_resolver_entry<asio::ip::tcp>& entry) { + auto certStatus = getSSLManager()->parseAndValidatePeerCertificate( + _stream.native_handle(), + entry.host_name(), + HostAndPort(entry.host_name(), entry.endpoint().port())); if (!certStatus.isOK()) { warning() << "Failed to validate peer certificate during SSL handshake: " << certStatus.getStatus(); diff --git a/src/mongo/executor/async_secure_stream.h b/src/mongo/executor/async_secure_stream.h index 6ea222e8a8d..f0d11b2b7db 100644 --- a/src/mongo/executor/async_secure_stream.h +++ b/src/mongo/executor/async_secure_stream.h @@ -60,7 +60,8 @@ public: private: void _handleConnect(asio::ip::tcp::resolver::iterator iter); - void _handleHandshake(std::error_code ec, const std::string& hostName); + void _handleHandshake(std::error_code ec, + const asio::ip::basic_resolver_entry<asio::ip::tcp>& entry); asio::io_service::strand* const _strand; asio::ssl::stream<asio::ip::tcp::socket> _stream; diff --git a/src/mongo/util/net/SConscript b/src/mongo/util/net/SConscript index d2647622471..194717b0d64 100644 --- a/src/mongo/util/net/SConscript +++ b/src/mongo/util/net/SConscript @@ -1,6 +1,7 @@ # -*- mode: python; -*- Import('env') +Import("has_option") env.Library( target='hostandport', @@ -94,6 +95,19 @@ env.CppUnitTest( ], ) +if has_option('ssl'): + env.CppUnitTest( + target='ssl_manager_test', + source=[ + 'ssl_options_test.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/server_options', + 'network', + ], + ) + env.Library( target='miniwebserver', source=[ diff --git a/src/mongo/util/net/asio_message_port.cpp b/src/mongo/util/net/asio_message_port.cpp index 19413c53435..5c569cb6fbc 100644 --- a/src/mongo/util/net/asio_message_port.cpp +++ b/src/mongo/util/net/asio_message_port.cpp @@ -384,8 +384,8 @@ bool ASIOMessagingPort::recv(Message& m) { throw asio::system_error(ec); } - auto swPeerInfo = - getSSLManager()->parseAndValidatePeerCertificate(_sslSock.native_handle(), ""); + auto swPeerInfo = getSSLManager()->parseAndValidatePeerCertificate( + _sslSock.native_handle(), "", _remote); if (!swPeerInfo.isOK()) { throw SocketException(SocketException::CONNECT_ERROR, swPeerInfo.getStatus().reason()); @@ -591,8 +591,8 @@ bool ASIOMessagingPort::secure(SSLManagerInterface* ssl, const std::string& remo return false; } - auto swPeerInfo = - getSSLManager()->parseAndValidatePeerCertificate(_sslSock.native_handle(), remoteHost); + auto swPeerInfo = getSSLManager()->parseAndValidatePeerCertificate( + _sslSock.native_handle(), remoteHost, _remote); if (!swPeerInfo.isOK()) { throw SocketException(SocketException::CONNECT_ERROR, swPeerInfo.getStatus().reason()); } diff --git a/src/mongo/util/net/sock.cpp b/src/mongo/util/net/sock.cpp index 457cd9d2bc8..22763c32b5d 100644 --- a/src/mongo/util/net/sock.cpp +++ b/src/mongo/util/net/sock.cpp @@ -397,7 +397,7 @@ bool Socket::secure(SSLManagerInterface* mgr, const std::string& remoteHost) { } _sslManager = mgr; _sslConnection.reset(_sslManager->connect(this)); - mgr->parseAndValidatePeerCertificateDeprecated(_sslConnection.get(), remoteHost); + mgr->parseAndValidatePeerCertificateDeprecated(_sslConnection.get(), remoteHost, HostAndPort()); return true; } @@ -415,7 +415,8 @@ SSLPeerInfo Socket::doSSLHandshake(const char* firstBytes, int len) { remoteString()); } _sslConnection.reset(_sslManager->accept(this, firstBytes, len)); - return _sslManager->parseAndValidatePeerCertificateDeprecated(_sslConnection.get(), ""); + return _sslManager->parseAndValidatePeerCertificateDeprecated( + _sslConnection.get(), "", HostAndPort(_remote.getAddr(), _remote.getPort())); } std::string Socket::getSNIServerName() const { diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index dd6e73c3e08..f4e0292ee31 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -301,11 +301,12 @@ public: virtual SSLConnection* accept(Socket* socket, const char* initialBytes, int len); - virtual SSLPeerInfo parseAndValidatePeerCertificateDeprecated(const SSLConnection* conn, - const std::string& remoteHost); + SSLPeerInfo parseAndValidatePeerCertificateDeprecated(const SSLConnection* conn, + const std::string& remoteHost, + const HostAndPort& hostForLogging) final; StatusWith<boost::optional<SSLPeerInfo>> parseAndValidatePeerCertificate( - SSL* conn, const std::string& remoteHost) final; + SSL* conn, const std::string& remoteHost, const HostAndPort& hostForLogging) final; virtual const SSLConfiguration& getSSLConfiguration() const { return _sslConfiguration; @@ -1387,35 +1388,34 @@ bool SSLManager::_hostNameMatch(const char* nameToMatch, const char* certHostNam } } -void recordTLSVersion(const SSL* conn) { +StatusWith<TLSVersion> mapTLSVersion(const SSL* conn) { int protocol = SSL_version(conn); - auto& counts = mongo::TLSVersionCounts::get(); switch (protocol) { case TLS1_VERSION: - counts.tls10.addAndFetch(1); - break; + return TLSVersion::kTLS10; case TLS1_1_VERSION: - counts.tls11.addAndFetch(1); - break; + return TLSVersion::kTLS11; case TLS1_2_VERSION: - counts.tls12.addAndFetch(1); - break; + return TLSVersion::kTLS12; #ifdef TLS1_3_VERSION case TLS1_3_VERSION: - counts.tls13.addAndFetch(1); - break; + return TLSVersion::kTLS13; #endif default: - // Do nothing - break; + return TLSVersion::kUnknown; } } StatusWith<boost::optional<SSLPeerInfo>> SSLManager::parseAndValidatePeerCertificate( - SSL* conn, const std::string& remoteHost) { + SSL* conn, const std::string& remoteHost, const HostAndPort& hostForLogging) { + + auto tlsVersionStatus = mapTLSVersion(conn); + if (!tlsVersionStatus.isOK()) { + return tlsVersionStatus.getStatus(); + } - recordTLSVersion(conn); + recordTLSVersion(tlsVersionStatus.getValue(), hostForLogging); if (!_sslConfiguration.hasCA && isSSLServer) return {boost::none}; @@ -1529,9 +1529,9 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManager::parseAndValidatePeerCertifi } -SSLPeerInfo SSLManager::parseAndValidatePeerCertificateDeprecated(const SSLConnection* conn, - const std::string& remoteHost) { - auto swPeerSubjectName = parseAndValidatePeerCertificate(conn->ssl, remoteHost); +SSLPeerInfo SSLManager::parseAndValidatePeerCertificateDeprecated( + const SSLConnection* conn, const std::string& remoteHost, const HostAndPort& hostForLogging) { + auto swPeerSubjectName = parseAndValidatePeerCertificate(conn->ssl, remoteHost, hostForLogging); // We can't use uassertStatusOK here because we need to throw a SocketException. if (!swPeerSubjectName.isOK()) { throw SocketException(SocketException::CONNECT_ERROR, @@ -1540,6 +1540,47 @@ SSLPeerInfo SSLManager::parseAndValidatePeerCertificateDeprecated(const SSLConne return swPeerSubjectName.getValue().get_value_or(SSLPeerInfo()); } +void recordTLSVersion(TLSVersion version, const HostAndPort& hostForLogging) { + StringData versionString; + auto& counts = mongo::TLSVersionCounts::get(); + switch (version) { + case TLSVersion::kTLS10: + counts.tls10.addAndFetch(1); + if (std::find(sslGlobalParams.tlsLogVersions.cbegin(), + sslGlobalParams.tlsLogVersions.cend(), + SSLParams::Protocols::TLS1_0) != sslGlobalParams.tlsLogVersions.cend()) { + versionString = "1.0"_sd; + } + break; + case TLSVersion::kTLS11: + counts.tls11.addAndFetch(1); + if (std::find(sslGlobalParams.tlsLogVersions.cbegin(), + sslGlobalParams.tlsLogVersions.cend(), + SSLParams::Protocols::TLS1_1) != sslGlobalParams.tlsLogVersions.cend()) { + versionString = "1.1"_sd; + } + break; + case TLSVersion::kTLS12: + counts.tls12.addAndFetch(1); + if (std::find(sslGlobalParams.tlsLogVersions.cbegin(), + sslGlobalParams.tlsLogVersions.cend(), + SSLParams::Protocols::TLS1_2) != sslGlobalParams.tlsLogVersions.cend()) { + versionString = "1.2"_sd; + } + break; + default: + if (!sslGlobalParams.tlsLogVersions.empty()) { + versionString = "unkown"_sd; + } + break; + } + + if (!versionString.empty()) { + log() << "Accepted connection with TLS Version " << versionString << " from connection " + << hostForLogging; + } +} + StatusWith<stdx::unordered_set<RoleName>> SSLManager::_parsePeerRoles(X509* peerCert) const { // exts is owned by the peerCert const STACK_OF(X509_EXTENSION)* exts = X509_get0_extensions(peerCert); @@ -1551,6 +1592,7 @@ StatusWith<stdx::unordered_set<RoleName>> SSLManager::_parsePeerRoles(X509* peer ASN1_OBJECT* rolesObj = OBJ_nid2obj(_rolesNid); + // Search all certificate extensions for our own stdx::unordered_set<RoleName> roles; for (int i = 0; i < extCount; i++) { diff --git a/src/mongo/util/net/ssl_manager.h b/src/mongo/util/net/ssl_manager.h index 0058f7223b2..74fe0686444 100644 --- a/src/mongo/util/net/ssl_manager.h +++ b/src/mongo/util/net/ssl_manager.h @@ -142,7 +142,9 @@ public: * a StatusWith instead. */ virtual SSLPeerInfo parseAndValidatePeerCertificateDeprecated( - const SSLConnection* conn, const std::string& remoteHost) = 0; + const SSLConnection* conn, + const std::string& remoteHost, + const HostAndPort& hostForLogging) = 0; /** * Gets the SSLConfiguration containing all information about the current SSL setup @@ -191,7 +193,7 @@ public: * X509 authorization will be returned. */ virtual StatusWith<boost::optional<SSLPeerInfo>> parseAndValidatePeerCertificate( - SSL* ssl, const std::string& remoteHost) = 0; + SSL* ssl, const std::string& remoteHost, const HostAndPort& hostForLogging) = 0; }; // Access SSL functions through this instance. @@ -211,5 +213,27 @@ const SSLParams& getSSLGlobalParams(); * packet if the client has selected a protocol which has been disabled by the server. */ boost::optional<std::array<std::uint8_t, 7>> checkTLSRequest(ConstDataRange cdr); -} + +/** + * Platform neutral TLS version enum + */ +enum class TLSVersion { + kUnknown, + kTLS10, + kTLS11, + kTLS12, +}; + +/** + * Map SSL version to platform-neutral enum. + */ +StatusWith<TLSVersion> mapTLSVersion(SSLConnection* conn); + +/** + * Record information about TLS versions and optionally log the TLS version + */ +void recordTLSVersion(TLSVersion version, const HostAndPort& hostForLogging); + + +} // namespace mongo #endif // #ifdef MONGO_CONFIG_SSL diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp index 0d1d3504ae7..659ab48b5d8 100644 --- a/src/mongo/util/net/ssl_options.cpp +++ b/src/mongo/util/net/ssl_options.cpp @@ -102,6 +102,14 @@ Status addSSLServerOptions(moe::OptionSection* options) { moe::String, "Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]"); + options + ->addOptionChaining( + "net.tls.logVersions", + "tlsLogVersions", + moe::String, + "Comma separated list of TLS protocols to log on connect [TLS1_0,TLS1_1,TLS1_2]") + .hidden(); + options->addOptionChaining("net.ssl.weakCertificateValidation", "sslWeakCertificateValidation", moe::Switch, @@ -130,6 +138,33 @@ Status addSSLServerOptions(moe::OptionSection* options) { return Status::OK(); } +Status storeTLSLogVersion(const std::string& loggedProtocols) { + // The tlsLogVersion field is composed of a comma separated list of protocols to + // log. First, tokenize the field. + const auto tokens = StringSplitter::split(loggedProtocols, ","); + + // All universally accepted tokens, and their corresponding enum representation. + const std::map<std::string, SSLParams::Protocols> validConfigs{ + {"TLS1_0", SSLParams::Protocols::TLS1_0}, + {"TLS1_1", SSLParams::Protocols::TLS1_1}, + {"TLS1_2", SSLParams::Protocols::TLS1_2}, + }; + + // Map the tokens to their enum values, and push them onto the list of logged protocols. + for (const std::string& token : tokens) { + auto mappedToken = validConfigs.find(token); + if (mappedToken != validConfigs.end()) { + sslGlobalParams.tlsLogVersions.push_back(mappedToken->second); + continue; + } + + return Status(ErrorCodes::BadValue, "Unrecognized tlsLogVersions '" + token + "'"); + } + + return Status::OK(); +} + + Status addSSLClientOptions(moe::OptionSection* options) { options->addOptionChaining("ssl", "ssl", moe::Switch, "use SSL for all connections"); @@ -363,6 +398,13 @@ Status storeSSLServerOptions(const moe::Environment& params) { } } + if (params.count("net.tls.logVersions")) { + const auto status = storeTLSLogVersion(params["net.tls.logVersions"].as<string>()); + if (!status.isOK()) { + return status; + } + } + if (params.count("net.ssl.weakCertificateValidation")) { sslGlobalParams.sslWeakCertificateValidation = params["net.ssl.weakCertificateValidation"].as<bool>(); diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h index 02a82108529..5d912d1ecdb 100644 --- a/src/mongo/util/net/ssl_options.h +++ b/src/mongo/util/net/ssl_options.h @@ -54,6 +54,7 @@ struct SSLParams { std::string sslCRLFile; // --sslCRLFile std::string sslCipherConfig; // --sslCipherConfig std::vector<Protocols> sslDisabledProtocols; // --sslDisabledProtocols + std::vector<Protocols> tlsLogVersions; // --tlsLogVersion bool sslWeakCertificateValidation = false; // --sslWeakCertificateValidation bool sslFIPSMode = false; // --sslFIPSMode bool sslAllowInvalidCertificates = false; // --sslAllowInvalidCertificates diff --git a/src/mongo/util/net/ssl_options_test.cpp b/src/mongo/util/net/ssl_options_test.cpp new file mode 100644 index 00000000000..148a54947ad --- /dev/null +++ b/src/mongo/util/net/ssl_options_test.cpp @@ -0,0 +1,272 @@ + +/** + * Copyright (C) 2018-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/platform/basic.h" + +#include "mongo/util/net/ssl_options.h" + +#include <ostream> + +#include "mongo/config.h" +#include "mongo/db/server_options_helpers.h" +#include "mongo/unittest/unittest.h" +#include "mongo/util/net/ssl_options.h" +#include "mongo/util/options_parser/environment.h" +#include "mongo/util/options_parser/option_section.h" +#include "mongo/util/options_parser/options_parser.h" + +namespace moe = mongo::optionenvironment; + +namespace mongo { +namespace { + +namespace test { +struct Vector : public std::vector<uint8_t> { + Vector(std::vector<uint8_t> v) : std::vector<uint8_t>(std::move(v)) {} +}; +std::ostream& operator<<(std::ostream& ss, const Vector& val) { + ss << '{'; + std::string comma; + for (const auto& b : val) { + ss << comma << b; + comma = ", "; + } + ss << '}'; + return ss; +} +} // namespace test + +class OptionsParserTester : public moe::OptionsParser { +public: + Status readConfigFile(const std::string& filename, std::string* config) { + if (filename != _filename) { + ::mongo::StringBuilder sb; + sb << "Parser using filename: " << filename + << " which does not match expected filename: " << _filename; + return Status(ErrorCodes::InternalError, sb.str()); + } + *config = _config; + return Status::OK(); + } + void setConfig(const std::string& filename, const std::string& config) { + _filename = filename; + _config = config; + } + +private: + std::string _filename; + std::string _config; +}; + +TEST(SetupOptions, sslModeDisabled) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--sslMode"); + argv.push_back("disabled"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(::mongo::addSSLServerOptions(&options)); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + ASSERT_OK(::mongo::storeSSLServerOptions(environment)); + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_disabled); +} + +TEST(SetupOptions, sslModeRequired) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::string sslPEMKeyFile = "jstests/libs/server.pem"; + std::string sslCAFFile = "jstests/libs/ca.pem"; + std::string sslCRLFile = "jstests/libs/crl.pem"; + std::string sslClusterFile = "jstests/libs/cluster_cert.pem"; + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--sslMode"); + argv.push_back("requireSSL"); + argv.push_back("--sslPEMKeyFile"); + argv.push_back(sslPEMKeyFile); + argv.push_back("--sslCAFile"); + argv.push_back(sslCAFFile); + argv.push_back("--sslCRLFile"); + argv.push_back(sslCRLFile); + argv.push_back("--sslClusterFile"); + argv.push_back(sslClusterFile); + argv.push_back("--sslAllowInvalidHostnames"); + argv.push_back("--sslAllowInvalidCertificates"); + argv.push_back("--sslWeakCertificateValidation"); + argv.push_back("--sslFIPSMode"); + argv.push_back("--sslPEMKeyPassword"); + argv.push_back("pw1"); + argv.push_back("--sslClusterPassword"); + argv.push_back("pw2"); + argv.push_back("--sslDisabledProtocols"); + argv.push_back("TLS1_1"); + argv.push_back("--tlsLogVersions"); + argv.push_back("TLS1_0"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(mongo::addSSLServerOptions(&options)); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + ASSERT_OK(mongo::storeSSLServerOptions(environment)); + + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_requireSSL); + ASSERT_EQ(::mongo::sslGlobalParams.sslPEMKeyFile.substr( + ::mongo::sslGlobalParams.sslPEMKeyFile.length() - sslPEMKeyFile.length()), + sslPEMKeyFile); + ASSERT_EQ(::mongo::sslGlobalParams.sslCAFile.substr( + ::mongo::sslGlobalParams.sslCAFile.length() - sslCAFFile.length()), + sslCAFFile); + ASSERT_EQ(::mongo::sslGlobalParams.sslCRLFile.substr( + ::mongo::sslGlobalParams.sslCRLFile.length() - sslCRLFile.length()), + sslCRLFile); + ASSERT_EQ(::mongo::sslGlobalParams.sslClusterFile.substr( + ::mongo::sslGlobalParams.sslClusterFile.length() - sslClusterFile.length()), + sslClusterFile); + ASSERT_EQ(::mongo::sslGlobalParams.sslAllowInvalidHostnames, true); + ASSERT_EQ(::mongo::sslGlobalParams.sslAllowInvalidCertificates, true); + ASSERT_EQ(::mongo::sslGlobalParams.sslWeakCertificateValidation, true); + ASSERT_EQ(::mongo::sslGlobalParams.sslFIPSMode, true); + ASSERT_EQ(::mongo::sslGlobalParams.sslPEMKeyPassword, "pw1"); + ASSERT_EQ(::mongo::sslGlobalParams.sslClusterPassword, "pw2"); + ASSERT_EQ(static_cast<int>(::mongo::sslGlobalParams.sslDisabledProtocols.back()), + static_cast<int>(::mongo::SSLParams::Protocols::TLS1_1)); + ASSERT_EQ(static_cast<int>(::mongo::sslGlobalParams.tlsLogVersions.back()), + static_cast<int>(::mongo::SSLParams::Protocols::TLS1_0)); +} + +TEST(SetupOptions, disableNonSSLConnectionLoggingFalse) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--setParameter"); + argv.push_back("disableNonSSLConnectionLogging=false"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.disableNonSSLConnectionLogging, false); +} + +TEST(SetupOptions, disableNonTLSConnectionLoggingFalse) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--setParameter"); + argv.push_back("disableNonTLSConnectionLogging=false"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.disableNonSSLConnectionLogging, false); +} + +TEST(SetupOptions, disableNonSSLConnectionLoggingTrue) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--setParameter"); + argv.push_back("disableNonSSLConnectionLogging=true"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.disableNonSSLConnectionLogging, true); +} + +TEST(SetupOptions, disableNonTLSConnectionLoggingTrue) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--setParameter"); + argv.push_back("disableNonTLSConnectionLogging=true"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.disableNonSSLConnectionLogging, true); +} + +TEST(SetupOptions, disableNonTLSConnectionLoggingInvalid) { + OptionsParserTester parser; + moe::Environment environment; + moe::OptionSection options; + + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); + + std::vector<std::string> argv; + argv.push_back("binaryname"); + argv.push_back("--setParameter"); + argv.push_back("disableNonTLSConnectionLogging=false"); + argv.push_back("--setParameter"); + argv.push_back("disableNonSSLConnectionLogging=false"); + std::map<std::string, std::string> env_map; + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + ASSERT_NOT_OK(mongo::storeServerOptions(environment)); +} + +} // namespace +} // namespace mongo |