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
33SETUP_TEARDOWN_TESTCONTEXT
34
35static void zap_handler_wrong_version (void * /*unused_*/)
36{
37 zap_handler_generic (zap_wrong_version);
38}
39
40static void zap_handler_wrong_request_id (void * /*unused_*/)
41{
42 zap_handler_generic (zap_wrong_request_id);
43}
44
45static void zap_handler_wrong_status_invalid (void * /*unused_*/)
46{
47 zap_handler_generic (zap_status_invalid);
48}
49
50static void zap_handler_wrong_status_temporary_failure (void * /*unused_*/)
51{
52 zap_handler_generic (zap_status_temporary_failure);
53}
54
55static void zap_handler_wrong_status_internal_error (void * /*unused_*/)
56{
57 zap_handler_generic (zap_status_internal_error);
58}
59
60static void zap_handler_too_many_parts (void * /*unused_*/)
61{
62 zap_handler_generic (zap_too_many_parts);
63}
64
65static void zap_handler_disconnect (void * /*unused_*/)
66{
67 zap_handler_generic (zap_disconnect);
68}
69
70static void zap_handler_do_not_recv (void * /*unused_*/)
71{
72 zap_handler_generic (zap_do_not_recv);
73}
74
75static void zap_handler_do_not_send (void * /*unused_*/)
76{
77 zap_handler_generic (zap_do_not_send);
78}
79
80int 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
103void 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
126void 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
145void 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
157void 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
174void 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
186static void
187test_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
206static void
207test_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
218static 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
230static 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
242static void
243test_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
257static void
258test_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
275static void
276test_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
291static void
292test_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
315static void
316test_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
334static void
335test_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
344static void
345test_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
354static void
355test_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
428DEFINE_ZAP_ERROR_TESTS (
429 null, &socket_config_null_server, NULL, &socket_config_null_client, NULL)
430
431DEFINE_ZAP_ERROR_TESTS (
432 plain, &socket_config_plain_server, NULL, &socket_config_plain_client, NULL)
433
434static curve_client_data_t curve_client_data = {
435 valid_server_public, valid_client_public, valid_client_secret};
436
437DEFINE_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
457int 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