mirror of
https://github.com/zeromq/libzmq.git
synced 2025-10-07 19:44:47 +02:00
Updated security mechanisms to use variable-length commands
RFC23, RFC24, RFC26 now use variable-length command names that end in null octet (valid C strings) instead of fixed-length space padded strings.
This commit is contained in:
@@ -138,7 +138,7 @@ int zmq::curve_client_t::encode (msg_t *msg_)
|
|||||||
|
|
||||||
uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||||
|
|
||||||
memcpy (message, "MESSAGE ", 8);
|
memcpy (message, "MESSAGE\0", 8);
|
||||||
memcpy (message + 8, &cn_nonce, 8);
|
memcpy (message + 8, &cn_nonce, 8);
|
||||||
memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
|
memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
|
||||||
mlen - crypto_box_BOXZEROBYTES);
|
mlen - crypto_box_BOXZEROBYTES);
|
||||||
@@ -161,7 +161,7 @@ int zmq::curve_client_t::decode (msg_t *msg_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||||
if (memcmp (message, "MESSAGE ", 8)) {
|
if (memcmp (message, "MESSAGE\0", 8)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -235,11 +235,11 @@ int zmq::curve_client_t::hello_msg (msg_t *msg_)
|
|||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
uint8_t *hello = static_cast <uint8_t *> (msg_->data ());
|
uint8_t *hello = static_cast <uint8_t *> (msg_->data ());
|
||||||
|
|
||||||
memcpy (hello, "HELLO ", 8);
|
memcpy (hello, "HELLO\0", 6);
|
||||||
// CurveZMQ major and minor version numbers
|
// CurveZMQ major and minor version numbers
|
||||||
memcpy (hello + 8, "\1\0", 2);
|
memcpy (hello + 6, "\1\0", 2);
|
||||||
// Anti-amplification padding
|
// Anti-amplification padding
|
||||||
memset (hello + 10, 0, 70);
|
memset (hello + 8, 0, 72);
|
||||||
// Client public connection key
|
// Client public connection key
|
||||||
memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES);
|
memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES);
|
||||||
// Short nonce, prefixed by "CurveZMQHELLO---"
|
// Short nonce, prefixed by "CurveZMQHELLO---"
|
||||||
@@ -260,7 +260,7 @@ int zmq::curve_client_t::process_welcome (msg_t *msg_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * welcome = static_cast <uint8_t *> (msg_->data ());
|
const uint8_t * welcome = static_cast <uint8_t *> (msg_->data ());
|
||||||
if (memcmp (welcome, "WELCOME ", 8)) {
|
if (memcmp (welcome, "WELCOME\0", 8)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -346,18 +346,18 @@ int zmq::curve_client_t::initiate_msg (msg_t *msg_)
|
|||||||
mlen, initiate_nonce, cn_server, cn_secret);
|
mlen, initiate_nonce, cn_server, cn_secret);
|
||||||
zmq_assert (rc == 0);
|
zmq_assert (rc == 0);
|
||||||
|
|
||||||
rc = msg_->init_size (112 + mlen - crypto_box_BOXZEROBYTES);
|
rc = msg_->init_size (113 + mlen - crypto_box_BOXZEROBYTES);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
|
||||||
uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
||||||
|
|
||||||
memcpy (initiate, "INITIATE", 8);
|
memcpy (initiate, "INITIATE\0", 9);
|
||||||
// Cookie provided by the server in the WELCOME command
|
// Cookie provided by the server in the WELCOME command
|
||||||
memcpy (initiate + 8, cn_cookie, 96);
|
memcpy (initiate + 9, cn_cookie, 96);
|
||||||
// Short nonce, prefixed by "CurveZMQINITIATE"
|
// Short nonce, prefixed by "CurveZMQINITIATE"
|
||||||
memcpy (initiate + 104, &cn_nonce, 8);
|
memcpy (initiate + 105, &cn_nonce, 8);
|
||||||
// Box [C + vouch + metadata](C'->S')
|
// Box [C + vouch + metadata](C'->S')
|
||||||
memcpy (initiate + 112, initiate_box + crypto_box_BOXZEROBYTES,
|
memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
|
||||||
mlen - crypto_box_BOXZEROBYTES);
|
mlen - crypto_box_BOXZEROBYTES);
|
||||||
|
|
||||||
cn_nonce++;
|
cn_nonce++;
|
||||||
@@ -367,18 +367,18 @@ int zmq::curve_client_t::initiate_msg (msg_t *msg_)
|
|||||||
|
|
||||||
int zmq::curve_client_t::process_ready (msg_t *msg_)
|
int zmq::curve_client_t::process_ready (msg_t *msg_)
|
||||||
{
|
{
|
||||||
if (msg_->size () < 32) {
|
if (msg_->size () < 30) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
const uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
||||||
if (memcmp (ready, "READY ", 8)) {
|
if (memcmp (ready, "READY\0", 6)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t clen = (msg_->size () - 16) + crypto_box_BOXZEROBYTES;
|
const size_t clen = (msg_->size () - 14) + crypto_box_BOXZEROBYTES;
|
||||||
|
|
||||||
uint8_t ready_nonce [crypto_box_NONCEBYTES];
|
uint8_t ready_nonce [crypto_box_NONCEBYTES];
|
||||||
uint8_t ready_plaintext [crypto_box_ZEROBYTES + 256];
|
uint8_t ready_plaintext [crypto_box_ZEROBYTES + 256];
|
||||||
@@ -386,10 +386,10 @@ int zmq::curve_client_t::process_ready (msg_t *msg_)
|
|||||||
|
|
||||||
memset (ready_box, 0, crypto_box_BOXZEROBYTES);
|
memset (ready_box, 0, crypto_box_BOXZEROBYTES);
|
||||||
memcpy (ready_box + crypto_box_BOXZEROBYTES,
|
memcpy (ready_box + crypto_box_BOXZEROBYTES,
|
||||||
ready + 16, clen - crypto_box_BOXZEROBYTES);
|
ready + 14, clen - crypto_box_BOXZEROBYTES);
|
||||||
|
|
||||||
memcpy (ready_nonce, "CurveZMQREADY---", 16);
|
memcpy (ready_nonce, "CurveZMQREADY---", 16);
|
||||||
memcpy (ready_nonce + 16, ready + 8, 8);
|
memcpy (ready_nonce + 16, ready + 6, 8);
|
||||||
|
|
||||||
int rc = crypto_box_open_afternm (ready_plaintext, ready_box,
|
int rc = crypto_box_open_afternm (ready_plaintext, ready_box,
|
||||||
clen, ready_nonce, cn_precom);
|
clen, ready_nonce, cn_precom);
|
||||||
|
@@ -141,7 +141,7 @@ int zmq::curve_server_t::encode (msg_t *msg_)
|
|||||||
|
|
||||||
uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||||
|
|
||||||
memcpy (message, "MESSAGE ", 8);
|
memcpy (message, "MESSAGE\0", 8);
|
||||||
memcpy (message + 8, &cn_nonce, 8);
|
memcpy (message + 8, &cn_nonce, 8);
|
||||||
memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
|
memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
|
||||||
mlen - crypto_box_BOXZEROBYTES);
|
mlen - crypto_box_BOXZEROBYTES);
|
||||||
@@ -164,7 +164,7 @@ int zmq::curve_server_t::decode (msg_t *msg_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||||
if (memcmp (message, "MESSAGE ", 8)) {
|
if (memcmp (message, "MESSAGE\0", 8)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -236,13 +236,13 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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, "HELLO ", 8)) {
|
if (memcmp (hello, "HELLO\0", 6)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t major = hello [8];
|
const uint8_t major = hello [6];
|
||||||
const uint8_t minor = hello [9];
|
const uint8_t minor = hello [7];
|
||||||
|
|
||||||
if (major != 1 || minor != 0) {
|
if (major != 1 || minor != 0) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
@@ -327,7 +327,7 @@ int zmq::curve_server_t::welcome_msg (msg_t *msg_)
|
|||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
|
||||||
uint8_t * const welcome = static_cast <uint8_t *> (msg_->data ());
|
uint8_t * const welcome = static_cast <uint8_t *> (msg_->data ());
|
||||||
memcpy (welcome, "WELCOME ", 8);
|
memcpy (welcome, "WELCOME\0", 8);
|
||||||
memcpy (welcome + 8, welcome_nonce + 8, 16);
|
memcpy (welcome + 8, welcome_nonce + 8, 16);
|
||||||
memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144);
|
memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144);
|
||||||
|
|
||||||
@@ -336,13 +336,13 @@ int zmq::curve_server_t::welcome_msg (msg_t *msg_)
|
|||||||
|
|
||||||
int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||||
{
|
{
|
||||||
if (msg_->size () < 224) {
|
if (msg_->size () < 225) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
||||||
if (memcmp (initiate, "INITIATE", 8)) {
|
if (memcmp (initiate, "INITIATE\0", 9)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -353,10 +353,10 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
|||||||
|
|
||||||
// Open Box [C' + s'](t)
|
// Open Box [C' + s'](t)
|
||||||
memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
|
memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
|
||||||
memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 24, 80);
|
memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);
|
||||||
|
|
||||||
memcpy (cookie_nonce, "COOKIE--", 8);
|
memcpy (cookie_nonce, "COOKIE--", 8);
|
||||||
memcpy (cookie_nonce + 8, initiate + 8, 16);
|
memcpy (cookie_nonce + 8, initiate + 9, 16);
|
||||||
|
|
||||||
int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
|
int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
|
||||||
sizeof cookie_box,
|
sizeof cookie_box,
|
||||||
@@ -375,7 +375,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t clen = (msg_->size () - 112) + crypto_box_BOXZEROBYTES;
|
const size_t clen = (msg_->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 + 96 + 256];
|
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 96 + 256];
|
||||||
@@ -384,10 +384,10 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
|||||||
// Open Box [C + vouch + metadata](C'->S')
|
// Open Box [C + vouch + metadata](C'->S')
|
||||||
memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
|
memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
|
||||||
memcpy (initiate_box + crypto_box_BOXZEROBYTES,
|
memcpy (initiate_box + crypto_box_BOXZEROBYTES,
|
||||||
initiate + 112, clen - crypto_box_BOXZEROBYTES);
|
initiate + 113, clen - crypto_box_BOXZEROBYTES);
|
||||||
|
|
||||||
memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
|
memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
|
||||||
memcpy (initiate_nonce + 16, initiate + 104, 8);
|
memcpy (initiate_nonce + 16, initiate + 105, 8);
|
||||||
|
|
||||||
rc = crypto_box_open (initiate_plaintext, initiate_box,
|
rc = crypto_box_open (initiate_plaintext, initiate_box,
|
||||||
clen, initiate_nonce, cn_client, cn_secret);
|
clen, initiate_nonce, cn_client, cn_secret);
|
||||||
@@ -475,16 +475,16 @@ int zmq::curve_server_t::ready_msg (msg_t *msg_)
|
|||||||
mlen, ready_nonce, cn_precom);
|
mlen, ready_nonce, cn_precom);
|
||||||
zmq_assert (rc == 0);
|
zmq_assert (rc == 0);
|
||||||
|
|
||||||
rc = msg_->init_size (16 + mlen - crypto_box_BOXZEROBYTES);
|
rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
|
|
||||||
uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
||||||
|
|
||||||
memcpy (ready, "READY ", 8);
|
memcpy (ready, "READY\0", 6);
|
||||||
// Short nonce, prefixed by "CurveZMQREADY---"
|
// Short nonce, prefixed by "CurveZMQREADY---"
|
||||||
memcpy (ready + 8, &cn_nonce, 8);
|
memcpy (ready + 6, &cn_nonce, 8);
|
||||||
// Box [metadata](S'->C')
|
// Box [metadata](S'->C')
|
||||||
memcpy (ready + 16, ready_box + crypto_box_BOXZEROBYTES,
|
memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES,
|
||||||
mlen - crypto_box_BOXZEROBYTES);
|
mlen - crypto_box_BOXZEROBYTES);
|
||||||
|
|
||||||
cn_nonce++;
|
cn_nonce++;
|
||||||
|
@@ -52,7 +52,7 @@ const char *zmq::mechanism_t::socket_type_string (int socket_type) const
|
|||||||
static const char *names [] = {"PAIR", "PUB", "SUB", "REQ", "REP",
|
static const char *names [] = {"PAIR", "PUB", "SUB", "REQ", "REP",
|
||||||
"DEALER", "ROUTER", "PULL", "PUSH",
|
"DEALER", "ROUTER", "PULL", "PUSH",
|
||||||
"XPUB", "XSUB", "STREAM"};
|
"XPUB", "XSUB", "STREAM"};
|
||||||
zmq_assert (socket_type >= ZMQ_PAIR && socket_type <= ZMQ_STREAM);
|
zmq_assert (socket_type >= 0 && socket_type <= 10);
|
||||||
return names [socket_type];
|
return names [socket_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,8 +54,8 @@ int zmq::null_mechanism_t::next_handshake_message (msg_t *msg_)
|
|||||||
unsigned char *ptr = command_buffer;
|
unsigned char *ptr = command_buffer;
|
||||||
|
|
||||||
// Add mechanism string
|
// Add mechanism string
|
||||||
memcpy (ptr, "READY ", 8);
|
memcpy (ptr, "READY\0", 6);
|
||||||
ptr += 8;
|
ptr += 6;
|
||||||
|
|
||||||
// Add socket type property
|
// Add socket type property
|
||||||
const char *socket_type = socket_type_string (options.type);
|
const char *socket_type = socket_type_string (options.type);
|
||||||
@@ -91,13 +91,13 @@ int zmq::null_mechanism_t::process_handshake_message (msg_t *msg_)
|
|||||||
static_cast <unsigned char *> (msg_->data ());
|
static_cast <unsigned char *> (msg_->data ());
|
||||||
size_t bytes_left = msg_->size ();
|
size_t bytes_left = msg_->size ();
|
||||||
|
|
||||||
if (bytes_left < 8 || memcmp (ptr, "READY ", 8)) {
|
if (bytes_left < 6 || memcmp (ptr, "READY\0", 6)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += 8;
|
ptr += 6;
|
||||||
bytes_left -= 8;
|
bytes_left -= 6;
|
||||||
|
|
||||||
int rc = parse_metadata (ptr, bytes_left);
|
int rc = parse_metadata (ptr, bytes_left);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
|
@@ -295,9 +295,9 @@ int zmq::plain_mechanism_t::ready_command (msg_t *msg_) const
|
|||||||
|
|
||||||
unsigned char *ptr = command_buffer;
|
unsigned char *ptr = command_buffer;
|
||||||
|
|
||||||
// Add mechanism string
|
// Add command name
|
||||||
memcpy (ptr, "READY ", 8);
|
memcpy (ptr, "READY\0", 6);
|
||||||
ptr += 8;
|
ptr += 6;
|
||||||
|
|
||||||
// Add socket type property
|
// Add socket type property
|
||||||
const char *socket_type = socket_type_string (options.type);
|
const char *socket_type = socket_type_string (options.type);
|
||||||
@@ -325,11 +325,13 @@ int zmq::plain_mechanism_t::process_ready_command (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 ();
|
||||||
|
|
||||||
if (bytes_left < 8 || memcmp (ptr, "READY ", 8)) {
|
if (bytes_left < 6 || memcmp (ptr, "READY\0", 6)) {
|
||||||
errno = EPROTO;
|
errno = EPROTO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return parse_metadata (ptr + 8, bytes_left - 8);
|
ptr += 6;
|
||||||
|
bytes_left -= 6;
|
||||||
|
return parse_metadata (ptr, bytes_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmq::plain_mechanism_t::send_zap_request (const std::string &username,
|
void zmq::plain_mechanism_t::send_zap_request (const std::string &username,
|
||||||
|
@@ -104,7 +104,7 @@ int main (void)
|
|||||||
// Second frame contains the rest of greeting along with
|
// Second frame contains the rest of greeting along with
|
||||||
// the Ready command
|
// the Ready command
|
||||||
rc = zmq_recv (router, buffer, 255, 0);
|
rc = zmq_recv (router, buffer, 255, 0);
|
||||||
assert (rc == 99);
|
assert (rc == 97);
|
||||||
|
|
||||||
// First two bytes are major and minor version numbers.
|
// First two bytes are major and minor version numbers.
|
||||||
assert (buffer [0] == 3); // ZMTP/3.0
|
assert (buffer [0] == 3); // ZMTP/3.0
|
||||||
@@ -112,21 +112,20 @@ int main (void)
|
|||||||
|
|
||||||
// Mechanism is "NULL"
|
// Mechanism is "NULL"
|
||||||
assert (memcmp (buffer + 2, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 22) == 0);
|
assert (memcmp (buffer + 2, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 22) == 0);
|
||||||
assert (memcmp (buffer + 54, "\0\53READY ", 10) == 0);
|
assert (memcmp (buffer + 54, "\0\51READY\0", 8) == 0);
|
||||||
assert (memcmp (buffer + 64, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
assert (memcmp (buffer + 62, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||||
assert (memcmp (buffer + 86, "\10Identity\0\0\0\0", 13) == 0);
|
assert (memcmp (buffer + 84, "\10Identity\0\0\0\0", 13) == 0);
|
||||||
|
|
||||||
// Announce we are ready
|
// Announce we are ready
|
||||||
memcpy (buffer, "\0\53", 2);
|
memcpy (buffer, "\0\51READY\0", 8);
|
||||||
memcpy (buffer + 2, "READY ", 8);
|
memcpy (buffer + 8, "\13Socket-Type\0\0\0\6STREAM", 22);
|
||||||
memcpy (buffer + 10, "\13Socket-Type\0\0\0\6ROUTER", 22);
|
memcpy (buffer + 30, "\10Identity\0\0\0\0", 13);
|
||||||
memcpy (buffer + 32, "\10Identity\0\0\0\0", 13);
|
|
||||||
|
|
||||||
// Send Ready command
|
// Send Ready command
|
||||||
rc = zmq_msg_send (&identity, router, ZMQ_SNDMORE);
|
rc = zmq_msg_send (&identity, router, ZMQ_SNDMORE);
|
||||||
assert (rc > 0);
|
assert (rc > 0);
|
||||||
rc = zmq_send (router, buffer, 45, 0);
|
rc = zmq_send (router, buffer, 43, 0);
|
||||||
assert (rc == 45);
|
assert (rc == 43);
|
||||||
|
|
||||||
// Now we expect the data from the DEALER socket
|
// Now we expect the data from the DEALER socket
|
||||||
// First frame is, again, the identity of the connection
|
// First frame is, again, the identity of the connection
|
||||||
|
@@ -19,106 +19,44 @@
|
|||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "testutil.hpp"
|
#include "testutil.hpp"
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
zap_handler (void *zap)
|
zap_handler (void *zap)
|
||||||
{
|
{
|
||||||
int rc, more;
|
char *version = s_recv (zap);
|
||||||
size_t optlen;
|
char *sequence = s_recv (zap);
|
||||||
zmq_msg_t version, seqno, domain, mechanism, username, password;
|
char *domain = s_recv (zap);
|
||||||
zmq_msg_t status_code, status_text, user_id;
|
char *mechanism = s_recv (zap);
|
||||||
|
char *username = s_recv (zap);
|
||||||
|
char *password = s_recv (zap);
|
||||||
|
|
||||||
// Version
|
assert (streq (version, "1.0"));
|
||||||
rc = zmq_msg_init (&version);
|
assert (streq (mechanism, "PLAIN"));
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&version, zap, 0);
|
|
||||||
assert (rc == 3 && memcmp (zmq_msg_data (&version), "1.0", 3) == 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Sequence number
|
s_sendmore (zap, version);
|
||||||
rc = zmq_msg_init (&seqno);
|
s_sendmore (zap, sequence);
|
||||||
assert (rc == 0);
|
if (streq (username, "admin")
|
||||||
rc = zmq_msg_recv (&seqno, zap, 0);
|
&& streq (password, "password")) {
|
||||||
assert (rc != -1);
|
s_sendmore (zap, "200");
|
||||||
optlen = sizeof more;
|
s_sendmore (zap, "OK");
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
s_send (zap, "anonymous");
|
||||||
assert (rc == 0 && more == 1);
|
}
|
||||||
|
else {
|
||||||
|
s_sendmore (zap, "400");
|
||||||
|
s_sendmore (zap, "Invalid username or password");
|
||||||
|
s_send (zap, "");
|
||||||
|
}
|
||||||
|
|
||||||
// Domain
|
free (version);
|
||||||
rc = zmq_msg_init (&domain);
|
free (sequence);
|
||||||
assert (rc == 0);
|
free (domain);
|
||||||
rc = zmq_msg_recv (&domain, zap, 0);
|
free (mechanism);
|
||||||
assert (rc != -1);
|
free (username);
|
||||||
optlen = sizeof more;
|
free (password);
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Mechanism
|
int rc = zmq_close (zap);
|
||||||
rc = zmq_msg_init (&mechanism);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&mechanism, zap, 0);
|
|
||||||
assert (rc == 5 && memcmp (zmq_msg_data (&mechanism), "PLAIN", 5) == 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Username
|
|
||||||
rc = zmq_msg_init (&username);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&username, zap, 0);
|
|
||||||
bool username_ok = (rc == 5 && memcmp (zmq_msg_data (&username), "admin", 5) == 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Password
|
|
||||||
rc = zmq_msg_init (&password);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&password, zap, 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 0);
|
|
||||||
|
|
||||||
bool password_ok = (rc == 8 && memcmp (zmq_msg_data (&password), "password", 8) == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_send (&version, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 3);
|
|
||||||
|
|
||||||
rc = zmq_msg_send (&seqno, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc != -1);
|
|
||||||
|
|
||||||
rc = zmq_msg_init_size (&status_code, 3);
|
|
||||||
assert (rc == 0);
|
|
||||||
memcpy (zmq_msg_data (&status_code), username_ok && password_ok? "200": "400", 3);
|
|
||||||
rc = zmq_msg_send (&status_code, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 3);
|
|
||||||
|
|
||||||
rc = zmq_msg_init (&status_text);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_send (&status_text, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_init (&user_id);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_send (&user_id, zap, 0);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&domain);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&mechanism);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&username);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&password);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_close (zap);
|
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -20,93 +20,34 @@
|
|||||||
#include "platform.hpp"
|
#include "platform.hpp"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "testutil.hpp"
|
#include "testutil.hpp"
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
zap_handler (void *zap)
|
zap_handler (void *zap)
|
||||||
{
|
{
|
||||||
int rc, more;
|
char *version = s_recv (zap);
|
||||||
size_t optlen;
|
char *sequence = s_recv (zap);
|
||||||
zmq_msg_t version, seqno, domain, mechanism, key;
|
char *domain = s_recv (zap);
|
||||||
zmq_msg_t status_code, status_text, user_id;
|
char *mechanism = s_recv (zap);
|
||||||
|
char *client_key = s_recv (zap);
|
||||||
|
|
||||||
// Version
|
assert (streq (version, "1.0"));
|
||||||
rc = zmq_msg_init (&version);
|
assert (streq (mechanism, "CURVE"));
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&version, zap, 0);
|
|
||||||
assert (rc == 3 && memcmp (zmq_msg_data (&version), "1.0", 3) == 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Sequence number
|
s_sendmore (zap, version);
|
||||||
rc = zmq_msg_init (&seqno);
|
s_sendmore (zap, sequence);
|
||||||
assert (rc == 0);
|
s_sendmore (zap, "200");
|
||||||
rc = zmq_msg_recv (&seqno, zap, 0);
|
s_sendmore (zap, "OK");
|
||||||
assert (rc != -1);
|
s_send (zap, "anonymous");
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Domain
|
free (version);
|
||||||
rc = zmq_msg_init (&domain);
|
free (sequence);
|
||||||
assert (rc == 0);
|
free (domain);
|
||||||
rc = zmq_msg_recv (&domain, zap, 0);
|
free (mechanism);
|
||||||
assert (rc != -1);
|
free (client_key);
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Mechanism
|
int rc = zmq_close (zap);
|
||||||
rc = zmq_msg_init (&mechanism);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&mechanism, zap, 0);
|
|
||||||
assert (rc == 5 && memcmp (zmq_msg_data (&mechanism), "CURVE", 5) == 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 1);
|
|
||||||
|
|
||||||
// Key
|
|
||||||
rc = zmq_msg_init (&key);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_recv (&key, zap, 0);
|
|
||||||
optlen = sizeof more;
|
|
||||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
|
||||||
assert (rc == 0 && more == 0);
|
|
||||||
|
|
||||||
// Send response
|
|
||||||
rc = zmq_msg_send (&version, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 3);
|
|
||||||
|
|
||||||
rc = zmq_msg_send (&seqno, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc != -1);
|
|
||||||
|
|
||||||
rc = zmq_msg_init_size (&status_code, 3);
|
|
||||||
assert (rc == 0);
|
|
||||||
memcpy (zmq_msg_data (&status_code), "200", 3);
|
|
||||||
rc = zmq_msg_send (&status_code, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 3);
|
|
||||||
|
|
||||||
rc = zmq_msg_init (&status_text);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_send (&status_text, zap, ZMQ_SNDMORE);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_init (&user_id);
|
|
||||||
assert (rc == 0);
|
|
||||||
rc = zmq_msg_send (&user_id, zap, 0);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&domain);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&mechanism);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_msg_close (&key);
|
|
||||||
assert (rc == 0);
|
|
||||||
|
|
||||||
rc = zmq_close (zap);
|
|
||||||
assert (rc == 0);
|
assert (rc == 0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -115,7 +56,7 @@ zap_handler (void *zap)
|
|||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_LIBSODIUM
|
#ifndef HAVE_LIBSODIUM
|
||||||
printf("Libsodium not availabile - skipping test.\n");
|
printf("libsodium not installed, skipping CURVE test\n");
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
int rc;
|
int rc;
|
||||||
|
@@ -101,7 +101,7 @@ test_stream_to_dealer (void)
|
|||||||
// Second frame contains the rest of greeting along with
|
// Second frame contains the rest of greeting along with
|
||||||
// the Ready command
|
// the Ready command
|
||||||
rc = zmq_recv (stream, buffer, 255, 0);
|
rc = zmq_recv (stream, buffer, 255, 0);
|
||||||
assert (rc == 99);
|
assert (rc == 97);
|
||||||
|
|
||||||
// First two bytes are major and minor version numbers.
|
// First two bytes are major and minor version numbers.
|
||||||
assert (buffer [0] == 3); // ZMTP/3.0
|
assert (buffer [0] == 3); // ZMTP/3.0
|
||||||
@@ -109,21 +109,20 @@ test_stream_to_dealer (void)
|
|||||||
|
|
||||||
// Mechanism is "NULL"
|
// Mechanism is "NULL"
|
||||||
assert (memcmp (buffer + 2, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 22) == 0);
|
assert (memcmp (buffer + 2, "NULL\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 22) == 0);
|
||||||
assert (memcmp (buffer + 54, "\0\53READY ", 10) == 0);
|
assert (memcmp (buffer + 54, "\0\51READY\0", 8) == 0);
|
||||||
assert (memcmp (buffer + 64, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
assert (memcmp (buffer + 62, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||||
assert (memcmp (buffer + 86, "\10Identity\0\0\0\0", 13) == 0);
|
assert (memcmp (buffer + 84, "\10Identity\0\0\0\0", 13) == 0);
|
||||||
|
|
||||||
// Announce we are ready
|
// Announce we are ready
|
||||||
memcpy (buffer, "\0\53", 2);
|
memcpy (buffer, "\0\51READY\0", 8);
|
||||||
memcpy (buffer + 2, "READY ", 8);
|
memcpy (buffer + 8, "\13Socket-Type\0\0\0\6STREAM", 22);
|
||||||
memcpy (buffer + 10, "\13Socket-Type\0\0\0\6STREAM", 22);
|
memcpy (buffer + 30, "\10Identity\0\0\0\0", 13);
|
||||||
memcpy (buffer + 32, "\10Identity\0\0\0\0", 13);
|
|
||||||
|
|
||||||
// Send Ready command
|
// Send Ready command
|
||||||
rc = zmq_msg_send (&identity, stream, ZMQ_SNDMORE);
|
rc = zmq_msg_send (&identity, stream, ZMQ_SNDMORE);
|
||||||
assert (rc > 0);
|
assert (rc > 0);
|
||||||
rc = zmq_send (stream, buffer, 45, 0);
|
rc = zmq_send (stream, buffer, 43, 0);
|
||||||
assert (rc == 45);
|
assert (rc == 43);
|
||||||
|
|
||||||
// Now we expect the data from the DEALER socket
|
// Now we expect the data from the DEALER socket
|
||||||
// First frame is, again, the identity of the connection
|
// First frame is, again, the identity of the connection
|
||||||
|
@@ -76,4 +76,36 @@ bounce (void *server, void *client)
|
|||||||
assert (memcmp (buffer, content, 32) == 0);
|
assert (memcmp (buffer, content, 32) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Receive 0MQ string from socket and convert into C string
|
||||||
|
// Caller must free returned string. Returns NULL if the context
|
||||||
|
// is being terminated.
|
||||||
|
char *
|
||||||
|
s_recv (void *socket) {
|
||||||
|
char buffer [256];
|
||||||
|
int size = zmq_recv (socket, buffer, 255, 0);
|
||||||
|
if (size == -1)
|
||||||
|
return NULL;
|
||||||
|
if (size > 255)
|
||||||
|
size = 255;
|
||||||
|
buffer [size] = 0;
|
||||||
|
return strdup (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert C string to 0MQ string and send to socket
|
||||||
|
int
|
||||||
|
s_send (void *socket, const char *string) {
|
||||||
|
int size = zmq_send (socket, string, strlen (string), 0);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends string as 0MQ string, as multipart non-terminal
|
||||||
|
int
|
||||||
|
s_sendmore (void *socket, const char *string) {
|
||||||
|
int size = zmq_send (socket, string, strlen (string), ZMQ_SNDMORE);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define streq(s1,s2) (!strcmp ((s1), (s2)))
|
||||||
|
#define strneq(s1,s2) (strcmp ((s1), (s2)))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user