Commit e2d3ba9c authored by sigiesec's avatar sigiesec

Problem: classification ZMQ_HANDSHAKE_FAILED_* events is coarse-grained and partially misleading

Solution: redesign ZMQ_HANDSHAKE_FAILED_* events, introduce new class of ZMQ_HANDSHAKE_FAILED_AUTH events
parent f252f02b
......@@ -568,11 +568,37 @@ ZMQ_EXPORT void zmq_threadclose (void* thread);
#define ZMQ_BINDTODEVICE 90
/* DRAFT 0MQ socket events and monitoring */
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
/* Unspecified system errors during handshake. Event value is an errno. */
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
/* Handshake complete successfully with successful authentication (if *
* enabled). Event value is unused. */
#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION 0x2000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP 0x4000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZAP 0x8000
/* Protocol errors between ZMTP peers or between server and ZAP handler. *
* Event value is one of ZMQ_PROTOCOL_ERROR_* */
#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000
/* Failed authentication requests. Event value is the numeric ZAP status *
* code, i.e. 300, 400 or 500. */
#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002
#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014
// the following two may be due to erroneous configuration of a peer
#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001
#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002
#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000
#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005
/* DRAFT Context options */
#define ZMQ_MSG_T_SIZE 6
......
......@@ -107,7 +107,8 @@ int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
// Therefore, it should be changed to zmq_assert (false);
// CURVE I: invalid handshake command
current_error_detail = zmtp;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED);
errno = EPROTO;
rc = -1;
break;
......@@ -177,17 +178,22 @@ int zmq::curve_server_t::decode (msg_t *msg_)
{
zmq_assert (state == ready);
if (msg_->size () < 33) {
// CURVE I : invalid CURVE client, sent malformed command
current_error_detail = zmtp;
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return -1;
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
if (memcmp (message, "\x07MESSAGE", 8)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO;
return -1;
}
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
if (memcmp (message, "\x07MESSAGE", 8)) {
// CURVE I: invalid CURVE client, did not send MESSAGE
current_error_detail = zmtp;
if (msg_->size () < 33) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
errno = EPROTO;
return -1;
}
......@@ -197,6 +203,8 @@ int zmq::curve_server_t::decode (msg_t *msg_)
memcpy (message_nonce + 16, message + 8, 8);
uint64_t nonce = get_uint64(message + 8);
if (nonce <= cn_peer_nonce) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE);
errno = EPROTO;
return -1;
}
......@@ -214,8 +222,8 @@ int zmq::curve_server_t::decode (msg_t *msg_)
memcpy (message_box + crypto_box_BOXZEROBYTES,
message + 16, msg_->size () - 16);
int rc = crypto_box_open_afternm (message_plaintext, message_box,
clen, message_nonce, cn_precom);
rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
message_nonce, cn_precom);
if (rc == 0) {
rc = msg_->close ();
zmq_assert (rc == 0);
......@@ -235,7 +243,8 @@ int zmq::curve_server_t::decode (msg_t *msg_)
}
else {
// CURVE I : connection key used for MESSAGE is wrong
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
}
free (message_plaintext);
......@@ -246,17 +255,21 @@ int zmq::curve_server_t::decode (msg_t *msg_)
int zmq::curve_server_t::process_hello (msg_t *msg_)
{
if (msg_->size () != 200) {
// CURVE I: client HELLO is not correct size
current_error_detail = zmtp;
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return -1;
const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
if (memcmp (hello, "\x05HELLO", 6)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO;
return -1;
}
const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
if (memcmp (hello, "\x05HELLO", 6)) {
// CURVE I: client HELLO has invalid command name
current_error_detail = zmtp;
if (msg_->size () != 200) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO;
return -1;
}
......@@ -266,7 +279,8 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
if (major != 1 || minor != 0) {
// CURVE I: client HELLO has unknown version number
current_error_detail = zmtp;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO;
return -1;
}
......@@ -286,12 +300,12 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
memcpy (hello_box + crypto_box_BOXZEROBYTES, hello + 120, 80);
// Open Box [64 * %x0](C'->S)
int rc = crypto_box_open (hello_plaintext, hello_box,
sizeof hello_box,
hello_nonce, cn_client, secret_key);
rc = crypto_box_open (hello_plaintext, hello_box, sizeof hello_box,
hello_nonce, cn_client, secret_key);
if (rc != 0) {
// CURVE I: cannot open client HELLO -- wrong server key?
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
return -1;
}
......@@ -345,8 +359,8 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_)
cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80);
rc = crypto_box (welcome_ciphertext, welcome_plaintext,
sizeof welcome_plaintext,
welcome_nonce, cn_client, secret_key);
sizeof welcome_plaintext, welcome_nonce, cn_client,
secret_key);
// TODO I think we should change this back to zmq_assert (rc == 0);
// as it was before https://github.com/zeromq/libzmq/pull/1832
......@@ -370,17 +384,22 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_)
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
if (msg_->size () < 257) {
// CURVE I: client INITIATE is not correct size
current_error_detail = zmtp;
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return -1;
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
if (memcmp (initiate, "\x08INITIATE", 9)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO;
return -1;
}
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
if (memcmp (initiate, "\x08INITIATE", 9)) {
// CURVE I: client INITIATE has invalid command name
current_error_detail = zmtp;
if (msg_->size () < 257) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
errno = EPROTO;
return -1;
}
......@@ -396,12 +415,12 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
memcpy (cookie_nonce, "COOKIE--", 8);
memcpy (cookie_nonce + 8, initiate + 9, 16);
int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
sizeof cookie_box,
cookie_nonce, cookie_key);
rc = crypto_secretbox_open (cookie_plaintext, cookie_box, sizeof cookie_box,
cookie_nonce, cookie_key);
if (rc != 0) {
// CURVE I: cannot open client INITIATE cookie
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
return -1;
}
......@@ -413,7 +432,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
// client that knows the server's secret temporary cookie key
// CURVE I: client INITIATE cookie is not valid
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
return -1;
}
......@@ -437,7 +457,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
clen, initiate_nonce, cn_client, cn_secret);
if (rc != 0) {
// CURVE I: cannot open client INITIATE
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
return -1;
}
......@@ -462,7 +483,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
vouch_nonce, client_key, cn_secret);
if (rc != 0) {
// CURVE I: cannot open client INITIATE vouch
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
errno = EPROTO;
return -1;
}
......@@ -473,7 +495,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
// client that knows the server's secret short-term key
// CURVE I: invalid handshake from client (public key)
current_error_detail = encryption;
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE);
errno = EPROTO;
return -1;
}
......@@ -564,4 +587,16 @@ void zmq::curve_server_t::send_zap_request (const uint8_t *key)
zap_client_t::send_zap_request ("CURVE", 5, key, crypto_box_PUBLICKEYBYTES);
}
int zmq::curve_server_t::check_basic_command_structure (msg_t *msg_)
{
if (msg_->size () <= 1 || msg_->size () <= ((uint8_t *) msg_->data ())[0]) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED);
errno = EPROTO;
return -1;
}
return 0;
}
#endif
......@@ -104,6 +104,7 @@ namespace zmq
int produce_error (msg_t *msg_) const;
void send_zap_request (const uint8_t *key);
int check_basic_command_structure (msg_t *msg_);
};
}
......
......@@ -53,14 +53,6 @@ namespace zmq
error
};
// Provides more details when in status_t::error
enum error_detail_t {
no_detail,
zmtp,
zap,
encryption
};
mechanism_t (const options_t &options_);
virtual ~mechanism_t ();
......@@ -81,10 +73,6 @@ namespace zmq
// Returns the status of this mechanism.
virtual status_t status () const = 0;
// Returns details about of the current error of the mechanism.
// Returned value does not makes sense if the current status is not error.
virtual error_detail_t error_detail () const { return no_detail; }
void set_peer_identity (const void *id_ptr, size_t id_size);
void peer_identity (msg_t *msg_);
......
......@@ -1692,22 +1692,16 @@ void zmq::socket_base_t::event_handshake_failed_no_detail (
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL);
}
void zmq::socket_base_t::event_handshake_failed_zmtp (const std::string &addr_,
int err_)
{
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP);
}
void zmq::socket_base_t::event_handshake_failed_zap (const std::string &addr_,
int err_)
void zmq::socket_base_t::event_handshake_failed_protocol (
const std::string &addr_, int err_)
{
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ZAP);
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
}
void zmq::socket_base_t::event_handshake_failed_encryption (
const std::string &addr_, int err_)
void zmq::socket_base_t::event_handshake_failed_auth (const std::string &addr_,
int err_)
{
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH);
}
void zmq::socket_base_t::event_handshake_succeeded (const std::string &addr_,
......
......@@ -134,9 +134,8 @@ namespace zmq
void event_close_failed (const std::string &addr_, int err_);
void event_disconnected (const std::string &addr_, zmq::fd_t fd_);
void event_handshake_failed_no_detail(const std::string &addr_, int err_);
void event_handshake_failed_zmtp(const std::string &addr_, int err_);
void event_handshake_failed_zap(const std::string &addr_, int err_);
void event_handshake_failed_encryption(const std::string &addr_, int err_);
void event_handshake_failed_protocol(const std::string &addr_, int err_);
void event_handshake_failed_auth(const std::string &addr_, int err_);
void event_handshake_succeeded(const std::string &addr_, int err_);
protected:
......
......@@ -702,6 +702,8 @@ bool zmq::stream_engine_t::handshake ()
}
#endif
else {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
error (protocol_error);
return false;
}
......@@ -979,21 +981,12 @@ void zmq::stream_engine_t::error (error_reason_t reason)
}
zmq_assert (session);
#ifdef ZMQ_BUILD_DRAFT_API
int err = errno;
if (mechanism == NULL) {
if (reason == protocol_error)
socket->event_handshake_failed_zmtp (endpoint, err);
else
socket->event_handshake_failed_no_detail (endpoint, err);
} else if (mechanism->status () == mechanism_t::handshaking) {
if (mechanism->error_detail () == mechanism_t::zmtp)
socket->event_handshake_failed_zmtp (endpoint, err);
else if (mechanism->error_detail () == mechanism_t::zap)
socket->event_handshake_failed_zap (endpoint, err);
else if (mechanism->error_detail () == mechanism_t::encryption)
socket->event_handshake_failed_encryption (endpoint, err);
else
socket->event_handshake_failed_no_detail (endpoint, err);
// protocol errors have been signaled already at the point where they occurred
if (reason != protocol_error
&& (mechanism == NULL
|| mechanism->status () == mechanism_t::handshaking)) {
int err = errno;
socket->event_handshake_failed_no_detail (endpoint, err);
}
#endif
socket->event_disconnected (endpoint, (int) s);
......
......@@ -40,8 +40,7 @@ zap_client_t::zap_client_t (session_base_t *const session_,
const options_t &options_) :
mechanism_t (options_),
session (session_),
peer_address (peer_address_),
current_error_detail (no_detail)
peer_address (peer_address_)
{
}
......@@ -155,34 +154,35 @@ int zap_client_t::receive_and_process_zap_reply ()
return close_and_return (msg, -1);
}
if ((msg[i].flags () & msg_t::more) == (i < 6 ? 0 : msg_t::more)) {
// CURVE I : ZAP handler sent incomplete reply message
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY);
errno = EPROTO;
current_error_detail = mechanism_t::zap;
return close_and_return (msg, -1);
}
}
// Address delimiter frame
if (msg[0].size () > 0) {
// CURVE I: ZAP handler sent malformed reply message
// TODO can a ZAP handler produce such a message at all?
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED);
errno = EPROTO;
current_error_detail = mechanism_t::zap;
return close_and_return (msg, -1);
}
// Version frame
if (msg[1].size () != 3 || memcmp (msg[1].data (), "1.0", 3)) {
// CURVE I: ZAP handler sent bad version number
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION);
errno = EPROTO;
current_error_detail = mechanism_t::zap;
return close_and_return (msg, -1);
}
// Request id frame
if (msg[2].size () != 1 || memcmp (msg[2].data (), "1", 1)) {
// CURVE I: ZAP handler sent bad request ID
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID);
errno = EPROTO;
current_error_detail = mechanism_t::zap;
return close_and_return (msg, -1);
}
......@@ -191,9 +191,9 @@ int zap_client_t::receive_and_process_zap_reply ()
if (msg[3].size () != 3 || status_code_data[0] < '2'
|| status_code_data[0] > '5' || status_code_data[1] != '0'
|| status_code_data[2] != '0') {
// CURVE I: ZAP handler sent invalid status code
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE);
errno = EPROTO;
current_error_detail = mechanism_t::zap;
return close_and_return (msg, -1);
}
......@@ -208,6 +208,9 @@ int zap_client_t::receive_and_process_zap_reply ()
msg[6].size (), true);
if (rc != 0) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA);
errno = EPROTO;
return close_and_return (msg, -1);
}
......@@ -226,30 +229,23 @@ void zap_client_t::handle_zap_status_code ()
{
// we can assume here that status_code is a valid ZAP status code,
// i.e. 200, 300, 400 or 500
int err = 0;
int status_code_numeric = 0;
switch (status_code[0]) {
case '2':
return;
case '3':
err = EAGAIN;
status_code_numeric = 300;
break;
case '4':
err = EACCES;
status_code_numeric = 400;
break;
case '5':
err = EFAULT;
status_code_numeric = 500;
break;
}
// TODO use event_handshake_failed_zap here? but this is not a ZAP
// protocol error
session->get_socket ()->event_handshake_failed_no_detail (
session->get_endpoint (), err);
}
mechanism_t::error_detail_t zap_client_t::error_detail () const
{
return current_error_detail;
session->get_socket ()->event_handshake_failed_auth (
session->get_endpoint (), status_code_numeric);
}
zap_client_common_handshake_t::zap_client_common_handshake_t (
......
......@@ -57,19 +57,12 @@ class zap_client_t : public virtual mechanism_t
virtual int receive_and_process_zap_reply ();
virtual void handle_zap_status_code ();
// methods from mechanism_t
error_detail_t error_detail () const;
protected:
session_base_t *const session;
const std::string peer_address;
// Status code as received from ZAP handler
std::string status_code;
// Details about the current error state
// TODO remove this
error_detail_t current_error_detail;
};
class zap_client_common_handshake_t : public zap_client_t
......
......@@ -50,11 +50,37 @@
#define ZMQ_BINDTODEVICE 90
/* DRAFT 0MQ socket events and monitoring */
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
/* Unspecified system errors during handshake. Event value is an errno. */
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
/* Handshake complete successfully with successful authentication (if *
* enabled). Event value is unused. */
#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION 0x2000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP 0x4000
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZAP 0x8000
/* Protocol errors between ZMTP peers or between server and ZAP handler. *
* Event value is one of ZMQ_PROTOCOL_ERROR_* */
#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000
/* Failed authentication requests. Event value is the numeric ZAP status *
* code, i.e. 300, 400 or 500. */
#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002
#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014
// the following two may be due to erroneous configuration of a peer
#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001
#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002
#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000
#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005
/* DRAFT Context options */
#define ZMQ_MSG_T_SIZE 6
......
......@@ -103,7 +103,8 @@ void test_garbage_key(void *ctx,
#ifdef ZMQ_BUILD_DRAFT_API
int handshake_failed_encryption_event_count =
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
// handshake_failed_encryption_event_count should be at least two because
// expect_bounce_fail involves two exchanges
......@@ -149,9 +150,8 @@ void test_curve_security_with_bogus_client_credentials (
int event_count = 0;
#ifdef ZMQ_BUILD_DRAFT_API
// TODO add another event type ZMQ_EVENT_HANDSHAKE_FAILED_AUTH for this case?
event_count = expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EACCES);
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400);
assert (event_count <= 1);
#endif
......@@ -160,7 +160,10 @@ void test_curve_security_with_bogus_client_credentials (
|| 1 <= zmq_atomic_counter_value (zap_requests_handled));
}
void expect_zmtp_failure (void *client, char *my_endpoint, void *server, void *server_mon)
void expect_zmtp_mechanism_mismatch (void *client,
char *my_endpoint,
void *server,
void *server_mon)
{
// This must be caught by the curve_server class, not passed to ZAP
int rc = zmq_connect (client, my_endpoint);
......@@ -169,7 +172,9 @@ void expect_zmtp_failure (void *client, char *my_endpoint, void *server, void *s
close_zero_linger (client);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP);
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
#endif
assert (0 == zmq_atomic_counter_value (zap_requests_handled));
......@@ -183,7 +188,7 @@ void test_curve_security_with_null_client_credentials (void *ctx,
void *client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
expect_zmtp_failure (client, my_endpoint, server, server_mon);
expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
}
void test_curve_security_with_plain_client_credentials (void *ctx,
......@@ -198,7 +203,7 @@ void test_curve_security_with_plain_client_credentials (void *ctx,
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
assert (rc == 0);
expect_zmtp_failure (client, my_endpoint, server, server_mon);
expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
}
int connect_vanilla_socket (char *my_endpoint)
......@@ -279,11 +284,12 @@ void test_curve_security_invalid_hello_wrong_length (char *my_endpoint,
send_greeting (s);
// send CURVE HELLO of wrong size
send(s, "\x04\x05HELLO");
send(s, "\x04\x06\x05HELLO");
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
EPROTO);
expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
#endif
close (s);
......@@ -361,8 +367,9 @@ void test_curve_security_invalid_hello_command_name (char *my_endpoint,
send_command(s, hello);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
EPROTO);
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
#endif
close (s);
......@@ -388,8 +395,9 @@ void test_curve_security_invalid_hello_version (char *my_endpoint,
send_command (s, hello);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
EPROTO);
expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
#endif
close (s);
......@@ -459,11 +467,12 @@ void test_curve_security_invalid_initiate_length (char *my_endpoint,
assert (res == -1);
#endif
send(s, "\x04\x08INITIATE");
send(s, "\x04\x09\x08INITIATE");
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
EPROTO);
expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
#endif
close (s);
......@@ -510,8 +519,9 @@ void test_curve_security_invalid_initiate_command_name (char *my_endpoint,
send_command (s, initiate);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
EPROTO);
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
#endif
close (s);
......@@ -532,8 +542,9 @@ void test_curve_security_invalid_initiate_command_encrypted_cookie (
send_command (s, initiate);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION, EPROTO);
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
#endif
close (s);
......@@ -554,8 +565,9 @@ void test_curve_security_invalid_initiate_command_encrypted_content (
send_command (s, initiate);
#ifdef ZMQ_BUILD_DRAFT_API
expect_monitor_event_multiple (
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION, EPROTO);
expect_monitor_event_multiple (server_mon,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
#endif
close (s);
......@@ -648,7 +660,6 @@ int main (void)
server_mon, timeout);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
fprintf (stderr, "test_curve_security_with_null_client_credentials\n");
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
&server_mon, my_endpoint);
......@@ -664,7 +675,6 @@ int main (void)
server_mon);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
fprintf (stderr, "test_curve_security_unauthenticated_message\n");
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
&server_mon, my_endpoint);
......
......@@ -87,11 +87,12 @@ void test_zap_protocol_error (void *ctx,
void *server,
void *server_mon,
socket_config_fn socket_config_,
void *socket_config_data_)
void *socket_config_data_,
int expected_error)
{
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_EVENT_HANDSHAKE_FAILED_ZAP, EPROTO,
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, expected_error,
#else
0, 0,
#endif
......@@ -119,7 +120,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
&zap_handler_wrong_version, server_socket_config_,
server_socket_config_data_);
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
client_socket_config_, client_socket_config_data_);
client_socket_config_, client_socket_config_data_,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
#else
0
#endif
);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
......@@ -130,7 +137,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
&zap_handler_wrong_request_id, server_socket_config_,
server_socket_config_data_);
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
client_socket_config_, client_socket_config_data_);
client_socket_config_, client_socket_config_data_,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
#else
0
#endif
);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
......@@ -141,7 +154,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
&zap_handler_wrong_status_invalid, server_socket_config_,
server_socket_config_data_);
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
client_socket_config_, client_socket_config_data_);
client_socket_config_, client_socket_config_data_,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
#else
0
#endif
);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
......@@ -152,7 +171,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
&zap_handler_too_many_parts, server_socket_config_,
server_socket_config_data_);
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
client_socket_config_, client_socket_config_data_);
client_socket_config_, client_socket_config_data_,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
#else
0
#endif
);
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
handler);
......@@ -169,7 +194,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
server_socket_config_data_);
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EAGAIN,
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 300,
#else
0, 0,
#endif
......@@ -184,7 +209,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
&zap_handler_wrong_status_internal_error, server_socket_config_);
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
#ifdef ZMQ_BUILD_DRAFT_API
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EFAULT,
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 500,
#else
0, 0,
#endif
......
......@@ -331,11 +331,11 @@ void setup_context_and_server_side (
char monitor_endpoint [] = "inproc://monitor-server";
// Monitor handshake events on the server
rc = zmq_socket_monitor (
*server, monitor_endpoint,
ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
| ZMQ_EVENT_HANDSHAKE_FAILED_ZAP | ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP
| ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
rc = zmq_socket_monitor (*server, monitor_endpoint,
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
| ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
| ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
assert (rc == 0);
// Create socket for collecting monitor events
......@@ -514,7 +514,11 @@ int expect_monitor_event_multiple (void *server_mon,
}
if (event != expected_event
|| (-1 != expected_err && err != expected_err)) {
fprintf (stderr, "Unexpected event: %x (err = %i)\n", event, err);
fprintf (
stderr,
"Unexpected event: 0x%x, value = %i/0x%x (expected: 0x%x, value "
"= %i/0x%x)\n",
event, err, err, expected_event, expected_err, expected_err);
assert (false);
}
++count_of_expected_events;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment