From 9d94640edc5b6fc6a7d3a2b66abea680f478921e Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 30 Aug 2013 17:56:59 -0700 Subject: [PATCH] test failed CURVE auth adds expect_bounce_fail test function which is like bounce, but fails if messages arrive. --- tests/test_security.cpp | 17 +------ tests/test_security_curve.cpp | 83 ++++++++++++++++++++++++++++++++++- tests/testutil.hpp | 37 ++++++++++++++++ 3 files changed, 119 insertions(+), 18 deletions(-) diff --git a/tests/test_security.cpp b/tests/test_security.cpp index 882dabd5..089f8ab5 100644 --- a/tests/test_security.cpp +++ b/tests/test_security.cpp @@ -248,22 +248,7 @@ int main (void) assert (rc == 0); // Send message from inauthenticated client to server - const char *content = "12345678ABCDEFGH12345678abcdefgh"; - rc = zmq_send (client, content, 32, 0); - assert (rc == 32); - - // Receive message at server side (shouldn't arrive) - // Set timeout - optsize = sizeof (int); - int timeout = 1000; - rc = zmq_setsockopt(server, ZMQ_RCVTIMEO, &timeout, optsize); - assert (rc == 0); - - char buffer [32]; - // Should raise EAGAIN, inauthenticated message should never arrive - rc = zmq_recv (server, buffer, 32, 0); - assert (rc == -1); - assert (zmq_errno() == EAGAIN); + expect_bounce_fail(server, client); rc = zmq_close (client); assert (rc == 0); diff --git a/tests/test_security_curve.cpp b/tests/test_security_curve.cpp index 7804526c..ee143078 100644 --- a/tests/test_security_curve.cpp +++ b/tests/test_security_curve.cpp @@ -25,7 +25,17 @@ static void zap_handler (void *zap) { + int timeout = 250; + int rc; + rc = zmq_setsockopt(zap, ZMQ_RCVTIMEO, &timeout, sizeof (int)); + assert (rc == 0); char *version = s_recv (zap); + if (version == NULL) { + printf("ZAP timeout\n"); + rc = zmq_close(zap); + assert (rc == 0); + return; + } char *sequence = s_recv (zap); char *domain = s_recv (zap); char *address = s_recv (zap); @@ -52,10 +62,11 @@ static void zap_handler (void *zap) free (mechanism); free (client_key); - int rc = zmq_close (zap); + rc = zmq_close (zap); assert (rc == 0); } + int main (void) { #ifndef HAVE_LIBSODIUM @@ -84,7 +95,7 @@ int main (void) char client_secret [] = "D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs"; char server_public [] = "rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7"; char server_secret [] = "JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6"; - + as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); @@ -142,6 +153,74 @@ int main (void) // Wait until ZAP handler terminates. zmq_threadclose(zap_thread); + // Test that Curve rejects inauthenticated connections + + // Use the wrong client key + strcpy(client_public, "1111222233334444555566667777888899990000"); + + // Server socket will accept connections + server = zmq_socket (ctx, ZMQ_DEALER); + assert (server); + + // Client socket that will try to connect to server + client = zmq_socket (ctx, ZMQ_DEALER); + assert (client); + + 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); + assert (rc == 0); + rc = zmq_setsockopt(server, ZMQ_IDENTITY, "IDENT", 6); + assert (rc == 0); + + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + assert (rc == 0); + rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + assert (rc == 0); + rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + assert (rc == 0); + + // Test the client and server both have the right mechanism. + optsize = sizeof (int); + rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize); + assert (rc == 0); + assert (mechanism == ZMQ_CURVE); + rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize); + assert (rc == 0); + assert (mechanism == ZMQ_CURVE); + + // Test the server bit on both client and server. + rc = zmq_getsockopt (client, ZMQ_CURVE_SERVER, &as_server, &optsize); + assert (rc == 0); + assert (as_server == 0); + rc = zmq_getsockopt (server, ZMQ_CURVE_SERVER, &as_server, &optsize); + assert (rc == 0); + assert (as_server == 1); + + // Create and bind ZAP socket + zap = zmq_socket (ctx, ZMQ_REP); + assert (zap); + + rc = zmq_bind (zap, "inproc://zeromq.zap.01"); + assert (rc == 0); + + zap_thread = zmq_threadstart(&zap_handler, zap); + + rc = zmq_bind (server, "tcp://*:9997"); + assert (rc == 0); + rc = zmq_connect (client, "tcp://localhost:9997"); + assert (rc == 0); + + expect_bounce_fail(server, client); + + close_zero_linger (client); + rc = zmq_close (server); + assert (rc == 0); + + // Wait until ZAP handler terminates. + zmq_threadclose(zap_thread); + // Shutdown rc = zmq_ctx_term (ctx); assert (rc == 0); diff --git a/tests/testutil.hpp b/tests/testutil.hpp index ecb0b456..42f26090 100644 --- a/tests/testutil.hpp +++ b/tests/testutil.hpp @@ -83,6 +83,43 @@ bounce (void *server, void *client) assert (memcmp (buffer, content, 32) == 0); } +// Same as bounce, but expect messages to never arrive +// for security or subscriber reasons. + +void +expect_bounce_fail (void *server, void *client) +{ + const char *content = "12345678ABCDEFGH12345678abcdefgh"; + char buffer [32]; + + // Send message from client to server + int rc = zmq_send (client, content, 32, ZMQ_SNDMORE); + assert (rc == 32); + rc = zmq_send (client, content, 32, 0); + assert (rc == 32); + + // Receive message at server side (should not succeed) + int timeout = 250; + rc = zmq_setsockopt(server, ZMQ_RCVTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + rc = zmq_setsockopt(client, ZMQ_RCVTIMEO, &timeout, sizeof (int)); + assert (rc == 0); + + rc = zmq_recv (server, buffer, 32, 0); + assert (rc == -1); + assert (zmq_errno() == EAGAIN); + + + rc = zmq_send (server, content, 32, ZMQ_SNDMORE); + assert (rc == 32); + rc = zmq_send (server, content, 32, 0); + assert (rc == 32); + + rc = zmq_recv (client, buffer, 32, 0); + assert (rc == -1); + assert (zmq_errno() == EAGAIN); +} + // Receive 0MQ string from socket and convert into C string // Caller must free returned string. Returns NULL if the context // is being terminated.