diff options
author | Gregory Noma <gregory.noma@gmail.com> | 2018-06-07 16:30:07 -0400 |
---|---|---|
committer | Gregory Noma <gregory.noma@gmail.com> | 2018-07-05 10:07:46 -0400 |
commit | 96628864b50e4d0377dd920eef647e46c5bc5db8 (patch) | |
tree | 36eb7c7133a1464e28d57bad7cc0e0fce4971ec5 /src/mongo | |
parent | 711c076ef57c0ce3517ab9385c2fd3a005c941b3 (diff) | |
download | mongo-96628864b50e4d0377dd920eef647e46c5bc5db8.tar.gz |
SERVER-29917 Alias server options starting with 'ssl' to parameters starting with 'tls'
Add support for deprecated single names. All 'ssl' options are now
deprecated, superceded by their 'tls' counterparts. Add tests for
these options in server_options_test. Re-add functionality of
disableNonSSLConnectionLogging.
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"); |