Ejemplo n.º 1
0
void zmq::amqp_marshaller_t::basic_reject (
            uint16_t channel_,
            uint64_t delivery_tag_,
            bool requeue_)
{
    unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size);
    assert (args);

    size_t offset = 0;
    assert (offset + sizeof (uint64_t) <= i_amqp::frame_min_size);
    put_uint64 (args + offset, delivery_tag_);
    offset += sizeof (uint64_t);
    assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size);
    args [offset] = (
        ((requeue_ ? 1 : 0) << 0));
    offset += sizeof (uint8_t);

    command_t cmd = {
        channel_,
        i_amqp::basic_id,
        i_amqp::basic_reject_id,
        args,
        offset
    };
    command_queue.push (cmd);
}
Ejemplo n.º 2
0
void zmq::v2_encoder_t::message_ready ()
{
    //  Encode flags.
    unsigned char &protocol_flags = tmpbuf [0];
    protocol_flags = 0;
    if (in_progress->flags () & msg_t::more)
        protocol_flags |= v2_protocol_t::more_flag;
    if (in_progress->size () > 255)
        protocol_flags |= v2_protocol_t::large_flag;
    if (in_progress->flags () & msg_t::command)
        protocol_flags |= v2_protocol_t::command_flag;

    //  Encode the message length. For messages less then 256 bytes,
    //  the length is encoded as 8-bit unsigned integer. For larger
    //  messages, 64-bit unsigned integer in network byte order is used.
    const size_t size = in_progress->size ();
    if (unlikely (size > 255)) {
        put_uint64 (tmpbuf + 1, size);
        next_step (tmpbuf, 9, &v2_encoder_t::size_ready, false);
    }
    else {
        tmpbuf [1] = static_cast <uint8_t> (size);
        next_step (tmpbuf, 2, &v2_encoder_t::size_ready, false);
    }
}
Ejemplo n.º 3
0
void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
    session_base_t *session_)
{
    zmq_assert (!plugged);
    plugged = true;

    //  Connect to session object.
    zmq_assert (!session);
    zmq_assert (session_);
    session = session_;
    socket = session-> get_socket ();

    //  Connect to I/O threads poller object.
    io_object_t::plug (io_thread_);
    handle = add_fd (s);
    io_enabled = true;

    //  Send the 'length' and 'flags' fields of the identity message.
    //  The 'length' field is encoded in the long format.
    outpos = greeting_output_buffer;
    outpos [outsize++] = 0xff;
    put_uint64 (&outpos [outsize], options.identity_size + 1);
    outsize += 8;
    outpos [outsize++] = 0x7f;

    set_pollin (handle);
    set_pollout (handle);
    //  Flush all the data that may have been already received downstream.
    in_event ();
}
Ejemplo n.º 4
0
void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
    session_base_t *session_)
{
    zmq_assert (!plugged);
    plugged = true;

    //  Connect to session object.
    zmq_assert (!session);
    zmq_assert (session_);
    session = session_;
    socket = session-> get_socket ();

    //  Connect to I/O threads poller object.
    io_object_t::plug (io_thread_);
    handle = add_fd (s);
    io_error = false;

    if (options.raw_socket) {
        // no handshaking for raw sock, instantiate raw encoder and decoders
        encoder = new (std::nothrow) raw_encoder_t (out_batch_size);
        alloc_assert (encoder);

        decoder = new (std::nothrow) raw_decoder_t (in_batch_size);
        alloc_assert (decoder);

        // disable handshaking for raw socket
        handshaking = false;

        next_msg = &stream_engine_t::pull_msg_from_session;
        process_msg = &stream_engine_t::push_msg_to_session;

        if (options.raw_notify) {
            //  For raw sockets, send an initial 0-length message to the
            // application so that it knows a peer has connected.
            msg_t connector;
            connector.init();
            push_msg_to_session (&connector);
            connector.close();
            session->flush ();
        }
    }
    else {
        // start optional timer, to prevent handshake hanging on no input
        set_handshake_timer ();

        //  Send the 'length' and 'flags' fields of the identity message.
        //  The 'length' field is encoded in the long format.
        outpos = greeting_send;
        outpos [outsize++] = 0xff;
        put_uint64 (&outpos [outsize], options.identity_size + 1);
        outsize += 8;
        outpos [outsize++] = 0x7f;
    }

    set_pollin (handle);
    set_pollout (handle);
    //  Flush all the data that may have been already received downstream.
    in_event ();
}
Ejemplo n.º 5
0
void put_int64(int64_t i)
{
  if (i < 0) {
    put_char('-');
    i = -i;
  }
  put_uint64 ((uint64_t) i);
}
Ejemplo n.º 6
0
void log_display_headstart()
{
    int64_t mid = NUM_HEADSTARTS/2;
    put_string("\nHeadstarts:\n");
    for (int i = 0; i < NUM_HEADSTARTS; i++) {
        put_int64(i-mid);
        put_string(": ");
        put_uint64(global_log.headstarts[i]);
        put_string("\n");
    }
}
Ejemplo n.º 7
0
int zmq::curve_server_t::encode (msg_t *msg_)
{
    zmq_assert (state == connected);

    const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();

    uint8_t message_nonce [crypto_box_NONCEBYTES];
    memcpy (message_nonce, "CurveZMQMESSAGES", 16);
    put_uint64 (message_nonce + 16, cn_nonce);

    uint8_t flags = 0;
    if (msg_->flags () & msg_t::more)
        flags |= 0x01;
    if (msg_->flags () & msg_t::command)
        flags |= 0x02;

    uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (mlen));
    alloc_assert (message_plaintext);

    memset (message_plaintext, 0, crypto_box_ZEROBYTES);
    message_plaintext [crypto_box_ZEROBYTES] = flags;
    memcpy (message_plaintext + crypto_box_ZEROBYTES + 1,
            msg_->data (), msg_->size ());

    uint8_t *message_box = static_cast <uint8_t *> (malloc (mlen));
    alloc_assert (message_box);

    int rc = crypto_box_afternm (message_box, message_plaintext,
                                 mlen, message_nonce, cn_precom);
    zmq_assert (rc == 0);

    rc = msg_->close ();
    zmq_assert (rc == 0);

    rc = msg_->init_size (16 + mlen - crypto_box_BOXZEROBYTES);
    zmq_assert (rc == 0);

    uint8_t *message = static_cast <uint8_t *> (msg_->data ());

    memcpy (message, "\x07MESSAGE", 8);
    memcpy (message + 8, message_nonce + 16, 8);
    memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);

    free (message_plaintext);
    free (message_box);

    cn_nonce++;

    return 0;
}
Ejemplo n.º 8
0
/*
 * Read from a file. Returns the number of bytes read, or -1 on an
 * error, or possibly 0 if EOF. (I'm not entirely sure whether it
 * will return 0 on EOF, or return -1 and store SSH_FX_EOF in the
 * error indicator. It might even depend on the SFTP server.)
 */
struct sftp_request *fxp_read_send(struct fxp_handle *handle,
				   uint64_t offset, int len)
{
    struct sftp_request *req = sftp_alloc_request();
    struct sftp_packet *pktout;

    pktout = sftp_pkt_init(SSH_FXP_READ);
    put_uint32(pktout, req->id);
    put_string(pktout, handle->hstring, handle->hlen);
    put_uint64(pktout, offset);
    put_uint32(pktout, len);
    sftp_send(pktout);

    return req;
}
Ejemplo n.º 9
0
void zmq::amqp_marshaller_t::basic_deliver (
            uint16_t channel_,
            const i_amqp::shortstr_t consumer_tag_,
            uint64_t delivery_tag_,
            bool redelivered_,
            const i_amqp::shortstr_t exchange_,
            const i_amqp::shortstr_t routing_key_)
{
    unsigned char *args = (unsigned char*) malloc (i_amqp::frame_min_size);
    assert (args);

    size_t offset = 0;
    assert (offset + sizeof (uint8_t) + consumer_tag_.size <=
        i_amqp::frame_min_size);
    put_uint8 (args + offset, consumer_tag_.size);
    offset += sizeof (uint8_t);
    memcpy (args + offset, consumer_tag_.data, consumer_tag_.size);
    offset += consumer_tag_.size;
    assert (offset + sizeof (uint64_t) <= i_amqp::frame_min_size);
    put_uint64 (args + offset, delivery_tag_);
    offset += sizeof (uint64_t);
    assert (offset + sizeof (uint8_t) <= i_amqp::frame_min_size);
    args [offset] = (
        ((redelivered_ ? 1 : 0) << 0));
    offset += sizeof (uint8_t);
    assert (offset + sizeof (uint8_t) + exchange_.size <=
        i_amqp::frame_min_size);
    put_uint8 (args + offset, exchange_.size);
    offset += sizeof (uint8_t);
    memcpy (args + offset, exchange_.data, exchange_.size);
    offset += exchange_.size;
    assert (offset + sizeof (uint8_t) + routing_key_.size <=
        i_amqp::frame_min_size);
    put_uint8 (args + offset, routing_key_.size);
    offset += sizeof (uint8_t);
    memcpy (args + offset, routing_key_.data, routing_key_.size);
    offset += routing_key_.size;

    command_t cmd = {
        channel_,
        i_amqp::basic_id,
        i_amqp::basic_deliver_id,
        args,
        offset
    };
    command_queue.push (cmd);
}
Ejemplo n.º 10
0
bool zmq::v1_encoder_t::message_ready ()
{
    //  Release the content of the old message.
    int rc = in_progress.close ();
    errno_assert (rc == 0);

    //  Read new message. If there is none, return false.
    //  Note that new state is set only if write is successful. That way
    //  unsuccessful write will cause retry on the next state machine
    //  invocation.
    if (unlikely (!msg_source)) {
        rc = in_progress.init ();
        errno_assert (rc == 0);
        return false;
    }

    rc = msg_source->pull_msg (&in_progress);
    if (unlikely (rc)) {
        errno_assert (errno == EAGAIN);
        rc = in_progress.init ();
        errno_assert (rc == 0);
        return false;
    }

    //  Encode flags.
    unsigned char &protocol_flags = tmpbuf [0];
    protocol_flags = 0;
    if (in_progress.flags () & msg_t::more)
        protocol_flags |= v1_protocol_t::more_flag;
    if (in_progress.size () > 255)
        protocol_flags |= v1_protocol_t::large_flag;

    //  Encode the message length. For messages less then 256 bytes,
    //  the length is encoded as 8-bit unsigned integer. For larger
    //  messages, 64-bit unsigned integer in network byte order is used.
    const size_t size = in_progress.size ();
    if (unlikely (size > 255)) {
        put_uint64 (tmpbuf + 1, size);
        next_step (tmpbuf, 9, &v1_encoder_t::size_ready, false);
    }
    else {
        tmpbuf [1] = static_cast <uint8_t> (size);
        next_step (tmpbuf, 2, &v1_encoder_t::size_ready, false);
    }
    return true;
}
Ejemplo n.º 11
0
int zmq::curve_server_t::produce_ready (msg_t *msg_)
{
    const size_t metadata_length = basic_properties_len ();
    uint8_t ready_nonce[crypto_box_NONCEBYTES];

    uint8_t *ready_plaintext =
      static_cast<uint8_t *> (malloc (crypto_box_ZEROBYTES + metadata_length));
    alloc_assert (ready_plaintext);

    //  Create Box [metadata](S'->C')
    memset (ready_plaintext, 0, crypto_box_ZEROBYTES);
    uint8_t *ptr = ready_plaintext + crypto_box_ZEROBYTES;

    ptr += add_basic_properties (ptr, metadata_length);
    const size_t mlen = ptr - ready_plaintext;

    memcpy (ready_nonce, "CurveZMQREADY---", 16);
    put_uint64 (ready_nonce + 16, cn_nonce);

    uint8_t *ready_box = static_cast<uint8_t *> (
      malloc (crypto_box_BOXZEROBYTES + 16 + metadata_length));
    alloc_assert (ready_box);

    int rc = crypto_box_afternm (ready_box, ready_plaintext, mlen, ready_nonce,
                                 cn_precom);
    zmq_assert (rc == 0);

    free (ready_plaintext);

    rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES);
    errno_assert (rc == 0);

    uint8_t *ready = static_cast<uint8_t *> (msg_->data ());

    memcpy (ready, "\x05READY", 6);
    //  Short nonce, prefixed by "CurveZMQREADY---"
    memcpy (ready + 6, ready_nonce + 16, 8);
    //  Box [metadata](S'->C')
    memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);
    free (ready_box);

    cn_nonce++;

    return 0;
}
Ejemplo n.º 12
0
void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
    session_base_t *session_)
{
    zmq_assert (!plugged);
    plugged = true;

    //  Connect to session object.
    zmq_assert (!session);
    zmq_assert (session_);
    session = session_;
    socket = session-> get_socket ();

    //  Connect to I/O threads poller object.
    io_object_t::plug (io_thread_);
    handle = add_fd (s);
    io_error = false;

    if (options.raw_sock) {
        // no handshaking for raw sock, instantiate raw encoder and decoders
        encoder = new (std::nothrow) raw_encoder_t (out_batch_size);
        alloc_assert (encoder);

        decoder = new (std::nothrow) raw_decoder_t (in_batch_size);
        alloc_assert (decoder);

        // disable handshaking for raw socket
        handshaking = false;

        read_msg = &stream_engine_t::pull_msg_from_session;
        write_msg = &stream_engine_t::push_msg_to_session;
    }
    else {
        //  Send the 'length' and 'flags' fields of the identity message.
        //  The 'length' field is encoded in the long format.
        outpos = greeting_send;
        outpos [outsize++] = 0xff;
        put_uint64 (&outpos [outsize], options.identity_size + 1);
        outsize += 8;
        outpos [outsize++] = 0x7f;
    }

    set_pollin (handle);
    set_pollout (handle);
    //  Flush all the data that may have been already received downstream.
    in_event ();
}
Ejemplo n.º 13
0
int zmq::curve_server_t::produce_ready (msg_t *msg_)
{
    uint8_t ready_nonce [crypto_box_NONCEBYTES];
    uint8_t ready_plaintext [crypto_box_ZEROBYTES + 256];
    uint8_t ready_box [crypto_box_BOXZEROBYTES + 16 + 256];

    //  Create Box [metadata](S'->C')
    memset (ready_plaintext, 0, crypto_box_ZEROBYTES);
    uint8_t *ptr = ready_plaintext + crypto_box_ZEROBYTES;

    //  Add socket type property
    const char *socket_type = socket_type_string (options.type);
    ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));

    //  Add identity property
    if (options.type == ZMQ_REQ
    ||  options.type == ZMQ_DEALER
    ||  options.type == ZMQ_ROUTER)
        ptr += add_property (ptr, "Identity", options.identity, options.identity_size);

    const size_t mlen = ptr - ready_plaintext;

    memcpy (ready_nonce, "CurveZMQREADY---", 16);
    put_uint64 (ready_nonce + 16, cn_nonce);

    int rc = crypto_box_afternm (ready_box, ready_plaintext,
                                 mlen, ready_nonce, cn_precom);
    zmq_assert (rc == 0);

    rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES);
    errno_assert (rc == 0);

    uint8_t *ready = static_cast <uint8_t *> (msg_->data ());

    memcpy (ready, "\x05READY", 6);
    //  Short nonce, prefixed by "CurveZMQREADY---"
    memcpy (ready + 6, ready_nonce + 16, 8);
    //  Box [metadata](S'->C')
    memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);

    cn_nonce++;

    return 0;
}
Ejemplo n.º 14
0
bool zmq::zmq_encoder_t::message_ready ()
{
    //  Destroy content of the old message.
    zmq_msg_close(&in_progress);

    //  Read new message from the dispatcher. If there is none, return false.
    //  Note that new state is set only if write is successful. That way
    //  unsuccessful write will cause retry on the next state machine
    //  invocation.
    if (!source || !source->read (&in_progress)) {
        zmq_msg_init (&in_progress);
        return false;
    }

    //  Get the message size. If the prefix is not to be sent, adjust the
    //  size accordingly.
    size_t size = zmq_msg_size (&in_progress);
    if (trim) {
        zmq_assert (size);
        size_t prefix_size =
            (*(unsigned char*) zmq_msg_data (&in_progress)) + 1;
        zmq_assert (prefix_size <= size);
        size -= prefix_size;
    }

    //  For messages less than 255 bytes long, write one byte of message size.
    //  For longer messages write 0xff escape character followed by 8-byte
    //  message size.
    if (size < 255) {
        tmpbuf [0] = (unsigned char) size;
        next_step (tmpbuf, 1, &zmq_encoder_t::size_ready, true);
    }
    else {
        tmpbuf [0] = 0xff;
        put_uint64 (tmpbuf + 1, size);
        next_step (tmpbuf, 9, &zmq_encoder_t::size_ready, true);
    }
    return true;
}
Ejemplo n.º 15
0
int zmq::curve_client_t::produce_hello (msg_t *msg_)
{
    uint8_t hello_nonce [crypto_box_NONCEBYTES];
    uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t hello_box [crypto_box_BOXZEROBYTES + 80];

    //  Prepare the full nonce
    memcpy (hello_nonce, "CurveZMQHELLO---", 16);
    put_uint64 (hello_nonce + 16, cn_nonce);

    //  Create Box [64 * %x0](C'->S)
    memset (hello_plaintext, 0, sizeof hello_plaintext);

    int rc = crypto_box (hello_box, hello_plaintext,
                         sizeof hello_plaintext,
                         hello_nonce, server_key, cn_secret);
    if (rc == -1)
        return -1;

    rc = msg_->init_size (200);
    errno_assert (rc == 0);
    uint8_t *hello = static_cast <uint8_t *> (msg_->data ());

    memcpy (hello, "\x05HELLO", 6);
    //  CurveZMQ major and minor version numbers
    memcpy (hello + 6, "\1\0", 2);
    //  Anti-amplification padding
    memset (hello + 8, 0, 72);
    //  Client public connection key
    memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES);
    //  Short nonce, prefixed by "CurveZMQHELLO---"
    memcpy (hello + 112, hello_nonce + 16, 8);
    //  Signature, Box [64 * %x0](C'->S)
    memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80);

    cn_nonce++;

    return 0;
}
Ejemplo n.º 16
0
    static int produce_hello (void *data_,
                              const uint8_t *server_key_,
                              const uint64_t cn_nonce_,
                              const uint8_t *cn_public_,
                              const uint8_t *cn_secret_)
    {
        uint8_t hello_nonce[crypto_box_NONCEBYTES];
        uint8_t hello_plaintext[crypto_box_ZEROBYTES + 64];
        uint8_t hello_box[crypto_box_BOXZEROBYTES + 80];

        //  Prepare the full nonce
        memcpy (hello_nonce, "CurveZMQHELLO---", 16);
        put_uint64 (hello_nonce + 16, cn_nonce_);

        //  Create Box [64 * %x0](C'->S)
        memset (hello_plaintext, 0, sizeof hello_plaintext);

        int rc = crypto_box (hello_box, hello_plaintext, sizeof hello_plaintext,
                             hello_nonce, server_key_, cn_secret_);
        if (rc == -1)
            return -1;

        uint8_t *hello = static_cast<uint8_t *> (data_);

        memcpy (hello, "\x05HELLO", 6);
        //  CurveZMQ major and minor version numbers
        memcpy (hello + 6, "\1\0", 2);
        //  Anti-amplification padding
        memset (hello + 8, 0, 72);
        //  Client public connection key
        memcpy (hello + 80, cn_public_, crypto_box_PUBLICKEYBYTES);
        //  Short nonce, prefixed by "CurveZMQHELLO---"
        memcpy (hello + 112, hello_nonce + 16, 8);
        //  Signature, Box [64 * %x0](C'->S)
        memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80);

        return 0;
    }
Ejemplo n.º 17
0
void BinarySink_put_fxp_attrs(BinarySink *bs, struct fxp_attrs attrs)
{
    put_uint32(bs, attrs.flags);
    if (attrs.flags & SSH_FILEXFER_ATTR_SIZE)
	put_uint64(bs, attrs.size);
    if (attrs.flags & SSH_FILEXFER_ATTR_UIDGID) {
	put_uint32(bs, attrs.uid);
	put_uint32(bs, attrs.gid);
    }
    if (attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) {
	put_uint32(bs, attrs.permissions);
    }
    if (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME) {
	put_uint32(bs, attrs.atime);
	put_uint32(bs, attrs.mtime);
    }
    if (attrs.flags & SSH_FILEXFER_ATTR_EXTENDED) {
	/*
	 * We currently don't support sending any extended
	 * attributes.
	 */
    }
}
Ejemplo n.º 18
0
void zmq::v1_encoder_t::message_ready ()
{
    //  Get the message size.
    size_t size = in_progress->size ();

    //  Account for the 'flags' byte.
    size++;

    //  For messages less than 255 bytes long, write one byte of message size.
    //  For longer messages write 0xff escape character followed by 8-byte
    //  message size. In both cases 'flags' field follows.
    if (size < 255) {
        tmpbuf [0] = (unsigned char) size;
        tmpbuf [1] = (in_progress->flags () & msg_t::more);
        next_step (tmpbuf, 2, &v1_encoder_t::size_ready, false);
    }
    else {
        tmpbuf [0] = 0xff;
        put_uint64 (tmpbuf + 1, size);
        tmpbuf [9] = (in_progress->flags () & msg_t::more);
        next_step (tmpbuf, 10, &v1_encoder_t::size_ready, false);
    }
}
Ejemplo n.º 19
0
void log_display_outcome()
{
    char* outcome_names[] = OUTCOME_NAMES;
    var_t sought[] = OUTCOME_SOUGHT;
    int found = 0;
    for (int i = 0; i < HASH_TABLE_SIZE; i++) {
        log_entry_t *entry = global_log.hash_table + i;
        if (entry->count != 0) {
            put_uint64(entry->count);
            put_string(": ");
            int got = 1;
            for (int j = 0; j < LEN_OUTCOME; j++) {
                if (entry->outcome[j] != sought[j]) got = 0;
                put_string(outcome_names[j]);
                put_string("=");
                put_uint32((uint32_t) entry->outcome[j]);
                put_string(" ");
            }
            if (got == 1) found = 1;
            put_string("\n");
        }
    }
    put_string(found ? "OBSERVED\n" : "NOT OBSERVED\n");
}
Ejemplo n.º 20
0
    static int produce_initiate (void *data_,
                                 size_t size_,
                                 const uint64_t cn_nonce_,
                                 const uint8_t *server_key_,
                                 const uint8_t *public_key_,
                                 const uint8_t *secret_key_,
                                 const uint8_t *cn_public_,
                                 const uint8_t *cn_secret_,
                                 const uint8_t *cn_server_,
                                 const uint8_t *cn_cookie_,
                                 const uint8_t *metadata_plaintext_,
                                 const size_t metadata_length_)
    {
        uint8_t vouch_nonce[crypto_box_NONCEBYTES];
        uint8_t vouch_plaintext[crypto_box_ZEROBYTES + 64];
        uint8_t vouch_box[crypto_box_BOXZEROBYTES + 80];

        //  Create vouch = Box [C',S](C->S')
        memset (vouch_plaintext, 0, crypto_box_ZEROBYTES);
        memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public_, 32);
        memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key_, 32);

        memcpy (vouch_nonce, "VOUCH---", 8);
        randombytes (vouch_nonce + 8, 16);

        int rc = crypto_box (vouch_box, vouch_plaintext, sizeof vouch_plaintext,
                             vouch_nonce, cn_server_, secret_key_);
        if (rc == -1)
            return -1;

        uint8_t initiate_nonce[crypto_box_NONCEBYTES];
        uint8_t *initiate_box = static_cast<uint8_t *> (
          malloc (crypto_box_BOXZEROBYTES + 144 + metadata_length_));
        alloc_assert (initiate_box);
        uint8_t *initiate_plaintext = static_cast<uint8_t *> (
          malloc (crypto_box_ZEROBYTES + 128 + metadata_length_));
        alloc_assert (initiate_plaintext);

        //  Create Box [C + vouch + metadata](C'->S')
        memset (initiate_plaintext, 0, crypto_box_ZEROBYTES);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key_, 32);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32, vouch_nonce + 8,
                16);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48,
                vouch_box + crypto_box_BOXZEROBYTES, 80);
        memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48 + 80,
                metadata_plaintext_, metadata_length_);

        memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
        put_uint64 (initiate_nonce + 16, cn_nonce_);

        rc = crypto_box (initiate_box, initiate_plaintext,
                         crypto_box_ZEROBYTES + 128 + metadata_length_,
                         initiate_nonce, cn_server_, cn_secret_);
        free (initiate_plaintext);

        if (rc == -1)
            return -1;

        uint8_t *initiate = static_cast<uint8_t *> (data_);

        zmq_assert (size_
                    == 113 + 128 + crypto_box_BOXZEROBYTES + metadata_length_);

        memcpy (initiate, "\x08INITIATE", 9);
        //  Cookie provided by the server in the WELCOME command
        memcpy (initiate + 9, cn_cookie_, 96);
        //  Short nonce, prefixed by "CurveZMQINITIATE"
        memcpy (initiate + 105, initiate_nonce + 16, 8);
        //  Box [C + vouch + metadata](C'->S')
        memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
                128 + metadata_length_ + crypto_box_BOXZEROBYTES);
        free (initiate_box);

        return 0;
    }
Ejemplo n.º 21
0
int zmq::curve_client_t::produce_initiate (msg_t *msg_)
{
    uint8_t vouch_nonce [crypto_box_NONCEBYTES];
    uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
    uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];

    //  Create vouch = Box [C',S](C->S')
    memset (vouch_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public, 32);
    memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key, 32);

    memcpy (vouch_nonce, "VOUCH---", 8);
    randombytes (vouch_nonce + 8, 16);

    int rc = crypto_box (vouch_box, vouch_plaintext,
                         sizeof vouch_plaintext,
                         vouch_nonce, cn_server, secret_key);
    zmq_assert (rc == 0);

    //  Assume here that metadata is limited to 256 bytes
    uint8_t initiate_nonce [crypto_box_NONCEBYTES];
    uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
    uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];

    //  Create Box [C + vouch + metadata](C'->S')
    memset (initiate_plaintext, 0, crypto_box_ZEROBYTES);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES,
            public_key, 32);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32,
            vouch_nonce + 8, 16);
    memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48,
            vouch_box + crypto_box_BOXZEROBYTES, 80);

    //  Metadata starts after vouch
    uint8_t *ptr = initiate_plaintext + crypto_box_ZEROBYTES + 128;

    //  Add socket type property
    const char *socket_type = socket_type_string (options.type);
    ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type));

    //  Add identity property
    if (options.type == ZMQ_REQ
    ||  options.type == ZMQ_DEALER
    ||  options.type == ZMQ_ROUTER)
        ptr += add_property (ptr, "Identity", options.identity, options.identity_size);

    const size_t mlen = ptr - initiate_plaintext;

    memcpy (initiate_nonce, "CurveZMQINITIATE", 16);
    put_uint64 (initiate_nonce + 16, cn_nonce);

    rc = crypto_box (initiate_box, initiate_plaintext,
                     mlen, initiate_nonce, cn_server, cn_secret);
    zmq_assert (rc == 0);

    rc = msg_->init_size (113 + mlen - crypto_box_BOXZEROBYTES);
    errno_assert (rc == 0);

    uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());

    memcpy (initiate, "\x08INITIATE", 9);
    //  Cookie provided by the server in the WELCOME command
    memcpy (initiate + 9, cn_cookie, 96);
    //  Short nonce, prefixed by "CurveZMQINITIATE"
    memcpy (initiate + 105, initiate_nonce + 16, 8);
    //  Box [C + vouch + metadata](C'->S')
    memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
            mlen - crypto_box_BOXZEROBYTES);
    cn_nonce++;

    return 0;
}
Ejemplo n.º 22
0
void put_uint32(uint32_t i)
{
  put_uint64((uint64_t) i);
}
Ejemplo n.º 23
0
void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
                                 session_base_t *session_)
{
    zmq_assert (!_plugged);
    _plugged = true;

    //  Connect to session object.
    zmq_assert (!_session);
    zmq_assert (session_);
    _session = session_;
    _socket = _session->get_socket ();

    //  Connect to I/O threads poller object.
    io_object_t::plug (io_thread_);
    _handle = add_fd (_s);
    _io_error = false;

    if (_options.raw_socket) {
        // no handshaking for raw sock, instantiate raw encoder and decoders
        _encoder = new (std::nothrow) raw_encoder_t (out_batch_size);
        alloc_assert (_encoder);

        _decoder = new (std::nothrow) raw_decoder_t (in_batch_size);
        alloc_assert (_decoder);

        // disable handshaking for raw socket
        _handshaking = false;

        _next_msg = &stream_engine_t::pull_msg_from_session;
        _process_msg = &stream_engine_t::push_raw_msg_to_session;

        properties_t properties;
        if (init_properties (properties)) {
            //  Compile metadata.
            zmq_assert (_metadata == NULL);
            _metadata = new (std::nothrow) metadata_t (properties);
            alloc_assert (_metadata);
        }

        if (_options.raw_notify) {
            //  For raw sockets, send an initial 0-length message to the
            // application so that it knows a peer has connected.
            msg_t connector;
            connector.init ();
            push_raw_msg_to_session (&connector);
            connector.close ();
            _session->flush ();
        }
    } else {
        // start optional timer, to prevent handshake hanging on no input
        set_handshake_timer ();

        //  Send the 'length' and 'flags' fields of the routing id message.
        //  The 'length' field is encoded in the long format.
        _outpos = _greeting_send;
        _outpos[_outsize++] = UCHAR_MAX;
        put_uint64 (&_outpos[_outsize], _options.routing_id_size + 1);
        _outsize += 8;
        _outpos[_outsize++] = 0x7f;
    }

    set_pollin (_handle);
    set_pollout (_handle);
    //  Flush all the data that may have been already received downstream.
    in_event ();
}