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