mirror of
https://github.com/zeromq/libzmq.git
synced 2025-10-07 11:24:32 +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 ());
|
||||
|
||||
memcpy (message, "MESSAGE ", 8);
|
||||
memcpy (message, "MESSAGE\0", 8);
|
||||
memcpy (message + 8, &cn_nonce, 8);
|
||||
memcpy (message + 16, message_box + 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 ());
|
||||
if (memcmp (message, "MESSAGE ", 8)) {
|
||||
if (memcmp (message, "MESSAGE\0", 8)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@@ -235,11 +235,11 @@ int zmq::curve_client_t::hello_msg (msg_t *msg_)
|
||||
errno_assert (rc == 0);
|
||||
uint8_t *hello = static_cast <uint8_t *> (msg_->data ());
|
||||
|
||||
memcpy (hello, "HELLO ", 8);
|
||||
memcpy (hello, "HELLO\0", 6);
|
||||
// CurveZMQ major and minor version numbers
|
||||
memcpy (hello + 8, "\1\0", 2);
|
||||
memcpy (hello + 6, "\1\0", 2);
|
||||
// Anti-amplification padding
|
||||
memset (hello + 10, 0, 70);
|
||||
memset (hello + 8, 0, 72);
|
||||
// Client public connection key
|
||||
memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES);
|
||||
// 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 ());
|
||||
if (memcmp (welcome, "WELCOME ", 8)) {
|
||||
if (memcmp (welcome, "WELCOME\0", 8)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@@ -346,18 +346,18 @@ int zmq::curve_client_t::initiate_msg (msg_t *msg_)
|
||||
mlen, initiate_nonce, cn_server, cn_secret);
|
||||
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);
|
||||
|
||||
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
|
||||
memcpy (initiate + 8, cn_cookie, 96);
|
||||
memcpy (initiate + 9, cn_cookie, 96);
|
||||
// Short nonce, prefixed by "CurveZMQINITIATE"
|
||||
memcpy (initiate + 104, &cn_nonce, 8);
|
||||
memcpy (initiate + 105, &cn_nonce, 8);
|
||||
// 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);
|
||||
|
||||
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_)
|
||||
{
|
||||
if (msg_->size () < 32) {
|
||||
if (msg_->size () < 30) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (ready, "READY ", 8)) {
|
||||
if (memcmp (ready, "READY\0", 6)) {
|
||||
errno = EPROTO;
|
||||
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_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);
|
||||
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 + 16, ready + 8, 8);
|
||||
memcpy (ready_nonce + 16, ready + 6, 8);
|
||||
|
||||
int rc = crypto_box_open_afternm (ready_plaintext, ready_box,
|
||||
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 ());
|
||||
|
||||
memcpy (message, "MESSAGE ", 8);
|
||||
memcpy (message, "MESSAGE\0", 8);
|
||||
memcpy (message + 8, &cn_nonce, 8);
|
||||
memcpy (message + 16, message_box + 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 ());
|
||||
if (memcmp (message, "MESSAGE ", 8)) {
|
||||
if (memcmp (message, "MESSAGE\0", 8)) {
|
||||
errno = EPROTO;
|
||||
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 ());
|
||||
if (memcmp (hello, "HELLO ", 8)) {
|
||||
if (memcmp (hello, "HELLO\0", 6)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t major = hello [8];
|
||||
const uint8_t minor = hello [9];
|
||||
const uint8_t major = hello [6];
|
||||
const uint8_t minor = hello [7];
|
||||
|
||||
if (major != 1 || minor != 0) {
|
||||
errno = EPROTO;
|
||||
@@ -327,7 +327,7 @@ int zmq::curve_server_t::welcome_msg (msg_t *msg_)
|
||||
errno_assert (rc == 0);
|
||||
|
||||
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 + 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_)
|
||||
{
|
||||
if (msg_->size () < 224) {
|
||||
if (msg_->size () < 225) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (initiate, "INITIATE", 8)) {
|
||||
if (memcmp (initiate, "INITIATE\0", 9)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@@ -353,10 +353,10 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
|
||||
// Open Box [C' + s'](t)
|
||||
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 + 8, initiate + 8, 16);
|
||||
memcpy (cookie_nonce + 8, initiate + 9, 16);
|
||||
|
||||
int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
|
||||
sizeof cookie_box,
|
||||
@@ -375,7 +375,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
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_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')
|
||||
memset (initiate_box, 0, 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 + 16, initiate + 104, 8);
|
||||
memcpy (initiate_nonce + 16, initiate + 105, 8);
|
||||
|
||||
rc = crypto_box_open (initiate_plaintext, initiate_box,
|
||||
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);
|
||||
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);
|
||||
|
||||
uint8_t *ready = static_cast <uint8_t *> (msg_->data ());
|
||||
|
||||
memcpy (ready, "READY ", 8);
|
||||
memcpy (ready, "READY\0", 6);
|
||||
// Short nonce, prefixed by "CurveZMQREADY---"
|
||||
memcpy (ready + 8, &cn_nonce, 8);
|
||||
memcpy (ready + 6, &cn_nonce, 8);
|
||||
// Box [metadata](S'->C')
|
||||
memcpy (ready + 16, ready_box + crypto_box_BOXZEROBYTES,
|
||||
memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES,
|
||||
mlen - crypto_box_BOXZEROBYTES);
|
||||
|
||||
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",
|
||||
"DEALER", "ROUTER", "PULL", "PUSH",
|
||||
"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];
|
||||
}
|
||||
|
||||
|
@@ -54,8 +54,8 @@ int zmq::null_mechanism_t::next_handshake_message (msg_t *msg_)
|
||||
unsigned char *ptr = command_buffer;
|
||||
|
||||
// Add mechanism string
|
||||
memcpy (ptr, "READY ", 8);
|
||||
ptr += 8;
|
||||
memcpy (ptr, "READY\0", 6);
|
||||
ptr += 6;
|
||||
|
||||
// Add socket type property
|
||||
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 ());
|
||||
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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr += 8;
|
||||
bytes_left -= 8;
|
||||
ptr += 6;
|
||||
bytes_left -= 6;
|
||||
|
||||
int rc = parse_metadata (ptr, bytes_left);
|
||||
if (rc == 0) {
|
||||
|
@@ -295,9 +295,9 @@ int zmq::plain_mechanism_t::ready_command (msg_t *msg_) const
|
||||
|
||||
unsigned char *ptr = command_buffer;
|
||||
|
||||
// Add mechanism string
|
||||
memcpy (ptr, "READY ", 8);
|
||||
ptr += 8;
|
||||
// Add command name
|
||||
memcpy (ptr, "READY\0", 6);
|
||||
ptr += 6;
|
||||
|
||||
// Add socket type property
|
||||
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 ());
|
||||
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;
|
||||
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,
|
||||
|
@@ -104,7 +104,7 @@ int main (void)
|
||||
// Second frame contains the rest of greeting along with
|
||||
// the Ready command
|
||||
rc = zmq_recv (router, buffer, 255, 0);
|
||||
assert (rc == 99);
|
||||
assert (rc == 97);
|
||||
|
||||
// First two bytes are major and minor version numbers.
|
||||
assert (buffer [0] == 3); // ZMTP/3.0
|
||||
@@ -112,21 +112,20 @@ int main (void)
|
||||
|
||||
// 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 + 54, "\0\53READY ", 10) == 0);
|
||||
assert (memcmp (buffer + 64, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||
assert (memcmp (buffer + 86, "\10Identity\0\0\0\0", 13) == 0);
|
||||
assert (memcmp (buffer + 54, "\0\51READY\0", 8) == 0);
|
||||
assert (memcmp (buffer + 62, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||
assert (memcmp (buffer + 84, "\10Identity\0\0\0\0", 13) == 0);
|
||||
|
||||
// Announce we are ready
|
||||
memcpy (buffer, "\0\53", 2);
|
||||
memcpy (buffer + 2, "READY ", 8);
|
||||
memcpy (buffer + 10, "\13Socket-Type\0\0\0\6ROUTER", 22);
|
||||
memcpy (buffer + 32, "\10Identity\0\0\0\0", 13);
|
||||
memcpy (buffer, "\0\51READY\0", 8);
|
||||
memcpy (buffer + 8, "\13Socket-Type\0\0\0\6STREAM", 22);
|
||||
memcpy (buffer + 30, "\10Identity\0\0\0\0", 13);
|
||||
|
||||
// Send Ready command
|
||||
rc = zmq_msg_send (&identity, router, ZMQ_SNDMORE);
|
||||
assert (rc > 0);
|
||||
rc = zmq_send (router, buffer, 45, 0);
|
||||
assert (rc == 45);
|
||||
rc = zmq_send (router, buffer, 43, 0);
|
||||
assert (rc == 43);
|
||||
|
||||
// Now we expect the data from the DEALER socket
|
||||
// First frame is, again, the identity of the connection
|
||||
|
@@ -19,106 +19,44 @@
|
||||
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "testutil.hpp"
|
||||
|
||||
static void *
|
||||
zap_handler (void *zap)
|
||||
{
|
||||
int rc, more;
|
||||
size_t optlen;
|
||||
zmq_msg_t version, seqno, domain, mechanism, username, password;
|
||||
zmq_msg_t status_code, status_text, user_id;
|
||||
char *version = s_recv (zap);
|
||||
char *sequence = s_recv (zap);
|
||||
char *domain = s_recv (zap);
|
||||
char *mechanism = s_recv (zap);
|
||||
char *username = s_recv (zap);
|
||||
char *password = s_recv (zap);
|
||||
|
||||
// Version
|
||||
rc = zmq_msg_init (&version);
|
||||
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);
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "PLAIN"));
|
||||
|
||||
// Sequence number
|
||||
rc = zmq_msg_init (&seqno);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_recv (&seqno, zap, 0);
|
||||
assert (rc != -1);
|
||||
optlen = sizeof more;
|
||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
||||
assert (rc == 0 && more == 1);
|
||||
s_sendmore (zap, version);
|
||||
s_sendmore (zap, sequence);
|
||||
if (streq (username, "admin")
|
||||
&& streq (password, "password")) {
|
||||
s_sendmore (zap, "200");
|
||||
s_sendmore (zap, "OK");
|
||||
s_send (zap, "anonymous");
|
||||
}
|
||||
else {
|
||||
s_sendmore (zap, "400");
|
||||
s_sendmore (zap, "Invalid username or password");
|
||||
s_send (zap, "");
|
||||
}
|
||||
|
||||
// Domain
|
||||
rc = zmq_msg_init (&domain);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_recv (&domain, zap, 0);
|
||||
assert (rc != -1);
|
||||
optlen = sizeof more;
|
||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
||||
assert (rc == 0 && more == 1);
|
||||
free (version);
|
||||
free (sequence);
|
||||
free (domain);
|
||||
free (mechanism);
|
||||
free (username);
|
||||
free (password);
|
||||
|
||||
// Mechanism
|
||||
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);
|
||||
int rc = zmq_close (zap);
|
||||
assert (rc == 0);
|
||||
|
||||
return NULL;
|
||||
|
@@ -20,93 +20,34 @@
|
||||
#include "platform.hpp"
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "testutil.hpp"
|
||||
|
||||
static void *
|
||||
zap_handler (void *zap)
|
||||
{
|
||||
int rc, more;
|
||||
size_t optlen;
|
||||
zmq_msg_t version, seqno, domain, mechanism, key;
|
||||
zmq_msg_t status_code, status_text, user_id;
|
||||
char *version = s_recv (zap);
|
||||
char *sequence = s_recv (zap);
|
||||
char *domain = s_recv (zap);
|
||||
char *mechanism = s_recv (zap);
|
||||
char *client_key = s_recv (zap);
|
||||
|
||||
// Version
|
||||
rc = zmq_msg_init (&version);
|
||||
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);
|
||||
assert (streq (version, "1.0"));
|
||||
assert (streq (mechanism, "CURVE"));
|
||||
|
||||
// Sequence number
|
||||
rc = zmq_msg_init (&seqno);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_recv (&seqno, zap, 0);
|
||||
assert (rc != -1);
|
||||
optlen = sizeof more;
|
||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
||||
assert (rc == 0 && more == 1);
|
||||
s_sendmore (zap, version);
|
||||
s_sendmore (zap, sequence);
|
||||
s_sendmore (zap, "200");
|
||||
s_sendmore (zap, "OK");
|
||||
s_send (zap, "anonymous");
|
||||
|
||||
// Domain
|
||||
rc = zmq_msg_init (&domain);
|
||||
assert (rc == 0);
|
||||
rc = zmq_msg_recv (&domain, zap, 0);
|
||||
assert (rc != -1);
|
||||
optlen = sizeof more;
|
||||
rc = zmq_getsockopt (zap, ZMQ_RCVMORE, &more, &optlen);
|
||||
assert (rc == 0 && more == 1);
|
||||
free (version);
|
||||
free (sequence);
|
||||
free (domain);
|
||||
free (mechanism);
|
||||
free (client_key);
|
||||
|
||||
// Mechanism
|
||||
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);
|
||||
int rc = zmq_close (zap);
|
||||
assert (rc == 0);
|
||||
|
||||
return NULL;
|
||||
@@ -115,7 +56,7 @@ zap_handler (void *zap)
|
||||
int main (void)
|
||||
{
|
||||
#ifndef HAVE_LIBSODIUM
|
||||
printf("Libsodium not availabile - skipping test.\n");
|
||||
printf("libsodium not installed, skipping CURVE test\n");
|
||||
return 0;
|
||||
#endif
|
||||
int rc;
|
||||
|
@@ -101,7 +101,7 @@ test_stream_to_dealer (void)
|
||||
// Second frame contains the rest of greeting along with
|
||||
// the Ready command
|
||||
rc = zmq_recv (stream, buffer, 255, 0);
|
||||
assert (rc == 99);
|
||||
assert (rc == 97);
|
||||
|
||||
// First two bytes are major and minor version numbers.
|
||||
assert (buffer [0] == 3); // ZMTP/3.0
|
||||
@@ -109,21 +109,20 @@ test_stream_to_dealer (void)
|
||||
|
||||
// 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 + 54, "\0\53READY ", 10) == 0);
|
||||
assert (memcmp (buffer + 64, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||
assert (memcmp (buffer + 86, "\10Identity\0\0\0\0", 13) == 0);
|
||||
assert (memcmp (buffer + 54, "\0\51READY\0", 8) == 0);
|
||||
assert (memcmp (buffer + 62, "\13Socket-Type\0\0\0\6DEALER", 22) == 0);
|
||||
assert (memcmp (buffer + 84, "\10Identity\0\0\0\0", 13) == 0);
|
||||
|
||||
// Announce we are ready
|
||||
memcpy (buffer, "\0\53", 2);
|
||||
memcpy (buffer + 2, "READY ", 8);
|
||||
memcpy (buffer + 10, "\13Socket-Type\0\0\0\6STREAM", 22);
|
||||
memcpy (buffer + 32, "\10Identity\0\0\0\0", 13);
|
||||
memcpy (buffer, "\0\51READY\0", 8);
|
||||
memcpy (buffer + 8, "\13Socket-Type\0\0\0\6STREAM", 22);
|
||||
memcpy (buffer + 30, "\10Identity\0\0\0\0", 13);
|
||||
|
||||
// Send Ready command
|
||||
rc = zmq_msg_send (&identity, stream, ZMQ_SNDMORE);
|
||||
assert (rc > 0);
|
||||
rc = zmq_send (stream, buffer, 45, 0);
|
||||
assert (rc == 45);
|
||||
rc = zmq_send (stream, buffer, 43, 0);
|
||||
assert (rc == 43);
|
||||
|
||||
// Now we expect the data from the DEALER socket
|
||||
// First frame is, again, the identity of the connection
|
||||
|
@@ -76,4 +76,36 @@ bounce (void *server, void *client)
|
||||
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
|
||||
|
Reference in New Issue
Block a user