Skip to content

Commit bb98712

Browse files
committed
CXX-1614 Fix crash setting client SSL options
1 parent 74bed41 commit bb98712

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

src/mongocxx/client.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,11 @@ client::client(const class uri& uri, const options::client& options) {
4444
if (!uri.ssl())
4545
throw exception{error_code::k_invalid_parameter,
4646
"cannot set SSL options if 'ssl=true' not in URI"};
47-
48-
auto mongoc_opts = options::make_ssl_opts(*options.ssl_opts());
49-
_impl->ssl_options = std::move(mongoc_opts.second);
50-
libmongoc::client_set_ssl_opts(_get_impl().client_t, &mongoc_opts.first);
5147
}
5248
#else
53-
if (uri.ssl() || options.ssl_opts())
49+
if (uri.ssl() || options.ssl_opts()) {
5450
throw exception{error_code::k_ssl_not_supported};
51+
}
5552
#endif
5653
auto new_client = libmongoc::client_new_from_uri(uri._impl->uri_t);
5754
if (!new_client) {
@@ -60,6 +57,14 @@ client::client(const class uri& uri, const options::client& options) {
6057
}
6158

6259
_impl = stdx::make_unique<impl>(std::move(new_client));
60+
61+
#if defined(MONGOCXX_ENABLE_SSL) && defined(MONGOC_ENABLE_SSL)
62+
if (options.ssl_opts()) {
63+
auto mongoc_opts = options::make_ssl_opts(*options.ssl_opts());
64+
_impl->ssl_options = std::move(mongoc_opts.second);
65+
libmongoc::client_set_ssl_opts(_get_impl().client_t, &mongoc_opts.first);
66+
}
67+
#endif
6368
}
6469

6570
client::client(void* implementation)

src/mongocxx/test/client.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,47 @@ TEST_CASE("integration tests for client metadata handshake feature") {
299299
run_test(*client);
300300
}
301301
}
302+
303+
#if defined(MONGOCXX_ENABLE_SSL) && defined(MONGOC_ENABLE_SSL)
304+
TEST_CASE("A client can be constructed with SSL options", "[client]") {
305+
MOCK_CLIENT
306+
307+
instance::current();
308+
309+
const std::string pem_file = "foo";
310+
const std::string pem_password = "bar";
311+
const std::string ca_file = "baz";
312+
const std::string ca_dir = "garply";
313+
const std::string crl_file = "crl_file";
314+
const bool allow_invalid_certificates = true;
315+
316+
bool set_ssl_opts_called = false;
317+
options::ssl ssl_opts;
318+
ssl_opts.pem_file(pem_file);
319+
ssl_opts.pem_password(pem_password);
320+
ssl_opts.ca_file(ca_file);
321+
ssl_opts.ca_dir(ca_dir);
322+
ssl_opts.crl_file(crl_file);
323+
ssl_opts.allow_invalid_certificates(allow_invalid_certificates);
324+
325+
::mongoc_ssl_opt_t interposed = {};
326+
327+
client_set_ssl_opts->interpose([&](::mongoc_client_t*, const ::mongoc_ssl_opt_t* opts) {
328+
set_ssl_opts_called = true;
329+
interposed = *opts;
330+
});
331+
332+
client c{uri{"mongodb://mongodb.example.com:9999/?ssl=true"},
333+
options::client().ssl_opts(ssl_opts)};
334+
335+
REQUIRE(set_ssl_opts_called);
336+
REQUIRE(interposed.pem_file == pem_file);
337+
REQUIRE(interposed.pem_pwd == pem_password);
338+
REQUIRE(interposed.ca_file == ca_file);
339+
REQUIRE(interposed.ca_dir == ca_dir);
340+
REQUIRE(interposed.crl_file == crl_file);
341+
REQUIRE(interposed.weak_cert_validation == allow_invalid_certificates);
342+
}
343+
#endif
344+
302345
} // namespace

src/mongocxx/test/pool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ TEST_CASE("a pool is created with the correct MongoDB URI", "[pool]") {
5959
REQUIRE(destroy_called);
6060
}
6161

62-
#if defined(MONGOC_ENABLE_SSL)
62+
#if defined(MONGOCXX_ENABLE_SSL) && defined(MONGOC_ENABLE_SSL)
6363
TEST_CASE(
6464
"If we pass an engaged SSL options struct to the pool class, we will use it to configure the "
6565
"underlying mongoc pool",

src/third_party/catch/include/helpers.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ MONGOCXX_INLINE_NAMESPACE_END
7676
#define MOCK_POOL MOCK_POOL_NOSSL
7777
#endif
7878

79-
#define MOCK_CLIENT \
79+
#define MOCK_CLIENT_NOSSL \
8080
auto client_new = libmongoc::client_new_from_uri.create_instance(); \
8181
auto client_destroy = libmongoc::client_destroy.create_instance(); \
8282
auto client_set_read_concern = libmongoc::client_set_read_concern.create_instance(); \
@@ -92,6 +92,15 @@ MONGOCXX_INLINE_NAMESPACE_END
9292
client_get_concern->interpose([](const mongoc_client_t*) { return nullptr; }).forever(); \
9393
auto client_start_session = libmongoc::client_start_session.create_instance();
9494

95+
#if defined(MONGOCXX_ENABLE_SSL) && defined(MONGOC_ENABLE_SSL)
96+
#define MOCK_CLIENT \
97+
MOCK_CLIENT_NOSSL \
98+
auto client_set_ssl_opts = libmongoc::client_set_ssl_opts.create_instance(); \
99+
client_set_ssl_opts->interpose([](::mongoc_client_t*, const ::mongoc_ssl_opt_t*) {});
100+
#else
101+
#define MOCK_CLIENT MOCK_CLIENT_NOSSL
102+
#endif
103+
95104
#define MOCK_DATABASE \
96105
auto get_database = libmongoc::client_get_database.create_instance(); \
97106
get_database->interpose([&](mongoc_client_t*, const char*) { return nullptr; }); \

0 commit comments

Comments
 (0)