summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2015-04-13 17:36:00 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2015-04-21 17:05:12 -0400
commit2366756e21aa4ef2d8c05502a5fe934f779ae2ff (patch)
treea27ca469a4896b3cf957a362f6eacf868ae56c48
parent4c1abad5a285071e55f1a88f619b13a290b3e794 (diff)
downloadmongo-2366756e21aa4ef2d8c05502a5fe934f779ae2ff.tar.gz
SERVER-17591: Allow TLS protocols to be disabled
-rw-r--r--src/mongo/util/net/ssl_manager.cpp33
-rw-r--r--src/mongo/util/net/ssl_options.cpp31
-rw-r--r--src/mongo/util/net/ssl_options.h8
3 files changed, 71 insertions, 1 deletions
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index af8bf305d91..30c76950b31 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -68,6 +68,18 @@ namespace mongo {
return "";
}
#else
+
+// Old copies of OpenSSL will not have constants to disable protocols they don't support.
+// Define them to values we can OR together safely to generically disable these protocols across
+// all versions of OpenSSL.
+#ifndef SSL_OP_NO_TLSv1_1
+#define SSL_OP_NO_TLSv1_1 0
+#endif
+#ifndef SSL_OP_NO_TLSv1_2
+#define SSL_OP_NO_TLSv1_2 0
+#endif
+
+
const std::string getSSLVersion(const std::string &prefix, const std::string &suffix) {
return prefix + SSLeay_version(SSLEAY_VERSION) + suffix;
}
@@ -158,6 +170,7 @@ namespace mongo {
const std::string& pempwd,
const std::string& clusterfile,
const std::string& clusterpwd,
+ const std::vector<SSLGlobalParams::Protocols>& disabledProtocols,
const std::string& cafile = "",
const std::string& crlfile = "",
const std::string& cipherConfig = "",
@@ -172,6 +185,7 @@ namespace mongo {
cafile(cafile),
crlfile(crlfile),
cipherConfig(cipherConfig),
+ disabledProtocols(disabledProtocols),
weakCertificateValidation(weakCertificateValidation),
allowInvalidCertificates(allowInvalidCertificates),
allowInvalidHostnames(allowInvalidHostnames),
@@ -184,6 +198,7 @@ namespace mongo {
std::string cafile;
std::string crlfile;
std::string cipherConfig;
+ std::vector<SSLGlobalParams::Protocols> disabledProtocols;
bool weakCertificateValidation;
bool allowInvalidCertificates;
bool allowInvalidHostnames;
@@ -329,6 +344,7 @@ namespace mongo {
sslGlobalParams.sslPEMKeyPassword,
sslGlobalParams.sslClusterFile,
sslGlobalParams.sslClusterPassword,
+ sslGlobalParams.sslDisabledProtocols,
sslGlobalParams.sslCAFile,
sslGlobalParams.sslCRLFile,
sslGlobalParams.sslCipherConfig,
@@ -587,7 +603,22 @@ namespace mongo {
// SSL_OP_ALL - Activate all bug workaround options, to support buggy client SSL's.
// SSL_OP_NO_SSLv2 - Disable SSL v2 support
// SSL_OP_NO_SSLv3 - Disable SSL v3 support
- SSL_CTX_set_options(*context, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
+ long supportedProtocols = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
+
+ // Set the supported TLS protocols. Allow --disabledProtocols to disable selected ciphers.
+ if (!params.disabledProtocols.empty()) {
+ for (std::vector<SSLGlobalParams::Protocols>::const_iterator it =
+ params.disabledProtocols.begin(); it != params.disabledProtocols.end(); ++it) {
+ if (*it == SSLGlobalParams::TLS1_0) {
+ supportedProtocols |= SSL_OP_NO_TLSv1;
+ } else if (*it == SSLGlobalParams::TLS1_1) {
+ supportedProtocols |= SSL_OP_NO_TLSv1_1;
+ } else if (*it == SSLGlobalParams::TLS1_2) {
+ supportedProtocols |= SSL_OP_NO_TLSv1_2;
+ }
+ }
+ }
+ SSL_CTX_set_options(*context, supportedProtocols);
// HIGH - Enable strong ciphers
// !EXPORT - Disable export ciphers (40/56 bit)
diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp
index c4ff4f2c48c..8bb00c90570 100644
--- a/src/mongo/util/net/ssl_options.cpp
+++ b/src/mongo/util/net/ssl_options.cpp
@@ -36,6 +36,7 @@
#include "mongo/base/status.h"
#include "mongo/db/server_options.h"
#include "mongo/util/log.h"
+#include "mongo/util/text.h"
#include "mongo/util/options_parser/startup_options.h"
namespace mongo {
@@ -75,6 +76,10 @@ namespace mongo {
"OpenSSL cipher configuration string")
.hidden();
+ options->addOptionChaining("net.ssl.disabledProtocols", "sslDisabledProtocols", moe::String,
+ "Comma separated list of disabled protocols")
+ .hidden();
+
options->addOptionChaining("net.ssl.weakCertificateValidation",
"sslWeakCertificateValidation", moe::Switch, "allow client to connect without "
"presenting a certificate");
@@ -116,6 +121,11 @@ namespace mongo {
.requires("ssl")
.requires("ssl.CAFile");
+ options->addOptionChaining("net.ssl.disabledProtocols", "sslDisabledProtocols", moe::String,
+ "Comma separated list of disabled protocols")
+ .requires("ssl")
+ .hidden();
+
options->addOptionChaining("net.ssl.allowInvalidHostnames", "sslAllowInvalidHostnames",
moe::Switch, "allow connections to servers with non-matching hostnames")
.requires("ssl");
@@ -237,6 +247,26 @@ namespace mongo {
sslGlobalParams.sslCipherConfig = params["net.ssl.sslCipherConfig"].as<string>();
}
+ if (params.count("net.ssl.disabledProtocols")) {
+ std::vector<std::string> tokens = StringSplitter::split(
+ params["net.ssl.disabledProtocols"].as<string>(), ",");
+
+ std::map<std::string, SSLGlobalParams::Protocols> validConfigs;
+ validConfigs["noTLS1_0"] = SSLGlobalParams::TLS1_0;
+ validConfigs["noTLS1_1"] = SSLGlobalParams::TLS1_1;
+ validConfigs["noTLS1_2"] = SSLGlobalParams::TLS1_2;
+ for (std::vector<std::string>::iterator it = tokens.begin(); it != tokens.end(); ++it) {
+ std::map<std::string, SSLGlobalParams::Protocols>::iterator mappedToken =
+ validConfigs.find(*it);
+ if (mappedToken != validConfigs.end()) {
+ sslGlobalParams.sslDisabledProtocols.push_back(mappedToken->second);
+ } else {
+ return Status(ErrorCodes::BadValue,
+ "Unrecognized disabledProtocols '" + *it +"'");
+ }
+ }
+ }
+
if (params.count("net.ssl.weakCertificateValidation")) {
sslGlobalParams.sslWeakCertificateValidation =
params["net.ssl.weakCertificateValidation"].as<bool>();
@@ -290,6 +320,7 @@ namespace mongo {
sslGlobalParams.sslCAFile.size() ||
sslGlobalParams.sslCRLFile.size() ||
sslGlobalParams.sslCipherConfig.size() ||
+ sslGlobalParams.sslDisabledProtocols.size() ||
sslGlobalParams.sslWeakCertificateValidation ||
sslGlobalParams.sslFIPSMode) {
return Status(ErrorCodes::BadValue,
diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h
index bc4f2dbbad4..09035b16c67 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -27,6 +27,8 @@
#pragma once
+#include <vector>
+
#include "mongo/base/status.h"
#include "mongo/client/export_macros.h"
#include "mongo/util/net/ssl_manager.h"
@@ -41,6 +43,11 @@ namespace mongo {
namespace moe = mongo::optionenvironment;
struct MONGO_CLIENT_API SSLGlobalParams {
+ enum Protocols {
+ TLS1_0,
+ TLS1_1,
+ TLS1_2
+ };
AtomicInt32 sslMode; // --sslMode - the SSL operation mode, see enum SSLModes
bool sslOnNormalPorts; // --sslOnNormalPorts (deprecated)
std::string sslPEMKeyFile; // --sslPEMKeyFile
@@ -50,6 +57,7 @@ namespace mongo {
std::string sslCAFile; // --sslCAFile
std::string sslCRLFile; // --sslCRLFile
std::string sslCipherConfig; // --sslCipherConfig
+ std::vector<Protocols> sslDisabledProtocols; // --sslDisabledProtocols
bool sslWeakCertificateValidation; // --sslWeakCertificateValidation
bool sslFIPSMode; // --sslFIPSMode
bool sslAllowInvalidCertificates; // --sslAllowInvalidCertificates