Commit 11b3c938 authored by sigiesec's avatar sigiesec

Problem: console output for PLAIN protocol errors

Solution: emit socket monitor events for PLAIN protocol errors (like CURVE)
parent e2d3ba9c
...@@ -182,15 +182,17 @@ int zmq::curve_server_t::decode (msg_t *msg_) ...@@ -182,15 +182,17 @@ int zmq::curve_server_t::decode (msg_t *msg_)
if (rc == -1) if (rc == -1)
return -1; return -1;
const size_t size = msg_->size ();
const uint8_t *message = static_cast <uint8_t *> (msg_->data ()); const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
if (memcmp (message, "\x07MESSAGE", 8)) {
if (size < 8 || memcmp (message, "\x07MESSAGE", 8)) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
if (msg_->size () < 33) { if (size < 33) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE); ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
...@@ -259,15 +261,17 @@ int zmq::curve_server_t::process_hello (msg_t *msg_) ...@@ -259,15 +261,17 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
if (rc == -1) if (rc == -1)
return -1; return -1;
const size_t size = msg_->size ();
const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ()); const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
if (memcmp (hello, "\x05HELLO", 6)) {
if (size < 6 || memcmp (hello, "\x05HELLO", 6)) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
if (msg_->size () != 200) { if (size != 200) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
...@@ -388,15 +392,17 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) ...@@ -388,15 +392,17 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
if (rc == -1) if (rc == -1)
return -1; return -1;
const size_t size = msg_->size ();
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ()); const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
if (memcmp (initiate, "\x08INITIATE", 9)) {
if (size < 9 || memcmp (initiate, "\x08INITIATE", 9)) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
if (msg_->size () < 257) { if (size < 257) {
session->get_socket ()->event_handshake_failed_protocol ( session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), session->get_endpoint (),
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE); ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
...@@ -438,7 +444,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) ...@@ -438,7 +444,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
return -1; return -1;
} }
const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES; const size_t clen = (size - 113) + crypto_box_BOXZEROBYTES;
uint8_t initiate_nonce [crypto_box_NONCEBYTES]; uint8_t initiate_nonce [crypto_box_NONCEBYTES];
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256]; uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
...@@ -587,16 +593,4 @@ void zmq::curve_server_t::send_zap_request (const uint8_t *key) ...@@ -587,16 +593,4 @@ void zmq::curve_server_t::send_zap_request (const uint8_t *key)
zap_client_t::send_zap_request ("CURVE", 5, key, crypto_box_PUBLICKEYBYTES); 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 #endif
...@@ -104,7 +104,6 @@ namespace zmq ...@@ -104,7 +104,6 @@ namespace zmq
int produce_error (msg_t *msg_) const; int produce_error (msg_t *msg_) const;
void send_zap_request (const uint8_t *key); void send_zap_request (const uint8_t *key);
int check_basic_command_structure (msg_t *msg_);
}; };
} }
......
...@@ -89,8 +89,9 @@ int zmq::plain_server_t::process_handshake_command (msg_t *msg_) ...@@ -89,8 +89,9 @@ int zmq::plain_server_t::process_handshake_command (msg_t *msg_)
rc = process_initiate (msg_); rc = process_initiate (msg_);
break; break;
default: default:
// Temporary support for security debugging // TODO see comment in curve_server_t::process_handshake_command
puts ("PLAIN I: invalid handshake command"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED);
errno = EPROTO; errno = EPROTO;
rc = -1; rc = -1;
break; break;
...@@ -106,12 +107,16 @@ int zmq::plain_server_t::process_handshake_command (msg_t *msg_) ...@@ -106,12 +107,16 @@ int zmq::plain_server_t::process_handshake_command (msg_t *msg_)
int zmq::plain_server_t::process_hello (msg_t *msg_) int zmq::plain_server_t::process_hello (msg_t *msg_)
{ {
int rc = check_basic_command_structure (msg_);
if (rc == -1)
return -1;
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 (); int bytes_left = msg_->size ();
if (bytes_left < 6 || memcmp (ptr, "\x05HELLO", 6)) { if (bytes_left < 6 || memcmp (ptr, "\x05HELLO", 6)) {
// Temporary support for security debugging session->get_socket ()->event_handshake_failed_protocol (
puts ("PLAIN I: invalid PLAIN client, did not send HELLO"); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -119,17 +124,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_) ...@@ -119,17 +124,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
bytes_left -= 6; bytes_left -= 6;
if (bytes_left < 1) { if (bytes_left < 1) {
// Temporary support for security debugging // PLAIN I: invalid PLAIN client, did not send username
puts ("PLAIN I: invalid PLAIN client, did not send username"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
const size_t username_length = static_cast <size_t> (*ptr++); const uint8_t username_length = *ptr++;
bytes_left -= 1; bytes_left -= 1;
if (bytes_left < username_length) { if (bytes_left < (int)username_length) {
// Temporary support for security debugging // PLAIN I: invalid PLAIN client, sent malformed username
puts ("PLAIN I: invalid PLAIN client, sent malformed username"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -137,17 +144,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_) ...@@ -137,17 +144,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
ptr += username_length; ptr += username_length;
bytes_left -= username_length; bytes_left -= username_length;
if (bytes_left < 1) { if (bytes_left < 1) {
// Temporary support for security debugging // PLAIN I: invalid PLAIN client, did not send password
puts ("PLAIN I: invalid PLAIN client, did not send password"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
const size_t password_length = static_cast <size_t> (*ptr++); const uint8_t password_length = *ptr++;
bytes_left -= 1; bytes_left -= 1;
if (bytes_left < password_length) { if (bytes_left < (int)password_length) {
// Temporary support for security debugging // PLAIN I: invalid PLAIN client, sent malformed password
puts ("PLAIN I: invalid PLAIN client, sent malformed password"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -156,8 +165,9 @@ int zmq::plain_server_t::process_hello (msg_t *msg_) ...@@ -156,8 +165,9 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
ptr += password_length; ptr += password_length;
bytes_left -= password_length; bytes_left -= password_length;
if (bytes_left > 0) { if (bytes_left > 0) {
// Temporary support for security debugging // PLAIN I: invalid PLAIN client, sent extraneous data
puts ("PLAIN I: invalid PLAIN client, sent extraneous data"); session->get_socket ()->event_handshake_failed_protocol (
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
...@@ -166,7 +176,7 @@ int zmq::plain_server_t::process_hello (msg_t *msg_) ...@@ -166,7 +176,7 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
// 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.
int rc = session->zap_connect (); rc = session->zap_connect ();
if (rc != 0) if (rc != 0)
return -1; return -1;
send_zap_request (username, password); send_zap_request (username, password);
...@@ -187,8 +197,8 @@ int zmq::plain_server_t::process_initiate (msg_t *msg_) ...@@ -187,8 +197,8 @@ int zmq::plain_server_t::process_initiate (msg_t *msg_)
const size_t bytes_left = msg_->size (); const size_t bytes_left = msg_->size ();
if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) { if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) {
// Temporary support for security debugging session->get_socket ()->event_handshake_failed_protocol (
puts ("PLAIN I: invalid PLAIN client, did not send INITIATE"); session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
errno = EPROTO; errno = EPROTO;
return -1; return -1;
} }
......
...@@ -248,6 +248,18 @@ void zap_client_t::handle_zap_status_code () ...@@ -248,6 +248,18 @@ void zap_client_t::handle_zap_status_code ()
session->get_endpoint (), status_code_numeric); session->get_endpoint (), status_code_numeric);
} }
int zap_client_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;
}
zap_client_common_handshake_t::zap_client_common_handshake_t ( zap_client_common_handshake_t::zap_client_common_handshake_t (
session_base_t *const session_, session_base_t *const session_,
const std::string &peer_address_, const std::string &peer_address_,
......
...@@ -57,6 +57,7 @@ class zap_client_t : public virtual mechanism_t ...@@ -57,6 +57,7 @@ class zap_client_t : public virtual mechanism_t
virtual int receive_and_process_zap_reply (); virtual int receive_and_process_zap_reply ();
virtual void handle_zap_status_code (); virtual void handle_zap_status_code ();
int check_basic_command_structure (msg_t *msg_);
protected: protected:
session_base_t *const session; session_base_t *const session;
const std::string peer_address; const std::string peer_address;
......
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