Skip to content

Commit

Permalink
WIP: add ZMQ_ZAP_DOMAIN_REQUIRED to hide backward incompatible change
Browse files Browse the repository at this point in the history
  • Loading branch information
bluca committed Oct 8, 2017
1 parent 13c977a commit 82a0959
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/zmq.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,7 @@ ZMQ_EXPORT void zmq_threadclose (void* thread);
#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
#define ZMQ_BINDTODEVICE 92
#define ZMQ_ZAP_DOMAIN_REQUIRED 93

/* DRAFT 0MQ socket events and monitoring */
/* Unspecified system errors during handshake. Event value is an errno. */
Expand Down
8 changes: 7 additions & 1 deletion src/curve_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,9 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
zmq_assert (rc == 0);

if (zap_required ()) {
// Given this is a backward-incompatible change, it's behind a socket
// option disabled by default.
if (zap_required () || !options.zap_domain_required) {
// Use ZAP protocol (RFC 27) to authenticate the user.
rc = session->zap_connect ();
if (rc == 0) {
Expand All @@ -404,6 +406,10 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
rc = receive_and_process_zap_reply ();
if (rc == -1)
return -1;
} else if (!options.zap_domain_required) {
// This supports the Stonehouse pattern (encryption without
// authentication) in legacy mode (allow empty ZAP domain).
state = sending_ready;
} else {
session->get_socket ()->event_handshake_failed_no_detail (
session->get_endpoint (), EFAULT);
Expand Down
18 changes: 17 additions & 1 deletion src/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ zmq::options_t::options_t () :
heartbeat_ttl (0),
heartbeat_interval (0),
heartbeat_timeout (-1),
use_fd (-1)
use_fd (-1),
zap_domain_required (false)
{
memset (curve_public_key, 0, CURVE_KEYSIZE);
memset (curve_secret_key, 0, CURVE_KEYSIZE);
Expand Down Expand Up @@ -628,6 +629,14 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
}
break;

case ZMQ_ZAP_DOMAIN_REQUIRED:
if (is_int) {
zap_domain_required = (value != 0);
return 0;
}
break;


default:
#if defined (ZMQ_ACT_MILITANT)
// There are valid scenarios for probing with unknown socket option
Expand Down Expand Up @@ -1052,6 +1061,13 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
}
break;

case ZMQ_ZAP_DOMAIN_REQUIRED:
if (is_int) {
*value = zap_domain_required;
return 0;
}
break;

default:
#if defined (ZMQ_ACT_MILITANT)
malformed = false;
Expand Down
3 changes: 3 additions & 0 deletions src/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ namespace zmq

// Device to bind the underlying socket to, eg. VRF or interface
std::string bound_device;

// Enforce a non-empty ZAP domain requirement for PLAIN auth
bool zap_domain_required;
};
}

Expand Down
5 changes: 4 additions & 1 deletion src/plain_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ zmq::plain_server_t::plain_server_t (session_base_t *session_,
// Note that there is no point to PLAIN if ZAP is not set up to handle the
// username and password, so if ZAP is not configured it is considered a
// failure.
zmq_assert (zap_required());
// Given this is a backward-incompatible change, it's behind a socket
// option disabled by default.
if (options.zap_domain_required)
zmq_assert (zap_required());
}

zmq::plain_server_t::~plain_server_t ()
Expand Down
1 change: 1 addition & 0 deletions src/zmq_draft.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
#define ZMQ_BINDTODEVICE 92
#define ZMQ_ZAP_DOMAIN_REQUIRED 93

/* DRAFT 0MQ socket events and monitoring */
/* Unspecified system errors during handshake. Event value is an errno. */
Expand Down
2 changes: 2 additions & 0 deletions tests/test_security_zap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);

#ifdef ZMQ_ZAP_DOMAIN_REQUIRED
// no ZAP handler
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
Expand All @@ -339,6 +340,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
client_socket_config_, client_socket_config_data_);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
#endif

// ZAP handler disconnecting on first message
fprintf(stderr, "test_zap_unsuccessful ZAP handler disconnects\n");
Expand Down
7 changes: 7 additions & 0 deletions tests/testutil_security.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ void socket_config_curve_server (void *server, void *server_secret)
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, test_zap_domain,
strlen (test_zap_domain));
assert (rc == 0);

#ifdef ZMQ_ZAP_DOMAIN_REQUIRED
int required = 1;
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN_REQUIRED, &required,
sizeof (int));
assert (rc == 0);
#endif
}

struct curve_client_data_t
Expand Down

0 comments on commit 82a0959

Please sign in to comment.