summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2018-09-17 18:31:30 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2018-10-31 11:10:15 -0400
commit573f92bd3567a70f2b6bdc8295a9d230dec1cf04 (patch)
tree9a75b04ef55382a79cf9784f17b9e137686b758f
parent5d32255fa766b9f62eca7144309aea0ce09abe1e (diff)
downloadmongo-573f92bd3567a70f2b6bdc8295a9d230dec1cf04.tar.gz
SERVER-36250 Add support for optionally logging specific negotiated TLS versions
(cherry picked from commit c377f378176e34987babf95db8ed70a12ce44b4f)
-rw-r--r--jstests/ssl/ssl_count_protocols.js22
-rw-r--r--src/mongo/executor/async_secure_stream.cpp11
-rw-r--r--src/mongo/executor/async_secure_stream.h3
-rw-r--r--src/mongo/transport/session_asio.h2
-rw-r--r--src/mongo/util/net/SConscript25
-rw-r--r--src/mongo/util/net/sock.cpp5
-rw-r--r--src/mongo/util/net/ssl_manager.cpp82
-rw-r--r--src/mongo/util/net/ssl_manager.h27
-rw-r--r--src/mongo/util/net/ssl_options.cpp42
-rw-r--r--src/mongo/util/net/ssl_options.h1
-rw-r--r--src/mongo/util/net/ssl_options_test.cpp272
11 files changed, 451 insertions, 41 deletions
diff --git a/jstests/ssl/ssl_count_protocols.js b/jstests/ssl/ssl_count_protocols.js
index b902b4532dd..ae21894eee0 100644
--- a/jstests/ssl/ssl_count_protocols.js
+++ b/jstests/ssl/ssl_count_protocols.js
@@ -17,6 +17,8 @@
sslMode: 'allowSSL',
sslPEMKeyFile: SERVER_CERT,
sslDisabledProtocols: 'none',
+ useLogFiles: true,
+ tlsLogVersions: "TLS1_0,TLS1_1,TLS1_2",
});
print(disabledProtocols);
@@ -45,6 +47,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 8696af24b81..02305b4a16d 100644
--- a/src/mongo/executor/async_secure_stream.cpp
+++ b/src/mongo/executor/async_secure_stream.cpp
@@ -100,13 +100,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 c1773de4bee..3c5f22433a9 100644
--- a/src/mongo/executor/async_secure_stream.h
+++ b/src/mongo/executor/async_secure_stream.h
@@ -62,7 +62,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/transport/session_asio.h b/src/mongo/transport/session_asio.h
index 2a906e42f49..51fce9efa73 100644
--- a/src/mongo/transport/session_asio.h
+++ b/src/mongo/transport/session_asio.h
@@ -323,7 +323,7 @@ private:
if (!ec && sslPeerInfo.subjectName.empty()) {
auto sslManager = getSSLManager();
auto swPeerInfo = sslManager->parseAndValidatePeerCertificate(
- _sslSocket->native_handle(), "");
+ _sslSocket->native_handle(), "", _remote);
if (swPeerInfo.isOK()) {
// The value of swPeerInfo is a bit complicated:
diff --git a/src/mongo/util/net/SConscript b/src/mongo/util/net/SConscript
index c233df484a2..c120b65990f 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 = env.Clone()
@@ -67,17 +68,19 @@ env.CppUnitTest(
],
)
-
-env.CppUnitTest(
- target='ssl_manager_test',
- source=[
- 'ssl_manager_test.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- 'network',
- ],
-)
+if has_option('ssl'):
+ env.CppUnitTest(
+ target='ssl_manager_test',
+ source=[
+ 'ssl_manager_test.cpp',
+ 'ssl_options_test.cpp',
+ ],
+ LIBDEPS=[
+ '$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/server_options',
+ 'network',
+ ],
+ )
env.CppIntegrationTest(
target='op_msg_integration_test',
diff --git a/src/mongo/util/net/sock.cpp b/src/mongo/util/net/sock.cpp
index 34c323facec..122c10eab93 100644
--- a/src/mongo/util/net/sock.cpp
+++ b/src/mongo/util/net/sock.cpp
@@ -393,7 +393,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;
}
@@ -411,7 +411,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());
}
std::string Socket::getSNIServerName() const {
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index 6893b2a2b42..2a4c5a32f44 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -396,11 +396,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;
@@ -1499,35 +1500,34 @@ SSLConnection* SSLManager::accept(Socket* socket, const char* initialBytes, int
}
-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};
@@ -1641,9 +1641,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,
@@ -1652,6 +1652,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);
@@ -1663,6 +1704,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 dc8899eef7a..68827d322de 100644
--- a/src/mongo/util/net/ssl_manager.h
+++ b/src/mongo/util/net/ssl_manager.h
@@ -145,7 +145,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
@@ -194,7 +196,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.
@@ -222,5 +224,26 @@ bool hostNameMatchForX509Certificates(std::string nameToMatch, std::string certH
*/
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 9b5408849ae..147bf971998 100644
--- a/src/mongo/util/net/ssl_options.cpp
+++ b/src/mongo/util/net/ssl_options.cpp
@@ -107,6 +107,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,
@@ -135,6 +143,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");
@@ -368,6 +403,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 73dd3988900..b6816bf27ed 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -57,6 +57,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