From 36a16ec7d1ce0f66c88bc8955daecb771ec918c9 Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Sat, 16 Mar 2019 17:51:25 +0100 Subject: [PATCH] Problem: test_security_plain not using a test framework Solution: migrate to Unity --- Makefile.am | 3 +- tests/test_security_plain.cpp | 228 +++++++++++++++++++--------------- 2 files changed, 128 insertions(+), 103 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2d4652a6..facc6f05 100644 --- a/Makefile.am +++ b/Makefile.am @@ -608,7 +608,8 @@ tests_test_security_null_LDADD = src/libzmq.la ${UNITY_LIBS} tests_test_security_null_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_security_plain_SOURCES = tests/test_security_plain.cpp -tests_test_security_plain_LDADD = src/libzmq.la +tests_test_security_plain_LDADD = src/libzmq.la ${UNITY_LIBS} +tests_test_security_plain_CPPFLAGS = ${UNITY_CPPFLAGS} tests_test_security_zap_SOURCES = \ tests/test_security_zap.cpp \ diff --git a/tests/test_security_plain.cpp b/tests/test_security_plain.cpp index 256bdeee..cc096d50 100644 --- a/tests/test_security_plain.cpp +++ b/tests/test_security_plain.cpp @@ -28,6 +28,8 @@ */ #include "testutil.hpp" +#include "testutil_unity.hpp" + #if defined(ZMQ_HAVE_WINDOWS) #include #include @@ -40,43 +42,37 @@ #include #endif -static void zap_handler (void *ctx_) +static void zap_handler (void *zap_) { - // Create and bind ZAP socket - void *zap = zmq_socket (ctx_, ZMQ_REP); - assert (zap); - int rc = zmq_bind (zap, "inproc://zeromq.zap.01"); - assert (rc == 0); - // Process ZAP requests forever while (true) { - char *version = s_recv (zap); + char *version = s_recv (zap_); if (!version) break; // Terminating - char *sequence = s_recv (zap); - char *domain = s_recv (zap); - char *address = s_recv (zap); - char *routing_id = s_recv (zap); - char *mechanism = s_recv (zap); - char *username = s_recv (zap); - char *password = s_recv (zap); + char *sequence = s_recv (zap_); + char *domain = s_recv (zap_); + char *address = s_recv (zap_); + char *routing_id = s_recv (zap_); + char *mechanism = s_recv (zap_); + char *username = s_recv (zap_); + char *password = s_recv (zap_); assert (streq (version, "1.0")); assert (streq (mechanism, "PLAIN")); assert (streq (routing_id, "IDENT")); - s_sendmore (zap, version); - s_sendmore (zap, sequence); + s_sendmore (zap_, version); + s_sendmore (zap_, sequence); if (streq (username, "admin") && streq (password, "password")) { - s_sendmore (zap, "200"); - s_sendmore (zap, "OK"); - s_sendmore (zap, "anonymous"); - s_send (zap, ""); + s_sendmore (zap_, "200"); + s_sendmore (zap_, "OK"); + s_sendmore (zap_, "anonymous"); + s_send (zap_, ""); } else { - s_sendmore (zap, "400"); - s_sendmore (zap, "Invalid username or password"); - s_sendmore (zap, ""); - s_send (zap, ""); + s_sendmore (zap_, "400"); + s_sendmore (zap_, "Invalid username or password"); + s_sendmore (zap_, ""); + s_send (zap_, ""); } free (version); free (sequence); @@ -87,94 +83,121 @@ static void zap_handler (void *ctx_) free (username); free (password); } - rc = zmq_close (zap); + int rc = zmq_close (zap_); assert (rc == 0); } -int main (void) +void *zap_thread; + +char my_endpoint[MAX_SOCKET_STRING]; + +static void setup_zap_handler () { - setup_test_environment (); - size_t len = MAX_SOCKET_STRING; - char my_endpoint[MAX_SOCKET_STRING]; - void *ctx = zmq_ctx_new (); - assert (ctx); - // Spawn ZAP handler - void *zap_thread = zmq_threadstart (&zap_handler, ctx); + // 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 (get_test_context (), ZMQ_REP); + TEST_ASSERT_SUCCESS_ERRNO (zmq_bind (handler, "inproc://zeromq.zap.01")); + zap_thread = zmq_threadstart (&zap_handler, handler); +} +static void teardown_zap_handler () +{ + // Wait until ZAP handler terminates + zmq_threadclose (zap_thread); +} + +const char domain[] = "test"; + +void *server; + +static void setup_server () +{ // Server socket will accept connections - void *server = zmq_socket (ctx, ZMQ_DEALER); - assert (server); - int rc = zmq_setsockopt (server, ZMQ_ROUTING_ID, "IDENT", 6); - const char domain[] = "test"; - assert (rc == 0); - rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, domain, strlen (domain)); - assert (rc == 0); - int as_server = 1; - rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); - assert (rc == 0); - rc = zmq_bind (server, "tcp://127.0.0.1:*"); - assert (rc == 0); - rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len); - assert (rc == 0); + server = test_context_socket (ZMQ_DEALER); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (server, ZMQ_ROUTING_ID, "IDENT", 6)); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, domain, strlen (domain))); + const int as_server = 1; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int))); + bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint); +} - char username[256]; - char password[256]; +static void teardown_server () +{ + test_context_socket_close (server); +} +void setUp () +{ + setup_test_context (); + setup_zap_handler (); + setup_server (); +} + +void tearDown () +{ + teardown_server (); + teardown_test_context (); + teardown_zap_handler (); +} + +void test_plain_success () +{ // Check PLAIN security with correct username/password - void *client = zmq_socket (ctx, ZMQ_DEALER); - assert (client); - strcpy (username, "admin"); - rc = - zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); - assert (rc == 0); - strcpy (password, "password"); - rc = - zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); - assert (rc == 0); - rc = zmq_connect (client, my_endpoint); - assert (rc == 0); + void *client = test_context_socket (ZMQ_DEALER); + const char username[] = "admin"; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username))); + const char password[] = "password"; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password))); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); bounce (server, client); - rc = zmq_close (client); - assert (rc == 0); + test_context_socket_close (client); +} +void test_plain_client_as_server_fails () +{ // Check PLAIN security with badly configured client (as_server) // This will be caught by the plain_server class, not passed to ZAP - client = zmq_socket (ctx, ZMQ_DEALER); - assert (client); - as_server = 1; - rc = zmq_setsockopt (client, ZMQ_ZAP_DOMAIN, domain, strlen (domain)); - assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int)); - assert (rc == 0); - rc = zmq_connect (client, my_endpoint); - assert (rc == 0); + void *client = test_context_socket (ZMQ_DEALER); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_ZAP_DOMAIN, domain, strlen (domain))); + const int as_server = 1; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_PLAIN_SERVER, &as_server, sizeof (int))); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); expect_bounce_fail (server, client); - close_zero_linger (client); + test_context_socket_close_zero_linger (client); +} +void test_plain_wrong_credentials_fails () +{ // Check PLAIN security -- failed authentication - client = zmq_socket (ctx, ZMQ_DEALER); - assert (client); - strcpy (username, "wronguser"); - strcpy (password, "wrongpass"); - rc = - zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username)); - assert (rc == 0); - rc = - zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password)); - assert (rc == 0); - rc = zmq_connect (client, my_endpoint); - assert (rc == 0); + void *client = test_context_socket (ZMQ_DEALER); + const char username[] = "wronguser"; + const char password[] = "wrongpass"; + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username))); + TEST_ASSERT_SUCCESS_ERRNO ( + zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password))); + TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint)); expect_bounce_fail (server, client); - close_zero_linger (client); + test_context_socket_close_zero_linger (client); +} +void test_plain_vanilla_socket () +{ // Unauthenticated messages from a vanilla socket shouldn't be received struct sockaddr_in ip4addr; fd_t s; unsigned short int port; - rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port); - assert (rc == 1); + int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port); + TEST_ASSERT_EQUAL_INT (1, rc); ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons (port); @@ -186,7 +209,7 @@ int main (void) s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); rc = connect (s, (struct sockaddr *) &ip4addr, sizeof (ip4addr)); - assert (rc > -1); + TEST_ASSERT_GREATER_THAN_INT (-1, rc); // send anonymous ZMTP/1.0 greeting send (s, "\x01\x00", 2, 0); // send sneaky message that shouldn't be received @@ -196,18 +219,19 @@ int main (void) char *buf = s_recv (server); if (buf != NULL) { printf ("Received unauthenticated message: %s\n", buf); - assert (buf == NULL); + TEST_ASSERT_NULL (buf); } close (s); - - // Shutdown - rc = zmq_close (server); - assert (rc == 0); - rc = zmq_ctx_term (ctx); - assert (rc == 0); - - // Wait until ZAP handler terminates - zmq_threadclose (zap_thread); - - return 0; +} + +int main (void) +{ + setup_test_environment (); + + UNITY_BEGIN (); + RUN_TEST (test_plain_success); + RUN_TEST (test_plain_client_as_server_fails); + RUN_TEST (test_plain_wrong_credentials_fails); + RUN_TEST (test_plain_vanilla_socket); + return UNITY_END (); }