summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Cooper <adam.cooper@mongodb.com>2018-06-11 13:38:54 -0400
committerAdam Cooper <adam.cooper@mongodb.com>2018-07-10 13:20:34 -0400
commit56d0fa54da38a40d96361df39967e48a9d26df78 (patch)
tree7eb2c511574627adf48ab02e2d0e22329892821c
parent5f42f89382821634d1daba179b9ae2236c2dffeb (diff)
downloadmongo-56d0fa54da38a40d96361df39967e48a9d26df78.tar.gz
SERVER-27264 Allow disabling no client certificate warning
(cherry picked from commit 14eb0afce97b372d0dc4d2a4c41a00318a36b0e2)
-rw-r--r--jstests/ssl/ssl_client_certificate_warning_suppression.js53
-rw-r--r--src/mongo/util/net/ssl_manager.cpp5
-rw-r--r--src/mongo/util/net/ssl_manager_apple.cpp22
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp11
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp12
-rw-r--r--src/mongo/util/net/ssl_options.h2
6 files changed, 93 insertions, 12 deletions
diff --git a/jstests/ssl/ssl_client_certificate_warning_suppression.js b/jstests/ssl/ssl_client_certificate_warning_suppression.js
new file mode 100644
index 00000000000..4c6fa63128e
--- /dev/null
+++ b/jstests/ssl/ssl_client_certificate_warning_suppression.js
@@ -0,0 +1,53 @@
+/**
+ * Tests the startup-only setParameter value suppressNoTLSPeerCertificateWarning which suppresses
+ * the log message "no SSL certificate provided by peer" when a client certificate is not provided.
+ * This only works if weak validation is enabled.
+ *
+ * This test confirms that the log message is output when the setParameter is set to true,
+ * and is not output when the setParameter is set to false.
+ */
+
+load('jstests/ssl/libs/ssl_helpers.js');
+
+(function() {
+ 'use strict';
+
+ function test(suppress) {
+ const opts = {
+ sslMode: 'requireSSL',
+ sslPEMKeyFile: "jstests/libs/server.pem",
+ sslCAFile: "jstests/libs/ca.pem",
+ waitForConnect: false,
+ sslAllowConnectionsWithoutCertificates: "",
+ setParameter: {suppressNoTLSPeerCertificateWarning: suppress}
+ };
+ clearRawMongoProgramOutput();
+ const mongod = MongoRunner.runMongod(opts);
+
+ assert.soon(function() {
+ return runMongoProgram('mongo',
+ '--ssl',
+ '--sslAllowInvalidHostnames',
+ '--sslCAFile',
+ CA_CERT,
+ '--port',
+ mongod.port,
+ '--eval',
+ 'quit()') === 0;
+ }, "mongo did not initialize properly");
+
+ const log = rawMongoProgramOutput();
+ assert.eq(suppress, log.search('no SSL certificate provided by peer') === -1);
+
+ try {
+ MongoRunner.stopMongod(mongod);
+ } catch (e) {
+ // Depending on timing, exitCode might be 0, 1, or -9.
+ // All that matters is that it dies, resmoke will tell us if that failed.
+ // So just let it go, the exit code never bothered us anyway.
+ }
+ }
+
+ test(true);
+ test(false);
+})();
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index eb515c0f088..66bd0eaa775 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -66,6 +66,11 @@ ExportedServerParameter<std::string, ServerParameterType::kStartupOnly>
setDiffieHellmanParameterPEMFile(ServerParameterSet::getGlobal(),
"opensslDiffieHellmanParameters",
&sslGlobalParams.sslPEMTempDHParam);
+
+ExportedServerParameter<bool, ServerParameterType::kStartupOnly>
+ suppressNoTLSPeerCertificateWarning(ServerParameterSet::getGlobal(),
+ "suppressNoTLSPeerCertificateWarning",
+ &sslGlobalParams.suppressNoTLSPeerCertificateWarning);
} // namespace
class OpenSSLCipherConfigParameter
diff --git a/src/mongo/util/net/ssl_manager_apple.cpp b/src/mongo/util/net/ssl_manager_apple.cpp
index 7466c18fa6e..e4a8e5fb9e3 100644
--- a/src/mongo/util/net/ssl_manager_apple.cpp
+++ b/src/mongo/util/net/ssl_manager_apple.cpp
@@ -1077,6 +1077,7 @@ private:
bool _weakValidation;
bool _allowInvalidCertificates;
bool _allowInvalidHostnames;
+ bool _suppressNoCertificateWarning;
asio::ssl::apple::Context _clientCtx;
asio::ssl::apple::Context _serverCtx;
CFUniquePtr<::CFArrayRef> _ca;
@@ -1086,7 +1087,8 @@ private:
SSLManagerApple::SSLManagerApple(const SSLParams& params, bool isServer)
: _weakValidation(params.sslWeakCertificateValidation),
_allowInvalidCertificates(params.sslAllowInvalidCertificates),
- _allowInvalidHostnames(params.sslAllowInvalidHostnames) {
+ _allowInvalidHostnames(params.sslAllowInvalidHostnames),
+ _suppressNoCertificateWarning(params.suppressNoTLSPeerCertificateWarning) {
uassertStatusOK(initSSLContext(&_clientCtx, params, ConnectionDirection::kOutgoing));
if (_clientCtx.certs) {
@@ -1257,9 +1259,19 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerApple::parseAndValidatePeerCe
const auto status = ::SSLCopyPeerTrust(ssl, &trust);
CFUniquePtr<::SecTrustRef> cftrust(trust);
if ((status != ::errSecSuccess) || (!cftrust)) {
- return badCert(str::stream() << "Unable to retreive SSL trust from peer: "
- << stringFromOSStatus(status),
- _weakValidation);
+ if (_weakValidation && _suppressNoCertificateWarning) {
+ return {boost::none};
+ } else {
+ if (status == ::errSecSuccess) {
+ return badCert(str::stream() << "no SSL certificate provided by peer: "
+ << stringFromOSStatus(status),
+ _weakValidation);
+ } else {
+ return badCert(str::stream() << "Unable to retreive SSL trust from peer: "
+ << stringFromOSStatus(status),
+ _weakValidation);
+ }
+ }
}
if (_ca) {
@@ -1284,7 +1296,7 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerApple::parseAndValidatePeerCe
auto cert = ::SecTrustGetCertificateAtIndex(cftrust.get(), 0);
if (!cert) {
- return badCert("no SSL certificate provided by peer", _weakValidation);
+ return badCert("no SSL certificate found in trust container", _weakValidation);
}
CFUniquePtr<::CFMutableArrayRef> oids(
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp
index 6b48b228926..1f61cfbac49 100644
--- a/src/mongo/util/net/ssl_manager_openssl.cpp
+++ b/src/mongo/util/net/ssl_manager_openssl.cpp
@@ -357,6 +357,7 @@ private:
bool _weakValidation;
bool _allowInvalidCertificates;
bool _allowInvalidHostnames;
+ bool _suppressNoCertificateWarning;
SSLConfiguration _sslConfiguration;
/**
@@ -575,7 +576,8 @@ SSLManagerOpenSSL::SSLManagerOpenSSL(const SSLParams& params, bool isServer)
_clientContext(nullptr, free_ssl_context),
_weakValidation(params.sslWeakCertificateValidation),
_allowInvalidCertificates(params.sslAllowInvalidCertificates),
- _allowInvalidHostnames(params.sslAllowInvalidHostnames) {
+ _allowInvalidHostnames(params.sslAllowInvalidHostnames),
+ _suppressNoCertificateWarning(params.suppressNoTLSPeerCertificateWarning) {
if (!_initSynchronousSSLContext(&_clientContext, params, ConnectionDirection::kOutgoing)) {
uasserted(16768, "ssl initialization problem");
}
@@ -1241,13 +1243,16 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerOpenSSL::parseAndValidatePeer
if (NULL == peerCert) { // no certificate presented by peer
if (_weakValidation) {
- warning() << "no SSL certificate provided by peer";
+ // do not give warning if certificate warnings are suppressed
+ if (!_suppressNoCertificateWarning) {
+ warning() << "no SSL certificate provided by peer";
+ }
+ return {boost::none};
} else {
auto msg = "no SSL certificate provided by peer; connection rejected";
error() << msg;
return Status(ErrorCodes::SSLHandshakeFailed, msg);
}
- return {boost::none};
}
ON_BLOCK_EXIT(X509_free, peerCert);
diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp
index b0dc13add24..fd159c7c7e3 100644
--- a/src/mongo/util/net/ssl_manager_windows.cpp
+++ b/src/mongo/util/net/ssl_manager_windows.cpp
@@ -303,6 +303,7 @@ private:
bool _weakValidation;
bool _allowInvalidCertificates;
bool _allowInvalidHostnames;
+ bool _suppressNoCertificateWarning;
SSLConfiguration _sslConfiguration;
SCHANNEL_CRED _clientCred;
@@ -372,7 +373,8 @@ namespace {
SSLManagerWindows::SSLManagerWindows(const SSLParams& params, bool isServer)
: _weakValidation(params.sslWeakCertificateValidation),
_allowInvalidCertificates(params.sslAllowInvalidCertificates),
- _allowInvalidHostnames(params.sslAllowInvalidHostnames) {
+ _allowInvalidHostnames(params.sslAllowInvalidHostnames),
+ _suppressNoCertificateWarning(params.suppressNoTLSPeerCertificateWarning) {
if (params.sslFIPSMode) {
BOOLEAN enabled = FALSE;
@@ -1641,14 +1643,16 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManagerWindows::parseAndValidatePeer
if (ss == SEC_E_NO_CREDENTIALS) { // no certificate presented by peer
if (_weakValidation) {
- warning() << "no SSL certificate provided by peer";
+ // do not give warning if "no certificate" warnings are suppressed
+ if (!_suppressNoCertificateWarning) {
+ warning() << "no SSL certificate provided by peer";
+ }
+ return {boost::none};
} else {
auto msg = "no SSL certificate provided by peer; connection rejected";
error() << msg;
return Status(ErrorCodes::SSLHandshakeFailed, msg);
}
-
- return {boost::none};
}
// Check for unexpected errors
diff --git a/src/mongo/util/net/ssl_options.h b/src/mongo/util/net/ssl_options.h
index 20127cb5c2b..f8071b782a6 100644
--- a/src/mongo/util/net/ssl_options.h
+++ b/src/mongo/util/net/ssl_options.h
@@ -77,6 +77,8 @@ struct SSLParams {
bool sslAllowInvalidHostnames = false; // --sslAllowInvalidHostnames
bool disableNonSSLConnectionLogging =
false; // --setParameter disableNonSSLConnectionLogging=true
+ bool suppressNoTLSPeerCertificateWarning =
+ false; // --setParameter suppressNoTLSPeerCertificateWarning
SSLParams() {
sslMode.store(SSLMode_disabled);