@@ -43,6 +43,18 @@ namespace mongo {
4343 return " " ;
4444 }
4545#else
46+
47+ // Old copies of OpenSSL will not have constants to disable protocols they don't support.
48+ // Define them to values we can OR together safely to generically disable these protocols across
49+ // all versions of OpenSSL.
50+ #ifndef SSL_OP_NO_TLSv1_1
51+ #define SSL_OP_NO_TLSv1_1 0
52+ #endif
53+ #ifndef SSL_OP_NO_TLSv1_2
54+ #define SSL_OP_NO_TLSv1_2 0
55+ #endif
56+
57+
4658 const std::string getSSLVersion (const std::string &prefix, const std::string &suffix) {
4759 return prefix + SSLeay_version (SSLEAY_VERSION) + suffix;
4860 }
@@ -132,6 +144,7 @@ namespace mongo {
132144 const std::string& pempwd,
133145 const std::string& clusterfile,
134146 const std::string& clusterpwd,
147+ const std::vector<SSLGlobalParams::Protocols>& disabledProtocols,
135148 const std::string& cafile = " " ,
136149 const std::string& crlfile = " " ,
137150 const std::string& cipherConfig = " " ,
@@ -146,6 +159,7 @@ namespace mongo {
146159 cafile (cafile),
147160 crlfile (crlfile),
148161 cipherConfig (cipherConfig),
162+ disabledProtocols (disabledProtocols),
149163 weakCertificateValidation (weakCertificateValidation),
150164 allowInvalidCertificates (allowInvalidCertificates),
151165 allowInvalidHostnames (allowInvalidHostnames),
@@ -158,6 +172,7 @@ namespace mongo {
158172 std::string cafile;
159173 std::string crlfile;
160174 std::string cipherConfig;
175+ std::vector<SSLGlobalParams::Protocols> disabledProtocols;
161176 bool weakCertificateValidation;
162177 bool allowInvalidCertificates;
163178 bool allowInvalidHostnames;
@@ -294,6 +309,7 @@ namespace mongo {
294309 sslGlobalParams.sslPEMKeyPassword ,
295310 sslGlobalParams.sslClusterFile ,
296311 sslGlobalParams.sslClusterPassword ,
312+ sslGlobalParams.sslDisabledProtocols ,
297313 sslGlobalParams.sslCAFile ,
298314 sslGlobalParams.sslCRLFile ,
299315 sslGlobalParams.sslCipherConfig ,
@@ -538,7 +554,22 @@ namespace mongo {
538554 // SSL_OP_ALL - Activate all bug workaround options, to support buggy client SSL's.
539555 // SSL_OP_NO_SSLv2 - Disable SSL v2 support
540556 // SSL_OP_NO_SSLv3 - Disable SSL v3 support
541- SSL_CTX_set_options (*context, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
557+ long supportedProtocols = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3;
558+
559+ // Set the supported TLS protocols. Allow --disabledProtocols to disable selected ciphers.
560+ if (!params.disabledProtocols .empty ()) {
561+ for (std::vector<SSLGlobalParams::Protocols>::const_iterator it =
562+ params.disabledProtocols .begin (); it != params.disabledProtocols .end (); ++it) {
563+ if (*it == SSLGlobalParams::TLS1_0) {
564+ supportedProtocols |= SSL_OP_NO_TLSv1;
565+ } else if (*it == SSLGlobalParams::TLS1_1) {
566+ supportedProtocols |= SSL_OP_NO_TLSv1_1;
567+ } else if (*it == SSLGlobalParams::TLS1_2) {
568+ supportedProtocols |= SSL_OP_NO_TLSv1_2;
569+ }
570+ }
571+ }
572+ SSL_CTX_set_options (*context, supportedProtocols);
542573
543574 // HIGH - Enable strong ciphers
544575 // !EXPORT - Disable export ciphers (40/56 bit)
@@ -769,39 +800,31 @@ namespace mongo {
769800 }
770801
771802 SSLConnection* SSLManager::connect (Socket* socket) {
772- SSLConnection* sslConn = new SSLConnection (_clientContext, socket, NULL , 0 );
773- ScopeGuard sslGuard = MakeGuard (::SSL_free, sslConn->ssl );
774- ScopeGuard bioGuard = MakeGuard (::BIO_free, sslConn->networkBIO );
803+ std::auto_ptr<SSLConnection> sslConn (new SSLConnection (_clientContext, socket, NULL , 0 ));
775804
776805 int ret;
777806 do {
778807 ret = ::SSL_connect (sslConn->ssl );
779- } while (!_doneWithSSLOp (sslConn, ret));
808+ } while (!_doneWithSSLOp (sslConn. get () , ret));
780809
781810 if (ret != 1 )
782- _handleSSLError (SSL_get_error (sslConn, ret), ret);
811+ _handleSSLError (SSL_get_error (sslConn. get () , ret), ret);
783812
784- sslGuard.Dismiss ();
785- bioGuard.Dismiss ();
786- return sslConn;
813+ return sslConn.release ();
787814 }
788815
789816 SSLConnection* SSLManager::accept (Socket* socket, const char * initialBytes, int len) {
790- SSLConnection* sslConn = new SSLConnection (_serverContext, socket, initialBytes, len);
791- ScopeGuard sslGuard = MakeGuard (::SSL_free, sslConn->ssl );
792- ScopeGuard bioGuard = MakeGuard (::BIO_free, sslConn->networkBIO );
817+ std::auto_ptr<SSLConnection> sslConn (new SSLConnection (_serverContext, socket, initialBytes, len));
793818
794819 int ret;
795820 do {
796821 ret = ::SSL_accept (sslConn->ssl );
797- } while (!_doneWithSSLOp (sslConn, ret));
822+ } while (!_doneWithSSLOp (sslConn. get () , ret));
798823
799824 if (ret != 1 )
800- _handleSSLError (SSL_get_error (sslConn, ret), ret);
825+ _handleSSLError (SSL_get_error (sslConn. get () , ret), ret);
801826
802- sslGuard.Dismiss ();
803- bioGuard.Dismiss ();
804- return sslConn;
827+ return sslConn.release ();
805828 }
806829
807830 // TODO SERVER-11601 Use NFC Unicode canonicalization
0 commit comments