Merge pull request #3449 from sigiesec/migrate-security-tests

Migrate security tests for NULL and PLAIN mechanisms to Unity
This commit is contained in:
Luca Boccassi 2019-03-18 12:54:52 +00:00 committed by GitHub
commit 645df4e602
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 314 additions and 231 deletions

View File

@ -419,7 +419,8 @@ test_apps = \
tests/test_unbind_wildcard \
tests/test_ctx_options \
tests/test_ctx_destroy \
tests/test_security_null \
tests/test_security_no_zap_handler \
tests/test_security_null \
tests/test_security_plain \
tests/test_security_zap \
tests/test_iov \
@ -598,11 +599,17 @@ tests_test_ctx_destroy_SOURCES = tests/test_ctx_destroy.cpp
tests_test_ctx_destroy_LDADD = src/libzmq.la ${UNITY_LIBS}
tests_test_ctx_destroy_CPPFLAGS = ${UNITY_CPPFLAGS}
tests_test_security_no_zap_handler_SOURCES = tests/test_security_no_zap_handler.cpp
tests_test_security_no_zap_handler_LDADD = src/libzmq.la ${UNITY_LIBS}
tests_test_security_no_zap_handler_CPPFLAGS = ${UNITY_CPPFLAGS}
tests_test_security_null_SOURCES = tests/test_security_null.cpp
tests_test_security_null_LDADD = src/libzmq.la
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 \

View File

@ -41,12 +41,12 @@ environment:
configuration: Debug
WITH_LIBSODIUM: ON
ENABLE_CURVE: ON
TEST_OPTIONS: '-E "(test_spec_router|test_spec_pushpull|test_metadata|test_security_curve|test_dgram)"'
TEST_OPTIONS: '-E "(test_many_sockets)"'
- platform: x64
configuration: Debug
WITH_LIBSODIUM: ON
ENABLE_CURVE: ON
TEST_OPTIONS: '-E "(test_spec_router|test_spec_pushpull|test_metadata|test_security_curve|test_dgram)"'
TEST_OPTIONS: '-E "(test_many_sockets)"'
- platform: Win32
configuration: Release
WITH_LIBSODIUM: OFF
@ -133,8 +133,6 @@ before_build:
# - cmd: set BUILDLOG="%LIBZMQ_SRCDIR%\build.log"
- cmd: md "%LIBZMQ_BUILDDIR%"
- cd "%LIBZMQ_BUILDDIR%"
- cmd: if "%PLATFORM%" == "Win32" set EXTRA_FLAGS='-D CMAKE_C_FLAGS_RELEASE="/MT" -D CMAKE_C_FLAGS_DEBUG="/MTd"'
- cmd: if "%PLATFORM%" == "x64" set EXTRA_FLAGS='-D CMAKE_C_FLAGS_RELEASE="/MT" -D CMAKE_C_FLAGS_DEBUG="/MTd"'
- cmd: if "%PLATFORM%" == "cygwin64" set APPVEYOR_BUILD_FOLDER=/cygdrive/C/projects/libzmq
- cmd: if "%ENABLE_ANALYSIS%"=="ON" ( set LIBZMQ_WERROR="OFF" ) else ( set LIBZMQ_WERROR="ON" )
- cmd: cmake -D CMAKE_INCLUDE_PATH="%SODIUM_INCLUDE_DIR%" -D CMAKE_LIBRARY_PATH="%SODIUM_LIBRARY_DIR%" -D WITH_LIBSODIUM="%WITH_LIBSODIUM%" -D ENABLE_DRAFTS="%ENABLE_DRAFTS%" -D ENABLE_ANALYSIS="%ENABLE_ANALYSIS%" -D ENABLE_CURVE="%ENABLE_CURVE%" -D API_POLLER="%API_POLLER%" -D POLLER="%POLLER%" %EXTRA_FLAGS% -D WITH_LIBSODIUM="%WITH_LIBSODIUM%" -D LIBZMQ_WERROR="%LIBZMQ_WERROR%" -G "%CMAKE_GENERATOR%" "%APPVEYOR_BUILD_FOLDER%"
@ -183,7 +181,7 @@ after_build:
# -Dsonar.cxx.compiler.regex=^(?<filename>.*)\\((?<line>[0-9]+)\\):\\x20warning\\x20(?<id>C\\d\\d\\d\\d):(?<message>.*)$
- cmd: cd %LIBZMQ_BUILDDIR%\bin\%Configuration%"
- cmd: if "%WITH_LIBSODIUM%"=="ON" copy "%SODIUM_LIBRARY_DIR%\libsodium.dll" .
- cmd: 7z a -y -bd -mx=9 libzmq.zip *.exe *.dll
- cmd: 7z a -y -bd -mx=9 libzmq.zip *.exe *.dll *.pdb
- ps: Push-AppveyorArtifact "libzmq.zip" -Filename "libzmq-${env:Platform}-${env:Configuration}.zip"
test_script:

View File

@ -31,6 +31,7 @@ set(tests
test_unbind_wildcard
test_ctx_options
test_ctx_destroy
test_security_no_zap_handler
test_security_null
test_security_plain
test_security_zap

View File

@ -0,0 +1,90 @@
/*
Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file
This file is part of libzmq, the ZeroMQ core engine in C++.
libzmq is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
As a special exception, the Contributors give you permission to link
this library with independent modules to produce an executable,
regardless of the license terms of these independent modules, and to
copy and distribute the resulting executable under terms of your choice,
provided that you also meet, for each linked independent module, the
terms and conditions of the license of that module. An independent
module is a module which is not derived from or based on this library.
If you modify this library, you must extend this exception to your
version of the library.
libzmq 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 <http://www.gnu.org/licenses/>.
*/
#include "testutil.hpp"
#include "testutil_unity.hpp"
void setUp ()
{
setup_test_context ();
}
void tearDown ()
{
teardown_test_context ();
}
void test_no_zap_handler ()
{
// We first test client/server with a ZAP domain but with no handler
// If there is no handler, libzmq should ignore the ZAP option unless
// ZMQ_ZAP_ENFORCE_DOMAIN is set
void *server = test_context_socket (ZMQ_DEALER);
void *client = test_context_socket (ZMQ_DEALER);
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5));
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
bounce (server, client);
test_context_socket_close_zero_linger (client);
test_context_socket_close_zero_linger (server);
}
void test_no_zap_handler_enforce_domain ()
{
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
// Now set ZMQ_ZAP_ENFORCE_DOMAIN which strictly enforces the ZAP
// RFC but is backward-incompatible, now it should fail
void *server = test_context_socket (ZMQ_DEALER);
void *client = test_context_socket (ZMQ_DEALER);
int required = 1;
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required, sizeof (int)));
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5));
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
expect_bounce_fail (server, client);
test_context_socket_close_zero_linger (client);
test_context_socket_close_zero_linger (server);
#endif
}
int main ()
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_no_zap_handler);
RUN_TEST (test_no_zap_handler_enforce_domain);
return UNITY_END ();
}

View File

@ -28,6 +28,8 @@
*/
#include "testutil.hpp"
#include "testutil_unity.hpp"
#if defined(ZMQ_HAVE_WINDOWS)
#include <winsock2.h>
#include <ws2tcpip.h>
@ -80,140 +82,97 @@ static void zap_handler (void *handler_)
close_zero_linger (handler_);
}
int main (void)
void *zap_thread;
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);
// We first test client/server with a ZAP domain but with no handler
// If there is no handler, libzmq should ignore the ZAP option unless
// ZMQ_ZAP_ENFORCE_DOMAIN is set
void *server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
void *client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
int rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
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);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
bounce (server, client);
close_zero_linger (client);
close_zero_linger (server);
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
// Now set ZMQ_ZAP_ENFORCE_DOMAIN which strictly enforces the ZAP
// RFC but is backward-incompatible, now it should fail
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
int required = 1;
rc =
zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required, sizeof (int));
assert (rc == 0);
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
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);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
expect_bounce_fail (server, client);
close_zero_linger (client);
close_zero_linger (server);
#endif
// 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);
rc = zmq_bind (handler, "inproc://zeromq.zap.01");
assert (rc == 0);
void *zap_thread = zmq_threadstart (&zap_handler, handler);
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);
}
// We bounce between a binding server and a connecting client
static void teardown_zap_handler ()
{
// Wait until ZAP handler terminates
zmq_threadclose (zap_thread);
}
void setUp ()
{
setup_test_context ();
setup_zap_handler ();
}
void tearDown ()
{
teardown_test_context ();
teardown_zap_handler ();
}
void test_no_domain ()
{
// We first test client/server with no ZAP domain
// Libzmq does not call our ZAP handler, the connect must succeed
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
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);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
void *server = test_context_socket (ZMQ_DEALER);
void *client = test_context_socket (ZMQ_DEALER);
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
bounce (server, client);
close_zero_linger (client);
close_zero_linger (server);
test_context_socket_close_zero_linger (client);
test_context_socket_close_zero_linger (server);
}
void test_wrong_domain_fails ()
{
// Now define a ZAP domain for the server; this enables
// authentication. We're using the wrong domain so this test
// must fail.
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5);
assert (rc == 0);
rc = zmq_bind (server, "tcp://127.0.0.1:*");
assert (rc == 0);
len = MAX_SOCKET_STRING;
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
assert (rc == 0);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
void *server = test_context_socket (ZMQ_DEALER);
void *client = test_context_socket (ZMQ_DEALER);
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5));
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
expect_bounce_fail (server, client);
close_zero_linger (client);
close_zero_linger (server);
test_context_socket_close_zero_linger (client);
test_context_socket_close_zero_linger (server);
}
void test_success ()
{
// 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:*");
assert (rc == 0);
len = MAX_SOCKET_STRING;
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
assert (rc == 0);
rc = zmq_connect (client, my_endpoint);
assert (rc == 0);
void *server = test_context_socket (ZMQ_DEALER);
void *client = test_context_socket (ZMQ_DEALER);
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4));
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
TEST_ASSERT_SUCCESS_ERRNO (zmq_connect (client, my_endpoint));
bounce (server, client);
close_zero_linger (client);
close_zero_linger (server);
test_context_socket_close_zero_linger (client);
test_context_socket_close_zero_linger (server);
}
void test_vanilla_socket ()
{
// Unauthenticated messages from a vanilla socket shouldn't be received
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5);
assert (rc == 0);
rc = zmq_bind (server, "tcp://127.0.0.1:*");
assert (rc == 0);
len = MAX_SOCKET_STRING;
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
assert (rc == 0);
void *server = test_context_socket (ZMQ_DEALER);
TEST_ASSERT_SUCCESS_ERRNO (
zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5));
char my_endpoint[MAX_SOCKET_STRING];
bind_loopback_ipv4 (server, my_endpoint, sizeof my_endpoint);
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);
@ -225,7 +184,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
@ -235,16 +194,20 @@ 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);
close_zero_linger (server);
// Shutdown
rc = zmq_ctx_term (ctx);
assert (rc == 0);
// Wait until ZAP handler terminates
zmq_threadclose (zap_thread);
return 0;
test_context_socket_close_zero_linger (server);
}
int main ()
{
setup_test_environment ();
UNITY_BEGIN ();
RUN_TEST (test_no_domain);
RUN_TEST (test_wrong_domain_fails);
RUN_TEST (test_success);
RUN_TEST (test_vanilla_socket);
return UNITY_END ();
}

View File

@ -28,6 +28,8 @@
*/
#include "testutil.hpp"
#include "testutil_unity.hpp"
#if defined(ZMQ_HAVE_WINDOWS)
#include <winsock2.h>
#include <ws2tcpip.h>
@ -40,43 +42,37 @@
#include <unistd.h>
#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 ();
}