1 /*
2 Copyright (c) 2007-2019 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 #include "testutil_security.hpp"
30
31 #include <stdlib.h>
32 #include <string.h>
33
34 const char *test_zap_domain = "ZAPTEST";
35
socket_config_null_client(void * server_,void * server_secret_)36 void socket_config_null_client (void *server_, void *server_secret_)
37 {
38 LIBZMQ_UNUSED (server_);
39 LIBZMQ_UNUSED (server_secret_);
40 }
41
socket_config_null_server(void * server_,void * server_secret_)42 void socket_config_null_server (void *server_, void *server_secret_)
43 {
44 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
45 server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
46 #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
47 int required = server_secret_ ? *static_cast<int *> (server_secret_) : 0;
48 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
49 &required, sizeof (int)));
50 #else
51 LIBZMQ_UNUSED (server_secret_);
52 #endif
53 }
54
55 static const char test_plain_username[] = "testuser";
56 static const char test_plain_password[] = "testpass";
57
socket_config_plain_client(void * server_,void * server_secret_)58 void socket_config_plain_client (void *server_, void *server_secret_)
59 {
60 LIBZMQ_UNUSED (server_secret_);
61
62 TEST_ASSERT_SUCCESS_ERRNO (
63 zmq_setsockopt (server_, ZMQ_PLAIN_PASSWORD, test_plain_password, 8));
64 TEST_ASSERT_SUCCESS_ERRNO (
65 zmq_setsockopt (server_, ZMQ_PLAIN_USERNAME, test_plain_username, 8));
66 }
67
socket_config_plain_server(void * server_,void * server_secret_)68 void socket_config_plain_server (void *server_, void *server_secret_)
69 {
70 LIBZMQ_UNUSED (server_secret_);
71
72 int as_server = 1;
73 TEST_ASSERT_SUCCESS_ERRNO (
74 zmq_setsockopt (server_, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)));
75 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
76 server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
77 }
78
79 char valid_client_public[41];
80 char valid_client_secret[41];
81 char valid_server_public[41];
82 char valid_server_secret[41];
83
setup_testutil_security_curve()84 void setup_testutil_security_curve ()
85 {
86 // Generate new keypairs for these tests
87 TEST_ASSERT_SUCCESS_ERRNO (
88 zmq_curve_keypair (valid_client_public, valid_client_secret));
89 TEST_ASSERT_SUCCESS_ERRNO (
90 zmq_curve_keypair (valid_server_public, valid_server_secret));
91 }
92
socket_config_curve_server(void * server_,void * server_secret_)93 void socket_config_curve_server (void *server_, void *server_secret_)
94 {
95 int as_server = 1;
96 TEST_ASSERT_SUCCESS_ERRNO (
97 zmq_setsockopt (server_, ZMQ_CURVE_SERVER, &as_server, sizeof (int)));
98 TEST_ASSERT_SUCCESS_ERRNO (
99 zmq_setsockopt (server_, ZMQ_CURVE_SECRETKEY, server_secret_, 41));
100 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
101 server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
102
103 #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
104 int required = 1;
105 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
106 &required, sizeof (int)));
107 #endif
108 }
109
socket_config_curve_client(void * client_,void * data_)110 void socket_config_curve_client (void *client_, void *data_)
111 {
112 const curve_client_data_t *const curve_client_data =
113 static_cast<const curve_client_data_t *> (data_);
114
115 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
116 client_, ZMQ_CURVE_SERVERKEY, curve_client_data->server_public, 41));
117 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
118 client_, ZMQ_CURVE_PUBLICKEY, curve_client_data->client_public, 41));
119 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
120 client_, ZMQ_CURVE_SECRETKEY, curve_client_data->client_secret, 41));
121 }
122
123 void *zap_requests_handled;
124
zap_handler_generic(zap_protocol_t zap_protocol_,const char * expected_routing_id_)125 void zap_handler_generic (zap_protocol_t zap_protocol_,
126 const char *expected_routing_id_)
127 {
128 void *control = zmq_socket (get_test_context (), ZMQ_REQ);
129 TEST_ASSERT_NOT_NULL (control);
130 TEST_ASSERT_SUCCESS_ERRNO (
131 zmq_connect (control, "inproc://handler-control"));
132
133 void *handler = zmq_socket (get_test_context (), ZMQ_REP);
134 TEST_ASSERT_NOT_NULL (handler);
135 TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01"));
136
137 // Signal main thread that we are ready
138 send_string_expect_success (control, "GO", 0);
139
140 zmq_pollitem_t items[] = {
141 {control, 0, ZMQ_POLLIN, 0},
142 {handler, 0, ZMQ_POLLIN, 0},
143 };
144
145 // if ordered not to receive the request, ignore the second poll item
146 const int numitems = (zap_protocol_ == zap_do_not_recv) ? 1 : 2;
147
148 // Process ZAP requests forever
149 while (zmq_poll (items, numitems, -1) >= 0) {
150 if (items[0].revents & ZMQ_POLLIN) {
151 recv_string_expect_success (control, "STOP", 0);
152 break; // Terminating - main thread signal
153 }
154 if (!(items[1].revents & ZMQ_POLLIN))
155 continue;
156
157 char *version = s_recv (handler);
158 if (!version)
159 break; // Terminating - peer's socket closed
160 if (zap_protocol_ == zap_disconnect) {
161 free (version);
162 break;
163 }
164
165 char *sequence = s_recv (handler);
166 char *domain = s_recv (handler);
167 char *address = s_recv (handler);
168 char *routing_id = s_recv (handler);
169 char *mechanism = s_recv (handler);
170 bool authentication_succeeded = false;
171 if (streq (mechanism, "CURVE")) {
172 uint8_t client_key[32];
173 TEST_ASSERT_EQUAL_INT (32, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (
174 handler, client_key, 32, 0)));
175
176 char client_key_text[41];
177 zmq_z85_encode (client_key_text, client_key, 32);
178
179 authentication_succeeded =
180 streq (client_key_text, valid_client_public);
181 } else if (streq (mechanism, "PLAIN")) {
182 char client_username[32];
183 int size = TEST_ASSERT_SUCCESS_ERRNO (
184 zmq_recv (handler, client_username, 32, 0));
185 client_username[size] = 0;
186
187 char client_password[32];
188 size = TEST_ASSERT_SUCCESS_ERRNO (
189 zmq_recv (handler, client_password, 32, 0));
190 client_password[size] = 0;
191
192 authentication_succeeded =
193 streq (test_plain_username, client_username)
194 && streq (test_plain_password, client_password);
195 } else if (streq (mechanism, "NULL")) {
196 authentication_succeeded = true;
197 } else {
198 char msg[128];
199 printf ("Unsupported mechanism: %s\n", mechanism);
200 TEST_FAIL_MESSAGE (msg);
201 }
202
203 TEST_ASSERT_EQUAL_STRING ("1.0", version);
204 TEST_ASSERT_EQUAL_STRING (expected_routing_id_, routing_id);
205
206 send_string_expect_success (
207 handler,
208 zap_protocol_ == zap_wrong_version ? "invalid_version" : version,
209 ZMQ_SNDMORE);
210 send_string_expect_success (handler,
211 zap_protocol_ == zap_wrong_request_id
212 ? "invalid_request_id"
213 : sequence,
214 ZMQ_SNDMORE);
215
216 if (authentication_succeeded) {
217 const char *status_code;
218 switch (zap_protocol_) {
219 case zap_status_internal_error:
220 status_code = "500";
221 break;
222 case zap_status_temporary_failure:
223 status_code = "300";
224 break;
225 case zap_status_invalid:
226 status_code = "invalid_status";
227 break;
228 default:
229 status_code = "200";
230 }
231 send_string_expect_success (handler, status_code, ZMQ_SNDMORE);
232 send_string_expect_success (handler, "OK", ZMQ_SNDMORE);
233 send_string_expect_success (handler, "anonymous", ZMQ_SNDMORE);
234 if (zap_protocol_ == zap_too_many_parts) {
235 send_string_expect_success (handler, "", ZMQ_SNDMORE);
236 }
237 if (zap_protocol_ != zap_do_not_send)
238 send_string_expect_success (handler, "", 0);
239 } else {
240 send_string_expect_success (handler, "400", ZMQ_SNDMORE);
241 send_string_expect_success (handler, "Invalid client public key",
242 ZMQ_SNDMORE);
243 send_string_expect_success (handler, "", ZMQ_SNDMORE);
244 if (zap_protocol_ != zap_do_not_send)
245 send_string_expect_success (handler, "", 0);
246 }
247 free (version);
248 free (sequence);
249 free (domain);
250 free (address);
251 free (routing_id);
252 free (mechanism);
253
254 zmq_atomic_counter_inc (zap_requests_handled);
255 }
256 TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (handler, "inproc://zeromq.zap.01"));
257 close_zero_linger (handler);
258
259 if (zap_protocol_ != zap_disconnect) {
260 send_string_expect_success (control, "STOPPED", 0);
261 }
262 close_zero_linger (control);
263 }
264
zap_handler(void *)265 void zap_handler (void *)
266 {
267 zap_handler_generic (zap_ok);
268 }
269
setup_handshake_socket_monitor(void * server_,void ** server_mon_,const char * monitor_endpoint_)270 static void setup_handshake_socket_monitor (void *server_,
271 void **server_mon_,
272 const char *monitor_endpoint_)
273 {
274 // Monitor handshake events on the server
275 TEST_ASSERT_SUCCESS_ERRNO (zmq_socket_monitor (
276 server_, monitor_endpoint_,
277 ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
278 | ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
279 | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL));
280
281 // Create socket for collecting monitor events
282 *server_mon_ = test_context_socket (ZMQ_PAIR);
283 int linger = 0;
284 TEST_ASSERT_SUCCESS_ERRNO (
285 zmq_setsockopt (*server_mon_, ZMQ_LINGER, &linger, sizeof (linger)));
286
287 // Connect it to the inproc endpoints so they'll get events
288 TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*server_mon_, monitor_endpoint_));
289 }
290
setup_context_and_server_side(void ** zap_control_,void ** zap_thread_,void ** server_,void ** server_mon_,char * my_endpoint_,zmq_thread_fn zap_handler_,socket_config_fn socket_config_,void * socket_config_data_,const char * routing_id_)291 void setup_context_and_server_side (void **zap_control_,
292 void **zap_thread_,
293 void **server_,
294 void **server_mon_,
295 char *my_endpoint_,
296 zmq_thread_fn zap_handler_,
297 socket_config_fn socket_config_,
298 void *socket_config_data_,
299 const char *routing_id_)
300 {
301 // Spawn ZAP handler
302 zap_requests_handled = zmq_atomic_counter_new ();
303 TEST_ASSERT_NOT_NULL (zap_requests_handled);
304
305 *zap_control_ = test_context_socket (ZMQ_REP);
306 TEST_ASSERT_SUCCESS_ERRNO (
307 zmq_bind (*zap_control_, "inproc://handler-control"));
308 int linger = 0;
309 TEST_ASSERT_SUCCESS_ERRNO (
310 zmq_setsockopt (*zap_control_, ZMQ_LINGER, &linger, sizeof (linger)));
311
312 if (zap_handler_ != NULL) {
313 *zap_thread_ = zmq_threadstart (zap_handler_, NULL);
314
315 recv_string_expect_success (*zap_control_, "GO", 0);
316 } else
317 *zap_thread_ = NULL;
318
319 // Server socket will accept connections
320 *server_ = test_context_socket (ZMQ_DEALER);
321 TEST_ASSERT_SUCCESS_ERRNO (
322 zmq_setsockopt (*server_, ZMQ_LINGER, &linger, sizeof (linger)));
323 // As per API by default there's no limit to the size of a message,
324 // but the sanitizer allocator will barf over a gig or so
325 int64_t max_msg_size = 64 * 1024 * 1024;
326 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
327 *server_, ZMQ_MAXMSGSIZE, &max_msg_size, sizeof (int64_t)));
328
329 socket_config_ (*server_, socket_config_data_);
330
331 TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
332 *server_, ZMQ_ROUTING_ID, routing_id_, strlen (routing_id_)));
333
334 bind_loopback_ipv4 (*server_, my_endpoint_, MAX_SOCKET_STRING);
335
336 const char server_monitor_endpoint[] = "inproc://monitor-server";
337 setup_handshake_socket_monitor (*server_, server_mon_,
338 server_monitor_endpoint);
339 }
340
shutdown_context_and_server_side(void * zap_thread_,void * server_,void * server_mon_,void * zap_control_,bool zap_handler_stopped_)341 void shutdown_context_and_server_side (void *zap_thread_,
342 void *server_,
343 void *server_mon_,
344 void *zap_control_,
345 bool zap_handler_stopped_)
346 {
347 if (zap_thread_ && !zap_handler_stopped_) {
348 send_string_expect_success (zap_control_, "STOP", 0);
349 recv_string_expect_success (zap_control_, "STOPPED", 0);
350 TEST_ASSERT_SUCCESS_ERRNO (
351 zmq_unbind (zap_control_, "inproc://handler-control"));
352 }
353 test_context_socket_close (zap_control_);
354 zmq_socket_monitor (server_, NULL, 0);
355 test_context_socket_close (server_mon_);
356 test_context_socket_close (server_);
357
358 // Wait until ZAP handler terminates
359 if (zap_thread_)
360 zmq_threadclose (zap_thread_);
361
362 zmq_atomic_counter_destroy (&zap_requests_handled);
363 }
364
create_and_connect_client(char * my_endpoint_,socket_config_fn socket_config_,void * socket_config_data_,void ** client_mon_)365 void *create_and_connect_client (char *my_endpoint_,
366 socket_config_fn socket_config_,
367 void *socket_config_data_,
368 void **client_mon_)
369 {
370 void *client = test_context_socket (ZMQ_DEALER);
371 // As per API by default there's no limit to the size of a message,
372 // but the sanitizer allocator will barf over a gig or so
373 int64_t max_msg_size = 64 * 1024 * 1024;
374 TEST_ASSERT_SUCCESS_ERRNO (
375 zmq_setsockopt (client, ZMQ_MAXMSGSIZE, &max_msg_size, sizeof (int64_t)));
376
377 socket_config_ (client, socket_config_data_);
378
379 TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint_));
380
381 if (client_mon_) {
382 setup_handshake_socket_monitor (client, client_mon_,
383 "inproc://client-monitor");
384 }
385
386 return client;
387 }
388
expect_new_client_bounce_fail(char * my_endpoint_,void * server_,socket_config_fn socket_config_,void * socket_config_data_,void ** client_mon_,int expected_client_event_,int expected_client_value_)389 void expect_new_client_bounce_fail (char *my_endpoint_,
390 void *server_,
391 socket_config_fn socket_config_,
392 void *socket_config_data_,
393 void **client_mon_,
394 int expected_client_event_,
395 int expected_client_value_)
396 {
397 void *my_client_mon = NULL;
398 TEST_ASSERT_TRUE (client_mon_ == NULL || expected_client_event_ == 0);
399 if (expected_client_event_ != 0)
400 client_mon_ = &my_client_mon;
401 void *client = create_and_connect_client (my_endpoint_, socket_config_,
402 socket_config_data_, client_mon_);
403 expect_bounce_fail (server_, client);
404
405 if (expected_client_event_ != 0) {
406 int events_received = 0;
407 events_received = expect_monitor_event_multiple (
408 my_client_mon, expected_client_event_, expected_client_value_, false);
409
410 TEST_ASSERT_EQUAL_INT (1, events_received);
411
412 test_context_socket_close (my_client_mon);
413 }
414
415 test_context_socket_close_zero_linger (client);
416 }
417