From 47a67183526530bc8e9ac9ffe5325c5dfd3a0b2e Mon Sep 17 00:00:00 2001 From: Prashant Mital Date: Mon, 9 Mar 2020 16:06:50 -0700 Subject: [PATCH] PYTHON-2161 add support for tlsDisableOcspEndpointCheck URI option --- pymongo/client_options.py | 6 +- pymongo/common.py | 6 +- pymongo/database.py | 2 +- pymongo/encryption.py | 2 +- pymongo/mongo_client.py | 11 +- pymongo/ocsp_support.py | 4 + pymongo/pyopenssl_context.py | 18 +- pymongo/ssl_support.py | 5 +- pymongo/uri_parser.py | 43 ++- test/test_ssl.py | 18 +- test/test_uri_parser.py | 2 +- test/test_uri_spec.py | 28 +- test/uri_options/tls-options.json | 426 +++++++++++++++++++++++++++++- 13 files changed, 538 insertions(+), 33 deletions(-) diff --git a/pymongo/client_options.py b/pymongo/client_options.py index 7bb68a910..4f40629e7 100644 --- a/pymongo/client_options.py +++ b/pymongo/client_options.py @@ -80,10 +80,11 @@ def _parse_ssl_options(options): cert_reqs = options.get('ssl_cert_reqs') match_hostname = options.get('ssl_match_hostname', True) crlfile = options.get('ssl_crlfile') + check_ocsp_endpoint = options.get('ssl_check_ocsp_endpoint', True) ssl_kwarg_keys = [k for k in options if k.startswith('ssl_') and options[k]] - if use_ssl == False and ssl_kwarg_keys: + if use_ssl is False and ssl_kwarg_keys: raise ConfigurationError("ssl has not been enabled but the " "following ssl parameters have been set: " "%s. Please set `ssl=True` or remove." @@ -101,7 +102,8 @@ def _parse_ssl_options(options): ca_certs, cert_reqs, crlfile, - match_hostname) + match_hostname, + check_ocsp_endpoint) return ctx, match_hostname return None, match_hostname diff --git a/pymongo/common.py b/pymongo/common.py index 12777b7ac..8b586c4b4 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -617,6 +617,7 @@ URI_OPTIONS_VALIDATOR_MAP = { 'tlscafile': validate_readable, 'tlscertificatekeyfile': validate_readable, 'tlscertificatekeyfilepassword': validate_string_or_none, + 'tlsdisableocspendpointcheck': validate_boolean_or_string, 'tlsinsecure': validate_boolean_or_string, 'w': validate_non_negative_int_or_basestring, 'wtimeoutms': validate_non_negative_integer, @@ -668,6 +669,7 @@ INTERNAL_URI_OPTION_NAME_MAP = { 'tlscafile': 'ssl_ca_certs', 'tlscertificatekeyfile': 'ssl_certfile', 'tlscertificatekeyfilepassword': 'ssl_pem_passphrase', + 'tlsdisableocspendpointcheck': 'ssl_check_ocsp_endpoint', } # Map from deprecated URI option names to a tuple indicating the method of @@ -726,7 +728,7 @@ def validate_auth_option(option, value): if lower not in _AUTH_OPTIONS: raise ConfigurationError('Unknown ' 'authentication option: %s' % (option,)) - return lower, value + return option, value def validate(option, value): @@ -735,7 +737,7 @@ def validate(option, value): lower = option.lower() validator = VALIDATORS.get(lower, raise_config_error) value = validator(option, value) - return lower, value + return option, value def get_validated_options(options, warn=True): diff --git a/pymongo/database.py b/pymongo/database.py index 144a1f6b4..7137c96bf 100644 --- a/pymongo/database.py +++ b/pymongo/database.py @@ -1471,7 +1471,7 @@ class Database(common.BaseObject): "instance of %s" % (string_type.__name__,)) common.validate_auth_mechanism('mechanism', mechanism) - validated_options = {} + validated_options = common._CaseInsensitiveDictionary() for option, value in iteritems(kwargs): normalized, val = common.validate_auth_option(option, value) validated_options[normalized] = val diff --git a/pymongo/encryption.py b/pymongo/encryption.py index f71cd48b6..952470809 100644 --- a/pymongo/encryption.py +++ b/pymongo/encryption.py @@ -107,7 +107,7 @@ class _EncryptionIO(MongoCryptCallback): endpoint = kms_context.endpoint message = kms_context.message host, port = parse_host(endpoint, _HTTPS_PORT) - ctx = get_ssl_context(None, None, None, None, None, None, True) + ctx = get_ssl_context(None, None, None, None, None, None, True, True) opts = PoolOptions(connect_timeout=_KMS_CONNECT_TIMEOUT, socket_timeout=_KMS_CONNECT_TIMEOUT, ssl_context=ctx) diff --git a/pymongo/mongo_client.py b/pymongo/mongo_client.py index 9b33fa2cd..ac00a38e8 100644 --- a/pymongo/mongo_client.py +++ b/pymongo/mongo_client.py @@ -459,6 +459,9 @@ class MongoClient(common.BaseObject): ``ssl_keyfile``. Only necessary if the private key is encrypted. Only supported by python 2.7.9+ (pypy 2.5.1+) and 3.3+. Defaults to ``None``. + - `tlsDisableOCSPEndpointCheck`: (boolean) If ``True``, disables + certificate revocation status checking via the OCSP responder + specified on the server certificate. Defaults to ``False``. - `ssl`: (boolean) Alias for ``tls``. - `ssl_certfile`: The certificate file used to identify the local connection against mongod. Implies ``tls=True``. Defaults to @@ -488,6 +491,10 @@ class MongoClient(common.BaseObject): .. mongodoc:: connections + .. versionchanged:: 3.11 + Added the ``tlsDisableOCSPEndpointCheck`` keyword argument and + URI option. + .. versionchanged:: 3.9 Added the ``retryReads`` keyword argument and URI option. Added the ``tlsInsecure`` keyword argument and URI option. @@ -645,8 +652,8 @@ class MongoClient(common.BaseObject): # Handle deprecated options in kwarg options. keyword_opts = _handle_option_deprecations(keyword_opts) # Validate kwarg options. - keyword_opts = common._CaseInsensitiveDictionary( - dict(common.validate(k, v) for k, v in keyword_opts.items())) + keyword_opts = common._CaseInsensitiveDictionary(dict(common.validate( + keyword_opts.cased_key(k), v) for k, v in keyword_opts.items())) # Override connection string options with kwarg options. opts.update(keyword_opts) diff --git a/pymongo/ocsp_support.py b/pymongo/ocsp_support.py index daa83e39b..be0927799 100644 --- a/pymongo/ocsp_support.py +++ b/pymongo/ocsp_support.py @@ -289,6 +289,10 @@ def _ocsp_callback(conn, ocsp_bytes, user_data): if must_staple: _LOGGER.debug("Must-staple cert with no stapled response, hard fail.") return 0 + if not user_data.check_ocsp_endpoint: + _LOGGER.debug("OCSP endpoint checking is disabled, soft fail.") + # No stapled OCSP response, checking responder URI diabled, soft fail. + return 1 # https://tools.ietf.org/html/rfc6960#section-3.1 ext = _get_extension(cert, _AuthorityInformationAccess) if ext is None: diff --git a/pymongo/pyopenssl_context.py b/pymongo/pyopenssl_context.py index 1011893e2..c073427de 100644 --- a/pymongo/pyopenssl_context.py +++ b/pymongo/pyopenssl_context.py @@ -141,6 +141,7 @@ class _CallbackData(object): """Data class which is passed to the OCSP callback.""" def __init__(self): self.trusted_ca_certs = None + self.check_ocsp_endpoint = None class SSLContext(object): @@ -148,21 +149,21 @@ class SSLContext(object): context. """ - __slots__ = ('_protocol', '_ctx', '_check_hostname', '_callback_data') + __slots__ = ('_protocol', '_ctx', '_callback_data', '_check_hostname') def __init__(self, protocol): self._protocol = protocol self._ctx = _SSL.Context(self._protocol) - self._check_hostname = True self._callback_data = _CallbackData() + self._check_hostname = True # OCSP # XXX: Find a better place to do this someday, since this is client # side configuration and wrap_socket tries to support both client and # server side sockets. + self._callback_data.check_ocsp_endpoint = True self._ctx.set_ocsp_client_callback( callback=_ocsp_callback, data=self._callback_data) - @property def protocol(self): """The protocol version chosen when constructing the context. @@ -199,6 +200,17 @@ class SSLContext(object): check_hostname = property(__get_check_hostname, __set_check_hostname) + def __get_check_ocsp_endpoint(self): + return self._callback_data.check_ocsp_endpoint + + def __set_check_ocsp_endpoint(self, value): + if not isinstance(value, bool): + raise TypeError("check_ocsp must be True or False") + self._callback_data.check_ocsp_endpoint = value + + check_ocsp_endpoint = property(__get_check_ocsp_endpoint, + __set_check_ocsp_endpoint) + def __get_options(self): # Calling set_options adds the option to the existing bitmask and # returns the new bitmask. diff --git a/pymongo/ssl_support.py b/pymongo/ssl_support.py index 4307d9774..b5847244c 100644 --- a/pymongo/ssl_support.py +++ b/pymongo/ssl_support.py @@ -102,7 +102,8 @@ if HAVE_SSL: ca_certs, cert_reqs, crlfile, - match_hostname) = args + match_hostname, + check_ocsp_endpoint) = args verify_mode = CERT_REQUIRED if cert_reqs is None else cert_reqs ctx = _ssl.SSLContext(_ssl.PROTOCOL_SSLv23) # SSLContext.check_hostname was added in CPython 2.7.9 and 3.4. @@ -111,6 +112,8 @@ if HAVE_SSL: ctx.check_hostname = match_hostname else: ctx.check_hostname = False + if hasattr(ctx, "check_ocsp_endpoint"): + ctx.check_ocsp_endpoint = check_ocsp_endpoint if hasattr(ctx, "options"): # Explicitly disable SSLv2, SSLv3 and TLS compression. Note that # up to date versions of MongoDB 2.4 and above already disable diff --git a/pymongo/uri_parser.py b/pymongo/uri_parser.py index a6b0a46cd..779a8c5ed 100644 --- a/pymongo/uri_parser.py +++ b/pymongo/uri_parser.py @@ -126,12 +126,16 @@ def parse_host(entity, default_port=DEFAULT_PORT): return host.lower(), port -_IMPLICIT_TLSINSECURE_OPTS = {"tlsallowinvalidcertificates", - "tlsallowinvalidhostnames"} +# Options whose values are implicitly determined by tlsInsecure. +_IMPLICIT_TLSINSECURE_OPTS = { + "tlsallowinvalidcertificates", + "tlsallowinvalidhostnames", + "tlsdisableocspendpointcheck",} -_TLSINSECURE_EXCLUDE_OPTS = (_IMPLICIT_TLSINSECURE_OPTS | - {INTERNAL_URI_OPTION_NAME_MAP[k] for k in - _IMPLICIT_TLSINSECURE_OPTS}) +# Options that cannot be specified when tlsInsecure is also specified. +_TLSINSECURE_EXCLUDE_OPTS = ( + {k for k in _IMPLICIT_TLSINSECURE_OPTS} | + {INTERNAL_URI_OPTION_NAME_MAP[k] for k in _IMPLICIT_TLSINSECURE_OPTS}) def _parse_options(opts, delim): @@ -172,6 +176,33 @@ def _handle_security_options(options): raise InvalidURI(err_msg % ( options.cased_key('tlsinsecure'), options.cased_key(opt))) + # Convenience function to retrieve option values based on public or private names. + def _getopt(opt): + return (options.get(opt) or + options.get(INTERNAL_URI_OPTION_NAME_MAP[opt])) + + # Handle co-occurence of OCSP & tlsAllowInvalidCertificates options. + tlsallowinvalidcerts = _getopt('tlsallowinvalidcertificates') + if tlsallowinvalidcerts is not None: + if 'tlsdisableocspendpointcheck' in options: + err_msg = ("URI options %s and %s cannot be specified " + "simultaneously.") + raise InvalidURI(err_msg % ( + 'tlsallowinvalidcertificates', options.cased_key( + 'tlsdisableocspendpointcheck'))) + if tlsallowinvalidcerts is True: + options['tlsdisableocspendpointcheck'] = True + + # Handle co-occurence of CRL and OCSP-related options. + tlscrlfile = _getopt('tlscrlfile') + if tlscrlfile is not None: + for opt in ('tlsinsecure', 'tlsallowinvalidcertificates', + 'tlsdisableocspendpointcheck'): + if options.get(opt) is True: + err_msg = ("URI option %s=True cannot be specified when " + "CRL checking is enabled.") + raise InvalidURI(err_msg % (opt,)) + if 'ssl' in options and 'tls' in options: def truth_value(val): if val in ('true', 'false'): @@ -235,7 +266,7 @@ def _normalize_options(options): tlsinsecure = options.get('tlsinsecure') if tlsinsecure is not None: for opt in _IMPLICIT_TLSINSECURE_OPTS: - intname = INTERNAL_URI_OPTION_NAME_MAP.get(opt, None) + intname = INTERNAL_URI_OPTION_NAME_MAP[opt] # Internal options are logical inverse of public options. options[intname] = not tlsinsecure diff --git a/test/test_ssl.py b/test/test_ssl.py index f663a2e19..0987354c7 100644 --- a/test/test_ssl.py +++ b/test/test_ssl.py @@ -345,17 +345,17 @@ class TestSSL(IntegrationTest): # Python > 2.7.9. If SSLContext doesn't have load_default_certs # it also doesn't have check_hostname. ctx = get_ssl_context( - None, None, None, None, ssl.CERT_NONE, None, False) + None, None, None, None, ssl.CERT_NONE, None, False, True) if hasattr(ctx, 'load_default_certs'): self.assertFalse(ctx.check_hostname) ctx = get_ssl_context( - None, None, None, None, ssl.CERT_NONE, None, True) + None, None, None, None, ssl.CERT_NONE, None, True, True) self.assertFalse(ctx.check_hostname) ctx = get_ssl_context( - None, None, None, None, ssl.CERT_REQUIRED, None, False) + None, None, None, None, ssl.CERT_REQUIRED, None, False, True) self.assertFalse(ctx.check_hostname) ctx = get_ssl_context( - None, None, None, None, ssl.CERT_REQUIRED, None, True) + None, None, None, None, ssl.CERT_REQUIRED, None, True, True) if _PY37PLUS: self.assertTrue(ctx.check_hostname) else: @@ -493,7 +493,7 @@ class TestSSL(IntegrationTest): def test_system_certs_config_error(self): ctx = get_ssl_context( - None, None, None, None, ssl.CERT_NONE, None, False) + None, None, None, None, ssl.CERT_NONE, None, False, True) if ((sys.platform != "win32" and hasattr(ctx, "set_default_verify_paths")) or hasattr(ctx, "load_default_certs")): @@ -526,11 +526,11 @@ class TestSSL(IntegrationTest): ssl_support.HAVE_WINCERTSTORE = False try: ctx = get_ssl_context( - None, None, None, CA_PEM, ssl.CERT_REQUIRED, None, True) + None, None, None, CA_PEM, ssl.CERT_REQUIRED, None, True, True) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, CA_PEM) - ctx = get_ssl_context(None, None, None, None, None, None, True) + ctx = get_ssl_context(None, None, None, None, None, None, True, True) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, ssl_support.certifi.where()) finally: @@ -548,11 +548,11 @@ class TestSSL(IntegrationTest): raise SkipTest("Need wincertstore to test wincertstore.") ctx = get_ssl_context( - None, None, None, CA_PEM, ssl.CERT_REQUIRED, None, True) + None, None, None, CA_PEM, ssl.CERT_REQUIRED, None, True, True) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, CA_PEM) - ctx = get_ssl_context(None, None, None, None, None, None, True) + ctx = get_ssl_context(None, None, None, None, None, None, True, True) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, ssl_support._WINCERTS.name) diff --git a/test/test_uri_parser.py b/test/test_uri_parser.py index a921c6656..8d1f55a0d 100644 --- a/test/test_uri_parser.py +++ b/test/test_uri_parser.py @@ -470,7 +470,7 @@ class TestURI(unittest.TestCase): uri = "mongodb://example.com/?tlsInsecure=true" res = { "ssl_match_hostname": False, "ssl_cert_reqs": CERT_NONE, - "tlsinsecure": True} + "tlsinsecure": True, 'ssl_check_ocsp_endpoint': False} self.assertEqual(res, parse_uri(uri)["options"]) def test_tlsinsecure_legacy_conflict(self): diff --git a/test/test_uri_spec.py b/test/test_uri_spec.py index 9bc7cb178..cfca63345 100644 --- a/test/test_uri_spec.py +++ b/test/test_uri_spec.py @@ -37,7 +37,33 @@ URI_OPTIONS_TEST_PATH = os.path.join( TEST_DESC_SKIP_LIST = [ "Valid options specific to single-threaded drivers are parsed correctly", - "Invalid serverSelectionTryOnce causes a warning"] + "Invalid serverSelectionTryOnce causes a warning", + "tlsDisableCertificateRevocationCheck can be set to true", + "tlsDisableCertificateRevocationCheck can be set to false", + "tlsAllowInvalidCertificates and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "tlsAllowInvalidCertificates=true and tlsDisableCertificateRevocationCheck=false raises an error", + "tlsAllowInvalidCertificates=false and tlsDisableCertificateRevocationCheck=true raises an error", + "tlsAllowInvalidCertificates and tlsDisableCertificateRevocationCheck both present (and false) raises an error", + "tlsDisableCertificateRevocationCheck and tlsAllowInvalidCertificates both present (and true) raises an error", + "tlsDisableCertificateRevocationCheck=true and tlsAllowInvalidCertificates=false raises an error", + "tlsDisableCertificateRevocationCheck=false and tlsAllowInvalidCertificates=true raises an error", + "tlsDisableCertificateRevocationCheck and tlsAllowInvalidCertificates both present (and false) raises an error", + "tlsInsecure and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "tlsInsecure=true and tlsDisableCertificateRevocationCheck=false raises an error", + "tlsInsecure=false and tlsDisableCertificateRevocationCheck=true raises an error", + "tlsInsecure and tlsDisableCertificateRevocationCheck both present (and false) raises an error", + "tlsDisableCertificateRevocationCheck and tlsInsecure both present (and true) raises an error", + "tlsDisableCertificateRevocationCheck=true and tlsInsecure=false raises an error", + "tlsDisableCertificateRevocationCheck=false and tlsInsecure=true raises an error", + "tlsDisableCertificateRevocationCheck and tlsInsecure both present (and false) raises an error", + "tlsDisableCertificateRevocationCheck and tlsDisableOCSPEndpointCheck both present (and true) raises an error", + "tlsDisableCertificateRevocationCheck=true and tlsDisableOCSPEndpointCheck=false raises an error", + "tlsDisableCertificateRevocationCheck=false and tlsDisableOCSPEndpointCheck=true raises an error", + "tlsDisableCertificateRevocationCheck and tlsDisableOCSPEndpointCheck both present (and false) raises an error", + "tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "tlsDisableOCSPEndpointCheck=true and tlsDisableCertificateRevocationCheck=false raises an error", + "tlsDisableOCSPEndpointCheck=false and tlsDisableCertificateRevocationCheck=true raises an error", + "tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevocationCheck both present (and false) raises an error"] class TestAllScenarios(unittest.TestCase): diff --git a/test/uri_options/tls-options.json b/test/uri_options/tls-options.json index 6db80ed62..edf604294 100644 --- a/test/uri_options/tls-options.json +++ b/test/uri_options/tls-options.json @@ -2,7 +2,7 @@ "tests": [ { "description": "Valid required tls options are parsed correctly", - "uri": "mongodb://example.com/?tls=true&tlsCAFile=ca.pem&tlsCertificateKeyFile=cert.pem&tlsCertificateKeyFilePassword=hunter2", + "uri": "mongodb://example.com/?tls=true&tlsCAFile=ca.pem&tlsCertificateKeyFile=cert.pem", "valid": true, "warning": false, "hosts": null, @@ -10,7 +10,17 @@ "options": { "tls": true, "tlsCAFile": "ca.pem", - "tlsCertificateKeyFile": "cert.pem", + "tlsCertificateKeyFile": "cert.pem" + } + }, + { + "description": "Valid tlsCertificateKeyFilePassword is parsed correctly", + "uri": "mongodb://example.com/?tlsCertificateKeyFilePassword=hunter2", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { "tlsCertificateKeyFilePassword": "hunter2" } }, @@ -75,8 +85,8 @@ } }, { - "description": "Invalid tlsAllowInsecure causes a warning", - "uri": "mongodb://example.com/?tlsAllowInsecure=invalid", + "description": "Invalid tlsInsecure causes a warning", + "uri": "mongodb://example.com/?tlsInsecure=invalid", "valid": true, "warning": true, "hosts": null, @@ -226,6 +236,414 @@ "hosts": null, "auth": null, "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck can be set to true", + "uri": "mongodb://example.com/?tls=true&tlsDisableCertificateRevocationCheck=true", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { + "tls": true, + "tlsDisableCertificateRevocationCheck": true + } + }, + { + "description": "tlsDisableCertificateRevocationCheck can be set to false", + "uri": "mongodb://example.com/?tls=true&tlsDisableCertificateRevocationCheck=false", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { + "tls": true, + "tlsDisableCertificateRevocationCheck": false + } + }, + { + "description": "tlsAllowInvalidCertificates and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates=true and tlsDisableCertificateRevocationCheck=false raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates=false and tlsDisableCertificateRevocationCheck=true raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=false&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates and tlsDisableCertificateRevocationCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=false&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsAllowInvalidCertificates both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsAllowInvalidCertificates=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=true and tlsAllowInvalidCertificates=false raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsAllowInvalidCertificates=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=false and tlsAllowInvalidCertificates=true raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsAllowInvalidCertificates=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsAllowInvalidCertificates both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsAllowInvalidCertificates=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsInsecure=true&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure=true and tlsDisableCertificateRevocationCheck=false raises an error", + "uri": "mongodb://example.com/?tlsInsecure=true&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure=false and tlsDisableCertificateRevocationCheck=true raises an error", + "uri": "mongodb://example.com/?tlsInsecure=false&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure and tlsDisableCertificateRevocationCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsInsecure=false&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsInsecure both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsInsecure=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=true and tlsInsecure=false raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsInsecure=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=false and tlsInsecure=true raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsInsecure=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsInsecure both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsInsecure=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsDisableOCSPEndpointCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=true and tlsDisableOCSPEndpointCheck=false raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=true&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck=false and tlsDisableOCSPEndpointCheck=true raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableCertificateRevocationCheck and tlsDisableOCSPEndpointCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableCertificateRevocationCheck=false&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevocationCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=true and tlsDisableCertificateRevocationCheck=false raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=false and tlsDisableCertificateRevocationCheck=true raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsDisableCertificateRevocationCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevocationCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsDisableCertificateRevocationCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck can be set to true", + "uri": "mongodb://example.com/?tls=true&tlsDisableOCSPEndpointCheck=true", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { + "tls": true, + "tlsDisableOCSPEndpointCheck": true + } + }, + { + "description": "tlsDisableOCSPEndpointCheck can be set to false", + "uri": "mongodb://example.com/?tls=true&tlsDisableOCSPEndpointCheck=false", + "valid": true, + "warning": false, + "hosts": null, + "auth": null, + "options": { + "tls": true, + "tlsDisableOCSPEndpointCheck": false + } + }, + { + "description": "tlsInsecure and tlsDisableOCSPEndpointCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsInsecure=true&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure=true and tlsDisableOCSPEndpointCheck=false raises an error", + "uri": "mongodb://example.com/?tlsInsecure=true&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure=false and tlsDisableOCSPEndpointCheck=true raises an error", + "uri": "mongodb://example.com/?tlsInsecure=false&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsInsecure and tlsDisableOCSPEndpointCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsInsecure=false&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsInsecure both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsInsecure=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=true and tlsInsecure=false raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsInsecure=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=false and tlsInsecure=true raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsInsecure=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsInsecure both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsInsecure=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates and tlsDisableOCSPEndpointCheck both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates=true and tlsDisableOCSPEndpointCheck=false raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=true&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates=false and tlsDisableOCSPEndpointCheck=true raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=false&tlsDisableOCSPEndpointCheck=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsAllowInvalidCertificates and tlsDisableOCSPEndpointCheck both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsAllowInvalidCertificates=false&tlsDisableOCSPEndpointCheck=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsAllowInvalidCertificates both present (and true) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsAllowInvalidCertificates=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=true and tlsAllowInvalidCertificates=false raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=true&tlsAllowInvalidCertificates=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck=false and tlsAllowInvalidCertificates=true raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsAllowInvalidCertificates=true", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} + }, + { + "description": "tlsDisableOCSPEndpointCheck and tlsAllowInvalidCertificates both present (and false) raises an error", + "uri": "mongodb://example.com/?tlsDisableOCSPEndpointCheck=false&tlsAllowInvalidCertificates=false", + "valid": false, + "warning": false, + "hosts": null, + "auth": null, + "options": {} } ] }