Skip to content

Commit 7f1f705

Browse files
authored
Merge pull request #3018 from bluca/null_auth_regression
Problem: backward incompatible change to NULL with ZAP
2 parents 7722381 + 1c5a63e commit 7f1f705

4 files changed

Lines changed: 75 additions & 21 deletions

File tree

src/null_mechanism.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,27 @@ int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_)
6969
errno = EAGAIN;
7070
return -1;
7171
}
72+
// Given this is a backward-incompatible change, it's behind a socket
73+
// option disabled by default.
7274
int rc = session->zap_connect ();
73-
if (rc == -1) {
75+
if (rc == -1 && options.zap_enforce_domain) {
7476
session->get_socket ()->event_handshake_failed_no_detail (
7577
session->get_endpoint (), EFAULT);
7678
return -1;
79+
} else if (rc == 0) {
80+
send_zap_request ();
81+
zap_request_sent = true;
82+
83+
// TODO actually, it is quite unlikely that we can read the ZAP
84+
// reply already, but removing this has some strange side-effect
85+
// (probably because the pipe's in_active flag is true until a read
86+
// is attempted)
87+
rc = receive_and_process_zap_reply ();
88+
if (rc != 0)
89+
return -1;
90+
91+
zap_reply_received = true;
7792
}
78-
send_zap_request ();
79-
zap_request_sent = true;
80-
81-
// TODO actually, it is quite unlikely that we can read the ZAP
82-
// reply already, but removing this has some strange side-effect
83-
// (probably because the pipe's in_active flag is true until a read
84-
// is attempted)
85-
rc = receive_and_process_zap_reply ();
86-
if (rc != 0)
87-
return -1;
88-
89-
zap_reply_received = true;
9093
}
9194

9295
if (zap_reply_received && status_code != "200") {

tests/test_security_null.cpp

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,22 +88,65 @@ int main (void)
8888
void *ctx = zmq_ctx_new ();
8989
assert (ctx);
9090

91+
// We first test client/server with a ZAP domain but with no handler
92+
// If there is no handler, libzmq should ignore the ZAP option unless
93+
// ZMQ_ZAP_ENFORCE_DOMAIN is set
94+
void *server = zmq_socket (ctx, ZMQ_DEALER);
95+
assert (server);
96+
void *client = zmq_socket (ctx, ZMQ_DEALER);
97+
assert (client);
98+
int rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
99+
assert (rc == 0);
100+
rc = zmq_bind (server, "tcp://127.0.0.1:*");
101+
assert (rc == 0);
102+
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
103+
assert (rc == 0);
104+
rc = zmq_connect (client, my_endpoint);
105+
assert (rc == 0);
106+
bounce (server, client);
107+
close_zero_linger (client);
108+
close_zero_linger (server);
109+
110+
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
111+
// Now set ZMQ_ZAP_ENFORCE_DOMAIN which strictly enforces the ZAP
112+
// RFC but is backward-incompatible, now it should fail
113+
server = zmq_socket (ctx, ZMQ_DEALER);
114+
assert (server);
115+
client = zmq_socket (ctx, ZMQ_DEALER);
116+
assert (client);
117+
int required = 1;
118+
rc =
119+
zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required, sizeof (int));
120+
assert (rc == 0);
121+
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 5);
122+
assert (rc == 0);
123+
rc = zmq_bind (server, "tcp://127.0.0.1:*");
124+
assert (rc == 0);
125+
rc = zmq_getsockopt (server, ZMQ_LAST_ENDPOINT, my_endpoint, &len);
126+
assert (rc == 0);
127+
rc = zmq_connect (client, my_endpoint);
128+
assert (rc == 0);
129+
expect_bounce_fail (server, client);
130+
close_zero_linger (client);
131+
close_zero_linger (server);
132+
#endif
133+
91134
// Spawn ZAP handler
92135
// We create and bind ZAP socket in main thread to avoid case
93136
// where child thread does not start up fast enough.
94137
void *handler = zmq_socket (ctx, ZMQ_REP);
95138
assert (handler);
96-
int rc = zmq_bind (handler, "inproc://zeromq.zap.01");
139+
rc = zmq_bind (handler, "inproc://zeromq.zap.01");
97140
assert (rc == 0);
98141
void *zap_thread = zmq_threadstart (&zap_handler, handler);
99142

100143
// We bounce between a binding server and a connecting client
101144

102145
// We first test client/server with no ZAP domain
103146
// Libzmq does not call our ZAP handler, the connect must succeed
104-
void *server = zmq_socket (ctx, ZMQ_DEALER);
147+
server = zmq_socket (ctx, ZMQ_DEALER);
105148
assert (server);
106-
void *client = zmq_socket (ctx, ZMQ_DEALER);
149+
client = zmq_socket (ctx, ZMQ_DEALER);
107150
assert (client);
108151
rc = zmq_bind (server, "tcp://127.0.0.1:*");
109152
assert (rc == 0);

tests/test_security_zap.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,12 @@ void test_zap_errors (socket_config_fn server_socket_config_,
326326

327327
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
328328
// no ZAP handler
329+
int enforce = 1;
329330
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
330-
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
331-
&server_mon, my_endpoint, NULL,
332-
server_socket_config_);
331+
setup_context_and_server_side (
332+
&ctx, &handler, &zap_thread, &server, &server_mon, my_endpoint, NULL,
333+
server_socket_config_,
334+
server_socket_config_data_ ? server_socket_config_data_ : &enforce);
333335
test_zap_unsuccessful_no_handler (
334336
ctx, my_endpoint, server, server_mon,
335337
#ifdef ZMQ_BUILD_DRAFT_API

tests/testutil_security.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,17 @@ void socket_config_null_client (void *server, void *server_secret)
4747

4848
void socket_config_null_server (void *server, void *server_secret)
4949
{
50-
LIBZMQ_UNUSED (server_secret);
51-
5250
int rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, test_zap_domain,
5351
strlen (test_zap_domain));
5452
assert (rc == 0);
53+
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
54+
int required = server_secret ? *(int *) server_secret : 0;
55+
rc =
56+
zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required, sizeof (int));
57+
assert (rc == 0);
58+
#else
59+
LIBZMQ_UNUSED (server_secret);
60+
#endif
5561
}
5662

5763
// PLAIN specific functions

0 commit comments

Comments
 (0)