diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/mongod_options.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/server_options_test.cpp | 322 | ||||
-rw-r--r-- | src/mongo/transport/session_asio.h | 3 | ||||
-rw-r--r-- | src/mongo/util/cmdline_utils/censor_cmdline.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 57 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.cpp | 443 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.h | 1 | ||||
-rw-r--r-- | src/mongo/util/options_parser/option_description.cpp | 39 | ||||
-rw-r--r-- | src/mongo/util/options_parser/option_description.h | 10 | ||||
-rw-r--r-- | src/mongo/util/options_parser/option_section.cpp | 150 | ||||
-rw-r--r-- | src/mongo/util/options_parser/option_section.h | 23 | ||||
-rw-r--r-- | src/mongo/util/options_parser/options_parser.cpp | 173 | ||||
-rw-r--r-- | src/mongo/util/options_parser/options_parser_test.cpp | 15 |
13 files changed, 899 insertions, 355 deletions
diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp index b497c71ed7c..510b62dc354 100644 --- a/src/mongo/db/mongod_options.cpp +++ b/src/mongo/db/mongod_options.cpp @@ -226,7 +226,7 @@ Status addMongodOptions(moe::OptionSection* options) { "", moe::Bool, "disable data file preallocation - will often hurt performance", - "storage.preallocDataFiles") + {"storage.preallocDataFiles"}) .setSources(moe::SourceYAMLConfig); storage_options @@ -234,7 +234,7 @@ Status addMongodOptions(moe::OptionSection* options) { "nssize", moe::Int, ".ns file size (in MB) for new databases", - "storage.nsSize") + {"storage.nsSize"}) .setDefault(moe::Value(16)); storage_options @@ -242,20 +242,20 @@ Status addMongodOptions(moe::OptionSection* options) { "quota", moe::Switch, "limits each database to a certain number of files (8 default)", - "storage.quota.enforced") + {"storage.quota.enforced"}) .incompatibleWith("keyFile"); storage_options.addOptionChaining("storage.mmapv1.quota.maxFilesPerDB", "quotaFiles", moe::Int, "number of files allowed per db, implies --quota", - "storage.quota.maxFilesPerDB"); + {"storage.quota.maxFilesPerDB"}); storage_options.addOptionChaining("storage.mmapv1.smallFiles", "smallfiles", moe::Switch, "use a smaller default file size", - "storage.smallFiles"); + {"storage.smallFiles"}); storage_options .addOptionChaining("storage.syncPeriodSecs", @@ -325,7 +325,7 @@ Status addMongodOptions(moe::OptionSection* options) { "journalOptions", moe::Int, "journal diagnostic options", - "storage.journal.debugFlags") + {"storage.journal.debugFlags"}) .incompatibleWith("durOptions"); storage_options @@ -338,7 +338,7 @@ Status addMongodOptions(moe::OptionSection* options) { "journalCommitInterval", moe::Int, "how often to group/batch commit (ms)", - "storage.mmapv1.journal.commitIntervalMs"); + {"storage.mmapv1.journal.commitIntervalMs"}); // Deprecated option that we don't want people to use for performance reasons storage_options diff --git a/src/mongo/db/server_options_test.cpp b/src/mongo/db/server_options_test.cpp index 8eddeb88dfc..720265ab19b 100644 --- a/src/mongo/db/server_options_test.cpp +++ b/src/mongo/db/server_options_test.cpp @@ -51,6 +51,7 @@ #include "mongo/logger/logger.h" #include "mongo/unittest/unittest.h" #include "mongo/util/log.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" @@ -762,6 +763,7 @@ TEST(SetupOptions, NonNumericSampleRateYAMLConfigOptionFailsToParse) { moe::Environment environment; moe::OptionSection options; + ASSERT_OK(::mongo::addGeneralServerOptions(&options)); std::vector<std::string> argv; @@ -777,6 +779,326 @@ TEST(SetupOptions, NonNumericSampleRateYAMLConfigOptionFailsToParse) { ASSERT_NOT_OK(parser.run(options, argv, env_map, &environment)); } +TEST(SetupOptions, tlsModeDisabled) { + 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("--tlsMode"); + argv.push_back("disabled"); + std::map<std::string, std::string> env_map; + + Status ret = ::mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_disabled); +} + +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; + + Status ret = ::mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_disabled); +} + +TEST(SetupOptions, tlsModeRequired) { + 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("--tlsMode"); + argv.push_back("requireTLS"); + argv.push_back("--tlsPEMKeyFile"); + argv.push_back(sslPEMKeyFile); + argv.push_back("--tlsCAFile"); + argv.push_back(sslCAFFile); + argv.push_back("--tlsCRLFile"); + argv.push_back(sslCRLFile); + argv.push_back("--tlsClusterFile"); + argv.push_back(sslClusterFile); + argv.push_back("--tlsAllowInvalidHostnames"); + argv.push_back("--tlsAllowInvalidCertificates"); + argv.push_back("--tlsWeakCertificateValidation"); + argv.push_back("--tlsFIPSMode"); + argv.push_back("--tlsPEMKeyPassword"); + argv.push_back("pw1"); + argv.push_back("--tlsClusterPassword"); + argv.push_back("pw2"); + argv.push_back("--tlsDisabledProtocols"); + argv.push_back("TLS1_1"); + std::map<std::string, std::string> env_map; + + Status addRet = mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = 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)); +} + +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"); + std::map<std::string, std::string> env_map; + + Status addRet = mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = 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)); +} + +#ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS +TEST(SetupOptions, tlsModeRequiredCertificateSelector) { + 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("--tlsMode"); + argv.push_back("requireTLS"); + argv.push_back("--tlsCertificateSelector"); + argv.push_back("subject=Subject 1"); + argv.push_back("--tlsClusterCertificateSelector"); + argv.push_back("subject=Subject 2"); + std::map<std::string, std::string> env_map; + + Status addRet = mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeSSLServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_requireSSL); + ASSERT_EQ(::mongo::sslGlobalParams.sslCertificateSelector.subject, "Subject 1"); + ASSERT_EQ(::mongo::sslGlobalParams.sslClusterCertificateSelector.subject, "Subject 2"); +} + +TEST(SetupOptions, sslModeRequiredCertificateSelector) { + 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("requireSSL"); + argv.push_back("--sslCertificateSelector"); + argv.push_back("subject=Subject 1"); + argv.push_back("--sslClusterCertificateSelector"); + argv.push_back("subject=Subject 2"); + std::map<std::string, std::string> env_map; + + Status addRet = mongo::addSSLServerOptions(&options); + + ASSERT_OK(parser.run(options, argv, env_map, &environment)); + Status storeRet = mongo::storeSSLServerOptions(environment); + + ASSERT_EQ(::mongo::sslGlobalParams.sslMode.load(), ::mongo::sslGlobalParams.SSLMode_requireSSL); + ASSERT_EQ(::mongo::sslGlobalParams.sslCertificateSelector.subject, "Subject 1"); + ASSERT_EQ(::mongo::sslGlobalParams.sslClusterCertificateSelector.subject, "Subject 2"); +} + +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; + + ::mongo::sslGlobalParams.disableNonSSLConnectionLoggingSet = false; + 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; + + ::mongo::sslGlobalParams.disableNonSSLConnectionLoggingSet = false; + 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; + + ::mongo::sslGlobalParams.disableNonSSLConnectionLoggingSet = false; + 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)); +} +#endif + #if !defined(_WIN32) && !(defined(__APPLE__) && TARGET_OS_TV) #define ASSERT_BOOST_SUCCESS(ec) ASSERT_FALSE(ec) << ec.message() diff --git a/src/mongo/transport/session_asio.h b/src/mongo/transport/session_asio.h index f9fac4276a0..d1c2bd865eb 100644 --- a/src/mongo/transport/session_asio.h +++ b/src/mongo/transport/session_asio.h @@ -640,7 +640,8 @@ private: uasserted(ErrorCodes::SSLHandshakeFailed, "The server is configured to only allow SSL connections"); } else { - if (_tl->_sslMode() == SSLParams::SSLMode_preferSSL) { + if (!sslGlobalParams.disableNonSSLConnectionLogging && + _tl->_sslMode() == SSLParams::SSLMode_preferSSL) { LOG(0) << "SSL mode is set to 'preferred' and connection " << id() << " to " << remote() << " is not using SSL."; } diff --git a/src/mongo/util/cmdline_utils/censor_cmdline.cpp b/src/mongo/util/cmdline_utils/censor_cmdline.cpp index e903242ac75..9f0113b85b3 100644 --- a/src/mongo/util/cmdline_utils/censor_cmdline.cpp +++ b/src/mongo/util/cmdline_utils/censor_cmdline.cpp @@ -41,7 +41,9 @@ static bool _isPasswordSwitch(char const* switchName); static bool _isPasswordArgument(const char* argumentName) { static const char* const passwordArguments[] = { + "net.tls.PEMKeyPassword", "net.ssl.PEMKeyPassword", + "net.tls.clusterPassword", "net.ssl.clusterPassword", "processManagement.windowsService.servicePassword", "security.kmip.clientCertificatePassword", @@ -57,7 +59,9 @@ static bool _isPasswordArgument(const char* argumentName) { static bool _isPasswordSwitch(const char* switchName) { static const char* const passwordSwitches[] = { + "tlsPEMKeyPassword", "sslPEMKeyPassword", + "tlsClusterPassword", "sslClusterPassword", "servicePassword", "kmipClientCertificatePassword", diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index 66bd0eaa775..682a415985d 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -52,16 +52,6 @@ namespace mongo { namespace { -/** - * Configurable via --setParameter disableNonSSLConnectionLogging=true. If false (default) - * if the sslMode is set to preferSSL, we will log connections that are not using SSL. - * If true, such log messages will be suppressed. - */ -ExportedServerParameter<bool, ServerParameterType::kStartupOnly> - disableNonSSLConnectionLoggingParameter(ServerParameterSet::getGlobal(), - "disableNonSSLConnectionLogging", - &sslGlobalParams.disableNonSSLConnectionLogging); - ExportedServerParameter<std::string, ServerParameterType::kStartupOnly> setDiffieHellmanParameterPEMFile(ServerParameterSet::getGlobal(), "opensslDiffieHellmanParameters", @@ -85,7 +75,7 @@ public: if (!sslGlobalParams.sslCipherConfig.empty()) { return Status( ErrorCodes::BadValue, - "opensslCipherConfig setParameter is incompatible with net.ssl.sslCipherConfig"); + "opensslCipherConfig setParameter is incompatible with net.tls.tlsCipherConfig"); } // Note that there is very little validation that we can do here. // OpenSSL exposes no API to validate a cipher config string. The only way to figure out @@ -98,6 +88,51 @@ public: } } openSSLCipherConfig; +/** + * Configurable via --setParameter disableNonSSLConnectionLogging=true. If false (default) + * if the sslMode is set to preferSSL, we will log connections that are not using SSL. + * If true, such log messages will be suppressed. + */ +class DisableNonSSLConnectionLoggingParameter + : public ExportedServerParameter<bool, ServerParameterType::kStartupOnly> { +public: + DisableNonSSLConnectionLoggingParameter() + : ExportedServerParameter<bool, ServerParameterType::kStartupOnly>( + ServerParameterSet::getGlobal(), + "disableNonSSLConnectionLogging", + &sslGlobalParams.disableNonSSLConnectionLogging) {} + Status validate(const bool& potentialNewValue) final { + warning() << "Option: disableNonSSLConnectionLogging is deprecated. Please use " + << "disableNonTLSConnectionLogging instead."; + if (sslGlobalParams.disableNonSSLConnectionLoggingSet) { + return Status(ErrorCodes::BadValue, + "Error parsing command line: Multiple occurrences of option " + "disableNonTLSConnectionLogging"); + } + sslGlobalParams.disableNonSSLConnectionLoggingSet = true; + return Status::OK(); + } +} disableNonSSLConnectionLogging; + +class DisableNonTLSConnectionLoggingParameter + : public ExportedServerParameter<bool, ServerParameterType::kStartupOnly> { +public: + DisableNonTLSConnectionLoggingParameter() + : ExportedServerParameter<bool, ServerParameterType::kStartupOnly>( + ServerParameterSet::getGlobal(), + "disableNonTLSConnectionLogging", + &sslGlobalParams.disableNonSSLConnectionLogging) {} + Status validate(const bool& potentialNewValue) final { + if (sslGlobalParams.disableNonSSLConnectionLoggingSet) { + return Status(ErrorCodes::BadValue, + "Error parsing command line: Multiple occurrences of option " + "disableNonTLSConnectionLogging"); + } + sslGlobalParams.disableNonSSLConnectionLoggingSet = true; + return Status::OK(); + } +} disableNonTLSConnectionLogging; + #ifdef MONGO_CONFIG_SSL namespace { diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp index 72ee5b041c9..5c33666362c 100644 --- a/src/mongo/util/net/ssl_options.cpp +++ b/src/mongo/util/net/ssl_options.cpp @@ -170,166 +170,238 @@ Status parseCertificateSelector(SSLParams::CertificateSelector* selector, Status addSSLServerOptions(moe::OptionSection* options) { options - ->addOptionChaining("net.ssl.sslOnNormalPorts", - "sslOnNormalPorts", + ->addOptionChaining("net.tls.tlsOnNormalPorts", + "tlsOnNormalPorts", moe::Switch, - "use ssl on configured ports") + "Use TLS on configured ports", + {"net.ssl.sslOnNormalPorts"}, + {"sslOnNormalPorts"}) .setSources(moe::SourceAllLegacy) + .incompatibleWith("net.tls.mode") .incompatibleWith("net.ssl.mode"); - options->addOptionChaining( - "net.ssl.mode", - "sslMode", - moe::String, - "set the SSL operation mode (disabled|allowSSL|preferSSL|requireSSL)"); + options + ->addOptionChaining("net.tls.mode", + "tlsMode", + moe::String, + "Set the TLS operation mode (disabled|allowTLS|preferTLS|requireTLS)") + .incompatibleWith("net.ssl.mode"); + options + ->addOptionChaining("net.ssl.mode", + "sslMode", + moe::String, + "Set the TLS operation mode (disabled|allowSSL|preferSSL|requireSSL)") + .incompatibleWith("net.tls.mode"); - options->addOptionChaining( - "net.ssl.PEMKeyFile", "sslPEMKeyFile", moe::String, "PEM file for ssl"); + options->addOptionChaining("net.tls.PEMKeyFile", + "tlsPEMKeyFile", + moe::String, + "PEM file for TLS", + {"net.ssl.PEMKeyFile"}, + {"sslPEMKeyFile"}); options - ->addOptionChaining( - "net.ssl.PEMKeyPassword", "sslPEMKeyPassword", moe::String, "PEM file password") + ->addOptionChaining("net.tls.PEMKeyPassword", + "tlsPEMKeyPassword", + moe::String, + "PEM file password", + {"net.ssl.PEMKeyPassword"}, + {"sslPEMKeyPassword"}) .setImplicit(moe::Value(std::string(""))); - options->addOptionChaining("net.ssl.clusterFile", - "sslClusterFile", + options->addOptionChaining("net.tls.clusterFile", + "tlsClusterFile", moe::String, - "Key file for internal SSL authentication"); + "Key file for internal TLS authentication", + {"net.ssl.clusterFile"}, + {"sslClusterFile"}); options - ->addOptionChaining("net.ssl.clusterPassword", - "sslClusterPassword", + ->addOptionChaining("net.tls.clusterPassword", + "tlsClusterPassword", moe::String, - "Internal authentication key file password") + "Internal authentication key file password", + {"net.ssl.clusterPassword"}, + {"sslClusterPassword"}) .setImplicit(moe::Value(std::string(""))); - options->addOptionChaining( - "net.ssl.CAFile", "sslCAFile", moe::String, "Certificate Authority file for SSL"); + options->addOptionChaining("net.tls.CAFile", + "tlsCAFile", + moe::String, + "Certificate Authority file for TLS", + {"net.ssl.CAFile"}, + {"sslCAFile"}); - options->addOptionChaining( - "net.ssl.CRLFile", "sslCRLFile", moe::String, "Certificate Revocation List file for SSL"); + options->addOptionChaining("net.tls.CRLFile", + "tlsCRLFile", + moe::String, + "Certificate Revocation List file for TLS", + {"net.ssl.CRLFile"}, + {"sslCRLFile"}); options - ->addOptionChaining("net.ssl.sslCipherConfig", - "sslCipherConfig", + ->addOptionChaining("net.tls.tlsCipherConfig", + "tlsCipherConfig", moe::String, - "OpenSSL cipher configuration string") + "OpenSSL cipher configuration string", + {"net.ssl.sslCipherConfig"}, + {"sslCipherConfig"}) .hidden(); options->addOptionChaining( - "net.ssl.disabledProtocols", - "sslDisabledProtocols", + "net.tls.disabledProtocols", + "tlsDisabledProtocols", moe::String, - "Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]"); + "Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]", + {"net.ssl.disabledProtocols"}, + {"sslDisabledProtocols"}); - options->addOptionChaining("net.ssl.weakCertificateValidation", - "sslWeakCertificateValidation", + options->addOptionChaining("net.tls.weakCertificateValidation", + "tlsWeakCertificateValidation", moe::Switch, - "allow client to connect without " - "presenting a certificate"); + "Allow client to connect without presenting a certificate", + {"net.ssl.weakCertificateValidation"}, + {"sslWeakCertificateValidation"}); - // Alias for --sslWeakCertificateValidation. - options->addOptionChaining("net.ssl.allowConnectionsWithoutCertificates", - "sslAllowConnectionsWithoutCertificates", + // Alias for --tlsWeakCertificateValidation. + options->addOptionChaining("net.tls.allowConnectionsWithoutCertificates", + "tlsAllowConnectionsWithoutCertificates", moe::Switch, - "allow client to connect without presenting a certificate"); + "Allow client to connect without presenting a certificate", + {"net.ssl.allowConnectionsWithoutCertificates"}, + {"sslAllowConnectionsWithoutCertificates"}); - options->addOptionChaining("net.ssl.allowInvalidHostnames", - "sslAllowInvalidHostnames", + options->addOptionChaining("net.tls.allowInvalidHostnames", + "tlsAllowInvalidHostnames", moe::Switch, - "Allow server certificates to provide non-matching hostnames"); + "Allow server certificates to provide non-matching hostnames", + {"net.ssl.allowInvalidHostnames"}, + {"sslAllowInvalidHostnames"}); - options->addOptionChaining("net.ssl.allowInvalidCertificates", - "sslAllowInvalidCertificates", + options->addOptionChaining("net.tls.allowInvalidCertificates", + "tlsAllowInvalidCertificates", moe::Switch, - "allow connections to servers with invalid certificates"); + "Allow connections to servers with invalid certificates", + {"net.ssl.allowInvalidCertificates"}, + {"sslAllowInvalidCertificates"}); - options->addOptionChaining( - "net.ssl.FIPSMode", "sslFIPSMode", moe::Switch, "activate FIPS 140-2 mode at startup"); + options->addOptionChaining("net.tls.FIPSMode", + "tlsFIPSMode", + moe::Switch, + "Activate FIPS 140-2 mode at startup", + {"net.ssl.FIPSMode"}, + {"sslFIPSMode"}); #ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS options - ->addOptionChaining("net.ssl.certificateSelector", - "sslCertificateSelector", + ->addOptionChaining("net.tls.certificateSelector", + "tlsCertificateSelector", moe::String, - "SSL Certificate in system store") - .incompatibleWith("net.ssl.PEMKeyFile") - .incompatibleWith("net.ssl.PEMKeyPassword") - .setSources(moe::SourceYAMLCLI); + "TLS Certificate in system store", + {"net.ssl.certificateSelector"}, + {"sslCertificateSelector"}) + .incompatibleWith("net.tls.PEMKeyFile") + .incompatibleWith("net.tls.PEMKeyPassword"); + options - ->addOptionChaining("net.ssl.clusterCertificateSelector", - "sslClusterCertificateSelector", + ->addOptionChaining("net.tls.clusterCertificateSelector", + "tlsClusterCertificateSelector", moe::String, - "SSL Certificate in system store for internal SSL authentication") - .incompatibleWith("net.ssl.clusterFile") - .incompatibleWith("net.ssl.clusterFilePassword") - .setSources(moe::SourceYAMLCLI); + "SSL/TLS Certificate in system store for internal TLS authentication", + {"net.ssl.clusterCertificateSelector"}, + {"sslClusterCertificateSelector"}) + .incompatibleWith("net.tls.clusterFile") + .incompatibleWith("net.tls.clusterFilePassword"); #endif return Status::OK(); } Status addSSLClientOptions(moe::OptionSection* options) { - options->addOptionChaining("ssl", "ssl", moe::Switch, "use SSL for all connections"); + options->addOptionChaining( + "tls", "tls", moe::Switch, "use TLS for all connections", {"ssl"}, {"ssl"}); options - ->addOptionChaining( - "ssl.CAFile", "sslCAFile", moe::String, "Certificate Authority file for SSL") - .requires("ssl"); + ->addOptionChaining("tls.CAFile", + "tlsCAFile", + moe::String, + "Certificate Authority file for TLS", + {"ssl.CAFile"}, + {"sslCAFile"}) + .requires("tls"); options - ->addOptionChaining( - "ssl.PEMKeyFile", "sslPEMKeyFile", moe::String, "PEM certificate/key file for SSL") - .requires("ssl"); + ->addOptionChaining("tls.PEMKeyFile", + "tlsPEMKeyFile", + moe::String, + "PEM certificate/key file for TLS", + {"ssl.PEMKeyFile"}, + {"sslPEMKeyFile"}) + .requires("tls"); options - ->addOptionChaining("ssl.PEMKeyPassword", - "sslPEMKeyPassword", + ->addOptionChaining("tls.PEMKeyPassword", + "tlsPEMKeyPassword", moe::String, - "password for key in PEM file for SSL") - .requires("ssl"); + "Password for key in PEM file for TLS", + {"ssl.PEMKeyPassword"}, + {"sslPEMKeyPassword"}) + .requires("tls"); options - ->addOptionChaining( - "ssl.CRLFile", "sslCRLFile", moe::String, "Certificate Revocation List file for SSL") - .requires("ssl") - .requires("ssl.CAFile"); + ->addOptionChaining("tls.CRLFile", + "tlsCRLFile", + moe::String, + "Certificate Revocation List file for TLS", + {"ssl.CRLFile"}, + {"sslCRLFile"}) + .requires("tls") + .requires("tls.CAFile"); options - ->addOptionChaining("net.ssl.allowInvalidHostnames", - "sslAllowInvalidHostnames", + ->addOptionChaining("net.tls.allowInvalidHostnames", + "tlsAllowInvalidHostnames", moe::Switch, - "allow connections to servers with non-matching hostnames") - .requires("ssl"); + "Allow connections to servers with non-matching hostnames", + {"net.ssl.allowInvalidHostnames"}, + {"sslAllowInvalidHostnames"}) + .requires("tls"); options - ->addOptionChaining("ssl.allowInvalidCertificates", - "sslAllowInvalidCertificates", + ->addOptionChaining("tls.allowInvalidCertificates", + "tlsAllowInvalidCertificates", moe::Switch, - "allow connections to servers with invalid certificates") - .requires("ssl"); + "Allow connections to servers with invalid certificates", + {"ssl.allowInvalidCertificates"}, + {"sslAllowInvalidCertificates"}) + .requires("tls"); - options->addOptionChaining( - "ssl.FIPSMode", "sslFIPSMode", moe::Switch, "activate FIPS 140-2 mode at startup"); + options->addOptionChaining("tls.FIPSMode", + "tlsFIPSMode", + moe::Switch, + "Activate FIPS 140-2 mode at startup", + {"ssl.FIPSMode"}, + {"sslFIPSMode"}); #ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS options - ->addOptionChaining("ssl.certificateSelector", - "sslCertificateSelector", + ->addOptionChaining("tls.certificateSelector", + "tlsCertificateSelector", moe::String, - "SSL Certificate in system store") - .incompatibleWith("ssl.PEMKeyFile") - .incompatibleWith("ssl.PEMKeyPassword") - .setSources(moe::SourceYAMLCLI); + "TLS Certificate in system store", + {"ssl.certificateSelector"}, + {"sslCertificateSelector"}) + .incompatibleWith("tls.PEMKeyFile") + .incompatibleWith("tls.PEMKeyPassword"); #endif - options - ->addOptionChaining( - "ssl.disabledProtocols", - "sslDisabledProtocols", - moe::String, - "Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]") - .setSources(moe::SourceYAMLCLI); + options->addOptionChaining( + "tls.disabledProtocols", + "tlsDisabledProtocols", + moe::String, + "Comma separated list of TLS protocols to disable [TLS1_0,TLS1_1,TLS1_2]", + {"ssl.disabledProtocols"}, + {"sslDisabledProtocols"}); return Status::OK(); } @@ -337,26 +409,26 @@ Status addSSLClientOptions(moe::OptionSection* options) { Status validateSSLServerOptions(const moe::Environment& params) { #ifdef _WIN32 if (params.count("install") || params.count("reinstall")) { - if (params.count("net.ssl.PEMKeyFile") && - !boost::filesystem::path(params["net.ssl.PEMKeyFile"].as<string>()).is_absolute()) { + if (params.count("net.tls.PEMKeyFile") && + !boost::filesystem::path(params["net.tls.PEMKeyFile"].as<string>()).is_absolute()) { return Status(ErrorCodes::BadValue, "PEMKeyFile requires an absolute file path with Windows services"); } - if (params.count("net.ssl.clusterFile") && - !boost::filesystem::path(params["net.ssl.clusterFile"].as<string>()).is_absolute()) { + if (params.count("net.tls.clusterFile") && + !boost::filesystem::path(params["net.tls.clusterFile"].as<string>()).is_absolute()) { return Status(ErrorCodes::BadValue, "clusterFile requires an absolute file path with Windows services"); } - if (params.count("net.ssl.CAFile") && - !boost::filesystem::path(params["net.ssl.CAFile"].as<string>()).is_absolute()) { + if (params.count("net.tls.CAFile") && + !boost::filesystem::path(params["net.tls.CAFile"].as<string>()).is_absolute()) { return Status(ErrorCodes::BadValue, "CAFile requires an absolute file path with Windows services"); } - if (params.count("net.ssl.CRLFile") && - !boost::filesystem::path(params["net.ssl.CRLFile"].as<string>()).is_absolute()) { + if (params.count("net.tls.CRLFile") && + !boost::filesystem::path(params["net.tls.CRLFile"].as<string>()).is_absolute()) { return Status(ErrorCodes::BadValue, "CRLFile requires an absolute file path with Windows services"); } @@ -367,13 +439,13 @@ Status validateSSLServerOptions(const moe::Environment& params) { } Status canonicalizeSSLServerOptions(moe::Environment* params) { - if (params->count("net.ssl.sslOnNormalPorts") && - (*params)["net.ssl.sslOnNormalPorts"].as<bool>() == true) { - Status ret = params->set("net.ssl.mode", moe::Value(std::string("requireSSL"))); + if (params->count("net.tls.tlsOnNormalPorts") && + (*params)["net.tls.tlsOnNormalPorts"].as<bool>() == true) { + Status ret = params->set("net.tls.mode", moe::Value(std::string("requireTLS"))); if (!ret.isOK()) { return ret; } - ret = params->remove("net.ssl.sslOnNormalPorts"); + ret = params->remove("net.tls.tlsOnNormalPorts"); if (!ret.isOK()) { return ret; } @@ -383,7 +455,20 @@ Status canonicalizeSSLServerOptions(moe::Environment* params) { } Status storeSSLServerOptions(const moe::Environment& params) { - if (params.count("net.ssl.mode")) { + if (params.count("net.tls.mode")) { + std::string sslModeParam = params["net.tls.mode"].as<string>(); + if (sslModeParam == "disabled") { + sslGlobalParams.sslMode.store(SSLParams::SSLMode_disabled); + } else if (sslModeParam == "allowTLS") { + sslGlobalParams.sslMode.store(SSLParams::SSLMode_allowSSL); + } else if (sslModeParam == "preferTLS") { + sslGlobalParams.sslMode.store(SSLParams::SSLMode_preferSSL); + } else if (sslModeParam == "requireTLS") { + sslGlobalParams.sslMode.store(SSLParams::SSLMode_requireSSL); + } else { + return Status(ErrorCodes::BadValue, "unsupported value for tlsMode " + sslModeParam); + } + } else if (params.count("net.ssl.mode")) { std::string sslModeParam = params["net.ssl.mode"].as<string>(); if (sslModeParam == "disabled") { sslGlobalParams.sslMode.store(SSLParams::SSLMode_disabled); @@ -398,50 +483,50 @@ Status storeSSLServerOptions(const moe::Environment& params) { } } - if (params.count("net.ssl.PEMKeyFile")) { + if (params.count("net.tls.PEMKeyFile")) { sslGlobalParams.sslPEMKeyFile = - boost::filesystem::absolute(params["net.ssl.PEMKeyFile"].as<string>()).generic_string(); + boost::filesystem::absolute(params["net.tls.PEMKeyFile"].as<string>()).generic_string(); } - if (params.count("net.ssl.PEMKeyPassword")) { - sslGlobalParams.sslPEMKeyPassword = params["net.ssl.PEMKeyPassword"].as<string>(); + if (params.count("net.tls.PEMKeyPassword")) { + sslGlobalParams.sslPEMKeyPassword = params["net.tls.PEMKeyPassword"].as<string>(); } - if (params.count("net.ssl.clusterFile")) { + if (params.count("net.tls.clusterFile")) { sslGlobalParams.sslClusterFile = - boost::filesystem::absolute(params["net.ssl.clusterFile"].as<string>()) + boost::filesystem::absolute(params["net.tls.clusterFile"].as<string>()) .generic_string(); } - if (params.count("net.ssl.clusterPassword")) { - sslGlobalParams.sslClusterPassword = params["net.ssl.clusterPassword"].as<string>(); + if (params.count("net.tls.clusterPassword")) { + sslGlobalParams.sslClusterPassword = params["net.tls.clusterPassword"].as<string>(); } - if (params.count("net.ssl.CAFile")) { + if (params.count("net.tls.CAFile")) { sslGlobalParams.sslCAFile = - boost::filesystem::absolute(params["net.ssl.CAFile"].as<std::string>()) + boost::filesystem::absolute(params["net.tls.CAFile"].as<std::string>()) .generic_string(); } - if (params.count("net.ssl.CRLFile")) { + if (params.count("net.tls.CRLFile")) { sslGlobalParams.sslCRLFile = - boost::filesystem::absolute(params["net.ssl.CRLFile"].as<std::string>()) + boost::filesystem::absolute(params["net.tls.CRLFile"].as<std::string>()) .generic_string(); } - if (params.count("net.ssl.sslCipherConfig")) { + if (params.count("net.tls.tlsCipherConfig")) { warning() - << "net.ssl.sslCipherConfig is deprecated. It will be removed in a future release."; + << "net.tls.tlsCipherConfig is deprecated. It will be removed in a future release."; if (!sslGlobalParams.sslCipherConfig.empty()) { return Status(ErrorCodes::BadValue, - "net.ssl.sslCipherConfig is incompatible with the openSSLCipherConfig " + "net.tls.tlsCipherConfig is incompatible with the openTLSCipherConfig " "setParameter"); } - sslGlobalParams.sslCipherConfig = params["net.ssl.sslCipherConfig"].as<string>(); + sslGlobalParams.sslCipherConfig = params["net.tls.tlsCipherConfig"].as<string>(); } - if (params.count("net.ssl.disabledProtocols")) { - const auto status = storeDisabledProtocols(params["net.ssl.disabledProtocols"].as<string>(), + if (params.count("net.tls.disabledProtocols")) { + const auto status = storeDisabledProtocols(params["net.tls.disabledProtocols"].as<string>(), DisabledProtocolsMode::kAcceptNegativePrefix); if (!status.isOK()) { return status; @@ -460,40 +545,44 @@ Status storeSSLServerOptions(const moe::Environment& params) { #endif } - if (params.count("net.ssl.weakCertificateValidation")) { + if (params.count("net.tls.weakCertificateValidation")) { sslGlobalParams.sslWeakCertificateValidation = - params["net.ssl.weakCertificateValidation"].as<bool>(); - } else if (params.count("net.ssl.allowConnectionsWithoutCertificates")) { + params["net.tls.weakCertificateValidation"].as<bool>(); + } else if (params.count("net.tls.allowConnectionsWithoutCertificates")) { sslGlobalParams.sslWeakCertificateValidation = - params["net.ssl.allowConnectionsWithoutCertificates"].as<bool>(); + params["net.tls.allowConnectionsWithoutCertificates"].as<bool>(); } - if (params.count("net.ssl.allowInvalidHostnames")) { + + if (params.count("net.tls.allowInvalidHostnames")) { sslGlobalParams.sslAllowInvalidHostnames = - params["net.ssl.allowInvalidHostnames"].as<bool>(); + params["net.tls.allowInvalidHostnames"].as<bool>(); } - if (params.count("net.ssl.allowInvalidCertificates")) { + + if (params.count("net.tls.allowInvalidCertificates")) { sslGlobalParams.sslAllowInvalidCertificates = - params["net.ssl.allowInvalidCertificates"].as<bool>(); + params["net.tls.allowInvalidCertificates"].as<bool>(); } - if (params.count("net.ssl.FIPSMode")) { - sslGlobalParams.sslFIPSMode = params["net.ssl.FIPSMode"].as<bool>(); + + if (params.count("net.tls.FIPSMode")) { + sslGlobalParams.sslFIPSMode = params["net.tls.FIPSMode"].as<bool>(); } #ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS - if (params.count("net.ssl.certificateSelector")) { + if (params.count("net.tls.certificateSelector")) { const auto status = parseCertificateSelector(&sslGlobalParams.sslCertificateSelector, - "net.ssl.certificateSelector", - params["net.ssl.certificateSelector"].as<std::string>()); + "net.tls.certificateSelector", + params["net.tls.certificateSelector"].as<std::string>()); if (!status.isOK()) { return status; } } - if (params.count("net.ssl.clusterCertificateSelector")) { + + if (params.count("net.tls.clusterCertificateSelector")) { const auto status = parseCertificateSelector( &sslGlobalParams.sslClusterCertificateSelector, - "net.ssl.clusterCertificateSelector", - params["net.ssl.clusterCertificateSelector"].as<std::string>()); + "net.tls.clusterCertificateSelector", + params["net.tls.clusterCertificateSelector"].as<std::string>()); if (!status.isOK()) { return status; } @@ -501,20 +590,24 @@ Status storeSSLServerOptions(const moe::Environment& params) { #endif int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); + auto a = sslGlobalParams.sslMode.load(); + auto b = sslGlobalParams.sslMode.load(); + if (a == b) { + } if (sslGlobalParams.sslMode.load() != SSLParams::SSLMode_disabled) { - bool usingCertifiateSelectors = params.count("net.ssl.certificateSelector"); + bool usingCertifiateSelectors = params.count("net.tls.certificateSelector"); if (sslGlobalParams.sslPEMKeyFile.size() == 0 && !usingCertifiateSelectors) { return Status(ErrorCodes::BadValue, - "need sslPEMKeyFile or certificateSelector when SSL is enabled"); + "need tlsPEMKeyFile or certificateSelector when TLS is enabled"); } if (!sslGlobalParams.sslCRLFile.empty() && sslGlobalParams.sslCAFile.empty()) { - return Status(ErrorCodes::BadValue, "need sslCAFile with sslCRLFile"); + return Status(ErrorCodes::BadValue, "need tlsCAFile with tlsCRLFile"); } std::string sslCANotFoundError( - "No SSL certificate validation can be performed since" + "No TLS certificate validation can be performed since" " no CA file has been provided; please specify an" - " sslCAFile parameter"); + " tlsCAFile parameter"); // When using cetificate selectors, we use the local system certificate store for verifying // X.509 certificates for auth instead of relying on a CA file. @@ -526,21 +619,21 @@ Status storeSSLServerOptions(const moe::Environment& params) { sslGlobalParams.sslClusterFile.size() || sslGlobalParams.sslClusterPassword.size() || sslGlobalParams.sslCAFile.size() || sslGlobalParams.sslCRLFile.size() || sslGlobalParams.sslCipherConfig.size() || - params.count("net.ssl.disabledProtocols") || + params.count("net.tls.disabledProtocols") || #ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS - params.count("net.ssl.certificateSelector") || - params.count("net.ssl.clusterCertificateSelector") || + params.count("net.tls.certificateSelector") || + params.count("net.tls.clusterCertificateSelector") || #endif sslGlobalParams.sslWeakCertificateValidation) { return Status(ErrorCodes::BadValue, - "need to enable SSL via the sslMode flag when " - "using SSL configuration parameters"); + "need to enable TLS via the sslMode/tlsMode flag when " + "using TLS configuration parameters"); } if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_sendKeyFile || clusterAuthMode == ServerGlobalParams::ClusterAuthMode_sendX509 || clusterAuthMode == ServerGlobalParams::ClusterAuthMode_x509) { if (sslGlobalParams.sslMode.load() == SSLParams::SSLMode_disabled) { - return Status(ErrorCodes::BadValue, "need to enable SSL via the sslMode flag"); + return Status(ErrorCodes::BadValue, "need to enable TLS via the tlsMode flag"); } } if (sslGlobalParams.sslMode.load() == SSLParams::SSLMode_allowSSL) { @@ -549,42 +642,50 @@ Status storeSSLServerOptions(const moe::Environment& params) { (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_x509 && !serverGlobalParams.transitionToAuth)) { return Status(ErrorCodes::BadValue, - "cannot have x.509 cluster authentication in allowSSL mode"); + "cannot have x.509 cluster authentication in allowTLS mode"); } } return Status::OK(); } Status storeSSLClientOptions(const moe::Environment& params) { - if (params.count("ssl") && params["ssl"].as<bool>() == true) { + if (params.count("tls") && params["tls"].as<bool>() == true) { sslGlobalParams.sslMode.store(SSLParams::SSLMode_requireSSL); } - if (params.count("ssl.PEMKeyFile")) { - sslGlobalParams.sslPEMKeyFile = params["ssl.PEMKeyFile"].as<std::string>(); + + if (params.count("tls.PEMKeyFile")) { + sslGlobalParams.sslPEMKeyFile = params["tls.PEMKeyFile"].as<std::string>(); } - if (params.count("ssl.PEMKeyPassword")) { - sslGlobalParams.sslPEMKeyPassword = params["ssl.PEMKeyPassword"].as<std::string>(); + + if (params.count("tls.PEMKeyPassword")) { + sslGlobalParams.sslPEMKeyPassword = params["tls.PEMKeyPassword"].as<std::string>(); } - if (params.count("ssl.CAFile")) { - sslGlobalParams.sslCAFile = params["ssl.CAFile"].as<std::string>(); + + if (params.count("tls.CAFile")) { + sslGlobalParams.sslCAFile = params["tls.CAFile"].as<std::string>(); } - if (params.count("ssl.CRLFile")) { - sslGlobalParams.sslCRLFile = params["ssl.CRLFile"].as<std::string>(); + + if (params.count("tls.CRLFile")) { + sslGlobalParams.sslCRLFile = params["tls.CRLFile"].as<std::string>(); } - if (params.count("net.ssl.allowInvalidHostnames")) { + + + if (params.count("net.tls.allowInvalidHostnames")) { sslGlobalParams.sslAllowInvalidHostnames = - params["net.ssl.allowInvalidHostnames"].as<bool>(); + params["net.tls.allowInvalidHostnames"].as<bool>(); } - if (params.count("ssl.allowInvalidCertificates")) { + + if (params.count("tls.allowInvalidCertificates")) { sslGlobalParams.sslAllowInvalidCertificates = true; } - if (params.count("ssl.FIPSMode")) { + + if (params.count("tls.FIPSMode")) { sslGlobalParams.sslFIPSMode = true; } - if (params.count("ssl.disabledProtocols")) { + if (params.count("tls.disabledProtocols")) { const auto status = - storeDisabledProtocols(params["ssl.disabledProtocols"].as<std::string>()); + storeDisabledProtocols(params["tls.disabledProtocols"].as<std::string>()); if (!status.isOK()) { return status; } @@ -603,11 +704,11 @@ Status storeSSLClientOptions(const moe::Environment& params) { } #ifdef MONGO_CONFIG_SSL_CERTIFICATE_SELECTORS - if (params.count("ssl.certificateSelector")) { + if (params.count("tls.certificateSelector")) { const auto status = parseCertificateSelector(&sslGlobalParams.sslCertificateSelector, - "ssl.certificateSelector", - params["ssl.certificateSelector"].as<std::string>()); + "tls.certificateSelector", + params["tls.certificateSelector"].as<std::string>()); if (!status.isOK()) { return status; } diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h index f8071b782a6..e7ba7656fe4 100644 --- a/src/mongo/util/net/ssl_options.h +++ b/src/mongo/util/net/ssl_options.h @@ -77,6 +77,7 @@ struct SSLParams { bool sslAllowInvalidHostnames = false; // --sslAllowInvalidHostnames bool disableNonSSLConnectionLogging = false; // --setParameter disableNonSSLConnectionLogging=true + bool disableNonSSLConnectionLoggingSet = false; bool suppressNoTLSPeerCertificateWarning = false; // --setParameter suppressNoTLSPeerCertificateWarning diff --git a/src/mongo/util/options_parser/option_description.cpp b/src/mongo/util/options_parser/option_description.cpp index ae0b22965af..4b0f80b4334 100644 --- a/src/mongo/util/options_parser/option_description.cpp +++ b/src/mongo/util/options_parser/option_description.cpp @@ -90,26 +90,9 @@ Status checkValueType(OptionType type, Value value) { OptionDescription::OptionDescription(const std::string& dottedName, const std::string& singleName, const OptionType type, - const std::string& description) - : _dottedName(dottedName), - _singleName(singleName), - _type(type), - _description(description), - _isVisible(true), - _default(Value()), - _implicit(Value()), - _isComposing(false), - _sources(SourceAll), - _positionalStart(-1), - _positionalEnd(-1), - _constraints(), - _deprecatedDottedNames() {} - -OptionDescription::OptionDescription(const std::string& dottedName, - const std::string& singleName, - const OptionType type, const std::string& description, - const std::vector<std::string>& deprecatedDottedNames) + const std::vector<std::string>& deprecatedDottedNames, + const std::vector<std::string>& deprecatedSingleNames) : _dottedName(dottedName), _singleName(singleName), _type(type), @@ -122,22 +105,8 @@ OptionDescription::OptionDescription(const std::string& dottedName, _positionalStart(-1), _positionalEnd(-1), _constraints(), - _deprecatedDottedNames(deprecatedDottedNames) { - // Verify deprecated dotted names. - // No empty deprecated dotted names. - if (std::count(_deprecatedDottedNames.begin(), _deprecatedDottedNames.end(), "")) { - StringBuilder sb; - sb << "Attempted to register option with empty string for deprecated dotted name"; - uasserted(ErrorCodes::BadValue, sb.str()); - } - // Should not be the same as _dottedName. - if (std::count(_deprecatedDottedNames.begin(), _deprecatedDottedNames.end(), dottedName)) { - StringBuilder sb; - sb << "Attempted to register option with conflict between dottedName and deprecated " - << "dotted name: " << _dottedName; - uasserted(ErrorCodes::BadValue, sb.str()); - } -} + _deprecatedDottedNames(deprecatedDottedNames), + _deprecatedSingleNames(deprecatedSingleNames) {} OptionDescription& OptionDescription::hidden() { _isVisible = false; diff --git a/src/mongo/util/options_parser/option_description.h b/src/mongo/util/options_parser/option_description.h index 5d6bce0a048..98f9ca06e7e 100644 --- a/src/mongo/util/options_parser/option_description.h +++ b/src/mongo/util/options_parser/option_description.h @@ -78,13 +78,9 @@ public: OptionDescription(const std::string& dottedName, const std::string& singleName, const OptionType type, - const std::string& description); - - OptionDescription(const std::string& dottedName, - const std::string& singleName, - const OptionType type, const std::string& description, - const std::vector<std::string>& deprecatedDottedNames); + const std::vector<std::string>& deprecatedDottedNames = {}, + const std::vector<std::string>& deprecatedSingleNames = {}); /* * The following functions are part of the chaining interface for option registration. See @@ -231,6 +227,8 @@ public: // Deprecated dotted names - aliases for '_dottedName'. std::vector<std::string> _deprecatedDottedNames; + // Deprecated single names - aliases for '_singleName'. + std::vector<std::string> _deprecatedSingleNames; }; } // namespace optionenvironment diff --git a/src/mongo/util/options_parser/option_section.cpp b/src/mongo/util/options_parser/option_section.cpp index ff77ab0be10..53889a27777 100644 --- a/src/mongo/util/options_parser/option_section.cpp +++ b/src/mongo/util/options_parser/option_section.cpp @@ -57,69 +57,115 @@ Status OptionSection::addSection(const OptionSection& subSection) { return Status::OK(); } -OptionDescription& OptionSection::addOptionChaining(const std::string& dottedName, - const std::string& singleName, - const OptionType type, - const std::string& description) { - std::vector<std::string> v; - return addOptionChaining(dottedName, singleName, type, description, v); -} - -OptionDescription& OptionSection::addOptionChaining(const std::string& dottedName, - const std::string& singleName, - const OptionType type, - const std::string& description, - const std::string& deprecatedDottedName) { - std::vector<std::string> v; - v.push_back(deprecatedDottedName); - return addOptionChaining(dottedName, singleName, type, description, v); -} - OptionDescription& OptionSection::addOptionChaining( const std::string& dottedName, const std::string& singleName, const OptionType type, const std::string& description, - const std::vector<std::string>& deprecatedDottedNames) { - OptionDescription option(dottedName, singleName, type, description, deprecatedDottedNames); + const std::vector<std::string>& deprecatedDottedNames, + const std::vector<std::string>& deprecatedSingleNames) { + OptionDescription option( + dottedName, singleName, type, description, deprecatedDottedNames, deprecatedSingleNames); + // Verify deprecated dotted names. + // No empty deprecated dotted names. + if (std::count(deprecatedDottedNames.begin(), deprecatedDottedNames.end(), "")) { + StringBuilder sb; + sb << "Attempted to register option with empty string for deprecatedDottedName"; + uasserted(ErrorCodes::InternalError, sb.str()); + } - // Verify that single name, the dotted name and deprecated dotted names for this option - // conflicts with the names for any options we have already registered. - std::list<OptionDescription>::const_iterator oditerator; - for (oditerator = _options.begin(); oditerator != _options.end(); oditerator++) { - if (option._dottedName == oditerator->_dottedName) { + // Should not be the same as dottedName. + if (std::count(deprecatedDottedNames.begin(), deprecatedDottedNames.end(), dottedName)) { + StringBuilder sb; + sb << "Attempted to register option with conflict between dottedName and " + << "deprecatedDottedName: " << dottedName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + // Verify deprecated single names. + // No empty deprecated single names. + if (std::count(deprecatedSingleNames.begin(), deprecatedSingleNames.end(), "")) { + StringBuilder sb; + sb << "Attempted to register option with empty string for deprecatedSingleName"; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + // Should not be the same as singleName. + if (std::count(deprecatedSingleNames.begin(), deprecatedSingleNames.end(), singleName)) { + StringBuilder sb; + sb << "Attempted to register option with conflict between singleName and " + << "deprecatedSingleName: " << singleName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + for (const OptionDescription& od : _options) { + if (option._dottedName == od._dottedName) { StringBuilder sb; - sb << "Attempted to register option with duplicate dottedName: " << option._dottedName; + sb << "Attempted to register option with duplicate dottedName: " << dottedName; uasserted(ErrorCodes::InternalError, sb.str()); } + // Allow options with empty singleName since some options are not allowed on the command // line - if (!option._singleName.empty() && option._singleName == oditerator->_singleName) { + if (!option._singleName.empty() && option._singleName == od._singleName) { StringBuilder sb; - sb << "Attempted to register option with duplicate singleName: " << option._singleName; + sb << "Attempted to register option with duplicate singleName: " << singleName; uasserted(ErrorCodes::InternalError, sb.str()); } - // Deprecated dotted names should not conflict with dotted names or deprecated dotted - // names of any other options. - if (std::count(option._deprecatedDottedNames.begin(), - option._deprecatedDottedNames.end(), - oditerator->_dottedName)) { + + if (std::count( + od._deprecatedDottedNames.begin(), od._deprecatedDottedNames.end(), dottedName)) { StringBuilder sb; - sb << "Attempted to register option with duplicate deprecated dotted name " - << "(with another option's dotted name): " << option._dottedName; - uasserted(ErrorCodes::BadValue, sb.str()); + sb << "Attempted to register option with conflict between dottedName and existing " + "deprecatedDottedName: " + << dottedName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + if (std::count( + od._deprecatedSingleNames.begin(), od._deprecatedSingleNames.end(), singleName)) { + StringBuilder sb; + sb << "Attempted to register option with conflict between singleName and existing " + "deprecatedSingleName: " + << singleName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + for (const std::string& deprecatedDottedName : deprecatedDottedNames) { + if (deprecatedDottedName == od._dottedName) { + StringBuilder sb; + sb << "Attempted to register option with conflict between deprecatedDottedName " + "and existing dottedName: " + << dottedName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + if (std::count(od._deprecatedDottedNames.begin(), + od._deprecatedDottedNames.end(), + deprecatedDottedName)) { + StringBuilder sb; + sb << "Attempted to register option with duplicate deprecatedDottedName: " + << deprecatedDottedName; + uasserted(ErrorCodes::InternalError, sb.str()); + } } - for (std::vector<std::string>::const_iterator i = - oditerator->_deprecatedDottedNames.begin(); - i != oditerator->_deprecatedDottedNames.end(); - ++i) { - if (std::count(option._deprecatedDottedNames.begin(), - option._deprecatedDottedNames.end(), - *i)) { + + for (const std::string& deprecatedSingleName : deprecatedSingleNames) { + if (deprecatedSingleName == od._singleName) { StringBuilder sb; - sb << "Attempted to register option with duplicate deprecated dotted name " << *i - << " (other option " << oditerator->_dottedName << ")"; - uasserted(ErrorCodes::BadValue, sb.str()); + sb << "Attempted to register option with conflict between deprecatedSingleName " + "and existing singleName: " + << singleName; + uasserted(ErrorCodes::InternalError, sb.str()); + } + + if (std::count(od._deprecatedSingleNames.begin(), + od._deprecatedSingleNames.end(), + deprecatedSingleName)) { + StringBuilder sb; + sb << "Attempted to register option with duplicate deprecatedSingleName: " + << deprecatedSingleName; + uasserted(ErrorCodes::InternalError, sb.str()); } } } @@ -324,6 +370,18 @@ Status OptionSection::getBoostOptions(po::options_description* boostOptions, boostOptions->add_options()(oditerator->_singleName.c_str(), boostType.release(), oditerator->_description.c_str()); + + for (const std::string& depreatedSingleName : oditerator->_deprecatedSingleNames) { + std::unique_ptr<po::value_semantic> boostTypeDep; + Status retDep = typeToBoostType(&boostTypeDep, + oditerator->_type, + includeDefaults ? oditerator->_default : Value(), + oditerator->_implicit, + !(sources & SourceCommandLine)); + boostOptions->add_options()(depreatedSingleName.c_str(), + boostTypeDep.release(), + oditerator->_description.c_str()); + } } } diff --git a/src/mongo/util/options_parser/option_section.h b/src/mongo/util/options_parser/option_section.h index cea28d523d1..435711a1dea 100644 --- a/src/mongo/util/options_parser/option_section.h +++ b/src/mongo/util/options_parser/option_section.h @@ -110,22 +110,13 @@ public: * as another option. These represent programming errors that should not happen during * normal operation. */ - OptionDescription& addOptionChaining(const std::string& dottedName, - const std::string& singleName, - const OptionType type, - const std::string& description); - - OptionDescription& addOptionChaining(const std::string& dottedName, - const std::string& singleName, - const OptionType type, - const std::string& description, - const std::string& deprecatedDottedName); - - OptionDescription& addOptionChaining(const std::string& dottedName, - const std::string& singleName, - const OptionType type, - const std::string& description, - const std::vector<std::string>& deprecatedDottedNames); + OptionDescription& addOptionChaining( + const std::string& dottedName, + const std::string& singleName, + const OptionType type, + const std::string& description, + const std::vector<std::string>& deprecatedDottedNames = {}, + const std::vector<std::string>& deprecatedSingleNames = {}); // These functions are used by the OptionsParser to make calls into boost::program_options Status getBoostOptions(po::options_description* boostOptions, diff --git a/src/mongo/util/options_parser/options_parser.cpp b/src/mongo/util/options_parser/options_parser.cpp index ec1705c4e03..399c989dbfd 100644 --- a/src/mongo/util/options_parser/options_parser.cpp +++ b/src/mongo/util/options_parser/options_parser.cpp @@ -191,6 +191,7 @@ Status boostAnyToValue(const boost::any& anyValue, const OptionType& type, const Key& key, Value* value) { + try { if (anyValue.type() == typeid(StringVector_t)) { *value = Value(boost::any_cast<StringVector_t>(anyValue)); @@ -352,6 +353,90 @@ Status YAMLNodeToValue(const YAML::Node& YAMLNode, return stringToValue(stringVal, type, key, value); } +Status checkLongName(const po::variables_map& vm, + const std::string& singleName, + const std::string& canonicalSingleName, + const std::string& dottedName, + const OptionType& type, + Environment* environment, + bool* optionAdded) { + // Trim off the short option from our name so we can look it up correctly in our map + std::string long_name; + std::string::size_type commaOffset = singleName.find(','); + if (commaOffset != string::npos) { + if (commaOffset != singleName.size() - 2) { + StringBuilder sb; + sb << "Unexpected comma in option name: \"" << singleName << "\"" + << ": option name must be in the format \"option,o\" or \"option\", " + << "where \"option\" is the long name and \"o\" is the optional one " + << "character short alias"; + return Status(ErrorCodes::BadValue, sb.str()); + } + long_name = singleName.substr(0, commaOffset); + } else { + long_name = singleName; + } + + if (vm.count(long_name)) { + if (!vm[long_name].defaulted() && singleName != canonicalSingleName) { + warning() << "Option: " << singleName << " is deprecated. Please use " + << canonicalSingleName << " instead."; + } else if (long_name == "sslMode") { + warning() << "Option: sslMode is deprecated. Please use tlsMode instead."; + } + + Value optionValue; + Status ret = boostAnyToValue(vm[long_name].value(), type, long_name, &optionValue); + if (!ret.isOK()) { + return ret; + } + + // If this is really a StringMap, try to split on "key=value" for each element + // in our StringVector + if (type == StringMap) { + StringVector_t keyValueVector; + ret = optionValue.get(&keyValueVector); + if (!ret.isOK()) { + return ret; + } + StringMap_t mapValue; + for (StringVector_t::iterator keyValueVectorIt = keyValueVector.begin(); + keyValueVectorIt != keyValueVector.end(); + ++keyValueVectorIt) { + std::string key; + std::string value; + if (!mongoutils::str::splitOn(*keyValueVectorIt, '=', key, value)) { + StringBuilder sb; + sb << "Illegal option assignment: \"" << *keyValueVectorIt << "\""; + return Status(ErrorCodes::BadValue, sb.str()); + } + // Make sure we aren't setting an option to two different values + if (mapValue.count(key) > 0 && mapValue[key] != value) { + StringBuilder sb; + sb << "Key Value Option: " << dottedName + << " has a duplicate key from the same source: " << key; + return Status(ErrorCodes::BadValue, sb.str()); + } + mapValue[key] = value; + } + optionValue = Value(mapValue); + } + if (!(*optionAdded)) { + environment->set(dottedName, optionValue).transitional_ignore(); + } else if (!vm[long_name].defaulted()) { + StringBuilder sb; + sb << "Error parsing command line: Multiple occurrences of option \"" << long_name + << "\""; + return Status(ErrorCodes::BadValue, sb.str()); + } + if (!vm[long_name].defaulted()) { + *optionAdded = true; + } + } + + return Status::OK(); +} + // Add all the values in the given variables_map to our environment. See comments at the // beginning of this section. Status addBoostVariablesToEnvironment(const po::variables_map& vm, @@ -363,66 +448,34 @@ Status addBoostVariablesToEnvironment(const po::variables_map& vm, return ret; } - for (std::vector<OptionDescription>::const_iterator iterator = options_vector.begin(); - iterator != options_vector.end(); - iterator++) { - // Trim off the short option from our name so we can look it up correctly in our map - std::string long_name; - std::string::size_type commaOffset = iterator->_singleName.find(','); - if (commaOffset != string::npos) { - if (commaOffset != iterator->_singleName.size() - 2) { - StringBuilder sb; - sb << "Unexpected comma in option name: \"" << iterator->_singleName << "\"" - << ": option name must be in the format \"option,o\" or \"option\", " - << "where \"option\" is the long name and \"o\" is the optional one " - << "character short alias"; - return Status(ErrorCodes::BadValue, sb.str()); - } - long_name = iterator->_singleName.substr(0, commaOffset); - } else { - long_name = iterator->_singleName; + for (const OptionDescription& od : options_vector) { + + bool optionAdded = false; + ret = checkLongName(vm, + od._singleName, + od._singleName, + od._dottedName, + od._type, + environment, + &optionAdded); + + if (!ret.isOK()) { + return ret; } - if (vm.count(long_name)) { - Value optionValue; - Status ret = - boostAnyToValue(vm[long_name].value(), iterator->_type, long_name, &optionValue); + for (const std::string& deprecatedSingleName : od._deprecatedSingleNames) { + + ret = checkLongName(vm, + deprecatedSingleName, + od._singleName, + od._dottedName, + od._type, + environment, + &optionAdded); + if (!ret.isOK()) { return ret; } - - // If this is really a StringMap, try to split on "key=value" for each element - // in our StringVector - if (iterator->_type == StringMap) { - StringVector_t keyValueVector; - ret = optionValue.get(&keyValueVector); - if (!ret.isOK()) { - return ret; - } - StringMap_t mapValue; - for (StringVector_t::iterator keyValueVectorIt = keyValueVector.begin(); - keyValueVectorIt != keyValueVector.end(); - ++keyValueVectorIt) { - std::string key; - std::string value; - if (!mongoutils::str::splitOn(*keyValueVectorIt, '=', key, value)) { - StringBuilder sb; - sb << "Illegal option assignment: \"" << *keyValueVectorIt << "\""; - return Status(ErrorCodes::BadValue, sb.str()); - } - // Make sure we aren't setting an option to two different values - if (mapValue.count(key) > 0 && mapValue[key] != value) { - StringBuilder sb; - sb << "Key Value Option: " << iterator->_dottedName - << " has a duplicate key from the same source: " << key; - return Status(ErrorCodes::BadValue, sb.str()); - } - mapValue[key] = value; - } - optionValue = Value(mapValue); - } - - environment->set(iterator->_dottedName, optionValue).transitional_ignore(); } } return Status::OK(); @@ -965,6 +1018,16 @@ StatusWith<std::vector<std::string>> transformImplictOptions( } else { implicitOptions[opt._singleName] = &opt; } + + for (const std::string& deprecatedSingleName : opt._deprecatedSingleNames) { + pos = deprecatedSingleName.find(','); + if (pos != string::npos) { + implicitOptions[deprecatedSingleName.substr(0, pos)] = &opt; + implicitOptions[deprecatedSingleName.substr(pos + 1)] = &opt; + } else { + implicitOptions[deprecatedSingleName] = &opt; + } + } } std::vector<std::string> args; diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp index edbece614e6..144d5fa7a2a 100644 --- a/src/mongo/util/options_parser/options_parser_test.cpp +++ b/src/mongo/util/options_parser/options_parser_test.cpp @@ -3801,7 +3801,7 @@ TEST(YAMLConfigFile, DeprecatedDottedNameDeprecatedOnly) { moe::OptionSection testOpts; testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse"); - testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", "dotted.deprecated"); + testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", {"dotted.deprecated"}); std::vector<std::string> argv; argv.push_back("binaryname"); @@ -3824,14 +3824,14 @@ TEST(YAMLConfigFile, DeprecatedDottedNameDeprecatedOnly) { TEST(YAMLConfigFile, DeprecatedDottedNameSameAsCanonicalDottedName) { moe::OptionSection testOpts; ASSERT_THROWS(testOpts.addOptionChaining( - "dotted.canonical", "var1", moe::Int, "Var1", "dotted.canonical"), + "dotted.canonical", "var1", moe::Int, "Var1", {"dotted.canonical"}), ::mongo::DBException); } // Deprecated dotted name cannot be the empty string. TEST(YAMLConfigFile, DeprecatedDottedNameEmptyString) { moe::OptionSection testOpts; - ASSERT_THROWS(testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", ""), + ASSERT_THROWS(testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", {""}), ::mongo::DBException); } @@ -3840,16 +3840,17 @@ TEST(YAMLConfigFile, DeprecatedDottedNameSameAsOtherOptionsDottedName) { moe::OptionSection testOpts; testOpts.addOptionChaining("dotted.canonical1", "var1", moe::Int, "Var1"); ASSERT_THROWS(testOpts.addOptionChaining( - "dotted.canonical2", "var2", moe::Int, "Var2", "dotted.canonical1"), + "dotted.canonical2", "var2", moe::Int, "Var2", {"dotted.canonical1"}), ::mongo::DBException); } // Deprecated dotted name cannot be the same as another option's deprecated dotted name. TEST(YAMLConfigFile, DeprecatedDottedNameSameAsOtherOptionsDeprecatedDottedName) { moe::OptionSection testOpts; - testOpts.addOptionChaining("dotted.canonical1", "var1", moe::Int, "Var1", "dotted.deprecated1"); + testOpts.addOptionChaining( + "dotted.canonical1", "var1", moe::Int, "Var1", {"dotted.deprecated"}); ASSERT_THROWS(testOpts.addOptionChaining( - "dotted.canonical2", "var2", moe::Int, "Var2", "dotted.deprecated1"), + "dotted.canonical2", "var2", moe::Int, "Var2", {"dotted.deprecated"}), ::mongo::DBException); } @@ -3861,7 +3862,7 @@ TEST(YAMLConfigFile, DeprecatedDottedNameCanonicalAndDeprecated) { moe::OptionSection testOpts; testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse"); - testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", "dotted.deprecated"); + testOpts.addOptionChaining("dotted.canonical", "var1", moe::Int, "Var1", {"dotted.deprecated"}); std::vector<std::string> argv; argv.push_back("binaryname"); |