testutil_security.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file
  3. This file is part of libzmq, the ZeroMQ core engine in C++.
  4. libzmq is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU Lesser General Public License (LGPL) as published
  6. by the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. As a special exception, the Contributors give you permission to link
  9. this library with independent modules to produce an executable,
  10. regardless of the license terms of these independent modules, and to
  11. copy and distribute the resulting executable under terms of your choice,
  12. provided that you also meet, for each linked independent module, the
  13. terms and conditions of the license of that module. An independent
  14. module is a module which is not derived from or based on this library.
  15. If you modify this library, you must extend this exception to your
  16. version of the library.
  17. libzmq is distributed in the hope that it will be useful, but WITHOUT
  18. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  19. FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  20. License for more details.
  21. You should have received a copy of the GNU Lesser General Public License
  22. along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. */
  24. #include "testutil_security.hpp"
  25. #include <stdlib.h>
  26. #include <string.h>
  27. const char *test_zap_domain = "ZAPTEST";
  28. void socket_config_null_client (void *server_, void *server_secret_)
  29. {
  30. LIBZMQ_UNUSED (server_);
  31. LIBZMQ_UNUSED (server_secret_);
  32. }
  33. void socket_config_null_server (void *server_, void *server_secret_)
  34. {
  35. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  36. server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
  37. #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
  38. int required = server_secret_ ? *static_cast<int *> (server_secret_) : 0;
  39. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
  40. &required, sizeof (int)));
  41. #else
  42. LIBZMQ_UNUSED (server_secret_);
  43. #endif
  44. }
  45. static const char test_plain_username[] = "testuser";
  46. static const char test_plain_password[] = "testpass";
  47. void socket_config_plain_client (void *server_, void *server_secret_)
  48. {
  49. LIBZMQ_UNUSED (server_secret_);
  50. TEST_ASSERT_SUCCESS_ERRNO (
  51. zmq_setsockopt (server_, ZMQ_PLAIN_PASSWORD, test_plain_password, 8));
  52. TEST_ASSERT_SUCCESS_ERRNO (
  53. zmq_setsockopt (server_, ZMQ_PLAIN_USERNAME, test_plain_username, 8));
  54. }
  55. void socket_config_plain_server (void *server_, void *server_secret_)
  56. {
  57. LIBZMQ_UNUSED (server_secret_);
  58. int as_server = 1;
  59. TEST_ASSERT_SUCCESS_ERRNO (
  60. zmq_setsockopt (server_, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)));
  61. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  62. server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
  63. }
  64. char valid_client_public[41];
  65. char valid_client_secret[41];
  66. char valid_server_public[41];
  67. char valid_server_secret[41];
  68. void setup_testutil_security_curve ()
  69. {
  70. // Generate new keypairs for these tests
  71. TEST_ASSERT_SUCCESS_ERRNO (
  72. zmq_curve_keypair (valid_client_public, valid_client_secret));
  73. TEST_ASSERT_SUCCESS_ERRNO (
  74. zmq_curve_keypair (valid_server_public, valid_server_secret));
  75. }
  76. void socket_config_curve_server (void *server_, void *server_secret_)
  77. {
  78. int as_server = 1;
  79. TEST_ASSERT_SUCCESS_ERRNO (
  80. zmq_setsockopt (server_, ZMQ_CURVE_SERVER, &as_server, sizeof (int)));
  81. TEST_ASSERT_SUCCESS_ERRNO (
  82. zmq_setsockopt (server_, ZMQ_CURVE_SECRETKEY, server_secret_, 41));
  83. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  84. server_, ZMQ_ZAP_DOMAIN, test_zap_domain, strlen (test_zap_domain)));
  85. #ifdef ZMQ_ZAP_ENFORCE_DOMAIN
  86. int required = 1;
  87. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (server_, ZMQ_ZAP_ENFORCE_DOMAIN,
  88. &required, sizeof (int)));
  89. #endif
  90. }
  91. void socket_config_curve_client (void *client_, void *data_)
  92. {
  93. const curve_client_data_t *const curve_client_data =
  94. static_cast<const curve_client_data_t *> (data_);
  95. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  96. client_, ZMQ_CURVE_SERVERKEY, curve_client_data->server_public, 41));
  97. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  98. client_, ZMQ_CURVE_PUBLICKEY, curve_client_data->client_public, 41));
  99. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  100. client_, ZMQ_CURVE_SECRETKEY, curve_client_data->client_secret, 41));
  101. }
  102. void *zap_requests_handled;
  103. void zap_handler_generic (zap_protocol_t zap_protocol_,
  104. const char *expected_routing_id_)
  105. {
  106. void *control = zmq_socket (get_test_context (), ZMQ_REQ);
  107. TEST_ASSERT_NOT_NULL (control);
  108. TEST_ASSERT_SUCCESS_ERRNO (
  109. zmq_connect (control, "inproc://handler-control"));
  110. void *handler = zmq_socket (get_test_context (), ZMQ_REP);
  111. TEST_ASSERT_NOT_NULL (handler);
  112. TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01"));
  113. // Signal main thread that we are ready
  114. send_string_expect_success (control, "GO", 0);
  115. zmq_pollitem_t items[] = {
  116. {control, 0, ZMQ_POLLIN, 0},
  117. {handler, 0, ZMQ_POLLIN, 0},
  118. };
  119. // if ordered not to receive the request, ignore the second poll item
  120. const int numitems = (zap_protocol_ == zap_do_not_recv) ? 1 : 2;
  121. // Process ZAP requests forever
  122. while (zmq_poll (items, numitems, -1) >= 0) {
  123. if (items[0].revents & ZMQ_POLLIN) {
  124. recv_string_expect_success (control, "STOP", 0);
  125. break; // Terminating - main thread signal
  126. }
  127. if (!(items[1].revents & ZMQ_POLLIN))
  128. continue;
  129. char *version = s_recv (handler);
  130. if (!version)
  131. break; // Terminating - peer's socket closed
  132. if (zap_protocol_ == zap_disconnect) {
  133. free (version);
  134. break;
  135. }
  136. char *sequence = s_recv (handler);
  137. char *domain = s_recv (handler);
  138. char *address = s_recv (handler);
  139. char *routing_id = s_recv (handler);
  140. char *mechanism = s_recv (handler);
  141. bool authentication_succeeded = false;
  142. if (streq (mechanism, "CURVE")) {
  143. uint8_t client_key[32];
  144. TEST_ASSERT_EQUAL_INT (32, TEST_ASSERT_SUCCESS_ERRNO (zmq_recv (
  145. handler, client_key, 32, 0)));
  146. char client_key_text[41];
  147. zmq_z85_encode (client_key_text, client_key, 32);
  148. authentication_succeeded =
  149. streq (client_key_text, valid_client_public);
  150. } else if (streq (mechanism, "PLAIN")) {
  151. char client_username[32];
  152. int size = TEST_ASSERT_SUCCESS_ERRNO (
  153. zmq_recv (handler, client_username, 32, 0));
  154. client_username[size] = 0;
  155. char client_password[32];
  156. size = TEST_ASSERT_SUCCESS_ERRNO (
  157. zmq_recv (handler, client_password, 32, 0));
  158. client_password[size] = 0;
  159. authentication_succeeded =
  160. streq (test_plain_username, client_username)
  161. && streq (test_plain_password, client_password);
  162. } else if (streq (mechanism, "NULL")) {
  163. authentication_succeeded = true;
  164. } else {
  165. char msg[128];
  166. printf ("Unsupported mechanism: %s\n", mechanism);
  167. TEST_FAIL_MESSAGE (msg);
  168. }
  169. TEST_ASSERT_EQUAL_STRING ("1.0", version);
  170. TEST_ASSERT_EQUAL_STRING (expected_routing_id_, routing_id);
  171. send_string_expect_success (
  172. handler,
  173. zap_protocol_ == zap_wrong_version ? "invalid_version" : version,
  174. ZMQ_SNDMORE);
  175. send_string_expect_success (handler,
  176. zap_protocol_ == zap_wrong_request_id
  177. ? "invalid_request_id"
  178. : sequence,
  179. ZMQ_SNDMORE);
  180. if (authentication_succeeded) {
  181. const char *status_code;
  182. switch (zap_protocol_) {
  183. case zap_status_internal_error:
  184. status_code = "500";
  185. break;
  186. case zap_status_temporary_failure:
  187. status_code = "300";
  188. break;
  189. case zap_status_invalid:
  190. status_code = "invalid_status";
  191. break;
  192. default:
  193. status_code = "200";
  194. }
  195. send_string_expect_success (handler, status_code, ZMQ_SNDMORE);
  196. send_string_expect_success (handler, "OK", ZMQ_SNDMORE);
  197. send_string_expect_success (handler, "anonymous", ZMQ_SNDMORE);
  198. if (zap_protocol_ == zap_too_many_parts) {
  199. send_string_expect_success (handler, "", ZMQ_SNDMORE);
  200. }
  201. if (zap_protocol_ != zap_do_not_send)
  202. send_string_expect_success (handler, "", 0);
  203. } else {
  204. send_string_expect_success (handler, "400", ZMQ_SNDMORE);
  205. send_string_expect_success (handler, "Invalid client public key",
  206. ZMQ_SNDMORE);
  207. send_string_expect_success (handler, "", ZMQ_SNDMORE);
  208. if (zap_protocol_ != zap_do_not_send)
  209. send_string_expect_success (handler, "", 0);
  210. }
  211. free (version);
  212. free (sequence);
  213. free (domain);
  214. free (address);
  215. free (routing_id);
  216. free (mechanism);
  217. zmq_atomic_counter_inc (zap_requests_handled);
  218. }
  219. TEST_ASSERT_SUCCESS_ERRNO (zmq_unbind (handler, "inproc://zeromq.zap.01"));
  220. close_zero_linger (handler);
  221. if (zap_protocol_ != zap_disconnect) {
  222. send_string_expect_success (control, "STOPPED", 0);
  223. }
  224. close_zero_linger (control);
  225. }
  226. void zap_handler (void *)
  227. {
  228. zap_handler_generic (zap_ok);
  229. }
  230. static void setup_handshake_socket_monitor (void *server_,
  231. void **server_mon_,
  232. const char *monitor_endpoint_)
  233. {
  234. // Monitor handshake events on the server
  235. TEST_ASSERT_SUCCESS_ERRNO (zmq_socket_monitor (
  236. server_, monitor_endpoint_,
  237. ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
  238. | ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
  239. | ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL));
  240. // Create socket for collecting monitor events
  241. *server_mon_ = test_context_socket (ZMQ_PAIR);
  242. int linger = 0;
  243. TEST_ASSERT_SUCCESS_ERRNO (
  244. zmq_setsockopt (*server_mon_, ZMQ_LINGER, &linger, sizeof (linger)));
  245. // Connect it to the inproc endpoints so they'll get events
  246. TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (*server_mon_, monitor_endpoint_));
  247. }
  248. void setup_context_and_server_side (void **zap_control_,
  249. void **zap_thread_,
  250. void **server_,
  251. void **server_mon_,
  252. char *my_endpoint_,
  253. zmq_thread_fn zap_handler_,
  254. socket_config_fn socket_config_,
  255. void *socket_config_data_,
  256. const char *routing_id_)
  257. {
  258. // Spawn ZAP handler
  259. zap_requests_handled = zmq_atomic_counter_new ();
  260. TEST_ASSERT_NOT_NULL (zap_requests_handled);
  261. *zap_control_ = test_context_socket (ZMQ_REP);
  262. TEST_ASSERT_SUCCESS_ERRNO (
  263. zmq_bind (*zap_control_, "inproc://handler-control"));
  264. int linger = 0;
  265. TEST_ASSERT_SUCCESS_ERRNO (
  266. zmq_setsockopt (*zap_control_, ZMQ_LINGER, &linger, sizeof (linger)));
  267. if (zap_handler_ != NULL) {
  268. *zap_thread_ = zmq_threadstart (zap_handler_, NULL);
  269. recv_string_expect_success (*zap_control_, "GO", 0);
  270. } else
  271. *zap_thread_ = NULL;
  272. // Server socket will accept connections
  273. *server_ = test_context_socket (ZMQ_DEALER);
  274. TEST_ASSERT_SUCCESS_ERRNO (
  275. zmq_setsockopt (*server_, ZMQ_LINGER, &linger, sizeof (linger)));
  276. // As per API by default there's no limit to the size of a message,
  277. // but the sanitizer allocator will barf over a gig or so
  278. int64_t max_msg_size = 64 * 1024 * 1024;
  279. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  280. *server_, ZMQ_MAXMSGSIZE, &max_msg_size, sizeof (int64_t)));
  281. socket_config_ (*server_, socket_config_data_);
  282. TEST_ASSERT_SUCCESS_ERRNO (zmq_setsockopt (
  283. *server_, ZMQ_ROUTING_ID, routing_id_, strlen (routing_id_)));
  284. bind_loopback_ipv4 (*server_, my_endpoint_, MAX_SOCKET_STRING);
  285. const char server_monitor_endpoint[] = "inproc://monitor-server";
  286. setup_handshake_socket_monitor (*server_, server_mon_,
  287. server_monitor_endpoint);
  288. }
  289. void shutdown_context_and_server_side (void *zap_thread_,
  290. void *server_,
  291. void *server_mon_,
  292. void *zap_control_,
  293. bool zap_handler_stopped_)
  294. {
  295. if (zap_thread_ && !zap_handler_stopped_) {
  296. send_string_expect_success (zap_control_, "STOP", 0);
  297. recv_string_expect_success (zap_control_, "STOPPED", 0);
  298. TEST_ASSERT_SUCCESS_ERRNO (
  299. zmq_unbind (zap_control_, "inproc://handler-control"));
  300. }
  301. test_context_socket_close (zap_control_);
  302. zmq_socket_monitor (server_, NULL, 0);
  303. test_context_socket_close (server_mon_);
  304. test_context_socket_close (server_);
  305. // Wait until ZAP handler terminates
  306. if (zap_thread_)
  307. zmq_threadclose (zap_thread_);
  308. zmq_atomic_counter_destroy (&zap_requests_handled);
  309. }
  310. void *create_and_connect_client (char *my_endpoint_,
  311. socket_config_fn socket_config_,
  312. void *socket_config_data_,
  313. void **client_mon_)
  314. {
  315. void *client = test_context_socket (ZMQ_DEALER);
  316. // As per API by default there's no limit to the size of a message,
  317. // but the sanitizer allocator will barf over a gig or so
  318. int64_t max_msg_size = 64 * 1024 * 1024;
  319. TEST_ASSERT_SUCCESS_ERRNO (
  320. zmq_setsockopt (client, ZMQ_MAXMSGSIZE, &max_msg_size, sizeof (int64_t)));
  321. socket_config_ (client, socket_config_data_);
  322. TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint_));
  323. if (client_mon_) {
  324. setup_handshake_socket_monitor (client, client_mon_,
  325. "inproc://client-monitor");
  326. }
  327. return client;
  328. }
  329. void expect_new_client_bounce_fail (char *my_endpoint_,
  330. void *server_,
  331. socket_config_fn socket_config_,
  332. void *socket_config_data_,
  333. void **client_mon_,
  334. int expected_client_event_,
  335. int expected_client_value_)
  336. {
  337. void *my_client_mon = NULL;
  338. TEST_ASSERT_TRUE (client_mon_ == NULL || expected_client_event_ == 0);
  339. if (expected_client_event_ != 0)
  340. client_mon_ = &my_client_mon;
  341. void *client = create_and_connect_client (my_endpoint_, socket_config_,
  342. socket_config_data_, client_mon_);
  343. expect_bounce_fail (server_, client);
  344. if (expected_client_event_ != 0) {
  345. int events_received = 0;
  346. events_received = expect_monitor_event_multiple (
  347. my_client_mon, expected_client_event_, expected_client_value_, false);
  348. TEST_ASSERT_EQUAL_INT (1, events_received);
  349. test_context_socket_close (my_client_mon);
  350. }
  351. test_context_socket_close_zero_linger (client);
  352. }