Commit 44f6aa3d authored by sigiesec's avatar sigiesec

Problem: gssapi_* do not emit ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL events

Solution: emit appropriate events
parent ca7eee35
...@@ -125,6 +125,9 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_) ...@@ -125,6 +125,9 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
} }
if (state != recv_next_token) { if (state != recv_next_token) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
......
...@@ -128,8 +128,15 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_) ...@@ -128,8 +128,15 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ()); const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
size_t bytes_left = msg_->size (); size_t bytes_left = msg_->size ();
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return rc;
// Get command string // Get command string
if (bytes_left < 8 || memcmp (ptr, "\x07MESSAGE", 8)) { if (bytes_left < 8 || memcmp (ptr, "\x07MESSAGE", 8)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -138,6 +145,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_) ...@@ -138,6 +145,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
// Get token length // Get token length
if (bytes_left < 4) { if (bytes_left < 4) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -148,6 +158,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_) ...@@ -148,6 +158,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
// Get token value // Get token value
if (bytes_left < wrapped.length) { if (bytes_left < wrapped.length) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -168,11 +181,16 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_) ...@@ -168,11 +181,16 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
maj_stat = gss_unwrap(&min_stat, context, &wrapped, &plaintext, maj_stat = gss_unwrap(&min_stat, context, &wrapped, &plaintext,
&state, (gss_qop_t *) NULL); &state, (gss_qop_t *) NULL);
// TODO I don't think it is a good idea to use zmq_assert here. If
// decryption fails, gss_unwrap returns GSS_S_BAD_SIG. This opens up
// to DoS attacks by clients! Instead, a
// ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC event should be emitted.
zmq_assert(maj_stat == GSS_S_COMPLETE); zmq_assert(maj_stat == GSS_S_COMPLETE);
zmq_assert(state); zmq_assert(state);
// Re-initialize msg_ for plaintext // Re-initialize msg_ for plaintext
int rc = msg_->close (); rc = msg_->close ();
zmq_assert (rc == 0); zmq_assert (rc == 0);
rc = msg_->init_size (plaintext.length-1); rc = msg_->init_size (plaintext.length-1);
...@@ -190,6 +208,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_) ...@@ -190,6 +208,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
free(wrapped.value); free(wrapped.value);
if (bytes_left > 0) { if (bytes_left > 0) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -231,8 +252,15 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va ...@@ -231,8 +252,15 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ()); const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
size_t bytes_left = msg_->size (); size_t bytes_left = msg_->size ();
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return rc;
// Get command string // Get command string
if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) { if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -241,6 +269,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va ...@@ -241,6 +269,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
// Get token length // Get token length
if (bytes_left < 4) { if (bytes_left < 4) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -250,6 +281,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va ...@@ -250,6 +281,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
// Get token value // Get token value
if (bytes_left < token_length_) { if (bytes_left < token_length_) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -264,6 +298,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va ...@@ -264,6 +298,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
} }
if (bytes_left > 0) { if (bytes_left > 0) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -317,14 +354,28 @@ int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_) ...@@ -317,14 +354,28 @@ int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_)
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ()); const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
size_t bytes_left = msg_->size (); size_t bytes_left = msg_->size ();
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return rc;
if (bytes_left < 6 || memcmp (ptr, "\x05READY", 6)) { if (bytes_left < 6 || memcmp (ptr, "\x05READY", 6)) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
ptr += 6; ptr += 6;
bytes_left -= 6; bytes_left -= 6;
return parse_metadata (ptr, bytes_left); rc = parse_metadata (ptr, bytes_left);
if (rc == -1)
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA);
return rc;
} }
const gss_OID zmq::gssapi_mechanism_base_t::convert_nametype (int zmq_nametype) const gss_OID zmq::gssapi_mechanism_base_t::convert_nametype (int zmq_nametype)
{ {
switch (zmq_nametype) { switch (zmq_nametype) {
......
...@@ -114,6 +114,9 @@ int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_) ...@@ -114,6 +114,9 @@ int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
} }
if (state != recv_next_token) { if (state != recv_next_token) {
session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
......
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