summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/ssl/set_parameter_ssl.js60
-rw-r--r--src/mongo/util/net/ssl_options.cpp72
-rw-r--r--src/mongo/util/net/ssl_options.h8
-rw-r--r--src/mongo/util/net/ssl_options_server.cpp22
-rw-r--r--src/mongo/util/net/ssl_parameters.cpp115
-rw-r--r--src/mongo/util/net/ssl_parameters.h2
-rw-r--r--src/mongo/util/net/ssl_parameters.idl6
7 files changed, 196 insertions, 89 deletions
diff --git a/jstests/ssl/set_parameter_ssl.js b/jstests/ssl/set_parameter_ssl.js
index 39b0e0040a9..ddb46df2309 100644
--- a/jstests/ssl/set_parameter_ssl.js
+++ b/jstests/ssl/set_parameter_ssl.js
@@ -3,14 +3,35 @@
var SERVER_CERT = "jstests/libs/server.pem";
var CA_CERT = "jstests/libs/ca.pem";
-function testSSLTransition(oldMode, newMode, shouldSucceed) {
+class TransportMode {
+ constructor(sslName, tlsName) {
+ this.sslName = sslName;
+ this.tlsName = tlsName;
+ }
+
+ get sslMode() {
+ return this.sslName;
+ }
+
+ get tlsMode() {
+ return this.tlsName;
+ }
+}
+
+const invalid = new TransportMode("invalid", "invalid");
+const disabled = new TransportMode("disabled", "disabled");
+const allowed = new TransportMode("allowSSL", "allowTLS");
+const prefered = new TransportMode("preferSSL", "preferTLS");
+const required = new TransportMode("requireSSL", "requireTLS");
+
+function testTransportTransition(scheme, oldMode, newMode, shouldSucceed) {
var conn =
MongoRunner.runMongod({sslMode: oldMode, sslPEMKeyFile: SERVER_CERT, sslCAFile: CA_CERT});
var adminDB = conn.getDB("admin");
adminDB.createUser({user: "root", pwd: "pwd", roles: ['root']});
adminDB.auth("root", "pwd");
- var res = adminDB.runCommand({"setParameter": 1, "sslMode": newMode});
+ var res = adminDB.runCommand({"setParameter": 1, [scheme]: newMode[scheme]});
assert(res["ok"] == shouldSucceed, tojson(res));
if (!shouldSucceed) {
@@ -46,21 +67,26 @@ function testAuthModeTransition(oldMode, newMode, sslMode, shouldSucceed) {
MongoRunner.stopMongod(conn);
}
-testSSLTransition("allowSSL", "invalid", false);
-testSSLTransition("allowSSL", "disabled", false);
-testSSLTransition("allowSSL", "allowSSL", false);
-testSSLTransition("allowSSL", "preferSSL", true);
-testSSLTransition("allowSSL", "requireSSL", false);
-testSSLTransition("preferSSL", "invalid", false);
-testSSLTransition("preferSSL", "disabled", false);
-testSSLTransition("preferSSL", "allowSSL", false);
-testSSLTransition("preferSSL", "preferSSL", false);
-testSSLTransition("preferSSL", "requireSSL", true);
-testSSLTransition("requireSSL", "invalid", false);
-testSSLTransition("requireSSL", "disabled", false);
-testSSLTransition("requireSSL", "allowSSL", false);
-testSSLTransition("requireSSL", "preferSSL", false);
-testSSLTransition("requireSSL", "requireSSL", false);
+function testTransportTransitions(scheme) {
+ testTransportTransition(scheme, "allowSSL", invalid, false);
+ testTransportTransition(scheme, "allowSSL", disabled, false);
+ testTransportTransition(scheme, "allowSSL", allowed, false);
+ testTransportTransition(scheme, "allowSSL", prefered, true);
+ testTransportTransition(scheme, "allowSSL", required, false);
+ testTransportTransition(scheme, "preferSSL", invalid, false);
+ testTransportTransition(scheme, "preferSSL", disabled, false);
+ testTransportTransition(scheme, "preferSSL", allowed, false);
+ testTransportTransition(scheme, "preferSSL", prefered, false);
+ testTransportTransition(scheme, "preferSSL", required, true);
+ testTransportTransition(scheme, "requireSSL", invalid, false);
+ testTransportTransition(scheme, "requireSSL", disabled, false);
+ testTransportTransition(scheme, "requireSSL", allowed, false);
+ testTransportTransition(scheme, "requireSSL", prefered, false);
+ testTransportTransition(scheme, "requireSSL", required, false);
+}
+
+testTransportTransitions("sslMode");
+testTransportTransitions("tlsMode");
testAuthModeTransition("sendKeyFile", "invalid", "requireSSL", false);
testAuthModeTransition("sendKeyFile", "keyFile", "requireSSL", false);
diff --git a/src/mongo/util/net/ssl_options.cpp b/src/mongo/util/net/ssl_options.cpp
index cab1a47d05f..b86c4d0e130 100644
--- a/src/mongo/util/net/ssl_options.cpp
+++ b/src/mongo/util/net/ssl_options.cpp
@@ -162,4 +162,76 @@ Status parseCertificateSelector(SSLParams::CertificateSelector* selector,
return Status::OK();
}
+StatusWith<SSLParams::SSLModes> SSLParams::sslModeParse(StringData strMode) {
+ if (strMode == "disabled") {
+ return SSLParams::SSLMode_disabled;
+ } else if (strMode == "allowSSL") {
+ return SSLParams::SSLMode_allowSSL;
+ } else if (strMode == "preferSSL") {
+ return SSLParams::SSLMode_preferSSL;
+ } else if (strMode == "requireSSL") {
+ return SSLParams::SSLMode_requireSSL;
+ } else {
+ return Status(
+ ErrorCodes::BadValue,
+ str::stream()
+ << "Invalid sslMode setting '"
+ << strMode
+ << "', expected one of: 'disabled', 'allowSSL', 'preferSSL', or 'requireSSL'");
+ }
+}
+
+StatusWith<SSLParams::SSLModes> SSLParams::tlsModeParse(StringData strMode) {
+ if (strMode == "disabled") {
+ return SSLParams::SSLMode_disabled;
+ } else if (strMode == "allowTLS") {
+ return SSLParams::SSLMode_allowSSL;
+ } else if (strMode == "preferTLS") {
+ return SSLParams::SSLMode_preferSSL;
+ } else if (strMode == "requireTLS") {
+ return SSLParams::SSLMode_requireSSL;
+ } else {
+ return Status(
+ ErrorCodes::BadValue,
+ str::stream()
+ << "Invalid tlsMode setting '"
+ << strMode
+ << "', expected one of: 'disabled', 'allowTLS', 'preferTLS', or 'requireTLS'");
+ }
+}
+
+
+std::string SSLParams::sslModeFormat(AtomicInt32::WordType mode) {
+ switch (mode) {
+ case SSLParams::SSLMode_disabled:
+ return "disabled";
+ case SSLParams::SSLMode_allowSSL:
+ return "allowSSL";
+ case SSLParams::SSLMode_preferSSL:
+ return "preferSSL";
+ case SSLParams::SSLMode_requireSSL:
+ return "requireSSL";
+ default:
+ // Default case because sslMode is an AtomicInt32 and not bound by enum rules.
+ return "unknown";
+ }
+}
+
+std::string SSLParams::tlsModeFormat(AtomicInt32::WordType mode) {
+ switch (mode) {
+ case SSLParams::SSLMode_disabled:
+ return "disabled";
+ case SSLParams::SSLMode_allowSSL:
+ return "allowTLS";
+ case SSLParams::SSLMode_preferSSL:
+ return "preferTLS";
+ case SSLParams::SSLMode_requireSSL:
+ return "requireTLS";
+ default:
+ // Default case because sslMode is an AtomicInt32 and not bound by enum rules.
+ return "unknown";
+ }
+}
+
+
} // namespace mongo
diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h
index 391c9a98bdb..a5f4d936cb6 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -34,6 +34,7 @@
#include <vector>
#include "mongo/base/status.h"
+#include "mongo/base/status_with.h"
#include "mongo/config.h"
namespace mongo {
@@ -91,7 +92,7 @@ struct SSLParams {
sslMode.store(SSLMode_disabled);
}
- enum SSLModes {
+ enum SSLModes : AtomicInt32::WordType {
/**
* Make unencrypted outgoing connections and do not accept incoming SSL-connections.
*/
@@ -112,6 +113,11 @@ struct SSLParams {
*/
SSLMode_requireSSL
};
+
+ static StatusWith<SSLModes> sslModeParse(StringData strMode);
+ static StatusWith<SSLModes> tlsModeParse(StringData strMode);
+ static std::string sslModeFormat(AtomicInt32::WordType mode);
+ static std::string tlsModeFormat(AtomicInt32::WordType mode);
};
extern SSLParams sslGlobalParams;
diff --git a/src/mongo/util/net/ssl_options_server.cpp b/src/mongo/util/net/ssl_options_server.cpp
index 0af940adf63..bcca608e8bf 100644
--- a/src/mongo/util/net/ssl_options_server.cpp
+++ b/src/mongo/util/net/ssl_options_server.cpp
@@ -248,27 +248,17 @@ Status storeTLSLogVersion(const std::string& loggedProtocols) {
Status storeSSLServerOptions(const moe::Environment& params) {
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);
+ auto swMode = SSLParams::tlsModeParse(sslModeParam);
+ if (swMode.isOK()) {
+ sslGlobalParams.sslMode.store(swMode.getValue());
} else {
return {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);
- } else if (sslModeParam == "allowSSL") {
- sslGlobalParams.sslMode.store(SSLParams::SSLMode_allowSSL);
- } else if (sslModeParam == "preferSSL") {
- sslGlobalParams.sslMode.store(SSLParams::SSLMode_preferSSL);
- } else if (sslModeParam == "requireSSL") {
- sslGlobalParams.sslMode.store(SSLParams::SSLMode_requireSSL);
+ auto swMode = SSLParams::sslModeParse(sslModeParam);
+ if (swMode.isOK()) {
+ sslGlobalParams.sslMode.store(swMode.getValue());
} else {
return {ErrorCodes::BadValue, "unsupported value for sslMode " + sslModeParam};
}
diff --git a/src/mongo/util/net/ssl_parameters.cpp b/src/mongo/util/net/ssl_parameters.cpp
index e8cfc506b1c..2fe9e66cb43 100644
--- a/src/mongo/util/net/ssl_parameters.cpp
+++ b/src/mongo/util/net/ssl_parameters.cpp
@@ -28,53 +28,22 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kNetwork
+
#include "mongo/platform/basic.h"
#include "mongo/client/authenticate.h"
#include "mongo/config.h"
#include "mongo/db/auth/sasl_command_constants.h"
#include "mongo/db/server_options.h"
+#include "mongo/util/log.h"
#include "mongo/util/net/ssl_options.h"
#include "mongo/util/net/ssl_parameters.h"
namespace mongo {
namespace {
-std::string sslModeStr() {
- switch (sslGlobalParams.sslMode.load()) {
- case SSLParams::SSLMode_disabled:
- return "disabled";
- case SSLParams::SSLMode_allowSSL:
- return "allowSSL";
- case SSLParams::SSLMode_preferSSL:
- return "preferSSL";
- case SSLParams::SSLMode_requireSSL:
- return "requireSSL";
- default:
- // Default case because sslMode is an AtomicInt32 and not bound by enum rules.
- return "unknown";
- }
-}
-StatusWith<SSLParams::SSLModes> sslModeParse(StringData strMode) {
- if (strMode == "disabled") {
- return SSLParams::SSLMode_disabled;
- } else if (strMode == "allowSSL") {
- return SSLParams::SSLMode_allowSSL;
- } else if (strMode == "preferSSL") {
- return SSLParams::SSLMode_preferSSL;
- } else if (strMode == "requireSSL") {
- return SSLParams::SSLMode_requireSSL;
- } else {
- return Status(
- ErrorCodes::BadValue,
- str::stream()
- << "Invalid sslMode setting '"
- << strMode
- << "', expected one of: 'disabled', 'allowSSL', 'preferSSL', or 'requireSSL'");
- }
-}
-
-std::string clusterAuthModeStr() {
+std::string clusterAuthModeFormat() {
switch (serverGlobalParams.clusterAuthMode.load()) {
case ServerGlobalParams::ClusterAuthMode_keyFile:
return "keyFile";
@@ -107,6 +76,32 @@ StatusWith<ServerGlobalParams::ClusterAuthModes> clusterAuthModeParse(StringData
}
}
+
+template <typename T, typename U>
+StatusWith<SSLParams::SSLModes> checkTLSModeTransition(T modeToString,
+ U stringToMode,
+ StringData parameterName,
+ StringData strMode) {
+ auto mode = stringToMode(strMode);
+ if (!mode.isOK()) {
+ return mode.getStatus();
+ }
+ auto oldMode = sslGlobalParams.sslMode.load();
+ if ((mode == SSLParams::SSLMode_preferSSL) && (oldMode == SSLParams::SSLMode_allowSSL)) {
+ return mode;
+ } else if ((mode == SSLParams::SSLMode_requireSSL) &&
+ (oldMode == SSLParams::SSLMode_preferSSL)) {
+ return mode;
+ } else {
+ return {ErrorCodes::BadValue,
+ str::stream() << "Illegal state transition for " << parameterName
+ << ", attempt to change from "
+ << modeToString(static_cast<SSLParams::SSLModes>(oldMode))
+ << " to "
+ << strMode};
+ }
+}
+
} // namespace
} // namespace mongo
@@ -143,7 +138,14 @@ mongo::Status mongo::onUpdateDisableNonTLSConnectionLogging(const bool&) {
}
void mongo::appendSSLModeToBSON(OperationContext*, BSONObjBuilder* builder, StringData fieldName) {
- builder->append(fieldName, sslModeStr());
+ warning() << "Use of deprecared server parameter 'sslMode', please use 'tlsMode' instead.";
+ builder->append(fieldName, SSLParams::sslModeFormat(sslGlobalParams.sslMode.load()));
+}
+
+void mongo::appendTLSModeToBSON(OperationContext*, BSONObjBuilder* builder, StringData fieldName) {
+ builder->append(
+ fieldName,
+ SSLParams::tlsModeFormat(static_cast<SSLParams::SSLModes>(sslGlobalParams.sslMode.load())));
}
mongo::Status mongo::setSSLModeFromString(StringData strMode) {
@@ -152,33 +154,36 @@ mongo::Status mongo::setSSLModeFromString(StringData strMode) {
"Unable to set sslMode, SSL support is not compiled into server"};
#endif
- auto swMode = sslModeParse(strMode);
- if (!swMode.isOK()) {
- return swMode.getStatus();
- }
+ warning() << "Use of deprecared server parameter 'sslMode', please use 'tlsMode' instead.";
- auto mode = swMode.getValue();
- auto oldMode = sslGlobalParams.sslMode.load();
- if ((mode == SSLParams::SSLMode_preferSSL) && (oldMode == SSLParams::SSLMode_allowSSL)) {
- sslGlobalParams.sslMode.store(mode);
- } else if ((mode == SSLParams::SSLMode_requireSSL) &&
- (oldMode == SSLParams::SSLMode_preferSSL)) {
- sslGlobalParams.sslMode.store(mode);
- } else {
- return {ErrorCodes::BadValue,
- str::stream() << "Illegal state transition for sslMode, attempt to change from "
- << sslModeStr()
- << " to "
- << strMode};
+ auto swNewMode = checkTLSModeTransition(
+ SSLParams::sslModeFormat, SSLParams::sslModeParse, "sslMode", strMode);
+ if (!swNewMode.isOK()) {
+ return swNewMode.getStatus();
}
+ sslGlobalParams.sslMode.store(swNewMode.getValue());
+ return Status::OK();
+}
+mongo::Status mongo::setTLSModeFromString(StringData strMode) {
+#ifndef MONGO_CONFIG_SSL
+ return {ErrorCodes::IllegalOperation,
+ "Unable to set tlsMode, TLS support is not compiled into server"};
+#endif
+ auto swNewMode = checkTLSModeTransition(
+ SSLParams::tlsModeFormat, SSLParams::tlsModeParse, "tlsMode", strMode);
+ if (!swNewMode.isOK()) {
+ return swNewMode.getStatus();
+ }
+ sslGlobalParams.sslMode.store(swNewMode.getValue());
return Status::OK();
}
+
void mongo::appendClusterAuthModeToBSON(OperationContext*,
BSONObjBuilder* builder,
StringData fieldName) {
- builder->append(fieldName, clusterAuthModeStr());
+ builder->append(fieldName, clusterAuthModeFormat());
}
mongo::Status mongo::setClusterAuthModeFromString(StringData strMode) {
@@ -214,7 +219,7 @@ mongo::Status mongo::setClusterAuthModeFromString(StringData strMode) {
} else {
return {ErrorCodes::BadValue,
str::stream() << "Illegal state transition for clusterAuthMode, change from "
- << clusterAuthModeStr()
+ << clusterAuthModeFormat()
<< " to "
<< strMode};
}
diff --git a/src/mongo/util/net/ssl_parameters.h b/src/mongo/util/net/ssl_parameters.h
index bd1d6304f4d..e88c3908382 100644
--- a/src/mongo/util/net/ssl_parameters.h
+++ b/src/mongo/util/net/ssl_parameters.h
@@ -57,7 +57,9 @@ Status onUpdateDisableNonTLSConnectionLogging(const bool&);
* Callbacks for setParameter 'sslMode'
*/
void appendSSLModeToBSON(OperationContext*, BSONObjBuilder*, StringData);
+void appendTLSModeToBSON(OperationContext*, BSONObjBuilder*, StringData);
Status setSSLModeFromString(StringData);
+Status setTLSModeFromString(StringData);
/**
* Callbacks for setParameter 'clusterAuthMode'
diff --git a/src/mongo/util/net/ssl_parameters.idl b/src/mongo/util/net/ssl_parameters.idl
index 56121e285b0..a276c52b94c 100644
--- a/src/mongo/util/net/ssl_parameters.idl
+++ b/src/mongo/util/net/ssl_parameters.idl
@@ -72,6 +72,12 @@ server_parameters:
append_bson: "appendSSLModeToBSON"
from_string: "setSSLModeFromString"
+ tlsMode:
+ description: "Transition from allowTLS to preferTLS, or from preferTLS to requireTLS"
+ set_at: runtime
+ append_bson: "appendTLSModeToBSON"
+ from_string: "setTLSModeFromString"
+
clusterAuthMode:
description: "Transition from sendKeyFile to sendX509, or sendX509 to x509 clusterAuthModes"
set_at: runtime