|
18 | 18 | #undef MONGOC_LOG_DOMAIN
|
19 | 19 | #define MONGOC_LOG_DOMAIN "client-test"
|
20 | 20 |
|
| 21 | +#define TRUST_DIR "tests/trust_dir" |
| 22 | +#define VERIFY_DIR TRUST_DIR "/verify" |
| 23 | +#define CAFILE TRUST_DIR "/verify/mongo_root.pem" |
| 24 | +#define PEMFILE_LOCALHOST TRUST_DIR "/keys/127.0.0.1.pem" |
| 25 | +#define PEMFILE_NOPASS TRUST_DIR "/keys/mongodb.com.pem" |
| 26 | + |
| 27 | + |
21 | 28 | static char *
|
22 | 29 | gen_test_user (void)
|
23 | 30 | {
|
@@ -1105,6 +1112,126 @@ test_mongoc_client_ssl_disabled (void)
|
1105 | 1112 | #endif
|
1106 | 1113 |
|
1107 | 1114 |
|
| 1115 | + |
| 1116 | +#ifdef MONGOC_ENABLE_SSL |
| 1117 | +static bool |
| 1118 | +_cmd (mock_server_t *server, |
| 1119 | + mongoc_client_t *client, |
| 1120 | + bool server_replies, |
| 1121 | + bson_error_t *error) |
| 1122 | +{ |
| 1123 | + future_t *future; |
| 1124 | + request_t *request; |
| 1125 | + bool r; |
| 1126 | + |
| 1127 | + future = future_client_command_simple (client, "db", tmp_bson ("{'cmd': 1}"), |
| 1128 | + NULL, NULL, error); |
| 1129 | + request = mock_server_receives_command (server, "db", MONGOC_QUERY_SLAVE_OK, |
| 1130 | + NULL); |
| 1131 | + ASSERT (request); |
| 1132 | + |
| 1133 | + if (server_replies) { |
| 1134 | + mock_server_replies_simple (request, "{'ok': 1}"); |
| 1135 | + } else { |
| 1136 | + mock_server_hangs_up (request); |
| 1137 | + } |
| 1138 | + |
| 1139 | + r = future_get_bool (future); |
| 1140 | + |
| 1141 | + future_destroy (future); |
| 1142 | + request_destroy (request); |
| 1143 | + |
| 1144 | + return r; |
| 1145 | +} |
| 1146 | + |
| 1147 | + |
| 1148 | + |
| 1149 | +static void |
| 1150 | +_test_ssl_reconnect (bool pooled) |
| 1151 | +{ |
| 1152 | + mongoc_uri_t *uri; |
| 1153 | + mock_server_t *server; |
| 1154 | + mongoc_ssl_opt_t client_opts = { 0 }; |
| 1155 | + mongoc_ssl_opt_t server_opts = { 0 }; |
| 1156 | + mongoc_client_pool_t *pool = NULL; |
| 1157 | + mongoc_client_t *client; |
| 1158 | + bson_error_t error; |
| 1159 | + future_t *future; |
| 1160 | + |
| 1161 | + client_opts.ca_file = CAFILE; |
| 1162 | + |
| 1163 | + server_opts.ca_file = CAFILE; |
| 1164 | + server_opts.pem_file = PEMFILE_LOCALHOST; |
| 1165 | + |
| 1166 | + server = mock_server_with_autoismaster (0); |
| 1167 | + mock_server_set_ssl_opts (server, &server_opts); |
| 1168 | + mock_server_run (server); |
| 1169 | + |
| 1170 | + uri = mongoc_uri_copy (mock_server_get_uri (server)); |
| 1171 | + mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 100); |
| 1172 | + |
| 1173 | + if (pooled) { |
| 1174 | + pool = mongoc_client_pool_new (uri); |
| 1175 | + mongoc_client_pool_set_ssl_opts (pool, &client_opts); |
| 1176 | + client = mongoc_client_pool_pop (pool); |
| 1177 | + } else { |
| 1178 | + client = mongoc_client_new_from_uri (uri); |
| 1179 | + mongoc_client_set_ssl_opts (client, &client_opts); |
| 1180 | + } |
| 1181 | + |
| 1182 | + ASSERT_OR_PRINT (_cmd (server, client, true /* server replies */, &error), |
| 1183 | + error); |
| 1184 | + |
| 1185 | + /* man-in-the-middle: hostname switches from 127.0.0.1 to mongodb.com */ |
| 1186 | + server_opts.pem_file = PEMFILE_NOPASS; |
| 1187 | + mock_server_set_ssl_opts (server, &server_opts); |
| 1188 | + |
| 1189 | + /* server closes connections */ |
| 1190 | + if (pooled) { |
| 1191 | + /* bg thread warns "failed to buffer", "handshake failed" */ |
| 1192 | + suppress_one_message (); |
| 1193 | + suppress_one_message (); |
| 1194 | + } |
| 1195 | + |
| 1196 | + ASSERT (!_cmd (server, client, false /* server hangs up */, &error)); |
| 1197 | + |
| 1198 | + /* next operation comes on a new connection, server verification fails */ |
| 1199 | + future = future_client_command_simple (client, "db", tmp_bson ("{'cmd': 1}"), |
| 1200 | + NULL, NULL, &error); |
| 1201 | + ASSERT (!future_get_bool (future)); |
| 1202 | + ASSERT_ERROR_CONTAINS (error, |
| 1203 | + MONGOC_ERROR_STREAM, |
| 1204 | + MONGOC_ERROR_STREAM_SOCKET, |
| 1205 | + "Failed to verify peer certificate"); |
| 1206 | + |
| 1207 | + if (pooled) { |
| 1208 | + mongoc_client_pool_push (pool, client); |
| 1209 | + mongoc_client_pool_destroy (pool); |
| 1210 | + } else { |
| 1211 | + mongoc_client_destroy (client); |
| 1212 | + } |
| 1213 | + |
| 1214 | + future_destroy (future); |
| 1215 | + mock_server_destroy (server); |
| 1216 | + mongoc_uri_destroy (uri); |
| 1217 | +} |
| 1218 | + |
| 1219 | + |
| 1220 | +static void |
| 1221 | +test_ssl_reconnect_single (void) |
| 1222 | +{ |
| 1223 | + _test_ssl_reconnect (false); |
| 1224 | +} |
| 1225 | + |
| 1226 | + |
| 1227 | +static void |
| 1228 | +test_ssl_reconnect_pooled (void) |
| 1229 | +{ |
| 1230 | + _test_ssl_reconnect (true); |
| 1231 | +} |
| 1232 | +#endif |
| 1233 | + |
| 1234 | + |
1108 | 1235 | void
|
1109 | 1236 | test_client_install (TestSuite *suite)
|
1110 | 1237 | {
|
@@ -1149,6 +1276,10 @@ test_client_install (TestSuite *suite)
|
1149 | 1276 | #ifdef MONGOC_ENABLE_SSL
|
1150 | 1277 | TestSuite_Add (suite, "/Client/ssl_opts/single", test_ssl_single);
|
1151 | 1278 | TestSuite_Add (suite, "/Client/ssl_opts/pooled", test_ssl_pooled);
|
| 1279 | + TestSuite_Add (suite, "/Client/ssl/reconnect/single", |
| 1280 | + test_ssl_reconnect_single); |
| 1281 | + TestSuite_Add (suite, "/Client/ssl/reconnect/pooled", |
| 1282 | + test_ssl_reconnect_pooled); |
1152 | 1283 | #else
|
1153 | 1284 | TestSuite_Add (suite, "/Client/ssl_disabled", test_mongoc_client_ssl_disabled);
|
1154 | 1285 | #endif
|
|
0 commit comments