1 | /* |
2 | Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file |
3 | |
4 | This file is part of libzmq, the ZeroMQ core engine in C++. |
5 | |
6 | libzmq is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU Lesser General Public License (LGPL) as published |
8 | by the Free Software Foundation; either version 3 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | As a special exception, the Contributors give you permission to link |
12 | this library with independent modules to produce an executable, |
13 | regardless of the license terms of these independent modules, and to |
14 | copy and distribute the resulting executable under terms of your choice, |
15 | provided that you also meet, for each linked independent module, the |
16 | terms and conditions of the license of that module. An independent |
17 | module is a module which is not derived from or based on this library. |
18 | If you modify this library, you must extend this exception to your |
19 | version of the library. |
20 | |
21 | libzmq is distributed in the hope that it will be useful, but WITHOUT |
22 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
23 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
24 | License for more details. |
25 | |
26 | You should have received a copy of the GNU Lesser General Public License |
27 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
28 | */ |
29 | |
30 | #include "testutil_security.hpp" |
31 | #include "testutil_unity.hpp" |
32 | |
33 | SETUP_TEARDOWN_TESTCONTEXT |
34 | |
35 | static void zap_handler_wrong_version (void * /*unused_*/) |
36 | { |
37 | zap_handler_generic (zap_wrong_version); |
38 | } |
39 | |
40 | static void zap_handler_wrong_request_id (void * /*unused_*/) |
41 | { |
42 | zap_handler_generic (zap_wrong_request_id); |
43 | } |
44 | |
45 | static void zap_handler_wrong_status_invalid (void * /*unused_*/) |
46 | { |
47 | zap_handler_generic (zap_status_invalid); |
48 | } |
49 | |
50 | static void zap_handler_wrong_status_temporary_failure (void * /*unused_*/) |
51 | { |
52 | zap_handler_generic (zap_status_temporary_failure); |
53 | } |
54 | |
55 | static void zap_handler_wrong_status_internal_error (void * /*unused_*/) |
56 | { |
57 | zap_handler_generic (zap_status_internal_error); |
58 | } |
59 | |
60 | static void zap_handler_too_many_parts (void * /*unused_*/) |
61 | { |
62 | zap_handler_generic (zap_too_many_parts); |
63 | } |
64 | |
65 | static void zap_handler_disconnect (void * /*unused_*/) |
66 | { |
67 | zap_handler_generic (zap_disconnect); |
68 | } |
69 | |
70 | static void zap_handler_do_not_recv (void * /*unused_*/) |
71 | { |
72 | zap_handler_generic (zap_do_not_recv); |
73 | } |
74 | |
75 | static void zap_handler_do_not_send (void * /*unused_*/) |
76 | { |
77 | zap_handler_generic (zap_do_not_send); |
78 | } |
79 | |
80 | int expect_new_client_bounce_fail_and_count_monitor_events ( |
81 | char *my_endpoint_, |
82 | void *server_, |
83 | socket_config_fn socket_config_, |
84 | void *socket_config_data_, |
85 | void **client_mon_, |
86 | void *server_mon_, |
87 | int expected_server_event_, |
88 | int expected_server_value_, |
89 | int expected_client_event_ = 0, |
90 | int expected_client_value_ = 0) |
91 | { |
92 | expect_new_client_bounce_fail ( |
93 | my_endpoint_, server_, socket_config_, socket_config_data_, client_mon_, |
94 | expected_client_event_, expected_client_value_); |
95 | |
96 | int events_received = 0; |
97 | events_received = expect_monitor_event_multiple ( |
98 | server_mon_, expected_server_event_, expected_server_value_); |
99 | |
100 | return events_received; |
101 | } |
102 | |
103 | void test_zap_unsuccessful (char *my_endpoint_, |
104 | void *server_, |
105 | void *server_mon_, |
106 | int expected_server_event_, |
107 | int expected_server_value_, |
108 | socket_config_fn socket_config_, |
109 | void *socket_config_data_, |
110 | void **client_mon_ = NULL, |
111 | int expected_client_event_ = 0, |
112 | int expected_client_value_ = 0) |
113 | { |
114 | int server_events_received = |
115 | expect_new_client_bounce_fail_and_count_monitor_events ( |
116 | my_endpoint_, server_, socket_config_, socket_config_data_, client_mon_, |
117 | server_mon_, expected_server_event_, expected_server_value_, |
118 | expected_client_event_, expected_client_value_); |
119 | |
120 | // there may be more than one ZAP request due to repeated attempts by the |
121 | // client (actually only in case if ZAP status code 300) |
122 | TEST_ASSERT_TRUE (server_events_received == 0 |
123 | || 1 <= zmq_atomic_counter_value (zap_requests_handled)); |
124 | } |
125 | |
126 | void test_zap_unsuccessful_no_handler (char *my_endpoint_, |
127 | void *server_, |
128 | void *server_mon_, |
129 | int expected_event_, |
130 | int expected_err_, |
131 | socket_config_fn socket_config_, |
132 | void *socket_config_data_, |
133 | void **client_mon_ = NULL) |
134 | { |
135 | const int events_received = |
136 | expect_new_client_bounce_fail_and_count_monitor_events ( |
137 | my_endpoint_, server_, socket_config_, socket_config_data_, client_mon_, |
138 | server_mon_, expected_event_, expected_err_); |
139 | |
140 | // there may be more than one ZAP request due to repeated attempts by the |
141 | // client |
142 | TEST_ASSERT_GREATER_THAN_INT (0, events_received); |
143 | } |
144 | |
145 | void test_zap_protocol_error (char *my_endpoint_, |
146 | void *server_, |
147 | void *server_mon_, |
148 | socket_config_fn socket_config_, |
149 | void *socket_config_data_, |
150 | int expected_error_) |
151 | { |
152 | test_zap_unsuccessful (my_endpoint_, server_, server_mon_, |
153 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, expected_error_, |
154 | socket_config_, socket_config_data_); |
155 | } |
156 | |
157 | void test_zap_unsuccessful_status_300 (char *my_endpoint_, |
158 | void *server_, |
159 | void *server_mon_, |
160 | socket_config_fn client_socket_config_, |
161 | void *client_socket_config_data_) |
162 | { |
163 | void *client_mon; |
164 | test_zap_unsuccessful ( |
165 | my_endpoint_, server_, server_mon_, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 300, |
166 | client_socket_config_, client_socket_config_data_, &client_mon); |
167 | |
168 | // we can use a 0 timeout here, since the client socket is already closed |
169 | assert_no_more_monitor_events_with_timeout (client_mon, 0); |
170 | |
171 | test_context_socket_close (client_mon); |
172 | } |
173 | |
174 | void test_zap_unsuccessful_status_500 (char *my_endpoint_, |
175 | void *server_, |
176 | void *server_mon_, |
177 | socket_config_fn client_socket_config_, |
178 | void *client_socket_config_data_) |
179 | { |
180 | test_zap_unsuccessful (my_endpoint_, server_, server_mon_, |
181 | ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 500, |
182 | client_socket_config_, client_socket_config_data_, |
183 | NULL, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 500); |
184 | } |
185 | |
186 | static void |
187 | test_zap_protocol_error_closure (socket_config_fn server_socket_config_, |
188 | socket_config_fn client_socket_config_, |
189 | void *client_socket_config_data_, |
190 | void *server_socket_config_data_, |
191 | zmq_thread_fn zap_handler_, |
192 | int expected_failure_) |
193 | { |
194 | void *handler, *zap_thread, *server, *server_mon; |
195 | char my_endpoint[MAX_SOCKET_STRING]; |
196 | |
197 | setup_context_and_server_side ( |
198 | &handler, &zap_thread, &server, &server_mon, my_endpoint, zap_handler_, |
199 | server_socket_config_, server_socket_config_data_); |
200 | test_zap_protocol_error (my_endpoint, server, server_mon, |
201 | client_socket_config_, client_socket_config_data_, |
202 | expected_failure_); |
203 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
204 | } |
205 | |
206 | static void |
207 | test_zap_protocol_error_wrong_version (socket_config_fn server_socket_config_, |
208 | socket_config_fn client_socket_config_, |
209 | void *client_socket_config_data_, |
210 | void *server_socket_config_data_) |
211 | { |
212 | test_zap_protocol_error_closure ( |
213 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
214 | server_socket_config_data_, &zap_handler_wrong_version, |
215 | ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION); |
216 | } |
217 | |
218 | static void test_zap_protocol_error_wrong_request_id ( |
219 | socket_config_fn server_socket_config_, |
220 | socket_config_fn client_socket_config_, |
221 | void *client_socket_config_data_, |
222 | void *server_socket_config_data_) |
223 | { |
224 | test_zap_protocol_error_closure ( |
225 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
226 | server_socket_config_data_, &zap_handler_wrong_request_id, |
227 | ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID); |
228 | } |
229 | |
230 | static void test_zap_protocol_error_wrong_status_invalid ( |
231 | socket_config_fn server_socket_config_, |
232 | socket_config_fn client_socket_config_, |
233 | void *client_socket_config_data_, |
234 | void *server_socket_config_data_) |
235 | { |
236 | test_zap_protocol_error_closure ( |
237 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
238 | server_socket_config_data_, &zap_handler_wrong_status_invalid, |
239 | ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE); |
240 | } |
241 | |
242 | static void |
243 | test_zap_protocol_error_too_many_parts (socket_config_fn server_socket_config_, |
244 | socket_config_fn client_socket_config_, |
245 | void *client_socket_config_data_, |
246 | void *server_socket_config_data_) |
247 | { |
248 | test_zap_protocol_error_closure ( |
249 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
250 | server_socket_config_data_, &zap_handler_too_many_parts, |
251 | ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY); |
252 | } |
253 | |
254 | // TODO the failed status (300/500) should be observable as monitoring events on the client side as well (they are |
255 | // already transmitted as an ERROR message) |
256 | |
257 | static void |
258 | test_zap_wrong_status_temporary_failure (socket_config_fn server_socket_config_, |
259 | socket_config_fn client_socket_config_, |
260 | void *client_socket_config_data_, |
261 | void *server_socket_config_data_) |
262 | { |
263 | void *handler, *zap_thread, *server, *server_mon; |
264 | char my_endpoint[MAX_SOCKET_STRING]; |
265 | setup_context_and_server_side ( |
266 | &handler, &zap_thread, &server, &server_mon, my_endpoint, |
267 | &zap_handler_wrong_status_temporary_failure, server_socket_config_, |
268 | server_socket_config_data_); |
269 | test_zap_unsuccessful_status_300 (my_endpoint, server, server_mon, |
270 | client_socket_config_, |
271 | client_socket_config_data_); |
272 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
273 | } |
274 | |
275 | static void |
276 | test_zap_wrong_status_internal_error (socket_config_fn server_socket_config_, |
277 | socket_config_fn client_socket_config_, |
278 | void *client_socket_config_data_) |
279 | { |
280 | void *handler, *zap_thread, *server, *server_mon; |
281 | char my_endpoint[MAX_SOCKET_STRING]; |
282 | setup_context_and_server_side ( |
283 | &handler, &zap_thread, &server, &server_mon, my_endpoint, |
284 | &zap_handler_wrong_status_internal_error, server_socket_config_); |
285 | test_zap_unsuccessful_status_500 (my_endpoint, server, server_mon, |
286 | client_socket_config_, |
287 | client_socket_config_data_); |
288 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
289 | } |
290 | |
291 | static void |
292 | test_zap_unsuccesful_no_handler_started (socket_config_fn server_socket_config_, |
293 | socket_config_fn client_socket_config_, |
294 | void *client_socket_config_data_, |
295 | void *server_socket_config_data_) |
296 | { |
297 | #ifdef ZMQ_ZAP_ENFORCE_DOMAIN |
298 | void *handler, *zap_thread, *server, *server_mon; |
299 | char my_endpoint[MAX_SOCKET_STRING]; |
300 | // TODO this looks wrong, where will the enforce value be used? |
301 | |
302 | // no ZAP handler |
303 | int enforce = 1; |
304 | setup_context_and_server_side ( |
305 | &handler, &zap_thread, &server, &server_mon, my_endpoint, NULL, |
306 | server_socket_config_, |
307 | server_socket_config_data_ ? server_socket_config_data_ : &enforce); |
308 | test_zap_unsuccessful_no_handler ( |
309 | my_endpoint, server, server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, |
310 | EFAULT, client_socket_config_, client_socket_config_data_); |
311 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
312 | #endif |
313 | } |
314 | |
315 | static void |
316 | test_zap_unsuccesful_no_handler_closure (socket_config_fn server_socket_config_, |
317 | socket_config_fn client_socket_config_, |
318 | void *client_socket_config_data_, |
319 | zmq_thread_fn zap_handler_func_, |
320 | bool zap_handler_disconnected_ = false) |
321 | { |
322 | void *handler, *zap_thread, *server, *server_mon; |
323 | char my_endpoint[MAX_SOCKET_STRING]; |
324 | setup_context_and_server_side (&handler, &zap_thread, &server, &server_mon, |
325 | my_endpoint, zap_handler_func_, |
326 | server_socket_config_); |
327 | test_zap_unsuccessful_no_handler ( |
328 | my_endpoint, server, server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, |
329 | EPIPE, client_socket_config_, client_socket_config_data_); |
330 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler, |
331 | zap_handler_disconnected_); |
332 | } |
333 | |
334 | static void |
335 | test_zap_unsuccesful_disconnect (socket_config_fn server_socket_config_, |
336 | socket_config_fn client_socket_config_, |
337 | void *client_socket_config_data_) |
338 | { |
339 | test_zap_unsuccesful_no_handler_closure ( |
340 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
341 | &zap_handler_disconnect, true); |
342 | } |
343 | |
344 | static void |
345 | test_zap_unsuccesful_do_not_recv (socket_config_fn server_socket_config_, |
346 | socket_config_fn client_socket_config_, |
347 | void *client_socket_config_data_) |
348 | { |
349 | test_zap_unsuccesful_no_handler_closure ( |
350 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
351 | &zap_handler_do_not_recv); |
352 | } |
353 | |
354 | static void |
355 | test_zap_unsuccesful_do_not_send (socket_config_fn server_socket_config_, |
356 | socket_config_fn client_socket_config_, |
357 | void *client_socket_config_data_) |
358 | { |
359 | test_zap_unsuccesful_no_handler_closure ( |
360 | server_socket_config_, client_socket_config_, client_socket_config_data_, |
361 | &zap_handler_do_not_send); |
362 | } |
363 | |
364 | #define DEFINE_ZAP_ERROR_TESTS( \ |
365 | name_, server_socket_config_, server_socket_config_data_, \ |
366 | client_socket_config_, client_socket_config_data_) \ |
367 | void test_zap_protocol_error_wrong_version_##name_ () \ |
368 | { \ |
369 | test_zap_protocol_error_wrong_version ( \ |
370 | server_socket_config_, client_socket_config_, \ |
371 | client_socket_config_data_, server_socket_config_data_); \ |
372 | } \ |
373 | void test_zap_protocol_error_wrong_request_id_##name_ () \ |
374 | { \ |
375 | test_zap_protocol_error_wrong_request_id ( \ |
376 | server_socket_config_, client_socket_config_, \ |
377 | client_socket_config_data_, server_socket_config_data_); \ |
378 | } \ |
379 | void test_zap_protocol_error_wrong_status_invalid_##name_ () \ |
380 | { \ |
381 | test_zap_protocol_error_wrong_status_invalid ( \ |
382 | server_socket_config_, client_socket_config_, \ |
383 | client_socket_config_data_, server_socket_config_data_); \ |
384 | } \ |
385 | void test_zap_protocol_error_too_many_parts_##name_ () \ |
386 | { \ |
387 | test_zap_protocol_error_too_many_parts ( \ |
388 | server_socket_config_, client_socket_config_, \ |
389 | client_socket_config_data_, server_socket_config_data_); \ |
390 | } \ |
391 | void test_zap_wrong_status_temporary_failure_##name_ () \ |
392 | { \ |
393 | test_zap_wrong_status_temporary_failure ( \ |
394 | server_socket_config_, client_socket_config_, \ |
395 | client_socket_config_data_, server_socket_config_data_); \ |
396 | } \ |
397 | void test_zap_wrong_status_internal_error_##name_ () \ |
398 | { \ |
399 | test_zap_wrong_status_internal_error (server_socket_config_, \ |
400 | client_socket_config_, \ |
401 | client_socket_config_data_); \ |
402 | } \ |
403 | void test_zap_unsuccessful_no_handler_started_##name_ () \ |
404 | { \ |
405 | test_zap_unsuccesful_no_handler_started ( \ |
406 | server_socket_config_, client_socket_config_, \ |
407 | client_socket_config_data_, server_socket_config_data_); \ |
408 | } \ |
409 | void test_zap_unsuccessful_disconnect_##name_ () \ |
410 | { \ |
411 | test_zap_unsuccesful_disconnect (server_socket_config_, \ |
412 | client_socket_config_, \ |
413 | client_socket_config_data_); \ |
414 | } \ |
415 | void test_zap_unsuccessful_do_not_recv_##name_ () \ |
416 | { \ |
417 | test_zap_unsuccesful_do_not_recv (server_socket_config_, \ |
418 | client_socket_config_, \ |
419 | client_socket_config_data_); \ |
420 | } \ |
421 | void test_zap_unsuccessful_do_not_send_##name_ () \ |
422 | { \ |
423 | test_zap_unsuccesful_do_not_send (server_socket_config_, \ |
424 | client_socket_config_, \ |
425 | client_socket_config_data_); \ |
426 | } |
427 | |
428 | DEFINE_ZAP_ERROR_TESTS ( |
429 | null, &socket_config_null_server, NULL, &socket_config_null_client, NULL) |
430 | |
431 | DEFINE_ZAP_ERROR_TESTS ( |
432 | plain, &socket_config_plain_server, NULL, &socket_config_plain_client, NULL) |
433 | |
434 | static curve_client_data_t curve_client_data = { |
435 | valid_server_public, valid_client_public, valid_client_secret}; |
436 | |
437 | DEFINE_ZAP_ERROR_TESTS (curve, |
438 | &socket_config_curve_server, |
439 | valid_server_secret, |
440 | &socket_config_curve_client, |
441 | &curve_client_data) |
442 | |
443 | #define RUN_ZAP_ERROR_TESTS(name_) \ |
444 | { \ |
445 | RUN_TEST (test_zap_protocol_error_wrong_version_##name_); \ |
446 | RUN_TEST (test_zap_protocol_error_wrong_request_id_##name_); \ |
447 | RUN_TEST (test_zap_protocol_error_wrong_status_invalid_##name_); \ |
448 | RUN_TEST (test_zap_protocol_error_too_many_parts_##name_); \ |
449 | RUN_TEST (test_zap_wrong_status_temporary_failure_##name_); \ |
450 | RUN_TEST (test_zap_wrong_status_internal_error_##name_); \ |
451 | RUN_TEST (test_zap_unsuccessful_no_handler_started_##name_); \ |
452 | RUN_TEST (test_zap_unsuccessful_disconnect_##name_); \ |
453 | RUN_TEST (test_zap_unsuccessful_do_not_recv_##name_); \ |
454 | RUN_TEST (test_zap_unsuccessful_do_not_send_##name_); \ |
455 | } |
456 | |
457 | int main () |
458 | { |
459 | setup_test_environment (); |
460 | |
461 | if (zmq_has ("curve" )) { |
462 | setup_testutil_security_curve (); |
463 | } |
464 | |
465 | UNITY_BEGIN (); |
466 | RUN_ZAP_ERROR_TESTS (null); |
467 | RUN_ZAP_ERROR_TESTS (plain); |
468 | if (zmq_has ("curve" )) { |
469 | RUN_ZAP_ERROR_TESTS (curve); |
470 | } |
471 | return UNITY_END (); |
472 | } |
473 | |