diff options
author | Adam Cooper <adam.cooper@mongodb.com> | 2018-06-11 13:38:54 -0400 |
---|---|---|
committer | Adam Cooper <adam.cooper@mongodb.com> | 2018-07-10 13:20:34 -0400 |
commit | 56d0fa54da38a40d96361df39967e48a9d26df78 (patch) | |
tree | 7eb2c511574627adf48ab02e2d0e22329892821c | |
parent | 5f42f89382821634d1daba179b9ae2236c2dffeb (diff) | |
download | mongo-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.js | 53 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 5 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_apple.cpp | 22 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_openssl.cpp | 11 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager_windows.cpp | 12 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_options.h | 2 |
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); |