diff --git a/.travis.yml b/.travis.yml index ef0818fb..699951be 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# libzmq +# Travis CI script language: c @@ -6,16 +6,10 @@ language: c before_script: # libsodium -# Commit 8d0942 broke installation (sodium.h not found) so for now -# we're checking out the last good commit. - git clone git://github.com/jedisct1/libsodium.git -- cd libsodium -- git checkout e2a30a -- ./autogen.sh -- ./configure && make check -- sudo make install -- sudo ldconfig -- cd .. +- ( cd libsodium; ./autogen.sh; ./configure; make check; sudo make install; sudo ldconfig ) -# Build and check libzmq -script: ./autogen.sh && ./configure && make && make check +# Build and check this project +script: +- ./autogen.sh && ./configure && make && make check +- sudo make install diff --git a/AUTHORS b/AUTHORS index aeeeab34..1249b6a5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,6 +7,7 @@ Copyright (c) 2010-2011 Miru Limited Copyright (c) 2011 VMware, Inc. Copyright (c) 2012 Spotify AB Copyright (c) 2013 Ericsson AB +Copyright (c) 2014 AppDynamics Inc. Individual Contributors ======================= diff --git a/doc/zmq_getsockopt.txt b/doc/zmq_getsockopt.txt index 6961cc7a..3732cd24 100644 --- a/doc/zmq_getsockopt.txt +++ b/doc/zmq_getsockopt.txt @@ -85,6 +85,8 @@ ZMQ_CURVE_SECRETKEY: Retrieve current CURVE secret key Retrieves the current long term secret key for the socket. You can provide either a 32 byte buffer, to retrieve the binary key value, or a 41 byte buffer, to retrieve the key in a printable Z85 format. +NOTE: to fetch a printable key, the buffer must be 41 bytes large +to hold the 40-char key value and one null byte. [horizontal] Option value type:: binary data or Z85 text string @@ -98,7 +100,9 @@ ZMQ_CURVE_SERVERKEY: Retrieve current CURVE server key Retrieves the current server key for the client socket. You can provide either a 32 byte buffer, to retrieve the binary key value, or -a 40 byte buffer, to retrieve the key in a printable Z85 format. +a 41-byte buffer, to retrieve the key in a printable Z85 format. +NOTE: to fetch a printable key, the buffer must be 41 bytes large +to hold the 40-char key value and one null byte. [horizontal] Option value type:: binary data or Z85 text string diff --git a/doc/zmq_setsockopt.txt b/doc/zmq_setsockopt.txt index ce8db3b3..be01fe13 100644 --- a/doc/zmq_setsockopt.txt +++ b/doc/zmq_setsockopt.txt @@ -112,13 +112,17 @@ ZMQ_CURVE_PUBLICKEY: Set CURVE public key ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the socket's long term public key. You must set this on CURVE client sockets, see linkzmq:zmq_curve[7]. You can provide the key as 32 binary -bytes, or as a 40-character string encoded in the Z85 encoding format. -The public key must always be used with the matching secret key. To -generate a public/secret key pair, use linkzmq:zmq_curve_keypair[3]. +bytes, or as a 40-character string encoded in the Z85 encoding format and +terminated in a null byte. The public key must always be used with the +matching secret key. To generate a public/secret key pair, use +linkzmq:zmq_curve_keypair[3]. + +NOTE: an option value size of 40 is supported for backwards compatibility, +though is deprecated. [horizontal] Option value type:: binary data or Z85 text string -Option value size:: 32 or 40 +Option value size:: 32 or 41 Default value:: NULL Applicable socket types:: all, when using TCP transport @@ -128,12 +132,15 @@ ZMQ_CURVE_SECRETKEY: Set CURVE secret key Sets the socket's long term secret key. You must set this on both CURVE client and server sockets, see linkzmq:zmq_curve[7]. You can provide the key as 32 binary bytes, or as a 40-character string encoded in the Z85 -encoding format. To generate a public/secret key pair, use -linkzmq:zmq_curve_keypair[3]. +encoding format and terminated in a null byte. To generate a public/secret +key pair, use linkzmq:zmq_curve_keypair[3]. + +NOTE: an option value size of 40 is supported for backwards compatibility, +though is deprecated. [horizontal] Option value type:: binary data or Z85 text string -Option value size:: 32 or 40 +Option value size:: 32 or 41 Default value:: NULL Applicable socket types:: all, when using TCP transport @@ -160,12 +167,17 @@ ZMQ_CURVE_SERVERKEY: Set CURVE server key ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the socket's long term server key. You must set this on CURVE client sockets, see linkzmq:zmq_curve[7]. You can provide the key as 32 binary -bytes, or as a 40-character string encoded in the Z85 encoding format. -This key must have been generated together with the server's secret key. +bytes, or as a 40-character string encoded in the Z85 encoding format and +terminated in a null byte. This key must have been generated together with +the server's secret key. To generate a public/secret key pair, use +linkzmq:zmq_curve_keypair[3]. + +NOTE: an option value size of 40 is supported for backwards compatibility, +though is deprecated. [horizontal] Option value type:: binary data or Z85 text string -Option value size:: 32 or 40 +Option value size:: 32 or 41 Default value:: NULL Applicable socket types:: all, when using TCP transport @@ -757,6 +769,9 @@ filter is applied then new connection source ip should be matched. To clear all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0). Filter is a null-terminated string with ipv6 or ipv4 CIDR. +NOTE: This option is deprecated, please use authentication via the ZAP API +and IP address whitelisting / blacklisting. + [horizontal] Option value type:: binary data Option value unit:: N/A diff --git a/src/options.cpp b/src/options.cpp index 22409ae7..84b2a7b1 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -366,17 +366,30 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, break; case ZMQ_CURVE_PUBLICKEY: + // TODO: refactor repeated code for these three options + // into set_curve_key (destination, optval, optlen) method + // ==> set_curve_key (curve_public_key, optval_, optvallen_); if (optvallen_ == CURVE_KEYSIZE) { memcpy (curve_public_key, optval_, CURVE_KEYSIZE); mechanism = ZMQ_CURVE; return 0; } else - if (optvallen_ == CURVE_KEYSIZE_Z85) { + if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) { zmq_z85_decode (curve_public_key, (char *) optval_); mechanism = ZMQ_CURVE; return 0; } + else + // Deprecated, not symmetrical with zmq_getsockopt + if (optvallen_ == CURVE_KEYSIZE_Z85) { + char z85_key [41]; + memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85); + z85_key [CURVE_KEYSIZE_Z85] = 0; + zmq_z85_decode (curve_public_key, z85_key); + mechanism = ZMQ_CURVE; + return 0; + } break; case ZMQ_CURVE_SECRETKEY: @@ -386,25 +399,46 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, return 0; } else - if (optvallen_ == CURVE_KEYSIZE_Z85) { + if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) { zmq_z85_decode (curve_secret_key, (char *) optval_); mechanism = ZMQ_CURVE; return 0; } + else + // Deprecated, not symmetrical with zmq_getsockopt + if (optvallen_ == CURVE_KEYSIZE_Z85) { + char z85_key [41]; + memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85); + z85_key [CURVE_KEYSIZE_Z85] = 0; + zmq_z85_decode (curve_secret_key, z85_key); + mechanism = ZMQ_CURVE; + return 0; + } break; case ZMQ_CURVE_SERVERKEY: if (optvallen_ == CURVE_KEYSIZE) { memcpy (curve_server_key, optval_, CURVE_KEYSIZE); - as_server = 0; mechanism = ZMQ_CURVE; + as_server = 0; return 0; } else - if (optvallen_ == CURVE_KEYSIZE_Z85) { + if (optvallen_ == CURVE_KEYSIZE_Z85 + 1) { zmq_z85_decode (curve_server_key, (char *) optval_); - as_server = 0; mechanism = ZMQ_CURVE; + as_server = 0; + return 0; + } + else + // Deprecated, not symmetrical with zmq_getsockopt + if (optvallen_ == CURVE_KEYSIZE_Z85) { + char z85_key [41]; + memcpy (z85_key, (char *) optval_, CURVE_KEYSIZE_Z85); + z85_key [CURVE_KEYSIZE_Z85] = 0; + zmq_z85_decode (curve_server_key, z85_key); + mechanism = ZMQ_CURVE; + as_server = 0; return 0; } break; diff --git a/tests/Makefile.am b/tests/Makefile.am index e3d685da..8c7b0bd7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -54,7 +54,7 @@ noinst_PROGRAMS = test_system \ test_metadata \ test_id2fd \ test_capabilities \ - test_xpub_wait_inproc + test_xpub_nodrop if !ON_MINGW noinst_PROGRAMS += test_shutdown_stress \ @@ -134,7 +134,7 @@ test_bind_src_address_SOURCES = test_bind_src_address.cpp test_metadata_SOURCES = test_metadata.cpp test_id2fd_SOURCES = test_id2fd.cpp test_capabilities_SOURCES = test_capabilities.cpp -test_xpub_wait_inproc_SOURCES = test_xpub_wait_inproc.cpp +test_xpub_nodrop_SOURCES = test_xpub_nodrop.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_security_curve.cpp b/tests/test_security_curve.cpp index d3850eaa..7b1350db 100644 --- a/tests/test_security_curve.cpp +++ b/tests/test_security_curve.cpp @@ -111,7 +111,7 @@ int main (void) int as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); - rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 40); + rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 41); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); @@ -121,11 +121,11 @@ int main (void) // Check CURVE security with valid credentials void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -138,11 +138,11 @@ int main (void) char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -153,11 +153,11 @@ int main (void) // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -168,11 +168,11 @@ int main (void) // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -187,11 +187,11 @@ int main (void) client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 41); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); diff --git a/tests/test_xpub_wait_inproc.cpp b/tests/test_xpub_nodrop.cpp similarity index 70% rename from tests/test_xpub_wait_inproc.cpp rename to tests/test_xpub_nodrop.cpp index 914d4f08..cc15e934 100644 --- a/tests/test_xpub_wait_inproc.cpp +++ b/tests/test_xpub_nodrop.cpp @@ -50,34 +50,33 @@ int main (void) rc = zmq_setsockopt (sub, ZMQ_SUBSCRIBE, "", 0); assert (rc == 0); - int hwmlimit = hwm-1; + int hwmlimit = hwm - 1; int send_count = 0; + // Send an empty message - for (int i = 0; i< hwmlimit; i++) { - rc = zmq_send (pub, NULL, 0, 0); - assert (rc == 0); - send_count++; + for (int i = 0; i < hwmlimit; i++) { + rc = zmq_send (pub, NULL, 0, 0); + assert (rc == 0); + send_count++; } int recv_count = 0; - do { - // Receive the message in the subscriber -// rc = zmq_recv (sub, buff, sizeof (buff), ZMQ_DONTWAIT); - rc = zmq_recv (sub, NULL, 0, ZMQ_DONTWAIT); - if( -1 == rc ) { - assert(EAGAIN == errno); - } - else - { - assert( 0 == rc ); - recv_count++; - } - } while( 0 == rc); + // Receive the message in the subscriber + rc = zmq_recv (sub, NULL, 0, ZMQ_DONTWAIT); + if (rc == -1) + assert (errno == EAGAIN); + else { + assert (rc == 0); + recv_count++; + } + } + while (rc == 0); - assert(send_count == recv_count); - // now test real blocking behavior - // set a timeout, default is infinite + assert (send_count == recv_count); + + // Now test real blocking behavior + // Set a timeout, default is infinite int timeout = 0; rc = zmq_setsockopt (pub, ZMQ_SNDTIMEO, &timeout, 4); assert (rc == 0); @@ -85,19 +84,15 @@ int main (void) send_count = 0; recv_count = 0; hwmlimit = hwm; - // Send an empty message - while( 0 == zmq_send (pub, NULL, 0, 0) ) - { - send_count++; - } - assert( EAGAIN == errno); + + // Send an empty message until we get an error, which must be EAGAIN + while (zmq_send (pub, "", 0, 0) == 0) + send_count++; + assert (errno == EAGAIN); - while( 0 == zmq_recv (sub, NULL, 0, ZMQ_DONTWAIT)) - { - recv_count ++; - } - - assert( send_count == recv_count); + while (zmq_recv (sub, NULL, 0, ZMQ_DONTWAIT) == 0) + recv_count++; + assert (send_count == recv_count); // Clean up. rc = zmq_close (pub);