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 | // TODO remove this workaround for handling libsodium/tweetnacl |
31 | |
32 | // To define SIZE_MAX with older compilers |
33 | #define __STDC_LIMIT_MACROS |
34 | |
35 | #if defined ZMQ_CUSTOM_PLATFORM_HPP |
36 | #include "platform.hpp" |
37 | #else |
38 | #include "../src/platform.hpp" |
39 | #endif |
40 | |
41 | #ifndef ZMQ_USE_TWEETNACL |
42 | #define ZMQ_USE_TWEETNACL |
43 | #endif |
44 | #ifdef ZMQ_USE_LIBSODIUM |
45 | #undef ZMQ_USE_LIBSODIUM |
46 | #endif |
47 | |
48 | #include "testutil.hpp" |
49 | #include "testutil_security.hpp" |
50 | #if defined(ZMQ_HAVE_WINDOWS) |
51 | #include <winsock2.h> |
52 | #include <ws2tcpip.h> |
53 | #include <stdexcept> |
54 | #define close closesocket |
55 | #else |
56 | #include <sys/socket.h> |
57 | #include <netinet/in.h> |
58 | #include <arpa/inet.h> |
59 | #include <unistd.h> |
60 | #endif |
61 | #include <unity.h> |
62 | |
63 | #include "../src/tweetnacl.h" |
64 | #include "../src/curve_client_tools.hpp" |
65 | #include "../src/random.hpp" |
66 | |
67 | char error_message_buffer[256]; |
68 | |
69 | void *handler; |
70 | void *zap_thread; |
71 | void *server; |
72 | void *server_mon; |
73 | char my_endpoint[MAX_SOCKET_STRING]; |
74 | |
75 | void setUp () |
76 | { |
77 | setup_test_context (); |
78 | setup_context_and_server_side (&handler, &zap_thread, &server, &server_mon, |
79 | my_endpoint); |
80 | } |
81 | |
82 | void tearDown () |
83 | { |
84 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
85 | teardown_test_context (); |
86 | } |
87 | |
88 | const int timeout = 250; |
89 | |
90 | const char large_routing_id[] = "0123456789012345678901234567890123456789" |
91 | "0123456789012345678901234567890123456789" |
92 | "0123456789012345678901234567890123456789" |
93 | "0123456789012345678901234567890123456789" |
94 | "0123456789012345678901234567890123456789" |
95 | "0123456789012345678901234567890123456789" |
96 | "012345678901234" ; |
97 | |
98 | static void zap_handler_large_routing_id (void * /*unused_*/) |
99 | { |
100 | zap_handler_generic (zap_ok, large_routing_id); |
101 | } |
102 | |
103 | void expect_new_client_curve_bounce_fail (const char *server_public_, |
104 | const char *client_public_, |
105 | const char *client_secret_, |
106 | char *my_endpoint_, |
107 | void *server_, |
108 | void **client_mon_ = NULL, |
109 | int expected_client_event_ = 0, |
110 | int expected_client_value_ = 0) |
111 | { |
112 | curve_client_data_t curve_client_data = {server_public_, client_public_, |
113 | client_secret_}; |
114 | expect_new_client_bounce_fail ( |
115 | my_endpoint_, server_, socket_config_curve_client, &curve_client_data, |
116 | client_mon_, expected_client_event_, expected_client_value_); |
117 | } |
118 | |
119 | void test_null_key (void *server_, |
120 | void *server_mon_, |
121 | char *my_endpoint_, |
122 | char *server_public_, |
123 | char *client_public_, |
124 | char *client_secret_) |
125 | { |
126 | expect_new_client_curve_bounce_fail (server_public_, client_public_, |
127 | client_secret_, my_endpoint_, server_); |
128 | |
129 | int handshake_failed_encryption_event_count = |
130 | expect_monitor_event_multiple (server_mon_, |
131 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
132 | ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC); |
133 | |
134 | // handshake_failed_encryption_event_count should be at least two because |
135 | // expect_bounce_fail involves two exchanges |
136 | // however, with valgrind we see only one event (maybe the next one takes |
137 | // very long, or does not happen at all because something else takes very |
138 | // long) |
139 | |
140 | fprintf (stderr, |
141 | "count of " |
142 | "ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL/" |
143 | "ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC events: %i\n" , |
144 | handshake_failed_encryption_event_count); |
145 | } |
146 | |
147 | void test_curve_security_with_valid_credentials () |
148 | { |
149 | curve_client_data_t curve_client_data = { |
150 | valid_server_public, valid_client_public, valid_client_secret}; |
151 | void *client_mon; |
152 | void *client = create_and_connect_client ( |
153 | my_endpoint, socket_config_curve_client, &curve_client_data, &client_mon); |
154 | bounce (server, client); |
155 | test_context_socket_close (client); |
156 | |
157 | int event = get_monitor_event_with_timeout (server_mon, NULL, NULL, -1); |
158 | assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED); |
159 | |
160 | assert_no_more_monitor_events_with_timeout (server_mon, timeout); |
161 | |
162 | event = get_monitor_event_with_timeout (client_mon, NULL, NULL, -1); |
163 | assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED); |
164 | |
165 | assert_no_more_monitor_events_with_timeout (client_mon, timeout); |
166 | |
167 | test_context_socket_close (client_mon); |
168 | } |
169 | |
170 | void test_curve_security_with_bogus_client_credentials () |
171 | { |
172 | // This must be caught by the ZAP handler |
173 | char bogus_public[41]; |
174 | char bogus_secret[41]; |
175 | zmq_curve_keypair (bogus_public, bogus_secret); |
176 | |
177 | expect_new_client_curve_bounce_fail ( |
178 | valid_server_public, bogus_public, bogus_secret, my_endpoint, server, |
179 | NULL, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400); |
180 | |
181 | int server_event_count = 0; |
182 | server_event_count = expect_monitor_event_multiple ( |
183 | server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400); |
184 | TEST_ASSERT_LESS_OR_EQUAL_INT (1, server_event_count); |
185 | |
186 | // there may be more than one ZAP request due to repeated attempts by the client |
187 | TEST_ASSERT (0 == server_event_count |
188 | || 1 <= zmq_atomic_counter_value (zap_requests_handled)); |
189 | } |
190 | |
191 | void expect_zmtp_mechanism_mismatch (void *client_, |
192 | char *my_endpoint_, |
193 | void *server_, |
194 | void *server_mon_) |
195 | { |
196 | // This must be caught by the curve_server class, not passed to ZAP |
197 | TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client_, my_endpoint_)); |
198 | expect_bounce_fail (server_, client_); |
199 | test_context_socket_close_zero_linger (client_); |
200 | |
201 | expect_monitor_event_multiple (server_mon_, |
202 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
203 | ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH); |
204 | |
205 | TEST_ASSERT_EQUAL_INT (0, zmq_atomic_counter_value (zap_requests_handled)); |
206 | } |
207 | |
208 | void test_curve_security_with_null_client_credentials () |
209 | { |
210 | void *client = test_context_socket (ZMQ_DEALER); |
211 | |
212 | expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon); |
213 | } |
214 | |
215 | void test_curve_security_with_plain_client_credentials () |
216 | { |
217 | void *client = test_context_socket (ZMQ_DEALER); |
218 | TEST_ASSERT_SUCCESS_ERRNO ( |
219 | zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin" , 5)); |
220 | TEST_ASSERT_SUCCESS_ERRNO ( |
221 | zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password" , 8)); |
222 | |
223 | expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon); |
224 | } |
225 | |
226 | fd_t connect_vanilla_socket (char *my_endpoint_) |
227 | { |
228 | fd_t s; |
229 | struct sockaddr_in ip4addr; |
230 | |
231 | unsigned short int port; |
232 | int rc = sscanf (my_endpoint_, "tcp://127.0.0.1:%hu" , &port); |
233 | TEST_ASSERT_EQUAL_INT (1, rc); |
234 | |
235 | ip4addr.sin_family = AF_INET; |
236 | ip4addr.sin_port = htons (port); |
237 | #if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600) |
238 | ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1" ); |
239 | #else |
240 | inet_pton (AF_INET, "127.0.0.1" , &ip4addr.sin_addr); |
241 | #endif |
242 | |
243 | s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); |
244 | rc = connect (s, reinterpret_cast<struct sockaddr *> (&ip4addr), |
245 | sizeof (ip4addr)); |
246 | TEST_ASSERT_GREATER_THAN_INT (-1, rc); |
247 | return s; |
248 | } |
249 | |
250 | void test_curve_security_unauthenticated_message () |
251 | { |
252 | // Unauthenticated messages from a vanilla socket shouldn't be received |
253 | fd_t s = connect_vanilla_socket (my_endpoint); |
254 | // send anonymous ZMTP/1.0 greeting |
255 | send (s, "\x01\x00" , 2, 0); |
256 | // send sneaky message that shouldn't be received |
257 | send (s, "\x08\x00sneaky\0" , 9, 0); |
258 | |
259 | zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); |
260 | char *buf = s_recv (server); |
261 | TEST_ASSERT_NULL_MESSAGE (buf, "Received unauthenticated message" ); |
262 | close (s); |
263 | } |
264 | |
265 | void send_all (fd_t fd_, const char *data_, socket_size_t size_) |
266 | { |
267 | while (size_ > 0) { |
268 | int res = send (fd_, data_, size_, 0); |
269 | TEST_ASSERT_GREATER_THAN_INT (0, res); |
270 | size_ -= res; |
271 | data_ += res; |
272 | } |
273 | } |
274 | |
275 | template <size_t N> void send (fd_t fd_, const char (&data_)[N]) |
276 | { |
277 | send_all (fd_, data_, N - 1); |
278 | } |
279 | |
280 | void send_greeting (fd_t s_) |
281 | { |
282 | send (s_, "\xff\0\0\0\0\0\0\0\0\x7f" ); // signature |
283 | send (s_, "\x03\x00" ); // version 3.0 |
284 | send (s_, "CURVE\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ); // mechanism CURVE |
285 | send (s_, "\0" ); // as-server == false |
286 | send (s_, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ); |
287 | } |
288 | |
289 | void test_curve_security_invalid_hello_wrong_length () |
290 | { |
291 | fd_t s = connect_vanilla_socket (my_endpoint); |
292 | |
293 | // send GREETING |
294 | send_greeting (s); |
295 | |
296 | // send CURVE HELLO of wrong size |
297 | send (s, "\x04\x06\x05HELLO" ); |
298 | |
299 | expect_monitor_event_multiple ( |
300 | server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
301 | ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); |
302 | |
303 | close (s); |
304 | } |
305 | |
306 | const size_t hello_length = 200; |
307 | const size_t welcome_length = 168; |
308 | |
309 | zmq::curve_client_tools_t make_curve_client_tools () |
310 | { |
311 | uint8_t valid_client_secret_decoded[32]; |
312 | uint8_t valid_client_public_decoded[32]; |
313 | |
314 | zmq_z85_decode (valid_client_public_decoded, valid_client_public); |
315 | zmq_z85_decode (valid_client_secret_decoded, valid_client_secret); |
316 | |
317 | uint8_t valid_server_public_decoded[32]; |
318 | zmq_z85_decode (valid_server_public_decoded, valid_server_public); |
319 | |
320 | return zmq::curve_client_tools_t (valid_client_public_decoded, |
321 | valid_client_secret_decoded, |
322 | valid_server_public_decoded); |
323 | } |
324 | |
325 | // same as htonll, which is only available on few platforms (recent Windows, but not on Linux, e.g.( |
326 | static uint64_t host_to_network (uint64_t value_) |
327 | { |
328 | // The answer is 42 |
329 | static const int num = 42; |
330 | |
331 | // Check the endianness |
332 | if (*reinterpret_cast<const char *> (&num) == num) { |
333 | const uint32_t high_part = htonl (static_cast<uint32_t> (value_ >> 32)); |
334 | const uint32_t low_part = |
335 | htonl (static_cast<uint32_t> (value_ & 0xFFFFFFFFLL)); |
336 | |
337 | return (static_cast<uint64_t> (low_part) << 32) | high_part; |
338 | } |
339 | return value_; |
340 | } |
341 | |
342 | template <size_t N> void send_command (fd_t s_, char (&command_)[N]) |
343 | { |
344 | if (N < 256) { |
345 | send (s_, "\x04" ); |
346 | char len = (char) N; |
347 | send_all (s_, &len, 1); |
348 | } else { |
349 | send (s_, "\x06" ); |
350 | uint64_t len = host_to_network (N); |
351 | send_all (s_, reinterpret_cast<char *> (&len), 8); |
352 | } |
353 | send_all (s_, command_, N); |
354 | } |
355 | |
356 | void test_curve_security_invalid_hello_command_name () |
357 | { |
358 | fd_t s = connect_vanilla_socket (my_endpoint); |
359 | |
360 | send_greeting (s); |
361 | |
362 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
363 | |
364 | // send CURVE HELLO with a misspelled command name (but otherwise correct) |
365 | char hello[hello_length]; |
366 | TEST_ASSERT_SUCCESS_ERRNO (tools.produce_hello (hello, 0)); |
367 | hello[5] = 'X'; |
368 | |
369 | send_command (s, hello); |
370 | |
371 | expect_monitor_event_multiple (server_mon, |
372 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
373 | ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); |
374 | |
375 | close (s); |
376 | } |
377 | |
378 | void test_curve_security_invalid_hello_version () |
379 | { |
380 | fd_t s = connect_vanilla_socket (my_endpoint); |
381 | |
382 | send_greeting (s); |
383 | |
384 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
385 | |
386 | // send CURVE HELLO with a wrong version number (but otherwise correct) |
387 | char hello[hello_length]; |
388 | TEST_ASSERT_SUCCESS_ERRNO (tools.produce_hello (hello, 0)); |
389 | hello[6] = 2; |
390 | |
391 | send_command (s, hello); |
392 | |
393 | expect_monitor_event_multiple ( |
394 | server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
395 | ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); |
396 | |
397 | close (s); |
398 | } |
399 | |
400 | void flush_read (fd_t fd_) |
401 | { |
402 | int res; |
403 | char buf[256]; |
404 | |
405 | while ((res = recv (fd_, buf, 256, 0)) == 256) { |
406 | } |
407 | TEST_ASSERT_NOT_EQUAL (-1, res); |
408 | } |
409 | |
410 | void recv_all (fd_t fd_, uint8_t *data_, socket_size_t len_) |
411 | { |
412 | socket_size_t received = 0; |
413 | while (received < len_) { |
414 | int res = recv (fd_, reinterpret_cast<char *> (data_), len_, 0); |
415 | TEST_ASSERT_GREATER_THAN_INT (0, res); |
416 | |
417 | data_ += res; |
418 | received += res; |
419 | } |
420 | } |
421 | |
422 | void recv_greeting (fd_t fd_) |
423 | { |
424 | uint8_t greeting[64]; |
425 | recv_all (fd_, greeting, 64); |
426 | // TODO assert anything about the greeting received from the server? |
427 | } |
428 | |
429 | fd_t connect_exchange_greeting_and_send_hello ( |
430 | char *my_endpoint_, zmq::curve_client_tools_t &tools_) |
431 | { |
432 | fd_t s = connect_vanilla_socket (my_endpoint_); |
433 | |
434 | send_greeting (s); |
435 | recv_greeting (s); |
436 | |
437 | // send valid CURVE HELLO |
438 | char hello[hello_length]; |
439 | TEST_ASSERT_SUCCESS_ERRNO (tools_.produce_hello (hello, 0)); |
440 | |
441 | send_command (s, hello); |
442 | return s; |
443 | } |
444 | |
445 | void test_curve_security_invalid_initiate_wrong_length () |
446 | { |
447 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
448 | |
449 | fd_t s = connect_exchange_greeting_and_send_hello (my_endpoint, tools); |
450 | |
451 | // receive but ignore WELCOME |
452 | flush_read (s); |
453 | |
454 | int res = get_monitor_event_with_timeout (server_mon, NULL, NULL, timeout); |
455 | TEST_ASSERT_EQUAL_INT (-1, res); |
456 | |
457 | send (s, "\x04\x09\x08INITIATE" ); |
458 | |
459 | expect_monitor_event_multiple ( |
460 | server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
461 | ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE); |
462 | |
463 | close (s); |
464 | } |
465 | |
466 | fd_t connect_exchange_greeting_and_hello_welcome ( |
467 | char *my_endpoint_, |
468 | void *server_mon_, |
469 | int timeout_, |
470 | zmq::curve_client_tools_t &tools_) |
471 | { |
472 | fd_t s = connect_exchange_greeting_and_send_hello (my_endpoint_, tools_); |
473 | |
474 | // receive but ignore WELCOME |
475 | uint8_t welcome[welcome_length + 2]; |
476 | recv_all (s, welcome, welcome_length + 2); |
477 | |
478 | uint8_t cn_precom[crypto_box_BEFORENMBYTES]; |
479 | TEST_ASSERT_SUCCESS_ERRNO ( |
480 | tools_.process_welcome (welcome + 2, welcome_length, cn_precom)); |
481 | |
482 | const int res = |
483 | get_monitor_event_with_timeout (server_mon_, NULL, NULL, timeout_); |
484 | TEST_ASSERT_EQUAL_INT (-1, res); |
485 | |
486 | return s; |
487 | } |
488 | |
489 | void test_curve_security_invalid_initiate_command_name () |
490 | { |
491 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
492 | fd_t s = connect_exchange_greeting_and_hello_welcome ( |
493 | my_endpoint, server_mon, timeout, tools); |
494 | |
495 | char initiate[257]; |
496 | tools.produce_initiate (initiate, 257, 1, NULL, 0); |
497 | // modify command name |
498 | initiate[5] = 'X'; |
499 | |
500 | send_command (s, initiate); |
501 | |
502 | expect_monitor_event_multiple (server_mon, |
503 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
504 | ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); |
505 | |
506 | close (s); |
507 | } |
508 | |
509 | void test_curve_security_invalid_initiate_command_encrypted_cookie () |
510 | { |
511 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
512 | fd_t s = connect_exchange_greeting_and_hello_welcome ( |
513 | my_endpoint, server_mon, timeout, tools); |
514 | |
515 | char initiate[257]; |
516 | tools.produce_initiate (initiate, 257, 1, NULL, 0); |
517 | // make garbage from encrypted cookie |
518 | initiate[30] = !initiate[30]; |
519 | |
520 | send_command (s, initiate); |
521 | |
522 | expect_monitor_event_multiple (server_mon, |
523 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
524 | ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC); |
525 | |
526 | close (s); |
527 | } |
528 | |
529 | void test_curve_security_invalid_initiate_command_encrypted_content () |
530 | { |
531 | zmq::curve_client_tools_t tools = make_curve_client_tools (); |
532 | fd_t s = connect_exchange_greeting_and_hello_welcome ( |
533 | my_endpoint, server_mon, timeout, tools); |
534 | |
535 | char initiate[257]; |
536 | tools.produce_initiate (initiate, 257, 1, NULL, 0); |
537 | // make garbage from encrypted content |
538 | initiate[150] = !initiate[150]; |
539 | |
540 | send_command (s, initiate); |
541 | |
542 | expect_monitor_event_multiple (server_mon, |
543 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, |
544 | ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC); |
545 | |
546 | close (s); |
547 | } |
548 | |
549 | void test_curve_security_invalid_keysize (void *ctx_) |
550 | { |
551 | // Check return codes for invalid buffer sizes |
552 | void *client = zmq_socket (ctx_, ZMQ_DEALER); |
553 | TEST_ASSERT_NOT_NULL (client); |
554 | errno = 0; |
555 | int rc = |
556 | zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, valid_server_public, 123); |
557 | assert (rc == -1 && errno == EINVAL); |
558 | errno = 0; |
559 | rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, valid_client_public, 123); |
560 | assert (rc == -1 && errno == EINVAL); |
561 | errno = 0; |
562 | rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, valid_client_secret, 123); |
563 | assert (rc == -1 && errno == EINVAL); |
564 | TEST_ASSERT_SUCCESS_ERRNO (zmq_close (client)); |
565 | } |
566 | |
567 | // TODO why isn't this const? |
568 | char null_key[] = "0000000000000000000000000000000000000000" ; |
569 | |
570 | void test_null_server_key () |
571 | { |
572 | // Check CURVE security with a null server key |
573 | // This will be caught by the curve_server class, not passed to ZAP |
574 | test_null_key (server, server_mon, my_endpoint, null_key, |
575 | valid_client_public, valid_client_secret); |
576 | } |
577 | |
578 | void test_null_client_public_key () |
579 | { |
580 | // Check CURVE security with a null client public key |
581 | // This will be caught by the curve_server class, not passed to ZAP |
582 | test_null_key (server, server_mon, my_endpoint, valid_server_public, |
583 | null_key, valid_client_secret); |
584 | } |
585 | |
586 | void test_null_client_secret_key () |
587 | { |
588 | // Check CURVE security with a null client public key |
589 | // This will be caught by the curve_server class, not passed to ZAP |
590 | test_null_key (server, server_mon, my_endpoint, valid_server_public, |
591 | valid_client_public, null_key); |
592 | } |
593 | |
594 | |
595 | int main (void) |
596 | { |
597 | if (!zmq_has ("curve" )) { |
598 | printf ("CURVE encryption not installed, skipping test\n" ); |
599 | return 0; |
600 | } |
601 | |
602 | zmq::random_open (); |
603 | |
604 | setup_testutil_security_curve (); |
605 | |
606 | |
607 | setup_test_environment (); |
608 | |
609 | UNITY_BEGIN (); |
610 | RUN_TEST (test_curve_security_with_valid_credentials); |
611 | RUN_TEST (test_null_server_key); |
612 | RUN_TEST (test_null_client_public_key); |
613 | RUN_TEST (test_null_client_secret_key); |
614 | RUN_TEST (test_curve_security_with_bogus_client_credentials); |
615 | RUN_TEST (test_curve_security_with_null_client_credentials); |
616 | RUN_TEST (test_curve_security_with_plain_client_credentials); |
617 | RUN_TEST (test_curve_security_unauthenticated_message); |
618 | |
619 | // tests with misbehaving CURVE client |
620 | RUN_TEST (test_curve_security_invalid_hello_wrong_length); |
621 | RUN_TEST (test_curve_security_invalid_hello_command_name); |
622 | RUN_TEST (test_curve_security_invalid_hello_version); |
623 | RUN_TEST (test_curve_security_invalid_initiate_wrong_length); |
624 | RUN_TEST (test_curve_security_invalid_initiate_command_name); |
625 | RUN_TEST (test_curve_security_invalid_initiate_command_encrypted_cookie); |
626 | RUN_TEST (test_curve_security_invalid_initiate_command_encrypted_content); |
627 | |
628 | // TODO this requires a deviating test setup, must be moved to a separate executable/fixture |
629 | // test with a large routing id (resulting in large metadata) |
630 | fprintf (stderr, |
631 | "test_curve_security_with_valid_credentials (large routing id)\n" ); |
632 | setup_test_context (); |
633 | setup_context_and_server_side (&handler, &zap_thread, &server, &server_mon, |
634 | my_endpoint, &zap_handler_large_routing_id, |
635 | &socket_config_curve_server, |
636 | &valid_server_secret, large_routing_id); |
637 | test_curve_security_with_valid_credentials (); |
638 | shutdown_context_and_server_side (zap_thread, server, server_mon, handler); |
639 | teardown_test_context (); |
640 | |
641 | void *ctx = zmq_ctx_new (); |
642 | test_curve_security_invalid_keysize (ctx); |
643 | TEST_ASSERT_SUCCESS_ERRNO (zmq_ctx_term (ctx)); |
644 | |
645 | zmq::random_close (); |
646 | |
647 | return UNITY_END (); |
648 | } |
649 | |