|
21 | 21 | #undef MONGOC_LOG_DOMAIN
|
22 | 22 | #define MONGOC_LOG_DOMAIN "client-test"
|
23 | 23 |
|
| 24 | +#define TRUST_DIR "tests/trust_dir" |
| 25 | +#define VERIFY_DIR TRUST_DIR "/verify" |
| 26 | +#define CAFILE TRUST_DIR "/verify/mongo_root.pem" |
| 27 | +#define PEMFILE_LOCALHOST TRUST_DIR "/keys/127.0.0.1.pem" |
| 28 | +#define PEMFILE_NOPASS TRUST_DIR "/keys/mongodb.com.pem" |
| 29 | + |
| 30 | + |
24 | 31 | static char *
|
25 | 32 | gen_test_user (void)
|
26 | 33 | {
|
@@ -971,6 +978,126 @@ test_ssl_pooled (void)
|
971 | 978 | #endif
|
972 | 979 |
|
973 | 980 |
|
| 981 | + |
| 982 | +#ifdef MONGOC_ENABLE_SSL |
| 983 | +static bool |
| 984 | +_cmd (mock_server_t *server, |
| 985 | + mongoc_client_t *client, |
| 986 | + bool server_replies, |
| 987 | + bson_error_t *error) |
| 988 | +{ |
| 989 | + future_t *future; |
| 990 | + request_t *request; |
| 991 | + bool r; |
| 992 | + |
| 993 | + future = future_client_command_simple (client, "db", tmp_bson ("{'cmd': 1}"), |
| 994 | + NULL, NULL, error); |
| 995 | + request = mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, |
| 996 | + "{'cmd': 1}"); |
| 997 | + ASSERT (request); |
| 998 | + |
| 999 | + if (server_replies) { |
| 1000 | + mock_server_replies_simple (request, "{'ok': 1}"); |
| 1001 | + } else { |
| 1002 | + mock_server_hangs_up (request); |
| 1003 | + } |
| 1004 | + |
| 1005 | + r = future_get_bool (future); |
| 1006 | + |
| 1007 | + future_destroy (future); |
| 1008 | + request_destroy (request); |
| 1009 | + |
| 1010 | + return r; |
| 1011 | +} |
| 1012 | + |
| 1013 | + |
| 1014 | + |
| 1015 | +static void |
| 1016 | +_test_ssl_reconnect (bool pooled) |
| 1017 | +{ |
| 1018 | + mongoc_uri_t *uri; |
| 1019 | + mock_server_t *server; |
| 1020 | + mongoc_ssl_opt_t client_opts = { 0 }; |
| 1021 | + mongoc_ssl_opt_t server_opts = { 0 }; |
| 1022 | + mongoc_client_pool_t *pool = NULL; |
| 1023 | + mongoc_client_t *client; |
| 1024 | + bson_error_t error; |
| 1025 | + future_t *future; |
| 1026 | + |
| 1027 | + client_opts.ca_file = CAFILE; |
| 1028 | + |
| 1029 | + server_opts.ca_file = CAFILE; |
| 1030 | + server_opts.pem_file = PEMFILE_LOCALHOST; |
| 1031 | + |
| 1032 | + server = mock_server_with_autoismaster (0); |
| 1033 | + mock_server_set_ssl_opts (server, &server_opts); |
| 1034 | + mock_server_run (server); |
| 1035 | + |
| 1036 | + uri = mongoc_uri_copy (mock_server_get_uri (server)); |
| 1037 | + mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 100); |
| 1038 | + |
| 1039 | + if (pooled) { |
| 1040 | + pool = mongoc_client_pool_new (uri); |
| 1041 | + mongoc_client_pool_set_ssl_opts (pool, &client_opts); |
| 1042 | + client = mongoc_client_pool_pop (pool); |
| 1043 | + } else { |
| 1044 | + client = mongoc_client_new_from_uri (uri); |
| 1045 | + mongoc_client_set_ssl_opts (client, &client_opts); |
| 1046 | + } |
| 1047 | + |
| 1048 | + ASSERT_OR_PRINT (_cmd (server, client, true /* server replies */, &error), |
| 1049 | + error); |
| 1050 | + |
| 1051 | + /* man-in-the-middle: hostname switches from 127.0.0.1 to mongodb.com */ |
| 1052 | + server_opts.pem_file = PEMFILE_NOPASS; |
| 1053 | + mock_server_set_ssl_opts (server, &server_opts); |
| 1054 | + |
| 1055 | + /* server closes connections */ |
| 1056 | + if (pooled) { |
| 1057 | + /* bg thread warns "failed to buffer", "handshake failed" */ |
| 1058 | + suppress_one_message (); |
| 1059 | + suppress_one_message (); |
| 1060 | + } |
| 1061 | + |
| 1062 | + ASSERT (!_cmd (server, client, false /* server hangs up */, &error)); |
| 1063 | + |
| 1064 | + /* next operation comes on a new connection, server verification fails */ |
| 1065 | + future = future_client_command_simple (client, "db", tmp_bson ("{'cmd': 1}"), |
| 1066 | + NULL, NULL, &error); |
| 1067 | + ASSERT (!future_get_bool (future)); |
| 1068 | + |
| 1069 | + /* server selection errors don't say *why* they failed in C Driver 1.2 */ |
| 1070 | + ASSERT_CMPINT (error.domain, ==, MONGOC_ERROR_SERVER_SELECTION); |
| 1071 | + ASSERT_CMPINT (error.code, ==, MONGOC_ERROR_SERVER_SELECTION_FAILURE); |
| 1072 | + |
| 1073 | + if (pooled) { |
| 1074 | + mongoc_client_pool_push (pool, client); |
| 1075 | + mongoc_client_pool_destroy (pool); |
| 1076 | + } else { |
| 1077 | + mongoc_client_destroy (client); |
| 1078 | + } |
| 1079 | + |
| 1080 | + future_destroy (future); |
| 1081 | + mock_server_destroy (server); |
| 1082 | + mongoc_uri_destroy (uri); |
| 1083 | +} |
| 1084 | + |
| 1085 | + |
| 1086 | +static void |
| 1087 | +test_ssl_reconnect_single (void) |
| 1088 | +{ |
| 1089 | + _test_ssl_reconnect (false); |
| 1090 | +} |
| 1091 | + |
| 1092 | + |
| 1093 | +static void |
| 1094 | +test_ssl_reconnect_pooled (void) |
| 1095 | +{ |
| 1096 | + _test_ssl_reconnect (true); |
| 1097 | +} |
| 1098 | +#endif |
| 1099 | + |
| 1100 | + |
974 | 1101 | void
|
975 | 1102 | test_client_install (TestSuite *suite)
|
976 | 1103 | {
|
@@ -1012,5 +1139,11 @@ test_client_install (TestSuite *suite)
|
1012 | 1139 | #ifdef MONGOC_ENABLE_SSL
|
1013 | 1140 | TestSuite_Add (suite, "/Client/ssl_opts/single", test_ssl_single);
|
1014 | 1141 | TestSuite_Add (suite, "/Client/ssl_opts/pooled", test_ssl_pooled);
|
| 1142 | + TestSuite_Add (suite, "/Client/ssl/reconnect/single", |
| 1143 | + test_ssl_reconnect_single); |
| 1144 | + TestSuite_Add (suite, "/Client/ssl/reconnect/pooled", |
| 1145 | + test_ssl_reconnect_pooled); |
| 1146 | +#else |
| 1147 | + TestSuite_Add (suite, "/Client/ssl_disabled", test_mongoc_client_ssl_disabled); |
1015 | 1148 | #endif
|
1016 | 1149 | }
|
0 commit comments