diff --git a/.gitignore b/.gitignore index 962f6643..6efc1c26 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ tests/test_srcfd tests/test_stream_disconnect tests/test_proxy_chain tests/test_bind_src_address +tests/test_metadata tests/test*.log tests/test*.trs src/platform.hpp* diff --git a/doc/zmq_msg_gets.txt b/doc/zmq_msg_gets.txt index 7b00fad5..5d6b3de6 100644 --- a/doc/zmq_msg_gets.txt +++ b/doc/zmq_msg_gets.txt @@ -37,9 +37,14 @@ The requested _property_ is unknown. EXAMPLE ------- -.To be done +.Getting the ZAP authenticated user id for a message: ---- -zmq_msg_t frame; +zmq_msg_t msg; +zmq_msg_init (&msg); +rc = zmq_msg_recv (&msg, dealer, 0); +assert (rc != -1); +char *user_id = zmq_msg_gets (&msg, "User-Id"); +zmq_msg_close (&msg); ---- diff --git a/src/curve_client.cpp b/src/curve_client.cpp index 4a0ef845..c02277d7 100644 --- a/src/curve_client.cpp +++ b/src/curve_client.cpp @@ -336,8 +336,7 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_) if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER || options.type == ZMQ_ROUTER) - ptr += add_property (ptr, "Identity", - options.identity, options.identity_size); + ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t mlen = ptr - initiate_plaintext; diff --git a/src/curve_server.cpp b/src/curve_server.cpp index cbf19d78..4badef05 100644 --- a/src/curve_server.cpp +++ b/src/curve_server.cpp @@ -497,8 +497,7 @@ int zmq::curve_server_t::produce_ready (msg_t *msg_) if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER || options.type == ZMQ_ROUTER) - ptr += add_property (ptr, "Identity", - options.identity, options.identity_size); + ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t mlen = ptr - ready_plaintext; diff --git a/src/gssapi_mechanism_base.cpp b/src/gssapi_mechanism_base.cpp index 647200f6..e51481c9 100644 --- a/src/gssapi_mechanism_base.cpp +++ b/src/gssapi_mechanism_base.cpp @@ -271,10 +271,8 @@ int zmq::gssapi_mechanism_base_t::produce_ready (msg_t *msg_) // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER - || options.type == ZMQ_ROUTER) { - ptr += add_property (ptr, "Identity", - options.identity, options.identity_size); - } + || options.type == ZMQ_ROUTER) + ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t command_size = ptr - command_buffer; const int rc = msg_->init_size (command_size); diff --git a/src/mechanism.cpp b/src/mechanism.cpp index 06247add..dc1ab829 100644 --- a/src/mechanism.cpp +++ b/src/mechanism.cpp @@ -50,6 +50,9 @@ void zmq::mechanism_t::peer_identity (msg_t *msg_) void zmq::mechanism_t::set_user_id (const void *data_, size_t size_) { user_id = blob_t (static_cast (data_), size_); + zap_properties.insert ( + metadata_t::dict_t::value_type ( + "User-Id", std::string ((char *) data_, size_))); } zmq::blob_t zmq::mechanism_t::get_user_id () const @@ -125,7 +128,6 @@ int zmq::mechanism_t::parse_metadata (const unsigned char *ptr_, if (rc == -1) return -1; } - if (zap_flag) zap_properties.insert ( metadata_t::dict_t::value_type ( diff --git a/src/plain_mechanism.cpp b/src/plain_mechanism.cpp index f6f6413e..ae1def48 100644 --- a/src/plain_mechanism.cpp +++ b/src/plain_mechanism.cpp @@ -279,10 +279,8 @@ int zmq::plain_mechanism_t::produce_initiate (msg_t *msg_) const // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER - || options.type == ZMQ_ROUTER) { - ptr += add_property (ptr, "Identity", - options.identity, options.identity_size); - } + || options.type == ZMQ_ROUTER) + ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t command_size = ptr - command_buffer; const int rc = msg_->init_size (command_size); @@ -327,10 +325,8 @@ int zmq::plain_mechanism_t::produce_ready (msg_t *msg_) const // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER - || options.type == ZMQ_ROUTER) { - ptr += add_property (ptr, "Identity", - options.identity, options.identity_size); - } + || options.type == ZMQ_ROUTER) + ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t command_size = ptr - command_buffer; const int rc = msg_->init_size (command_size); diff --git a/src/stream_engine.cpp b/src/stream_engine.cpp index 1d5c62e0..b7d40e8a 100644 --- a/src/stream_engine.cpp +++ b/src/stream_engine.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include "stream_engine.hpp" #include "io_thread.hpp" @@ -741,14 +742,6 @@ void zmq::stream_engine_t::mechanism_ready () properties_t properties; properties_t::const_iterator it; - // Add ZAP properties. - const properties_t& zap_properties = mechanism->get_zap_properties (); - it = zap_properties.begin (); - while (it != zap_properties.end ()) { - properties.insert (properties_t::value_type (it->first, it->second)); - it++; - } - // Add ZMTP properties. const properties_t& zmtp_properties = mechanism->get_zmtp_properties (); it = zmtp_properties.begin (); @@ -757,6 +750,14 @@ void zmq::stream_engine_t::mechanism_ready () it++; } + // Add ZAP properties. + const properties_t& zap_properties = mechanism->get_zap_properties (); + it = zap_properties.begin (); + while (it != zap_properties.end ()) { + properties.insert (properties_t::value_type (it->first, it->second)); + it++; + } + zmq_assert (metadata == NULL); if (!properties.empty ()) metadata = new (std::nothrow) metadata_t (properties); diff --git a/tests/Makefile.am b/tests/Makefile.am index e8856fff..ffbfcb7f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,7 +14,6 @@ noinst_PROGRAMS = test_system \ test_invalid_rep \ test_msg_flags \ test_connect_resolve \ - test_bind_src_address \ test_immediate \ test_last_endpoint \ test_term_endpoint \ @@ -48,7 +47,9 @@ noinst_PROGRAMS = test_system \ test_many_sockets \ test_ipc_wildcard \ test_diffserv \ - test_connect_rid + test_connect_rid \ + test_bind_src_address \ + test_metadata if !ON_MINGW noinst_PROGRAMS += test_shutdown_stress \ @@ -116,6 +117,7 @@ test_ipc_wildcard_SOURCES = test_ipc_wildcard.cpp test_diffserv_SOURCES = test_diffserv.cpp test_connect_rid_SOURCES = test_connect_rid.cpp test_bind_src_address_SOURCES = test_bind_src_address.cpp +test_metadata_SOURCES = test_metadata.cpp if !ON_MINGW test_shutdown_stress_SOURCES = test_shutdown_stress.cpp test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp diff --git a/tests/test_metadata.cpp b/tests/test_metadata.cpp new file mode 100644 index 00000000..4d8538b2 --- /dev/null +++ b/tests/test_metadata.cpp @@ -0,0 +1,116 @@ +/* + Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + + 0MQ is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 0MQ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "testutil.hpp" + +static void +zap_handler (void *handler) +{ + uint8_t metadata [] = { + 5, 'H', 'e', 'l', 'l', 'o', + 0, 0, 0, 5, 'W', 'o', 'r', 'l', 'd' + }; + + // Process ZAP requests forever + while (true) { + char *version = s_recv (handler); + if (!version) + break; // Terminating + + char *sequence = s_recv (handler); + char *domain = s_recv (handler); + char *address = s_recv (handler); + char *identity = s_recv (handler); + char *mechanism = s_recv (handler); + + assert (streq (version, "1.0")); + assert (streq (mechanism, "NULL")); + + s_sendmore (handler, version); + s_sendmore (handler, sequence); + if (streq (domain, "DOMAIN")) { + s_sendmore (handler, "200"); + s_sendmore (handler, "OK"); + s_sendmore (handler, "anonymous"); + zmq_send (handler, metadata, sizeof (metadata), 0); + } + else { + s_sendmore (handler, "400"); + s_sendmore (handler, "BAD DOMAIN"); + s_sendmore (handler, ""); + s_send (handler, ""); + } + free (version); + free (sequence); + free (domain); + free (address); + free (identity); + free (mechanism); + } + close_zero_linger (handler); +} + +int main (void) +{ + setup_test_environment(); + void *ctx = zmq_ctx_new (); + assert (ctx); + + // Spawn ZAP handler + // We create and bind ZAP socket in main thread to avoid case + // where child thread does not start up fast enough. + void *handler = zmq_socket (ctx, ZMQ_REP); + assert (handler); + int rc = zmq_bind (handler, "inproc://zeromq.zap.01"); + assert (rc == 0); + void *zap_thread = zmq_threadstart (&zap_handler, handler); + + void *server = zmq_socket (ctx, ZMQ_DEALER); + assert (server); + void *client = zmq_socket (ctx, ZMQ_DEALER); + assert (client); + rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "DOMAIN", 6); + assert (rc == 0); + rc = zmq_bind (server, "tcp://127.0.0.1:9001"); + assert (rc == 0); + rc = zmq_connect (client, "tcp://127.0.0.1:9001"); + assert (rc == 0); + + s_send (client, "This is a message"); + zmq_msg_t msg; + zmq_msg_init (&msg); + rc = zmq_msg_recv (&msg, server, 0); + assert (rc != -1); + assert (streq (zmq_msg_gets (&msg, "Hello"), "World")); + assert (streq (zmq_msg_gets (&msg, "Socket-Type"), "DEALER")); + assert (streq (zmq_msg_gets (&msg, "User-Id"), "anonymous")); + zmq_msg_close (&msg); + + close_zero_linger (client); + close_zero_linger (server); + + // Shutdown + rc = zmq_ctx_term (ctx); + assert (rc == 0); + + // Wait until ZAP handler terminates + zmq_threadclose (zap_thread); + + return 0; +} diff --git a/tests/test_security_null.cpp b/tests/test_security_null.cpp index b1b6756a..61de9e17 100644 --- a/tests/test_security_null.cpp +++ b/tests/test_security_null.cpp @@ -78,19 +78,19 @@ int main (void) // We bounce between a binding server and a connecting client -// // We first test client/server with no ZAP domain -// // Libzmq does not call our ZAP handler, the connect must succeed -// void *server = zmq_socket (ctx, ZMQ_DEALER); -// assert (server); -// void *client = zmq_socket (ctx, ZMQ_DEALER); -// assert (client); -// rc = zmq_bind (server, "tcp://127.0.0.1:9000"); -// assert (rc == 0); -// rc = zmq_connect (client, "tcp://127.0.0.1:9000"); -// assert (rc == 0); -// bounce (server, client); -// close_zero_linger (client); -// close_zero_linger (server); + // We first test client/server with no ZAP domain + // Libzmq does not call our ZAP handler, the connect must succeed + void *server = zmq_socket (ctx, ZMQ_DEALER); + assert (server); + void *client = zmq_socket (ctx, ZMQ_DEALER); + assert (client); + rc = zmq_bind (server, "tcp://127.0.0.1:9000"); + assert (rc == 0); + rc = zmq_connect (client, "tcp://127.0.0.1:9000"); + assert (rc == 0); + bounce (server, client); + close_zero_linger (client); + close_zero_linger (server); // Now define a ZAP domain for the server; this enables // authentication. We're using the wrong domain so this test @@ -109,20 +109,20 @@ int main (void) close_zero_linger (client); close_zero_linger (server); -// // Now use the right domain, the test must pass -// server = zmq_socket (ctx, ZMQ_DEALER); -// assert (server); -// client = zmq_socket (ctx, ZMQ_DEALER); -// assert (client); -// rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4); -// assert (rc == 0); -// rc = zmq_bind (server, "tcp://127.0.0.1:9002"); -// assert (rc == 0); -// rc = zmq_connect (client, "tcp://127.0.0.1:9002"); -// assert (rc == 0); -// bounce (server, client); -// close_zero_linger (client); -// close_zero_linger (server); + // Now use the right domain, the test must pass + server = zmq_socket (ctx, ZMQ_DEALER); + assert (server); + client = zmq_socket (ctx, ZMQ_DEALER); + assert (client); + rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4); + assert (rc == 0); + rc = zmq_bind (server, "tcp://127.0.0.1:9002"); + assert (rc == 0); + rc = zmq_connect (client, "tcp://127.0.0.1:9002"); + assert (rc == 0); + bounce (server, client); + close_zero_linger (client); + close_zero_linger (server); // Shutdown rc = zmq_ctx_term (ctx);