Skip to content

Commit 6860079

Browse files
committed
CDRIVER-935 pooled clients require SSL if opts set
In 1.1.x, all clients (pooled and single-threaded) required an SSL connection to the server only if "ssl=true" was in the URI. In 1.2.0 this changed unintentionally (but beneficially) for single-threaded clients: setting a single-threaded client's SSL options put the client in SSL mode, even if "ssl=true" is omitted from the URI. Pooled clients, however, stopped working entirely if the options are set but "ssl=true" is omitted. This patch fixes pooled clients and tests the new behavior for both.
1 parent 8fe13af commit 6860079

File tree

6 files changed

+140
-22
lines changed

6 files changed

+140
-22
lines changed

src/mongoc/mongoc-client-private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct _mongoc_client_t
5454
void *initiator_data;
5555

5656
#ifdef MONGOC_ENABLE_SSL
57+
bool use_ssl;
5758
mongoc_ssl_opt_t ssl_opts;
5859
char *pem_subject;
5960
#endif

src/mongoc/mongoc-client.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,8 @@ mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
274274
mongoc_stream_t *base_stream = NULL;
275275
#ifdef MONGOC_ENABLE_SSL
276276
mongoc_client_t *client = (mongoc_client_t *)user_data;
277-
const bson_t *options;
278-
bson_iter_t iter;
279277
const char *mechanism;
280-
int32_t connecttimeoutms = MONGOC_DEFAULT_CONNECTTIMEOUTMS;
278+
int32_t connecttimeoutms;
281279
#endif
282280

283281
BSON_ASSERT (uri);
@@ -314,11 +312,9 @@ mongoc_client_default_stream_initiator (const mongoc_uri_t *uri,
314312

315313
#ifdef MONGOC_ENABLE_SSL
316314
if (base_stream) {
317-
options = mongoc_uri_get_options (uri);
318315
mechanism = mongoc_uri_get_auth_mechanism (uri);
319316

320-
if ((bson_iter_init_find_case (&iter, options, "ssl") &&
321-
bson_iter_as_bool (&iter)) ||
317+
if (client->use_ssl ||
322318
(mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) {
323319
base_stream = mongoc_stream_tls_new (base_stream, &client->ssl_opts,
324320
true);
@@ -646,6 +642,7 @@ mongoc_client_set_ssl_opts (mongoc_client_t *client,
646642
BSON_ASSERT (client);
647643
BSON_ASSERT (opts);
648644

645+
client->use_ssl = true;
649646
memcpy (&client->ssl_opts, opts, sizeof client->ssl_opts);
650647

651648
bson_free (client->pem_subject);
@@ -712,10 +709,6 @@ _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topolog
712709
mongoc_client_t *client;
713710
const mongoc_read_prefs_t *read_prefs;
714711
const mongoc_write_concern_t *write_concern;
715-
#ifdef MONGOC_ENABLE_SSL
716-
const bson_t *options;
717-
bson_iter_t iter;
718-
#endif
719712

720713
BSON_ASSERT (uri);
721714

@@ -735,12 +728,10 @@ _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topolog
735728
mongoc_cluster_init (&client->cluster, client->uri, client);
736729

737730
#ifdef MONGOC_ENABLE_SSL
738-
options = mongoc_uri_get_options (client->uri);
739-
740-
if (bson_iter_init_find (&iter, options, "ssl") &&
741-
BSON_ITER_HOLDS_BOOL (&iter) &&
742-
bson_iter_bool (&iter)) {
743-
mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ());
731+
client->use_ssl = false;
732+
if (mongoc_uri_get_ssl (client->uri)) {
733+
/* sets use_ssl = true */
734+
mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ());
744735
}
745736
#endif
746737

tests/debug-stream.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ debug_stream_initiator (const mongoc_uri_t *uri,
180180

181181
default_stream = mongoc_client_default_stream_initiator (uri,
182182
host,
183-
user_data,
183+
stats->client,
184184
error);
185185

186186
return debug_stream_new (default_stream, stats);
@@ -191,6 +191,7 @@ void
191191
test_framework_set_debug_stream (mongoc_client_t *client,
192192
debug_stream_stats_t *stats)
193193
{
194+
stats->client = client;
194195
mongoc_client_set_stream_initiator (client,
195196
debug_stream_initiator,
196197
stats);

tests/test-libmongoc.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ test_framework_add_user_password (const char *uri_str,
443443
*
444444
*--------------------------------------------------------------------------
445445
*/
446-
static char *
446+
char *
447447
test_framework_add_user_password_from_env (const char *uri_str)
448448
{
449449
char *user;
@@ -858,6 +858,30 @@ test_framework_client_new ()
858858
}
859859

860860

861+
#ifdef MONGOC_ENABLE_SSL
862+
/*
863+
*--------------------------------------------------------------------------
864+
*
865+
* test_framework_get_ssl_opts --
866+
*
867+
* Get options for connecting to mongod over SSL (even if mongod
868+
* isn't actually SSL-enabled).
869+
*
870+
* Returns:
871+
* A pointer to constant global SSL-test options.
872+
*
873+
* Side effects:
874+
* None.
875+
*
876+
*--------------------------------------------------------------------------
877+
*/
878+
const mongoc_ssl_opt_t *
879+
test_framework_get_ssl_opts (void)
880+
{
881+
return &gSSLOptions;
882+
}
883+
#endif
884+
861885
/*
862886
*--------------------------------------------------------------------------
863887
*
@@ -874,7 +898,7 @@ test_framework_client_new ()
874898
*
875899
*--------------------------------------------------------------------------
876900
*/
877-
static void
901+
void
878902
test_framework_set_pool_ssl_opts (mongoc_client_pool_t *pool)
879903
{
880904
assert (pool);

tests/test-libmongoc.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,17 @@ bool test_framework_get_ssl (void);
3333
char *test_framework_add_user_password (const char *uri_str,
3434
const char *user,
3535
const char *password);
36+
char *test_framework_add_user_password_from_env (const char *uri_str);
3637
char *test_framework_get_uri_str_no_auth (const char *database_name);
3738
char *test_framework_get_uri_str (void);
3839
char *test_framework_get_unix_domain_socket_uri_str (void);
3940
char *test_framework_get_unix_domain_socket_path (void);
4041
mongoc_uri_t *test_framework_get_uri (void);
42+
#ifdef MONGOC_ENABLE_SSL
43+
const mongoc_ssl_opt_t *test_framework_get_ssl_opts (void);
44+
#endif
4145
void test_framework_set_ssl_opts (mongoc_client_t *client);
46+
void test_framework_set_pool_ssl_opts (mongoc_client_pool_t *pool);
4247
mongoc_client_t *test_framework_client_new (void);
4348
mongoc_client_pool_t *test_framework_client_pool_new (void);
4449
bool test_framework_max_wire_version_at_least (int version);
@@ -52,8 +57,9 @@ int test_framework_skip_if_single (void);
5257
int test_framework_skip_if_windows (void);
5358

5459
typedef struct _debug_stream_stats_t {
55-
int n_destroyed;
56-
int n_failed;
60+
mongoc_client_t *client;
61+
int n_destroyed;
62+
int n_failed;
5763
} debug_stream_stats_t;
5864

5965
void test_framework_set_debug_stream (mongoc_client_t *client,

tests/test-mongoc-client.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,97 @@ test_mongoc_client_unix_domain_socket (void *context)
880880
}
881881

882882

883+
#ifdef MONGOC_ENABLE_SSL
884+
static void
885+
_test_mongoc_client_ssl_opts (bool pooled)
886+
{
887+
char *host;
888+
uint16_t port;
889+
char *uri_str;
890+
char *uri_str_auth;
891+
char *uri_str_auth_ssl;
892+
mongoc_uri_t *uri;
893+
const mongoc_ssl_opt_t *ssl_opts;
894+
mongoc_client_pool_t *pool = NULL;
895+
mongoc_client_t *client;
896+
bool ret;
897+
bson_error_t error;
898+
int add_ssl_to_uri;
899+
900+
host = test_framework_get_host ();
901+
port = test_framework_get_port ();
902+
uri_str = bson_strdup_printf (
903+
"mongodb://%s:%d/?serverSelectionTimeoutMS=1000",
904+
host, port);
905+
906+
uri_str_auth = test_framework_add_user_password_from_env (uri_str);
907+
uri_str_auth_ssl = bson_strdup_printf ("%s&ssl=true", uri_str_auth);
908+
909+
ssl_opts = test_framework_get_ssl_opts ();
910+
911+
/* client uses SSL once SSL options are set, regardless of "ssl=true" */
912+
for (add_ssl_to_uri = 0; add_ssl_to_uri < 2; add_ssl_to_uri++) {
913+
914+
if (add_ssl_to_uri) {
915+
uri = mongoc_uri_new (uri_str_auth_ssl);
916+
} else {
917+
uri = mongoc_uri_new (uri_str_auth);
918+
}
919+
920+
if (pooled) {
921+
pool = mongoc_client_pool_new (uri);
922+
mongoc_client_pool_set_ssl_opts (pool, ssl_opts);
923+
client = mongoc_client_pool_pop (pool);
924+
} else {
925+
client = mongoc_client_new_from_uri (uri);
926+
mongoc_client_set_ssl_opts (client, ssl_opts);
927+
}
928+
929+
/* any operation */
930+
ret = mongoc_client_command_simple (client, "admin",
931+
tmp_bson ("{'ping': 1}"), NULL,
932+
NULL, &error);
933+
934+
if (test_framework_get_ssl ()) {
935+
ASSERT_OR_PRINT (ret, error);
936+
} else {
937+
/* TODO: CDRIVER-936 check the err msg has "SSL handshake failed" */
938+
ASSERT (!ret);
939+
ASSERT_CMPINT (MONGOC_ERROR_SERVER_SELECTION, ==, error.domain);
940+
}
941+
942+
if (pooled) {
943+
mongoc_client_pool_push (pool, client);
944+
mongoc_client_pool_destroy (pool);
945+
} else {
946+
mongoc_client_destroy (client);
947+
}
948+
949+
mongoc_uri_destroy (uri);
950+
}
951+
952+
bson_free (uri_str_auth_ssl);
953+
bson_free (uri_str_auth);
954+
bson_free (uri_str);
955+
bson_free (host);
956+
};
957+
958+
959+
static void
960+
test_ssl_single (void)
961+
{
962+
_test_mongoc_client_ssl_opts (false);
963+
}
964+
965+
966+
static void
967+
test_ssl_pooled (void)
968+
{
969+
_test_mongoc_client_ssl_opts (true);
970+
}
971+
#endif
972+
973+
883974
void
884975
test_client_install (TestSuite *suite)
885976
{
@@ -917,5 +1008,9 @@ test_client_install (TestSuite *suite)
9171008
#ifdef TODO_CDRIVER_689
9181009
TestSuite_Add (suite, "/Client/wire_version", test_wire_version);
9191010
#endif
920-
}
9211011

1012+
#ifdef MONGOC_ENABLE_SSL
1013+
TestSuite_Add (suite, "/Client/ssl_opts/single", test_ssl_single);
1014+
TestSuite_Add (suite, "/Client/ssl_opts/pooled", test_ssl_pooled);
1015+
#endif
1016+
}

0 commit comments

Comments
 (0)