mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-13 10:52:56 +01:00
Problem: strict ZAP protocol adherence is backward incompatible
Solution: add ZMQ_ZAP_ENFORCE_DOMAIN to hide backward incompatible change and make it disabled by default. In a future release that breaks API compatibility we can then switch the default to enabled in order to achieve full RFC compatibility. Fixes #2762
This commit is contained in:
parent
50bddbaac9
commit
b6aee51691
@ -838,6 +838,18 @@ Default value:: not set
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_ZAP_ENFORCE_DOMAIN: Retrieve ZAP domain handling mode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The 'ZMQ_ZAP_ENFORCE_DOMAIN' option shall retrieve the flag that determines
|
||||
whether a ZAP domain is strictly required or not.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: int
|
||||
Option value unit:: 0, 1
|
||||
Default value:: 0
|
||||
Applicable socket types:: all, when using ZAP
|
||||
|
||||
|
||||
ZMQ_VMCI_BUFFER_SIZE: Retrieve buffer size of the VMCI socket
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The `ZMQ_VMCI_BUFFER_SIZE` option shall retrieve the size of the underlying
|
||||
|
@ -1081,7 +1081,9 @@ ZMQ_ZAP_DOMAIN: Set RFC 27 authentication domain
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Sets the domain for ZAP (ZMQ RFC 27) authentication. A ZAP domain must be
|
||||
specified to enable authentication. When the ZAP domain is empty, which is
|
||||
the default, ZAP authentication is disabled.
|
||||
the default, ZAP authentication is disabled. This is not compatible with
|
||||
previous versions of libzmq, so it can be controlled by ZMQ_ZAP_ENFORCE_DOMAIN
|
||||
which for now is disabled by default.
|
||||
See http://rfc.zeromq.org/spec:27 for more details.
|
||||
|
||||
[horizontal]
|
||||
@ -1091,6 +1093,22 @@ Default value:: empty
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_ZAP_ENFORCE_DOMAIN: Set ZAP domain handling to strictly adhere the RFC
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The ZAP (ZMQ RFC 27) authentication protocol specifies that a domain must
|
||||
always be set. Older versions of libzmq did not follow the spec and allowed
|
||||
an empty domain to be set.
|
||||
This option can be used to enabled or disable the stricter, backward
|
||||
incompatible behaviour. For now it is disabled by default, but in a future
|
||||
version it will be enabled by default.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: int
|
||||
Option value unit:: 0, 1
|
||||
Default value:: 0
|
||||
Applicable socket types:: all, when using ZAP
|
||||
|
||||
|
||||
ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Assign an arbitrary number of filters that will be applied for each new TCP
|
||||
|
@ -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_ENFORCE_DOMAIN 93
|
||||
|
||||
/* DRAFT 0MQ socket events and monitoring */
|
||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
||||
|
@ -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_enforce_domain) {
|
||||
// Use ZAP protocol (RFC 27) to authenticate the user.
|
||||
rc = session->zap_connect ();
|
||||
if (rc == 0) {
|
||||
@ -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_enforce_domain) {
|
||||
// This supports the Stonehouse pattern (encryption without
|
||||
// authentication) in legacy mode (domain set but no handler).
|
||||
state = sending_ready;
|
||||
} else {
|
||||
session->get_socket ()->event_handshake_failed_no_detail (
|
||||
session->get_endpoint (), EFAULT);
|
||||
|
@ -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_enforce_domain (false)
|
||||
{
|
||||
memset (curve_public_key, 0, CURVE_KEYSIZE);
|
||||
memset (curve_secret_key, 0, CURVE_KEYSIZE);
|
||||
@ -628,6 +629,14 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||
if (is_int) {
|
||||
zap_enforce_domain = (value != 0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
#if defined (ZMQ_ACT_MILITANT)
|
||||
// There are valid scenarios for probing with unknown socket option
|
||||
@ -1052,6 +1061,13 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||
if (is_int) {
|
||||
*value = zap_enforce_domain;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined (ZMQ_ACT_MILITANT)
|
||||
malformed = false;
|
||||
|
@ -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_enforce_domain;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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_enforce_domain)
|
||||
zmq_assert (zap_required());
|
||||
}
|
||||
|
||||
zmq::plain_server_t::~plain_server_t ()
|
||||
|
@ -50,6 +50,7 @@
|
||||
#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90
|
||||
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
|
||||
#define ZMQ_BINDTODEVICE 92
|
||||
#define ZMQ_ZAP_ENFORCE_DOMAIN 93
|
||||
|
||||
/* DRAFT 0MQ socket events and monitoring */
|
||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
||||
|
@ -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_ENFORCE_DOMAIN
|
||||
// no ZAP handler
|
||||
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
@ -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");
|
||||
|
@ -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_ENFORCE_DOMAIN
|
||||
int required = 1;
|
||||
rc = zmq_setsockopt (server, ZMQ_ZAP_ENFORCE_DOMAIN, &required,
|
||||
sizeof (int));
|
||||
assert (rc == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct curve_client_data_t
|
||||
|
Loading…
Reference in New Issue
Block a user