void zcert_test (bool verbose) { printf (" * zcert: "); #if (ZMQ_VERSION_MAJOR == 4) // @selftest // Create temporary directory for test files # define TESTDIR ".test_zcert" zsys_dir_create (TESTDIR); // Create a simple certificate with metadata zcert_t *cert = zcert_new (); # if defined (HAVE_LIBSODIUM) zcert_set_meta (cert, "email", "*****@*****.**"); zcert_set_meta (cert, "name", "Pieter Hintjens"); zcert_set_meta (cert, "organization", "iMatix Corporation"); zcert_set_meta (cert, "version", "%d", 1); assert (streq (zcert_meta (cert, "email"), "*****@*****.**")); zlist_t *keys = zcert_meta_keys (cert); assert (zlist_size (keys) == 4); zlist_destroy (&keys); // Check the dup and eq methods zcert_t *shadow = zcert_dup (cert); assert (zcert_eq (cert, shadow)); zcert_destroy (&shadow); // Check we can save and load certificate zcert_save (cert, TESTDIR "/mycert.txt"); assert (zsys_file_exists (TESTDIR "/mycert.txt")); assert (zsys_file_exists (TESTDIR "/mycert.txt_secret")); // Load certificate, will in fact load secret one shadow = zcert_load (TESTDIR "/mycert.txt"); assert (shadow); assert (zcert_eq (cert, shadow)); zcert_destroy (&shadow); // Delete secret certificate, load public one int rc = zsys_file_delete (TESTDIR "/mycert.txt_secret"); assert (rc == 0); shadow = zcert_load (TESTDIR "/mycert.txt"); // 32-byte null key encodes as 40 '0' characters assert (streq (zcert_secret_txt (shadow), "0000000000000000000000000000000000000000")); zcert_destroy (&shadow); zcert_destroy (&cert); # else // Libsodium isn't installed; should have returned NULL assert (cert == NULL); # endif // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end #endif printf ("OK\n"); }
zcert_t * zcert_new_from (byte *public_key, byte *secret_key) { zcert_t *self = (zcert_t *) zmalloc (sizeof (zcert_t)); if (!self) return NULL; assert (public_key); assert (secret_key); self->metadata = zhash_new (); if (self->metadata) { zhash_autofree (self->metadata); memcpy (self->public_key, public_key, 32); memcpy (self->secret_key, secret_key, 32); #if (ZMQ_VERSION_MAJOR == 4) zmq_z85_encode (self->public_txt, self->public_key, 32); zmq_z85_encode (self->secret_txt, self->secret_key, 32); #else strcpy (self->public_txt, FORTY_ZEROES); strcpy (self->secret_txt, FORTY_ZEROES); #endif } else zcert_destroy (&self); return self; }
int main (int argc, char *argv []) { int argn = 1; char *filename = "mycert.txt"; if (argn < argc) filename = argv [argn++]; zsys_info ("Creating new CURVE certificate in %s", filename); zcert_t *cert = zcert_new (); if (s_get_meta (cert, "Enter your full name:", "name") || s_get_meta (cert, "Enter your email address:", "email") || s_get_meta (cert, "Enter your organization:", "organization")) return -1; char *timestr = zclock_timestr (); zcert_set_meta (cert, "created-by", "CZMQ zmakecert"); zcert_set_meta (cert, "date-created", "%s", timestr); free (timestr); zcert_dump (cert); zcert_save (cert, filename); zsys_info ("CURVE certificate created in %s and %s_secret", filename, filename); zcert_destroy (&cert); return 0; }
static agent_t * s_agent_new (zctx_t *ctx, void *control) { agent_t *self = (agent_t *) zmalloc (sizeof (agent_t)); self->ctx = ctx; self->control = control; self->state = waiting; self->dealer = zsocket_new (ctx, ZMQ_DEALER); // Connect our data socket to caller's endpoint self->data = zsocket_new (ctx, ZMQ_PAIR); char *endpoint = zstr_recv (self->control); int rc = zsocket_connect (self->data, "%s", endpoint); assert (rc != -1); free (endpoint); // Create new client codec using cert from API byte public_key [32]; byte secret_key [32]; rc = zmq_recv (self->control, public_key, 32, 0); assert (rc == 32); rc = zmq_recv (self->control, secret_key, 32, 0); assert (rc == 32); zcert_t *cert = zcert_new_from (public_key, secret_key); self->codec = curve_codec_new_client (cert); zcert_destroy (&cert); return self; }
curve_client_t * curve_client_new (zcert_t **cert_p) { curve_client_t *self = (curve_client_t *) zmalloc (sizeof (curve_client_t)); assert (self); self->ctx = zctx_new (); self->control = zthread_fork (self->ctx, s_agent_task, NULL); // Create separate data socket, send address on control socket self->data = zsocket_new (self->ctx, ZMQ_PAIR); assert (self->data); int rc = zsocket_bind (self->data, "inproc://data-%p", self->data); assert (rc != -1); zstr_sendfm (self->control, "inproc://data-%p", self->data); // Now send cert on control socket as well rc = zmq_send (self->control, zcert_public_key (*cert_p), 32, ZMQ_SNDMORE); assert (rc == 32); rc = zmq_send (self->control, zcert_secret_key (*cert_p), 32, 0); assert (rc == 32); zcert_destroy (cert_p); return self; }
void zcertstore_test (bool verbose) { printf (" * zcertstore: "); if (verbose) printf ("\n"); // @selftest // Create temporary directory for test files # define TESTDIR ".test_zcertstore" zsys_dir_create (TESTDIR); // Load certificate store from disk; it will be empty zcertstore_t *certstore = zcertstore_new (TESTDIR); assert (certstore); // Create a single new certificate and save to disk zcert_t *cert = zcert_new (); assert (cert); char *client_key = strdup (zcert_public_txt (cert)); assert (client_key); zcert_set_meta (cert, "name", "John Doe"); zcert_save (cert, TESTDIR "/mycert.txt"); zcert_destroy (&cert); // Check that certificate store refreshes as expected cert = zcertstore_lookup (certstore, client_key); assert (cert); assert (streq (zcert_meta (cert, "name"), "John Doe")); // Test custom loader test_loader_state *state = (test_loader_state *) zmalloc (sizeof (test_loader_state)); state->index = 0; zcertstore_set_loader (certstore, s_test_loader, s_test_destructor, (void *)state); #if (ZMQ_VERSION_MAJOR >= 4) cert = zcertstore_lookup (certstore, client_key); assert (cert == NULL); cert = zcertstore_lookup (certstore, "abcdefghijklmnopqrstuvwxyzabcdefghijklmn"); assert (cert); #endif free (client_key); if (verbose) zcertstore_print (certstore); zcertstore_destroy (&certstore); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
static void s_empty_store (zcertstore_t *self) { zcert_t *cert = (zcert_t *) zlist_pop (self->cert_list); while (cert) { zhash_delete (self->cert_hash, zcert_public_txt (cert)); zcert_destroy (&cert); cert = (zcert_t *) zlist_pop (self->cert_list); } assert (zlist_size (self->cert_list) == 0); assert (zhash_size (self->cert_hash) == 0); }
static void s_agent_destroy (agent_t **self_p) { assert (self_p); if (*self_p) { agent_t *self = *self_p; zcert_destroy (&self->cert); zhash_destroy (&self->metadata); zhash_destroy (&self->clients); free (self); *self_p = NULL; } }
server_connect (server_t *self, const char *endpoint) #endif { zsock_t *remote = zsock_new (ZMQ_DEALER); assert (remote); // No recovery if exhausted #ifdef CZMQ_BUILD_DRAFT_API // DRAFT-API: Security if (public_key){ zcert_t *cert = zcert_new_from_txt (self->public_key, self->secret_key); zcert_apply(cert, remote); zsock_set_curve_serverkey (remote, public_key); #ifndef ZMQ_CURVE // legacy ZMQ support // inline incase the underlying assert is removed bool ZMQ_CURVE = false; #endif assert (zsock_mechanism (remote) == ZMQ_CURVE); zcert_destroy(&cert); } #endif // Never block on sending; we use an infinite HWM and buffer as many // messages as needed in outgoing pipes. Note that the maximum number // is the overall tuple set size. zsock_set_unbounded (remote); if (zsock_connect (remote, "%s", endpoint)) { zsys_warning ("bad zgossip endpoint '%s'", endpoint); zsock_destroy (&remote); return; } // Send HELLO and then PUBLISH for each tuple we have zgossip_msg_t *gossip = zgossip_msg_new (); zgossip_msg_set_id (gossip, ZGOSSIP_MSG_HELLO); zgossip_msg_send (gossip, remote); tuple_t *tuple = (tuple_t *) zhashx_first (self->tuples); while (tuple) { zgossip_msg_set_id (gossip, ZGOSSIP_MSG_PUBLISH); zgossip_msg_set_key (gossip, tuple->key); zgossip_msg_set_value (gossip, tuple->value); zgossip_msg_send (gossip, remote); tuple = (tuple_t *) zhashx_next (self->tuples); } // Now monitor this remote for incoming messages zgossip_msg_destroy (&gossip); engine_handle_socket (self, remote, remote_handler); zlistx_add_end (self->remotes, remote); }
zcert_t * zcert_dup (zcert_t *self) { if (self) { zcert_t *copy = zcert_new_from (self->public_key, self->secret_key); if (copy) { zhash_destroy (©->metadata); copy->metadata = zhash_dup (self->metadata); if (!copy->metadata) zcert_destroy (©); } return copy; } else return NULL; }
void MessageProcessor::init(int port, zcert_t* transportKey) { if (port == 0) { OT_FAIL; } if (!zsys_has_curve()) { Log::vError("Error: libzmq has no libsodium support"); OT_FAIL; } zstr_sendx(zmqAuth_, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait(zmqAuth_); zsock_set_zap_domain(zmqSocket_, "global"); zsock_set_curve_server(zmqSocket_, 1); zcert_apply(transportKey, zmqSocket_); zcert_destroy(&transportKey); zsock_bind(zmqSocket_, "tcp://*:%d", port); }
void zcertstore_test (bool verbose) { printf (" * zcertstore: "); if (verbose) printf ("\n"); // @selftest // Create temporary directory for test files # define TESTDIR ".test_zcertstore" zsys_dir_create (TESTDIR); // Load certificate store from disk; it will be empty zcertstore_t *certstore = zcertstore_new (TESTDIR); assert (certstore); // Create a single new certificate and save to disk zcert_t *cert = zcert_new (); assert (cert); char *client_key = strdup (zcert_public_txt (cert)); assert (client_key); zcert_set_meta (cert, "name", "John Doe"); zcert_save (cert, TESTDIR "/mycert.txt"); zcert_destroy (&cert); // Check that certificate store refreshes as expected cert = zcertstore_lookup (certstore, client_key); assert (cert); assert (streq (zcert_meta (cert, "name"), "John Doe")); free (client_key); if (verbose) zcertstore_print (certstore); zcertstore_destroy (&certstore); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); // @end printf ("OK\n"); }
int main (void) { puts ("Creating new CURVE certificate"); zcert_t *cert = zcert_new (); if (s_get_meta (cert, "Enter your full name:", "name") || s_get_meta (cert, "Enter your email address:", "email") || s_get_meta (cert, "Enter your organization:", "organization")) return -1; char *timestr = zclock_timestr (); zcert_set_meta (cert, "created-by", "CZMQ makecert"); zcert_set_meta (cert, "date-created", timestr); free (timestr); zcert_dump (cert); zcert_save (cert, "mycert.txt"); puts ("I: CURVE certificate created in mycert.txt and mycert.txt_secret"); zcert_destroy (&cert); return 0; }
void curve_client_test (bool verbose) { printf (" * curve_client: "); // @selftest // Create temporary directory for test files zsys_dir_create (TESTDIR); // We'll create two new certificates and save the client public // certificate on disk; in a real case we'd transfer this securely // from the client machine to the server machine. zcert_t *server_cert = zcert_new (); zcert_save (server_cert, TESTDIR "/server.cert"); // We'll run the server as a background task, and the // client in this foreground thread. zthread_new (server_task, &verbose); zcert_t *client_cert = zcert_new (); zcert_save_public (client_cert, TESTDIR "/client.cert"); curve_client_t *client = curve_client_new (&client_cert); curve_client_set_metadata (client, "Client", "CURVEZMQ/curve_client"); curve_client_set_metadata (client, "Identity", "E475DA11"); curve_client_set_verbose (client, verbose); curve_client_connect (client, "tcp://127.0.0.1:9005", (byte *)zcert_public_key (server_cert)); curve_client_sendstr (client, "Hello, World"); char *reply = curve_client_recvstr (client); assert (streq (reply, "Hello, World")); free (reply); // Try a multipart message zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "Hello, World"); zmsg_addstr (msg, "Second frame"); curve_client_send (client, &msg); msg = curve_client_recv (client); assert (zmsg_size (msg) == 2); zmsg_destroy (&msg); // Now send messages of increasing size, check they work int count; int size = 0; for (count = 0; count < 18; count++) { if (verbose) printf ("Testing message of size=%d...\n", size); zframe_t *data = zframe_new (NULL, size); int byte_nbr; // Set data to sequence 0...255 repeated for (byte_nbr = 0; byte_nbr < size; byte_nbr++) zframe_data (data)[byte_nbr] = (byte) byte_nbr; msg = zmsg_new (); zmsg_prepend (msg, &data); curve_client_send (client, &msg); msg = curve_client_recv (client); data = zmsg_pop (msg); assert (data); assert (zframe_size (data) == size); for (byte_nbr = 0; byte_nbr < size; byte_nbr++) { assert (zframe_data (data)[byte_nbr] == (byte) byte_nbr); } zframe_destroy (&data); zmsg_destroy (&msg); size = size * 2 + 1; } // Signal end of test curve_client_sendstr (client, "END"); reply = curve_client_recvstr (client); free (reply); zcert_destroy (&server_cert); zcert_destroy (&client_cert); curve_client_destroy (&client); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end // Ensure server thread has exited before we do zclock_sleep (100); printf ("OK\n"); }
static void * server_task (void *args) { bool verbose = *((bool *) args); // Install the authenticator zctx_t *ctx = zctx_new (); zauth_t *auth = zauth_new (ctx); assert (auth); zauth_set_verbose (auth, verbose); zauth_configure_curve (auth, "*", TESTDIR); void *router = zsocket_new (ctx, ZMQ_ROUTER); int rc = zsocket_bind (router, "tcp://127.0.0.1:9005"); assert (rc != -1); zcert_t *server_cert = zcert_load (TESTDIR "/server.cert"); assert (server_cert); curve_codec_t *server = curve_codec_new_server (server_cert, ctx); assert (server); zcert_destroy (&server_cert); curve_codec_set_verbose (server, verbose); // Set some metadata properties curve_codec_set_metadata (server, "Server", "CURVEZMQ/curve_codec"); // Execute incoming frames until ready or exception // In practice we'd want a server instance per unique client while (!curve_codec_connected (server)) { zframe_t *sender = zframe_recv (router); zframe_t *input = zframe_recv (router); assert (input); zframe_t *output = curve_codec_execute (server, &input); assert (output); zframe_send (&sender, router, ZFRAME_MORE); zframe_send (&output, router, 0); } // Check client metadata char *client_name = (char *) zhash_lookup (curve_codec_metadata (server), "client"); assert (client_name); assert (streq (client_name, "CURVEZMQ/curve_client")); bool finished = false; while (!finished) { // Now act as echo service doing a full decode and encode zframe_t *sender = zframe_recv (router); zframe_t *encrypted = zframe_recv (router); assert (encrypted); zframe_t *cleartext = curve_codec_decode (server, &encrypted); assert (cleartext); if (memcmp (cleartext, "END", 3) == 0) finished = true; // Echo message back encrypted = curve_codec_encode (server, &cleartext); assert (encrypted); zframe_send (&sender, router, ZFRAME_MORE); zframe_send (&encrypted, router, 0); } curve_codec_destroy (&server); zauth_destroy (&auth); zctx_destroy (&ctx); return NULL; }
void certificate::reset(zcert_t* self) { if (self_) zcert_destroy(&self_); self_ = self; }
/// // Destroy a certificate in memory QZcert::~QZcert () { zcert_destroy (&self); }
/// // Destroy a certificate in memory void QmlZcertAttached::destruct (QmlZcert *qmlSelf) { zcert_destroy (&qmlSelf->self); };
void zyre_test (bool verbose) { printf (" * zyre: "); if (verbose) printf ("\n"); // @selftest // We'll use inproc gossip discovery so that this works without networking uint64_t version = zyre_version (); assert ((version / 10000) % 100 == ZYRE_VERSION_MAJOR); assert ((version / 100) % 100 == ZYRE_VERSION_MINOR); assert (version % 100 == ZYRE_VERSION_PATCH); // Create two nodes zyre_t *node1 = zyre_new ("node1"); assert (node1); assert (streq (zyre_name (node1), "node1")); zyre_set_header (node1, "X-HELLO", "World"); if (verbose) zyre_set_verbose (node1); // Set inproc endpoint for this node int rc = zyre_set_endpoint (node1, "inproc://zyre-node1"); assert (rc == 0); // Set up gossip network for this node zyre_gossip_bind (node1, "inproc://gossip-hub"); rc = zyre_start (node1); assert (rc == 0); zyre_t *node2 = zyre_new ("node2"); assert (node2); assert (streq (zyre_name (node2), "node2")); if (verbose) zyre_set_verbose (node2); // Set inproc endpoint for this node // First, try to use existing name, it'll fail rc = zyre_set_endpoint (node2, "inproc://zyre-node1"); assert (rc == -1); // Now use available name and confirm that it succeeds rc = zyre_set_endpoint (node2, "inproc://zyre-node2"); assert (rc == 0); // Set up gossip network for this node zyre_gossip_connect (node2, "inproc://gossip-hub"); rc = zyre_start (node2); assert (rc == 0); assert (strneq (zyre_uuid (node1), zyre_uuid (node2))); zyre_join (node1, "GLOBAL"); zyre_join (node2, "GLOBAL"); // Give time for them to interconnect zclock_sleep (250); if (verbose) zyre_dump (node1); zlist_t *peers = zyre_peers (node1); assert (peers); assert (zlist_size (peers) == 1); zlist_destroy (&peers); zyre_join (node1, "node1 group of one"); zyre_join (node2, "node2 group of one"); // Give them time to join their groups zclock_sleep (250); zlist_t *own_groups = zyre_own_groups (node1); assert (own_groups); assert (zlist_size (own_groups) == 2); zlist_destroy (&own_groups); zlist_t *peer_groups = zyre_peer_groups (node1); assert (peer_groups); assert (zlist_size (peer_groups) == 2); zlist_destroy (&peer_groups); char *value = zyre_peer_header_value (node2, zyre_uuid (node1), "X-HELLO"); assert (streq (value, "World")); zstr_free (&value); // One node shouts to GLOBAL zyre_shouts (node1, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT zmsg_t *msg = zyre_recv (node2); assert (msg); char *command = zmsg_popstr (msg); assert (streq (command, "ENTER")); zstr_free (&command); assert (zmsg_size (msg) == 4); char *peerid = zmsg_popstr (msg); char *name = zmsg_popstr (msg); assert (streq (name, "node1")); zstr_free (&name); zframe_t *headers_packed = zmsg_pop (msg); char *address = zmsg_popstr (msg); char *endpoint = zyre_peer_address (node2, peerid); assert (streq (address, endpoint)); zstr_free (&peerid); zstr_free (&endpoint); zstr_free (&address); assert (headers_packed); zhash_t *headers = zhash_unpack (headers_packed); assert (headers); zframe_destroy (&headers_packed); assert (streq ((char *) zhash_lookup (headers, "X-HELLO"), "World")); zhash_destroy (&headers); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); assert (zmsg_size (msg) == 3); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); assert (zmsg_size (msg) == 3); zmsg_destroy (&msg); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "SHOUT")); zstr_free (&command); zmsg_destroy (&msg); zyre_stop (node2); msg = zyre_recv (node2); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "STOP")); zstr_free (&command); zmsg_destroy (&msg); zyre_stop (node1); zyre_destroy (&node1); zyre_destroy (&node2); printf ("OK\n"); #ifdef ZYRE_BUILD_DRAFT_API if (zsys_has_curve()){ printf (" * zyre-curve: "); if (verbose) printf ("\n"); if (verbose) zsys_debug("----------------TESTING CURVE --------------"); zactor_t *speaker = zactor_new (zbeacon, NULL); assert (speaker); if (verbose) zstr_sendx (speaker, "VERBOSE", NULL); // ensuring we have a broadcast address zsock_send (speaker, "si", "CONFIGURE", 9999); char *hostname = zstr_recv (speaker); if (!*hostname) { printf ("OK (skipping test, no UDP broadcasting)\n"); zactor_destroy (&speaker); freen (hostname); return; } freen (hostname); zactor_destroy (&speaker); // zap setup zactor_t *auth = zactor_new(zauth, NULL); assert (auth); if (verbose) { zstr_sendx(auth, "VERBOSE", NULL); zsock_wait(auth); } zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait (auth); zyre_t *node3 = zyre_new ("node3"); zyre_t *node4 = zyre_new ("node4"); assert (node3); assert (node4); zyre_set_verbose (node3); zyre_set_verbose (node4); zyre_set_zap_domain(node3, "TEST"); zyre_set_zap_domain(node4, "TEST"); zsock_set_rcvtimeo(node3->inbox, 10000); zsock_set_rcvtimeo(node4->inbox, 10000); zcert_t *node3_cert = zcert_new (); zcert_t *node4_cert = zcert_new (); assert (node3_cert); assert (node4_cert); zyre_set_zcert(node3, node3_cert); zyre_set_zcert(node4, node4_cert); zyre_set_header(node3, "X-PUBLICKEY", "%s", zcert_public_txt(node3_cert)); zyre_set_header(node4, "X-PUBLICKEY", "%s", zcert_public_txt(node4_cert)); // test beacon if (verbose) zsys_debug ("----------------TESTING BEACON----------------"); rc = zyre_start(node3); assert (rc == 0); rc = zyre_start(node4); assert (rc == 0); zyre_join (node3, "GLOBAL"); zyre_join (node4, "GLOBAL"); zclock_sleep (1500); if (verbose) { zyre_dump (node3); zyre_dump (node4); } zyre_shouts (node3, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "ENTER")); zstr_free (&command); char *peerid = zmsg_popstr (msg); assert (peerid); name = zmsg_popstr (msg); assert (streq (name, "node3")); zmsg_destroy (&msg); msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "JOIN")); zstr_free (&command); zmsg_destroy(&msg); msg = zyre_recv (node4); assert (msg); command = zmsg_popstr (msg); assert (streq (command, "SHOUT")); zstr_free (&command); zmsg_destroy(&msg); zyre_leave(node3, "GLOBAL"); zyre_leave(node4, "GLOBAL"); zstr_free (&name); zstr_free (&peerid); zstr_free (&command); zyre_stop (node3); zyre_stop (node4); // give things a chance to settle... zclock_sleep (250); zyre_destroy(&node3); zyre_destroy(&node4); zcert_destroy(&node3_cert); zcert_destroy(&node4_cert); // test gossip if (verbose) zsys_debug ("----------------TESTING GOSSIP----------------"); zyre_t *node5 = zyre_new ("node5"); zyre_t *node6 = zyre_new ("node6"); assert (node5); assert (node6); if (verbose) { zyre_set_verbose (node5); zyre_set_verbose (node6); } // if it takes more than 10s, something probably went terribly wrong zsock_set_rcvtimeo(node5->inbox, 10000); zsock_set_rcvtimeo(node6->inbox, 10000); zcert_t *node5_cert = zcert_new (); zcert_t *node6_cert = zcert_new (); assert (node5_cert); assert (node6_cert); zyre_set_zcert(node5, node5_cert); zyre_set_zcert(node6, node6_cert); zyre_set_header(node5, "X-PUBLICKEY", "%s", zcert_public_txt(node5_cert)); zyre_set_header(node6, "X-PUBLICKEY", "%s", zcert_public_txt(node6_cert)); const char *gossip_cert = zcert_public_txt (node5_cert); // TODO- need to add zyre_gossip_port functions to get port from gossip bind(?) zyre_gossip_bind(node5, "tcp://127.0.0.1:9001"); zyre_gossip_connect_curve(node6, gossip_cert, "tcp://127.0.0.1:9001"); zyre_start(node5); zsock_wait(node5); zyre_start(node6); zsock_wait(node6); zyre_join (node5, "GLOBAL"); zyre_join (node6, "GLOBAL"); // give things a chance to settle... zclock_sleep (1500); if (verbose) { zyre_dump (node5); zyre_dump (node6); } zyre_shouts (node5, "GLOBAL", "Hello, World"); // Second node should receive ENTER, JOIN, and SHOUT msg = zyre_recv (node6); assert (msg); command = zmsg_popstr (msg); zsys_info(command); assert (streq (command, "ENTER")); zstr_free (&command); peerid = zmsg_popstr (msg); assert (peerid); name = zmsg_popstr (msg); zmsg_destroy (&msg); assert (streq (name, "node5")); zstr_free (&name); zyre_leave(node5, "GLOBAL"); zyre_leave(node6, "GLOBAL"); zyre_stop (node5); zyre_stop (node6); // give things a chance to settle... zclock_sleep (250); zstr_free (&peerid); zcert_destroy (&node5_cert); zcert_destroy (&node6_cert); zyre_destroy(&node5); zyre_destroy(&node6); zactor_destroy(&auth); printf ("OK\n"); } #endif }
// Authentication test procedure for zproxy sockets - matches zauth_test steps static void zproxy_test_authentication (int selected_sockets, bool verbose) { # define TESTDIR ".test_zproxy" # define TESTPWDS TESTDIR "/password-file" # define TESTCERT TESTDIR "/mycert.txt" # define TESTFRONTEND (selected_sockets & FRONTEND_SOCKET) # define TESTBACKEND (selected_sockets & BACKEND_SOCKET) // Demarcate test boundaries zsys_info ("zproxy: TEST authentication type=%s%s%s", TESTFRONTEND? "FRONTEND": "", TESTFRONTEND && TESTBACKEND? "+": "", TESTBACKEND? "BACKEND": ""); // Create temporary directory for test files zsys_dir_create (TESTDIR); // Clear out any test files from previous run if (zsys_file_exists (TESTPWDS)) zsys_file_delete (TESTPWDS); if (zsys_file_exists (TESTCERT)) zsys_file_delete (TESTCERT); zactor_t *proxy = NULL; zsock_t *faucet = NULL; zsock_t *sink = NULL; char *frontend = NULL; char *backend = NULL; // Check there's no authentication s_create_test_sockets (&proxy, &faucet, &sink, verbose); s_bind_proxy_sockets (proxy, &frontend, &backend); bool success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // Install the authenticator zactor_t *auth = zactor_new (zauth, NULL); assert (auth); if (verbose) { zstr_sendx (auth, "VERBOSE", NULL); zsock_wait (auth); } // Check there's no authentication on a default NULL server s_bind_proxy_sockets (proxy, &frontend, &backend); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // When we set a domain on the server, we switch on authentication // for NULL sockets, but with no policies, the client connection // will be allowed. s_send_proxy_command (proxy, "DOMAIN", selected_sockets, "global", NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // Blacklist 127.0.0.1, connection should fail s_send_proxy_command (proxy, "DOMAIN", selected_sockets, "global", NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); zstr_sendx (auth, "DENY", "127.0.0.1", NULL); zsock_wait (auth); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (!success); // Whitelist our address, which overrides the blacklist s_send_proxy_command (proxy, "DOMAIN", selected_sockets, "global", NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); zstr_sendx (auth, "ALLOW", "127.0.0.1", NULL); zsock_wait (auth); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // Try PLAIN authentication // Test negative case (no server-side passwords defined) s_send_proxy_command (proxy, "PLAIN", selected_sockets, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_plain_auth (faucet, sink, selected_sockets, "admin", "Password"); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (!success); // Test positive case (server-side passwords defined) FILE *password = fopen (TESTPWDS, "w"); assert (password); fprintf (password, "admin=Password\n"); fclose (password); s_send_proxy_command (proxy, "PLAIN", selected_sockets, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_plain_auth (faucet, sink, selected_sockets, "admin", "Password"); zstr_sendx (auth, "PLAIN", TESTPWDS, NULL); zsock_wait (auth); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // Test negative case (bad client password) s_send_proxy_command (proxy, "PLAIN", selected_sockets, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_plain_auth (faucet, sink, selected_sockets, "admin", "Bogus"); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (!success); if (zsys_has_curve ()) { // We'll create two new certificates and save the client public // certificate on disk zcert_t *server_cert = zcert_new (); assert (server_cert); zcert_t *client_cert = zcert_new (); assert (client_cert); char *public_key = zcert_public_txt (server_cert); char *secret_key = zcert_secret_txt (server_cert); // Try CURVE authentication // Test without setting-up any authentication s_send_proxy_command (proxy, "CURVE", selected_sockets, public_key, secret_key, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_curve_auth (faucet, sink, selected_sockets, client_cert, public_key); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (!success); // Test CURVE_ALLOW_ANY s_send_proxy_command (proxy, "CURVE", selected_sockets, public_key, secret_key, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_curve_auth (faucet, sink, selected_sockets, client_cert, public_key); zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait (auth); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); // Test with client certificate file in authentication folder s_send_proxy_command (proxy, "CURVE", selected_sockets, public_key, secret_key, NULL); s_bind_proxy_sockets (proxy, &frontend, &backend); s_configure_curve_auth (faucet, sink, selected_sockets, client_cert, public_key); zcert_save_public (client_cert, TESTCERT); zstr_sendx (auth, "CURVE", TESTDIR, NULL); zsock_wait (auth); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); zcert_destroy (&server_cert); zcert_destroy (&client_cert); } // Remove the authenticator and check a normal connection works zactor_destroy (&auth); s_bind_proxy_sockets (proxy, &frontend, &backend); success = s_can_connect (&proxy, &faucet, &sink, frontend, backend, verbose); assert (success); zsock_destroy (&faucet); zsock_destroy (&sink); zactor_destroy (&proxy); zstr_free (&frontend); zstr_free (&backend); }
static void * client_task (void *args) { bool verbose = *((bool *) args); char filename [256]; snprintf (filename, 255, TESTDIR "/client-%07d.cert", randof (10000000)); zcert_t *client_cert = zcert_new (); zcert_save_public (client_cert, filename); curve_client_t *client = curve_client_new (&client_cert); curve_client_set_verbose (client, verbose); zcert_t *server_cert = zcert_load (TESTDIR "/server.cert"); assert (server_cert); curve_client_connect (client, "tcp://127.0.0.1:9006", zcert_public_key (server_cert)); zcert_destroy (&server_cert); curve_client_sendstr (client, "Hello, World"); char *reply = curve_client_recvstr (client); assert (streq (reply, "Hello, World")); free (reply); // Try a multipart message zmsg_t *msg = zmsg_new (); zmsg_addstr (msg, "Hello, World"); zmsg_addstr (msg, "Second frame"); curve_client_send (client, &msg); msg = curve_client_recv (client); assert (zmsg_size (msg) == 2); zmsg_destroy (&msg); // Now send messages of increasing size, check they work int count; int size = 0; for (count = 0; count < 18; count++) { zframe_t *data = zframe_new (NULL, size); int byte_nbr; // Set data to sequence 0...255 repeated for (byte_nbr = 0; byte_nbr < size; byte_nbr++) zframe_data (data)[byte_nbr] = (byte) byte_nbr; msg = zmsg_new (); zmsg_prepend (msg, &data); curve_client_send (client, &msg); msg = curve_client_recv (client); data = zmsg_pop (msg); assert (data); assert (zframe_size (data) == size); for (byte_nbr = 0; byte_nbr < size; byte_nbr++) { assert (zframe_data (data)[byte_nbr] == (byte) byte_nbr); } zframe_destroy (&data); zmsg_destroy (&msg); size = size * 2 + 1; } // Signal end of test curve_client_sendstr (client, "END"); reply = curve_client_recvstr (client); free (reply); curve_client_destroy (&client); return NULL; }
void zgossip_test (bool verbose) { printf (" * zgossip: "); if (verbose) printf ("\n"); // @selftest // Test basic client-to-server operation of the protocol zactor_t *server = zactor_new (zgossip, "server"); assert (server); if (verbose) zstr_send (server, "VERBOSE"); zstr_sendx (server, "BIND", "inproc://zgossip", NULL); zsock_t *client = zsock_new (ZMQ_DEALER); assert (client); zsock_set_rcvtimeo (client, 2000); int rc = zsock_connect (client, "inproc://zgossip"); assert (rc == 0); // Send HELLO, which gets no message zgossip_msg_t *message = zgossip_msg_new (); zgossip_msg_set_id (message, ZGOSSIP_MSG_HELLO); zgossip_msg_send (message, client); // Send PING, expect PONG back zgossip_msg_set_id (message, ZGOSSIP_MSG_PING); zgossip_msg_send (message, client); zgossip_msg_recv (message, client); assert (zgossip_msg_id (message) == ZGOSSIP_MSG_PONG); zgossip_msg_destroy (&message); zactor_destroy (&server); zsock_destroy (&client); // Test peer-to-peer operations zactor_t *base = zactor_new (zgossip, "base"); assert (base); if (verbose) zstr_send (base, "VERBOSE"); // Set a 100msec timeout on clients so we can test expiry zstr_sendx (base, "SET", "server/timeout", "100", NULL); zstr_sendx (base, "BIND", "inproc://base", NULL); zactor_t *alpha = zactor_new (zgossip, "alpha"); assert (alpha); zstr_sendx (alpha, "CONNECT", "inproc://base", NULL); zstr_sendx (alpha, "PUBLISH", "inproc://alpha-1", "service1", NULL); zstr_sendx (alpha, "PUBLISH", "inproc://alpha-2", "service2", NULL); zactor_t *beta = zactor_new (zgossip, "beta"); assert (beta); zstr_sendx (beta, "CONNECT", "inproc://base", NULL); zstr_sendx (beta, "PUBLISH", "inproc://beta-1", "service1", NULL); zstr_sendx (beta, "PUBLISH", "inproc://beta-2", "service2", NULL); // got nothing zclock_sleep (200); zstr_send (alpha, "STATUS"); char *command, *status, *key, *value; zstr_recvx (alpha, &command, &key, &value, NULL); assert (streq (command, "DELIVER")); assert (streq (key, "inproc://alpha-1")); assert (streq (value, "service1")); zstr_free (&command); zstr_free (&key); zstr_free (&value); zstr_recvx (alpha, &command, &key, &value, NULL); assert (streq (command, "DELIVER")); assert (streq (key, "inproc://alpha-2")); assert (streq (value, "service2")); zstr_free (&command); zstr_free (&key); zstr_free (&value); zstr_recvx (alpha, &command, &key, &value, NULL); assert (streq (command, "DELIVER")); assert (streq (key, "inproc://beta-1")); assert (streq (value, "service1")); zstr_free (&command); zstr_free (&key); zstr_free (&value); zstr_recvx (alpha, &command, &key, &value, NULL); assert (streq (command, "DELIVER")); assert (streq (key, "inproc://beta-2")); assert (streq (value, "service2")); zstr_free (&command); zstr_free (&key); zstr_free (&value); zstr_recvx (alpha, &command, &status, NULL); assert (streq (command, "STATUS")); assert (atoi (status) == 4); zstr_free (&command); zstr_free (&status); zactor_destroy (&base); zactor_destroy (&alpha); zactor_destroy (&beta); #ifdef CZMQ_BUILD_DRAFT_API // DRAFT-API: Security // curve if (zsys_has_curve()) { if (verbose) printf("testing CURVE support"); zclock_sleep (2000); zactor_t *auth = zactor_new(zauth, NULL); assert (auth); if (verbose) { zstr_sendx (auth, "VERBOSE", NULL); zsock_wait (auth); } zstr_sendx(auth,"ALLOW","127.0.0.1",NULL); zsock_wait(auth); zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait (auth); server = zactor_new (zgossip, "server"); if (verbose) zstr_send (server, "VERBOSE"); assert (server); zcert_t *client1_cert = zcert_new (); zcert_t *server_cert = zcert_new (); zstr_sendx (server, "SET PUBLICKEY", zcert_public_txt (server_cert), NULL); zstr_sendx (server, "SET SECRETKEY", zcert_secret_txt (server_cert), NULL); zstr_sendx (server, "ZAP DOMAIN", "TEST", NULL); zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL); zstr_sendx (server, "PORT", NULL); zstr_recvx (server, &command, &value, NULL); assert (streq (command, "PORT")); int port = atoi (value); zstr_free (&command); zstr_free (&value); char endpoint [32]; sprintf (endpoint, "tcp://127.0.0.1:%d", port); zactor_t *client1 = zactor_new (zgossip, "client"); if (verbose) zstr_send (client1, "VERBOSE"); assert (client1); zstr_sendx (client1, "SET PUBLICKEY", zcert_public_txt (client1_cert), NULL); zstr_sendx (client1, "SET SECRETKEY", zcert_secret_txt (client1_cert), NULL); zstr_sendx (client1, "ZAP DOMAIN", "TEST", NULL); const char *public_txt = zcert_public_txt (server_cert); zstr_sendx (client1, "CONNECT", endpoint, public_txt, NULL); zstr_sendx (client1, "PUBLISH", "tcp://127.0.0.1:9001", "service1", NULL); zclock_sleep (500); zstr_send (server, "STATUS"); zclock_sleep (500); zstr_recvx (server, &command, &key, &value, NULL); assert (streq (command, "DELIVER")); assert (streq (value, "service1")); zstr_free (&command); zstr_free (&key); zstr_free (&value); zstr_sendx (client1, "$TERM", NULL); zstr_sendx (server, "$TERM", NULL); zclock_sleep(500); zcert_destroy (&client1_cert); zcert_destroy (&server_cert); zactor_destroy (&client1); zactor_destroy (&server); zactor_destroy (&auth); } #endif #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
int zauth_test (bool verbose) { printf (" * zauth: "); #if (ZMQ_VERSION_MAJOR == 4) // @selftest // Create temporary directory for test files # define TESTDIR ".test_zauth" zsys_dir_create (TESTDIR); // Install the authenticator zctx_t *ctx = zctx_new (); zauth_t *auth = zauth_new (ctx); assert (auth); zauth_set_verbose (auth, verbose); // A default NULL connection should always success, and not go through // our authentication infrastructure at all. void *server = zsocket_new (ctx, ZMQ_PUSH); void *client = zsocket_new (ctx, ZMQ_PULL); bool success = s_can_connect (server, client); assert (success); // When we set a domain on the server, we switch on authentication // for NULL sockets, but with no policies, the client connection will // be allowed. // // TODO: libzmq should accept new security options after unbind/bind // but for now we have to create a new server socket each time. server = zsocket_new (ctx, ZMQ_PUSH); zsocket_set_zap_domain (server, "global"); success = s_can_connect (server, client); assert (success); // Blacklist 127.0.0.1, connection should fail zauth_deny (auth, "127.0.0.1"); success = s_can_connect (server, client); assert (!success); // Whitelist our address, which overrides the blacklist zauth_allow (auth, "127.0.0.1"); success = s_can_connect (server, client); assert (success); // Try PLAIN authentication FILE *password = fopen (TESTDIR "/password-file", "w"); assert (password); fprintf (password, "admin=Password\n"); fclose (password); zsocket_set_plain_server (server, 1); zsocket_set_plain_username (client, "admin"); zsocket_set_plain_password (client, "Password"); success = s_can_connect (server, client); assert (!success); zauth_configure_plain (auth, "*", TESTDIR "/password-file"); success = s_can_connect (server, client); assert (success); zsocket_set_plain_password (client, "Bogus"); success = s_can_connect (server, client); assert (!success); # if defined (HAVE_LIBSODIUM) // Try CURVE authentication // We'll create two new certificates and save the client public // certificate on disk; in a real case we'd transfer this securely // from the client machine to the server machine. zcert_t *server_cert = zcert_new (); zcert_apply (server_cert, server); zsocket_set_curve_server (server, 1); zcert_t *client_cert = zcert_new (); zcert_apply (client_cert, client); char *server_key = zcert_public_txt (server_cert); zsocket_set_curve_serverkey (client, server_key); // We've not set-up any authentication, connection will fail success = s_can_connect (server, client); assert (!success); // PH: 2013/09/18 // There's an issue with libzmq where it sometimes fails to // connect even if the ZAP handler allows it. It's timing // dependent, so this is a voodoo hack. To be removed, I've // no idea this even applies to all boxes. sleep (1); // Test CURVE_ALLOW_ANY zauth_configure_curve (auth, "*", CURVE_ALLOW_ANY); success = s_can_connect (server, client); assert (success); // Test full client authentication using certificates zcert_save_public (client_cert, TESTDIR "/mycert.txt"); zauth_configure_curve (auth, "*", TESTDIR); success = s_can_connect (server, client); assert (success); zcert_destroy (&server_cert); zcert_destroy (&client_cert); # endif // Remove the authenticator and check a normal connection works zauth_destroy (&auth); success = s_can_connect (server, client); assert (success); zctx_destroy (&ctx); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end #endif printf ("OK\n"); return 0; }
void zcertstore_test (bool verbose) { printf (" * zcertstore: "); if (verbose) printf ("\n"); // @selftest const char *SELFTEST_DIR_RW = "src/selftest-rw"; const char *testbasedir = ".test_zcertstore"; const char *testfile = "mycert.txt"; char *basedirpath = NULL; // subdir in a test, under SELFTEST_DIR_RW char *filepath = NULL; // pathname to testfile in a test, in dirpath basedirpath = zsys_sprintf ("%s/%s", SELFTEST_DIR_RW, testbasedir); assert (basedirpath); filepath = zsys_sprintf ("%s/%s", basedirpath, testfile); assert (filepath); // Make sure old aborted tests do not hinder us zdir_t *dir = zdir_new (basedirpath, NULL); if (dir) { zdir_remove (dir, true); zdir_destroy (&dir); } zsys_file_delete (filepath); zsys_dir_delete (basedirpath); // Create temporary directory for test files zsys_dir_create (basedirpath); // Load certificate store from disk; it will be empty zcertstore_t *certstore = zcertstore_new (basedirpath); assert (certstore); // Create a single new certificate and save to disk zcert_t *cert = zcert_new (); assert (cert); char *client_key = strdup (zcert_public_txt (cert)); assert (client_key); zcert_set_meta (cert, "name", "John Doe"); zcert_save (cert, filepath); zcert_destroy (&cert); // Check that certificate store refreshes as expected cert = zcertstore_lookup (certstore, client_key); assert (cert); assert (streq (zcert_meta (cert, "name"), "John Doe")); #ifdef CZMQ_BUILD_DRAFT_API // DRAFT-API: Security // Iterate through certs zlistx_t *certs = zcertstore_certs(certstore); cert = (zcert_t *) zlistx_first(certs); int cert_count = 0; while (cert) { assert (streq (zcert_meta (cert, "name"), "John Doe")); cert = (zcert_t *) zlistx_next(certs); cert_count++; } assert(cert_count==1); zlistx_destroy(&certs); #endif // Test custom loader test_loader_state *state = (test_loader_state *) zmalloc (sizeof (test_loader_state)); state->index = 0; zcertstore_set_loader (certstore, s_test_loader, s_test_destructor, (void *)state); #if (ZMQ_VERSION_MAJOR >= 4) cert = zcertstore_lookup (certstore, client_key); assert (cert == NULL); cert = zcertstore_lookup (certstore, "abcdefghijklmnopqrstuvwxyzabcdefghijklmn"); assert (cert); #endif freen (client_key); if (verbose) zcertstore_print (certstore); zcertstore_destroy (&certstore); // Delete all test files dir = zdir_new (basedirpath, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); zstr_free (&basedirpath); zstr_free (&filepath); #if defined (__WINDOWS__) zsys_shutdown(); #endif // @end printf ("OK\n"); }
int zauth_test (bool verbose) { printf (" * zauth: "); #if (ZMQ_VERSION_MAJOR == 4) // @selftest // Create temporary directory for test files # define TESTDIR ".test_zauth" zsys_dir_create (TESTDIR); // Install the authenticator zctx_t *ctx = zctx_new (); zauth_t *auth = zauth_new (ctx); assert (auth); zauth_set_verbose (auth, verbose); // A default NULL connection should always success, and not // go through our authentication infrastructure at all. void *server = zsocket_new (ctx, ZMQ_PUSH); void *client = zsocket_new (ctx, ZMQ_PULL); bool success = s_can_connect (ctx, &server, &client); assert (success); // When we set a domain on the server, we switch on authentication // for NULL sockets, but with no policies, the client connection // will be allowed. zsocket_set_zap_domain (server, "global"); success = s_can_connect (ctx, &server, &client); assert (success); // Blacklist 127.0.0.1, connection should fail zsocket_set_zap_domain (server, "global"); zauth_deny (auth, "127.0.0.1"); success = s_can_connect (ctx, &server, &client); assert (!success); // Whitelist our address, which overrides the blacklist zsocket_set_zap_domain (server, "global"); zauth_allow (auth, "127.0.0.1"); success = s_can_connect (ctx, &server, &client); assert (success); // Try PLAIN authentication zsocket_set_plain_server (server, 1); zsocket_set_plain_username (client, "admin"); zsocket_set_plain_password (client, "Password"); success = s_can_connect (ctx, &server, &client); assert (!success); FILE *password = fopen (TESTDIR "/password-file", "w"); assert (password); fprintf (password, "admin=Password\n"); fclose (password); zsocket_set_plain_server (server, 1); zsocket_set_plain_username (client, "admin"); zsocket_set_plain_password (client, "Password"); zauth_configure_plain (auth, "*", TESTDIR "/password-file"); success = s_can_connect (ctx, &server, &client); assert (success); zsocket_set_plain_server (server, 1); zsocket_set_plain_username (client, "admin"); zsocket_set_plain_password (client, "Bogus"); success = s_can_connect (ctx, &server, &client); assert (!success); # if defined (HAVE_LIBSODIUM) // Try CURVE authentication // We'll create two new certificates and save the client public // certificate on disk; in a real case we'd transfer this securely // from the client machine to the server machine. zcert_t *server_cert = zcert_new (); zcert_t *client_cert = zcert_new (); char *server_key = zcert_public_txt (server_cert); // Test without setting-up any authentication zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsocket_set_curve_server (server, 1); zsocket_set_curve_serverkey (client, server_key); success = s_can_connect (ctx, &server, &client); assert (!success); // Test CURVE_ALLOW_ANY zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsocket_set_curve_server (server, 1); zsocket_set_curve_serverkey (client, server_key); zauth_configure_curve (auth, "*", CURVE_ALLOW_ANY); success = s_can_connect (ctx, &server, &client); assert (success); // Test full client authentication using certificates zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsocket_set_curve_server (server, 1); zsocket_set_curve_serverkey (client, server_key); zcert_save_public (client_cert, TESTDIR "/mycert.txt"); zauth_configure_curve (auth, "*", TESTDIR); success = s_can_connect (ctx, &server, &client); assert (success); zcert_destroy (&server_cert); zcert_destroy (&client_cert); # endif // Remove the authenticator and check a normal connection works zauth_destroy (&auth); success = s_can_connect (ctx, &server, &client); assert (success); zctx_destroy (&ctx); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); zdir_remove (dir, true); zdir_destroy (&dir); // @end #endif printf ("OK\n"); return 0; }
static rsRetVal addListener(instanceConf_t* iconf){ DEFiRet; DBGPRINTF("imczmq: addListener called..\n"); struct listener_t* pData; CHKmalloc(pData=(struct listener_t*)MALLOC(sizeof(struct listener_t))); pData->ruleset = iconf->pBindRuleset; pData->sock = zsock_new(iconf->sockType); if(!pData->sock) { errmsg.LogError(0, RS_RET_NO_ERRCODE, "imczmq: new socket failed for endpoints: %s", iconf->sockEndpoints); ABORT_FINALIZE(RS_RET_NO_ERRCODE); } DBGPRINTF("imczmq: created socket of type %d..\n", iconf->sockType); if(runModConf->authType) { if(!strcmp(runModConf->authType, "CURVESERVER")) { DBGPRINTF("imczmq: we are a CURVESERVER\n"); zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if(!serverCert) { errmsg.LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } zsock_set_zap_domain(pData->sock, "global"); zsock_set_curve_server(pData->sock, 1); zcert_apply(serverCert, pData->sock); zcert_destroy(&serverCert); } else if(!strcmp(runModConf->authType, "CURVECLIENT")) { DBGPRINTF("imczmq: we are a CURVECLIENT\n"); zcert_t *serverCert = zcert_load(runModConf->serverCertPath); if(!serverCert) { errmsg.LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->serverCertPath); ABORT_FINALIZE(RS_RET_ERR); } const char *server_key = zcert_public_txt(serverCert); zcert_destroy(&serverCert); zsock_set_curve_serverkey(pData->sock, server_key); zcert_t *clientCert = zcert_load(runModConf->clientCertPath); if(!clientCert) { errmsg.LogError(0, NO_ERRCODE, "could not load cert %s", runModConf->clientCertPath); ABORT_FINALIZE(RS_RET_ERR); } zcert_apply(clientCert, pData->sock); zcert_destroy(&clientCert); } } switch(iconf->sockType) { case ZMQ_SUB: #if defined(ZMQ_DISH) case ZMQ_DISH: #endif iconf->serverish = true; break; case ZMQ_PULL: #if defined(ZMQ_GATHER) case ZMQ_GATHER: #endif case ZMQ_ROUTER: #if defined(ZMQ_SERVER) case ZMQ_SERVER: #endif iconf->serverish = true; break; } if(iconf->topics) { char topic[256]; while(*iconf->topics) { char *delimiter = strchr(iconf->topics, ','); if(!delimiter) { delimiter = iconf->topics + strlen(iconf->topics); } memcpy (topic, iconf->topics, delimiter - iconf->topics); topic[delimiter-iconf->topics] = 0; DBGPRINTF("imczmq: subscribing to %s\n", topic); if(iconf->sockType == ZMQ_SUB) { zsock_set_subscribe (pData->sock, topic); } #if defined(ZMQ_DISH) else if(iconf->sockType == ZMQ_DISH) { int rc = zsock_join (pData->sock, topic); if(rc != 0) { errmsg.LogError(0, NO_ERRCODE, "could not join group %s", topic); ABORT_FINALIZE(RS_RET_ERR); } } #endif if(*delimiter == 0) { break; } iconf->topics = delimiter + 1; } } int rc = zsock_attach(pData->sock, (const char*)iconf->sockEndpoints, iconf->serverish); if (rc == -1) { errmsg.LogError(0, NO_ERRCODE, "zsock_attach to %s failed", iconf->sockEndpoints); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: attached socket to %s\n", iconf->sockEndpoints); rc = zlist_append(listenerList, (void *)pData); if(rc != 0) { errmsg.LogError(0, NO_ERRCODE, "could not append listener"); ABORT_FINALIZE(RS_RET_ERR); } finalize_it: RETiRet; }
void zauth_test (bool verbose) { printf (" * zauth: "); #if (ZMQ_VERSION_MAJOR == 4) if (verbose) printf ("\n"); // @selftest // Create temporary directory for test files # define TESTDIR ".test_zauth" zsys_dir_create (TESTDIR); // Check there's no authentication zsock_t *server = zsock_new (ZMQ_PUSH); assert (server); zsock_t *client = zsock_new (ZMQ_PULL); assert (client); bool success = s_can_connect (&server, &client); assert (success); // Install the authenticator zactor_t *auth = zactor_new (zauth, NULL); assert (auth); if (verbose) { zstr_sendx (auth, "VERBOSE", NULL); zsock_wait (auth); } // Check there's no authentication on a default NULL server success = s_can_connect (&server, &client); assert (success); // When we set a domain on the server, we switch on authentication // for NULL sockets, but with no policies, the client connection // will be allowed. zsock_set_zap_domain (server, "global"); success = s_can_connect (&server, &client); assert (success); // Blacklist 127.0.0.1, connection should fail zsock_set_zap_domain (server, "global"); zstr_sendx (auth, "DENY", "127.0.0.1", NULL); zsock_wait (auth); success = s_can_connect (&server, &client); assert (!success); // Whitelist our address, which overrides the blacklist zsock_set_zap_domain (server, "global"); zstr_sendx (auth, "ALLOW", "127.0.0.1", NULL); zsock_wait (auth); success = s_can_connect (&server, &client); assert (success); // Try PLAIN authentication zsock_set_plain_server (server, 1); zsock_set_plain_username (client, "admin"); zsock_set_plain_password (client, "Password"); success = s_can_connect (&server, &client); assert (!success); FILE *password = fopen (TESTDIR "/password-file", "w"); assert (password); fprintf (password, "admin=Password\n"); fclose (password); zsock_set_plain_server (server, 1); zsock_set_plain_username (client, "admin"); zsock_set_plain_password (client, "Password"); zstr_sendx (auth, "PLAIN", TESTDIR "/password-file", NULL); zsock_wait (auth); success = s_can_connect (&server, &client); assert (success); zsock_set_plain_server (server, 1); zsock_set_plain_username (client, "admin"); zsock_set_plain_password (client, "Bogus"); success = s_can_connect (&server, &client); assert (!success); if (zsys_has_curve ()) { // Try CURVE authentication // We'll create two new certificates and save the client public // certificate on disk; in a real case we'd transfer this securely // from the client machine to the server machine. zcert_t *server_cert = zcert_new (); assert (server_cert); zcert_t *client_cert = zcert_new (); assert (client_cert); char *server_key = zcert_public_txt (server_cert); // Test without setting-up any authentication zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsock_set_curve_server (server, 1); zsock_set_curve_serverkey (client, server_key); success = s_can_connect (&server, &client); assert (!success); // Test CURVE_ALLOW_ANY zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsock_set_curve_server (server, 1); zsock_set_curve_serverkey (client, server_key); zstr_sendx (auth, "CURVE", CURVE_ALLOW_ANY, NULL); zsock_wait (auth); success = s_can_connect (&server, &client); assert (success); // Test full client authentication using certificates zcert_apply (server_cert, server); zcert_apply (client_cert, client); zsock_set_curve_server (server, 1); zsock_set_curve_serverkey (client, server_key); zcert_save_public (client_cert, TESTDIR "/mycert.txt"); zstr_sendx (auth, "CURVE", TESTDIR, NULL); zsock_wait (auth); success = s_can_connect (&server, &client); assert (success); zcert_destroy (&server_cert); zcert_destroy (&client_cert); } // Remove the authenticator and check a normal connection works zactor_destroy (&auth); success = s_can_connect (&server, &client); assert (success); zsock_destroy (&client); zsock_destroy (&server); // Delete all test files zdir_t *dir = zdir_new (TESTDIR, NULL); assert (dir); zdir_remove (dir, true); zdir_destroy (&dir); // @end #endif printf ("OK\n"); }
static rsRetVal rcvData(){ DEFiRet; if(!listenerList) { listenerList = zlist_new(); if(!listenerList) { errmsg.LogError(0, NO_ERRCODE, "could not allocate list"); ABORT_FINALIZE(RS_RET_ERR); } } zactor_t *authActor; zcert_t *serverCert; if(runModConf->authenticator == 1) { authActor = zactor_new(zauth, NULL); zstr_sendx(authActor, "CURVE", runModConf->clientCertPath, NULL); zsock_wait(authActor); } instanceConf_t *inst; for(inst = runModConf->root; inst != NULL; inst=inst->next) { CHKiRet(addListener(inst)); } zpoller_t *poller = zpoller_new(NULL); if(!poller) { errmsg.LogError(0, NO_ERRCODE, "could not create poller"); ABORT_FINALIZE(RS_RET_ERR); } DBGPRINTF("imczmq: created poller\n"); struct listener_t *pData; pData = zlist_first(listenerList); if(!pData) { errmsg.LogError(0, NO_ERRCODE, "imczmq: no listeners were " "started, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } while(pData) { int rc = zpoller_add(poller, pData->sock); if(rc != 0) { errmsg.LogError(0, NO_ERRCODE, "imczmq: could not add " "socket to poller, input not activated.\n"); ABORT_FINALIZE(RS_RET_NO_RUN); } pData = zlist_next(listenerList); } zframe_t *frame; zsock_t *which = (zsock_t *)zpoller_wait(poller, -1); while(which) { if (zpoller_terminated(poller)) { break; } pData = zlist_first(listenerList); while(pData->sock != which) { pData = zlist_next(listenerList); } if(which == pData->sock) { DBGPRINTF("imczmq: found matching socket\n"); } frame = zframe_recv(which); char *buf = zframe_strdup(frame); if(buf == NULL) { DBGPRINTF("imczmq: null buffer\n"); continue; } smsg_t *pMsg; if(msgConstruct(&pMsg) == RS_RET_OK) { MsgSetRawMsg(pMsg, buf, strlen(buf)); MsgSetInputName(pMsg, s_namep); MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())); MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp()); MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP()); MsgSetMSGoffs(pMsg, 0); MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY); MsgSetRuleset(pMsg, pData->ruleset); pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME; submitMsg2(pMsg); } free(buf); which = (zsock_t *)zpoller_wait(poller, -1); } finalize_it: zframe_destroy(&frame); zpoller_destroy(&poller); pData = zlist_first(listenerList); while(pData) { zsock_destroy(&pData->sock); free(pData->ruleset); pData = zlist_next(listenerList); } zlist_destroy(&listenerList); zactor_destroy(&authActor); zcert_destroy(&serverCert); RETiRet; }