summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2018-08-29 18:14:39 +0000
committerSara Golemon <sara.golemon@mongodb.com>2018-09-20 19:28:09 +0000
commit62ddf96f847d5bbc301aad4fab94977671af417c (patch)
treee3fef080c717da48bff4f5bfe0f853bdc8a335db
parent85dbde9e17ec526911aba820564a6f299133263b (diff)
downloadmongo-62ddf96f847d5bbc301aad4fab94977671af417c.tar.gz
SERVER-36919 Add server setParameter tlsSuppressClientCertificate
(cherry picked from commit 1070aa3880ac73bc1923b44a372c61c209a35f61) Set parameter name mapped from tls* to ssl*
-rw-r--r--jstests/ssl/ssl_withhold_client_cert.js45
-rw-r--r--src/mongo/util/net/ssl_manager.cpp6
-rw-r--r--src/mongo/util/net/ssl_manager_apple.cpp4
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp10
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp2
-rw-r--r--src/mongo/util/net/ssl_options.h1
6 files changed, 65 insertions, 3 deletions
diff --git a/jstests/ssl/ssl_withhold_client_cert.js b/jstests/ssl/ssl_withhold_client_cert.js
new file mode 100644
index 00000000000..f8d7d287519
--- /dev/null
+++ b/jstests/ssl/ssl_withhold_client_cert.js
@@ -0,0 +1,45 @@
+// Test setParameter sslWithholdClientCertificate
+
+(function() {
+ "use strict";
+
+ function testRS(opts, expectWarning) {
+ const rsOpts = {
+ nodes: {node0: opts, node1: opts},
+ };
+ const rs = new ReplSetTest(rsOpts);
+ rs.startSet();
+ rs.initiate();
+ rs.awaitReplication();
+
+ const test = rs.getPrimary().getDB('test');
+ test.foo.insert({bar: "baz"});
+ rs.awaitReplication();
+
+ function checkWarning(member) {
+ const observed =
+ /no SSL certificate provided by peer/.test(cat(member.fullOptions.logFile));
+ assert.eq(observed, expectWarning);
+ }
+ checkWarning(rs.getPrimary());
+ checkWarning(rs.getSecondary());
+ rs.stopSet();
+ }
+
+ const base_options = {
+ sslMode: 'requireSSL',
+ sslPEMKeyFile: 'jstests/libs/server.pem',
+ sslCAFile: 'jstests/libs/ca.pem',
+ sslAllowInvalidHostnames: '',
+ useLogFiles: true,
+ };
+ testRS(base_options, false);
+
+ const test_options = Object.extend({
+ sslAllowConnectionsWithoutCertificates: '',
+ setParameter: 'sslWithholdClientCertificate=true',
+ },
+ base_options);
+
+ testRS(test_options, true);
+}());
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index 6a3f0045c76..70795912a97 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -72,6 +72,12 @@ ExportedServerParameter<bool, ServerParameterType::kStartupOnly>
suppressNoTLSPeerCertificateWarning(ServerParameterSet::getGlobal(),
"suppressNoTLSPeerCertificateWarning",
&sslGlobalParams.suppressNoTLSPeerCertificateWarning);
+
+ExportedServerParameter<bool, ServerParameterType::kStartupOnly> sslWithholdClientCertificate(
+ ServerParameterSet::getGlobal(),
+ "sslWithholdClientCertificate",
+ &sslGlobalParams.tlsWithholdClientCertificate);
+
} // namespace
class OpenSSLCipherConfigParameter
diff --git a/src/mongo/util/net/ssl_manager_apple.cpp b/src/mongo/util/net/ssl_manager_apple.cpp
index 8f3b6680d34..e8999ae32fe 100644
--- a/src/mongo/util/net/ssl_manager_apple.cpp
+++ b/src/mongo/util/net/ssl_manager_apple.cpp
@@ -1218,6 +1218,10 @@ Status SSLManagerApple::initSSLContext(asio::ssl::apple::Context* context,
};
if (direction == ConnectionDirection::kOutgoing) {
+ if (params.tlsWithholdClientCertificate) {
+ return Status::OK();
+ }
+
const auto status = selectCertificate(
params.sslClusterCertificateSelector, params.sslClusterFile, params.sslClusterPassword);
if (context->certs || !status.isOK()) {
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp
index d1bf3f8476c..333b149e463 100644
--- a/src/mongo/util/net/ssl_manager_openssl.cpp
+++ b/src/mongo/util/net/ssl_manager_openssl.cpp
@@ -718,13 +718,19 @@ Status SSLManagerOpenSSL::initSSLContext(SSL_CTX* context,
<< getSSLErrorMessage(ERR_get_error()));
}
- if (direction == ConnectionDirection::kOutgoing && !params.sslClusterFile.empty()) {
+ if (direction == ConnectionDirection::kOutgoing && params.tlsWithholdClientCertificate) {
+ // Do not send a client certificate if they have been suppressed.
+
+ } else if (direction == ConnectionDirection::kOutgoing && !params.sslClusterFile.empty()) {
+ // Use the configured clusterFile as our client certificate.
::EVP_set_pw_prompt("Enter cluster certificate passphrase");
if (!_setupPEM(context, params.sslClusterFile, params.sslClusterPassword)) {
return Status(ErrorCodes::InvalidSSLConfiguration, "Can not set up ssl clusterFile.");
}
+
} else if (!params.sslPEMKeyFile.empty()) {
- // Use the pemfile for everything else
+ // Use the base pemKeyFile for any other outgoing connections,
+ // as well as all incoming connections.
::EVP_set_pw_prompt("Enter PEM passphrase");
if (!_setupPEM(context, params.sslPEMKeyFile, params.sslPEMKeyPassword)) {
return Status(ErrorCodes::InvalidSSLConfiguration, "Can not set up PEM key file.");
diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp
index 7ac11406796..6ae5d567140 100644
--- a/src/mongo/util/net/ssl_manager_windows.cpp
+++ b/src/mongo/util/net/ssl_manager_windows.cpp
@@ -1301,7 +1301,7 @@ Status SSLManagerWindows::initSSLContext(SCHANNEL_CRED* cred,
}
if (direction == ConnectionDirection::kOutgoing) {
- if (_clientCertificates[0]) {
+ if (_clientCertificates[0] && !params.tlsWithholdClientCertificate) {
cred->cCreds = 1;
cred->paCred = _clientCertificates.data();
}
diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h
index d75cd8437d4..5613f665169 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -80,6 +80,7 @@ struct SSLParams {
false; // --setParameter disableNonSSLConnectionLogging=true
bool suppressNoTLSPeerCertificateWarning =
false; // --setParameter suppressNoTLSPeerCertificateWarning
+ bool tlsWithholdClientCertificate = false; // --setParameter tlsWithholdClientCertificate
SSLParams() {
sslMode.store(SSLMode_disabled);