mirror of
https://github.com/zeromq/libzmq.git
synced 2025-03-19 18:03:50 +00: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
|
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
|
ZMQ_VMCI_BUFFER_SIZE: Retrieve buffer size of the VMCI socket
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The `ZMQ_VMCI_BUFFER_SIZE` option shall retrieve the size of the underlying
|
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
|
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
|
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.
|
See http://rfc.zeromq.org/spec:27 for more details.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
@ -1091,6 +1093,22 @@ Default value:: empty
|
|||||||
Applicable socket types:: all, when using TCP transport
|
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
|
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
|
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_PRINCIPAL_NAMETYPE 90
|
||||||
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
|
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
|
||||||
#define ZMQ_BINDTODEVICE 92
|
#define ZMQ_BINDTODEVICE 92
|
||||||
|
#define ZMQ_ZAP_ENFORCE_DOMAIN 93
|
||||||
|
|
||||||
/* DRAFT 0MQ socket events and monitoring */
|
/* DRAFT 0MQ socket events and monitoring */
|
||||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
/* 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);
|
rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret);
|
||||||
zmq_assert (rc == 0);
|
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.
|
// Use ZAP protocol (RFC 27) to authenticate the user.
|
||||||
rc = session->zap_connect ();
|
rc = session->zap_connect ();
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
@ -404,6 +406,10 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
|||||||
rc = receive_and_process_zap_reply ();
|
rc = receive_and_process_zap_reply ();
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
return -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 {
|
} else {
|
||||||
session->get_socket ()->event_handshake_failed_no_detail (
|
session->get_socket ()->event_handshake_failed_no_detail (
|
||||||
session->get_endpoint (), EFAULT);
|
session->get_endpoint (), EFAULT);
|
||||||
|
@ -89,7 +89,8 @@ zmq::options_t::options_t () :
|
|||||||
heartbeat_ttl (0),
|
heartbeat_ttl (0),
|
||||||
heartbeat_interval (0),
|
heartbeat_interval (0),
|
||||||
heartbeat_timeout (-1),
|
heartbeat_timeout (-1),
|
||||||
use_fd (-1)
|
use_fd (-1),
|
||||||
|
zap_enforce_domain (false)
|
||||||
{
|
{
|
||||||
memset (curve_public_key, 0, CURVE_KEYSIZE);
|
memset (curve_public_key, 0, CURVE_KEYSIZE);
|
||||||
memset (curve_secret_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;
|
break;
|
||||||
|
|
||||||
|
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||||
|
if (is_int) {
|
||||||
|
zap_enforce_domain = (value != 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#if defined (ZMQ_ACT_MILITANT)
|
#if defined (ZMQ_ACT_MILITANT)
|
||||||
// There are valid scenarios for probing with unknown socket option
|
// 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;
|
break;
|
||||||
|
|
||||||
|
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||||
|
if (is_int) {
|
||||||
|
*value = zap_enforce_domain;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#if defined (ZMQ_ACT_MILITANT)
|
#if defined (ZMQ_ACT_MILITANT)
|
||||||
malformed = false;
|
malformed = false;
|
||||||
|
@ -242,6 +242,9 @@ namespace zmq
|
|||||||
|
|
||||||
// Device to bind the underlying socket to, eg. VRF or interface
|
// Device to bind the underlying socket to, eg. VRF or interface
|
||||||
std::string bound_device;
|
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
|
// 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
|
// username and password, so if ZAP is not configured it is considered a
|
||||||
// failure.
|
// 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 ()
|
zmq::plain_server_t::~plain_server_t ()
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90
|
#define ZMQ_GSSAPI_PRINCIPAL_NAMETYPE 90
|
||||||
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
|
#define ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE 91
|
||||||
#define ZMQ_BINDTODEVICE 92
|
#define ZMQ_BINDTODEVICE 92
|
||||||
|
#define ZMQ_ZAP_ENFORCE_DOMAIN 93
|
||||||
|
|
||||||
/* DRAFT 0MQ socket events and monitoring */
|
/* DRAFT 0MQ socket events and monitoring */
|
||||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
/* 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,
|
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||||
handler);
|
handler);
|
||||||
|
|
||||||
|
#ifdef ZMQ_ZAP_ENFORCE_DOMAIN
|
||||||
// no ZAP handler
|
// no ZAP handler
|
||||||
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
|
fprintf (stderr, "test_zap_unsuccessful no ZAP handler started\n");
|
||||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
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_);
|
client_socket_config_, client_socket_config_data_);
|
||||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||||
handler);
|
handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
// ZAP handler disconnecting on first message
|
// ZAP handler disconnecting on first message
|
||||||
fprintf(stderr, "test_zap_unsuccessful ZAP handler disconnects\n");
|
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,
|
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, test_zap_domain,
|
||||||
strlen (test_zap_domain));
|
strlen (test_zap_domain));
|
||||||
assert (rc == 0);
|
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
|
struct curve_client_data_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user