mirror of
https://github.com/zeromq/libzmq.git
synced 2025-03-20 10:23:47 +00:00
Merge pull request #1032 from hurtonm/master
PLAIN: Implement ERROR handling in client
This commit is contained in:
commit
3338c76bac
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
zmq::plain_client_t::plain_client_t (const options_t &options_) :
|
zmq::plain_client_t::plain_client_t (const options_t &options_) :
|
||||||
mechanism_t (options_),
|
mechanism_t (options_),
|
||||||
|
error_command_received (false),
|
||||||
state (sending_hello)
|
state (sending_hello)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -62,38 +63,45 @@ int zmq::plain_client_t::next_handshake_command (msg_t *msg_)
|
|||||||
|
|
||||||
int zmq::plain_client_t::process_handshake_command (msg_t *msg_)
|
int zmq::plain_client_t::process_handshake_command (msg_t *msg_)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
const unsigned char *cmd_data =
|
||||||
|
static_cast <unsigned char *> (msg_->data ());
|
||||||
|
const size_t data_size = msg_->size ();
|
||||||
|
|
||||||
switch (state) {
|
int rc = 0;
|
||||||
case waiting_for_welcome:
|
if (data_size >= 8 && !memcmp (cmd_data, "\7WELCOME", 8))
|
||||||
rc = process_welcome (msg_);
|
rc = process_welcome (cmd_data, data_size);
|
||||||
if (rc == 0)
|
else
|
||||||
state = sending_initiate;
|
if (data_size >= 6 && !memcmp (cmd_data, "\5READY", 6))
|
||||||
break;
|
rc = process_ready (cmd_data, data_size);
|
||||||
case waiting_for_ready:
|
else
|
||||||
rc = process_ready (msg_);
|
if (data_size >= 6 && !memcmp (cmd_data, "\5ERROR", 6))
|
||||||
if (rc == 0)
|
rc = process_error (cmd_data, data_size);
|
||||||
state = ready;
|
else {
|
||||||
break;
|
// Temporary support for security debugging
|
||||||
default:
|
puts ("PLAIN I: invalid handshake command");
|
||||||
// Temporary support for security debugging
|
errno = EPROTO;
|
||||||
puts ("PLAIN I: invalid handshake command");
|
rc = -1;
|
||||||
errno = EPROTO;
|
|
||||||
rc = -1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
rc = msg_->close ();
|
rc = msg_->close ();
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
rc = msg_->init ();
|
rc = msg_->init ();
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
zmq::mechanism_t::status_t zmq::plain_client_t::status () const
|
zmq::mechanism_t::status_t zmq::plain_client_t::status () const
|
||||||
{
|
{
|
||||||
return state == ready? mechanism_t::ready: mechanism_t::handshaking;
|
if (state == ready)
|
||||||
|
return mechanism_t::ready;
|
||||||
|
else
|
||||||
|
if (error_command_received)
|
||||||
|
return mechanism_t::error;
|
||||||
|
else
|
||||||
|
return mechanism_t::handshaking;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::plain_client_t::produce_hello (msg_t *msg_) const
|
int zmq::plain_client_t::produce_hello (msg_t *msg_) const
|
||||||
@ -125,17 +133,18 @@ int zmq::plain_client_t::produce_hello (msg_t *msg_) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::plain_client_t::process_welcome (msg_t *msg_)
|
int zmq::plain_client_t::process_welcome (
|
||||||
|
const unsigned char *cmd_data, size_t data_size)
|
||||||
{
|
{
|
||||||
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
|
if (state != waiting_for_welcome) {
|
||||||
const size_t bytes_left = msg_->size ();
|
|
||||||
|
|
||||||
if (bytes_left != 8 || memcmp (ptr, "\x07WELCOME", 8)) {
|
|
||||||
// Temporary support for security debugging
|
|
||||||
puts ("PLAIN I: invalid PLAIN client, did not send WELCOME");
|
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (data_size != 8) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state = sending_initiate;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,16 +179,35 @@ int zmq::plain_client_t::produce_initiate (msg_t *msg_) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::plain_client_t::process_ready (msg_t *msg_)
|
int zmq::plain_client_t::process_ready (
|
||||||
|
const unsigned char *cmd_data, size_t data_size)
|
||||||
{
|
{
|
||||||
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
|
if (state != waiting_for_ready) {
|
||||||
const size_t bytes_left = msg_->size ();
|
|
||||||
|
|
||||||
if (bytes_left < 6 || memcmp (ptr, "\x05READY", 6)) {
|
|
||||||
// Temporary support for security debugging
|
|
||||||
puts ("PLAIN I: invalid PLAIN client, did not send READY");
|
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return parse_metadata (ptr + 6, bytes_left - 6);
|
const int rc = parse_metadata (cmd_data + 6, data_size - 6);
|
||||||
|
if (rc == 0)
|
||||||
|
state = ready;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::plain_client_t::process_error (
|
||||||
|
const unsigned char *cmd_data, size_t data_size)
|
||||||
|
{
|
||||||
|
if (state != waiting_for_welcome && state != waiting_for_ready) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (data_size == 6) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const size_t size = static_cast <size_t> (cmd_data [6]);
|
||||||
|
if (6 + 1 + size != data_size) {
|
||||||
|
errno = EPROTO;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
error_command_received = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ namespace zmq
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool error_command_received;
|
||||||
|
|
||||||
enum state_t {
|
enum state_t {
|
||||||
sending_hello,
|
sending_hello,
|
||||||
waiting_for_welcome,
|
waiting_for_welcome,
|
||||||
@ -55,8 +57,12 @@ namespace zmq
|
|||||||
int produce_hello (msg_t *msg_) const;
|
int produce_hello (msg_t *msg_) const;
|
||||||
int produce_initiate (msg_t *msg_) const;
|
int produce_initiate (msg_t *msg_) const;
|
||||||
|
|
||||||
int process_welcome (msg_t *msg);
|
int process_welcome (
|
||||||
int process_ready (msg_t *msg_);
|
const unsigned char *cmd_data, size_t data_size);
|
||||||
|
int process_ready (
|
||||||
|
const unsigned char *cmd_data, size_t data_size);
|
||||||
|
int process_error (
|
||||||
|
const unsigned char *cmd_data, size_t data_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user