mirror of
https://github.com/zeromq/libzmq.git
synced 2025-03-03 12:58:05 +01:00
Merge pull request #2695 from sigiesec/fine-grained-handshake-error-codes
Problem: Values in ZMQ_EVENT_HANDSHAKE_FAILED_* are not helpful
This commit is contained in:
commit
31c72e22ab
@ -484,6 +484,7 @@ set (cxx-sources
|
||||
client.cpp
|
||||
clock.cpp
|
||||
ctx.cpp
|
||||
curve_mechanism_base.cpp
|
||||
curve_client.cpp
|
||||
curve_server.cpp
|
||||
dealer.cpp
|
||||
@ -504,6 +505,7 @@ set (cxx-sources
|
||||
mailbox.cpp
|
||||
mailbox_safe.cpp
|
||||
mechanism.cpp
|
||||
mechanism_base.cpp
|
||||
metadata.cpp
|
||||
msg.cpp
|
||||
mtrie.cpp
|
||||
|
@ -38,6 +38,8 @@ src_libzmq_la_SOURCES = \
|
||||
src/curve_client.cpp \
|
||||
src/curve_client.hpp \
|
||||
src/curve_client_tools.hpp \
|
||||
src/curve_mechanism_base.cpp \
|
||||
src/curve_mechanism_base.hpp \
|
||||
src/curve_server.cpp \
|
||||
src/curve_server.hpp \
|
||||
src/dbuffer.hpp \
|
||||
@ -97,6 +99,8 @@ src_libzmq_la_SOURCES = \
|
||||
src/mailbox_safe.hpp \
|
||||
src/mechanism.cpp \
|
||||
src/mechanism.hpp \
|
||||
src/mechanism_base.cpp \
|
||||
src/mechanism_base.hpp \
|
||||
src/metadata.cpp \
|
||||
src/metadata.hpp \
|
||||
src/msg.cpp \
|
||||
|
@ -80,6 +80,9 @@
|
||||
'../../src/ctx.hpp',
|
||||
'../../src/curve_client.cpp',
|
||||
'../../src/curve_client.hpp',
|
||||
'../../src/curve_client_tools.hpp',
|
||||
'../../src/curve_mechanism_base.cpp',
|
||||
'../../src/curve_mechanism_base.hpp',
|
||||
'../../src/curve_server.cpp',
|
||||
'../../src/curve_server.hpp',
|
||||
'../../src/dbuffer.hpp',
|
||||
@ -136,6 +139,8 @@
|
||||
'../../src/mailbox_safe.hpp',
|
||||
'../../src/mechanism.cpp',
|
||||
'../../src/mechanism.hpp ',
|
||||
'../../src/mechanism_base.cpp',
|
||||
'../../src/mechanism_base.hpp ',
|
||||
'../../src/metadata.cpp',
|
||||
'../../src/metadata.hpp',
|
||||
'../../src/msg.cpp',
|
||||
|
@ -121,6 +121,7 @@
|
||||
<File RelativePath="..\..\..\..\src\kqueue.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\lb.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\mailbox.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\mechanism.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\metadata.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\msg.cpp" />
|
||||
@ -173,6 +174,7 @@
|
||||
<File RelativePath="..\..\..\..\src\udp_engine.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\xpub.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\xsub.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\zap_client.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\zmq.cpp" />
|
||||
<File RelativePath="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</Filter>
|
||||
|
@ -180,6 +180,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mtrie.cpp" />
|
||||
@ -266,6 +268,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\v2_encoder.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{641C5F36-32EE-4323-B740-992B651CF9D6}</ProjectGuid>
|
||||
@ -180,6 +180,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mtrie.cpp" />
|
||||
@ -266,6 +268,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\v2_encoder.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{641C5F36-32EE-4323-B740-992B651CF9D6}</ProjectGuid>
|
||||
@ -180,6 +180,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mtrie.cpp" />
|
||||
@ -266,6 +268,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\v2_encoder.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{641C5F36-32EE-4323-B740-992B651CF9D6}</ProjectGuid>
|
||||
@ -180,6 +180,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mtrie.cpp" />
|
||||
@ -266,6 +268,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\v2_encoder.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@ -152,6 +152,7 @@
|
||||
<ClCompile Include="..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -177,6 +178,7 @@
|
||||
<ClCompile Include="..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\src\mtrie.cpp" />
|
||||
@ -242,6 +244,7 @@
|
||||
<ClCompile Include="..\..\..\src\vmci_listener.cpp" />
|
||||
<ClCompile Include="..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\src\zmq.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{641C5F36-32EE-4323-B740-992B651CF9D6}</ProjectGuid>
|
||||
@ -180,6 +180,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\clock.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\ctx.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\curve_server.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\dealer.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\decoder_allocators.cpp" />
|
||||
@ -205,6 +206,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\mailbox.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mailbox_safe.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mechanism_base.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\metadata.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\msg.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\mtrie.cpp" />
|
||||
@ -266,6 +268,7 @@
|
||||
<ClCompile Include="..\..\..\..\src\v2_encoder.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xpub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\xsub.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zap_client.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq.cpp" />
|
||||
<ClCompile Include="..\..\..\..\src\zmq_utils.cpp" />
|
||||
</ItemGroup>
|
||||
|
@ -99,18 +99,29 @@ ZMQ_EVENT_MONITOR_STOPPED
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Monitoring on this socket ended.
|
||||
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The ZMTP security mechanism handshake failed.
|
||||
The event value is unspecified.
|
||||
NOTE: in DRAFT state, not yet available in stable releases.
|
||||
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEED
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The ZMTP security mechanism handshake succeeded.
|
||||
The event value is unspecified.
|
||||
NOTE: in DRAFT state, not yet available in stable releases.
|
||||
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The ZMTP security mechanism handshake failed due to some mechanism protocol
|
||||
error, either between the ZMTP mechanism peers, or between the mechanism
|
||||
server and the ZAP handler. This indicates a configuration or implementation
|
||||
error in either peer resp. the ZAP handler.
|
||||
The event value is one of the ZMQ_PROTOCOL_ERROR_* values.
|
||||
NOTE: in DRAFT state, not yet available in stable releases.
|
||||
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The ZMTP security mechanism handshake failed due to an authentication failure.
|
||||
The event value is the status code returned by the ZAP handler (i.e. 300,
|
||||
400 or 500).
|
||||
NOTE: in DRAFT state, not yet available in stable releases.
|
||||
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
------------
|
||||
|
@ -568,11 +568,41 @@ ZMQ_EXPORT void zmq_threadclose (void* thread);
|
||||
#define ZMQ_BINDTODEVICE 90
|
||||
|
||||
/* DRAFT 0MQ socket events and monitoring */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
|
||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
|
||||
/* Handshake complete successfully with successful authentication (if *
|
||||
* enabled). Event value is unused. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION 0x2000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP 0x4000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZAP 0x8000
|
||||
/* Protocol errors between ZMTP peers or between server and ZAP handler. *
|
||||
* Event value is one of ZMQ_PROTOCOL_ERROR_* */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000
|
||||
/* Failed authentication requests. Event value is the numeric ZAP status *
|
||||
* code, i.e. 300, 400 or 500. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000
|
||||
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR 0x10000015
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY 0x10000016
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME 0x10000017
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA 0x10000018
|
||||
|
||||
// the following two may be due to erroneous configuration of a peer
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002
|
||||
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005
|
||||
|
||||
/* DRAFT Context options */
|
||||
#define ZMQ_MSG_T_SIZE 6
|
||||
|
@ -39,14 +39,15 @@
|
||||
#include "wire.hpp"
|
||||
#include "curve_client_tools.hpp"
|
||||
|
||||
zmq::curve_client_t::curve_client_t (const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
zmq::curve_client_t::curve_client_t (session_base_t *session_,
|
||||
const options_t &options_) :
|
||||
mechanism_base_t (session_, options_),
|
||||
curve_mechanism_base_t (
|
||||
session_, options_, "CurveZMQMESSAGEC", "CurveZMQMESSAGES"),
|
||||
state (send_hello),
|
||||
tools (options_.curve_public_key,
|
||||
options_.curve_secret_key,
|
||||
options_.curve_server_key),
|
||||
cn_nonce (1),
|
||||
cn_peer_nonce (1)
|
||||
options_.curve_server_key)
|
||||
{
|
||||
}
|
||||
|
||||
@ -92,6 +93,9 @@ int zmq::curve_client_t::process_handshake_command (msg_t *msg_)
|
||||
msg_size))
|
||||
rc = process_error (msg_data, msg_size);
|
||||
else {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
rc = -1;
|
||||
}
|
||||
@ -109,118 +113,13 @@ int zmq::curve_client_t::process_handshake_command (msg_t *msg_)
|
||||
int zmq::curve_client_t::encode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == connected);
|
||||
|
||||
uint8_t flags = 0;
|
||||
if (msg_->flags () & msg_t::more)
|
||||
flags |= 0x01;
|
||||
if (msg_->flags () & msg_t::command)
|
||||
flags |= 0x02;
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
|
||||
put_uint64 (message_nonce + 16, cn_nonce);
|
||||
|
||||
const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
|
||||
|
||||
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, tools.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;
|
||||
return curve_mechanism_base_t::encode (msg_);
|
||||
}
|
||||
|
||||
int zmq::curve_client_t::decode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == connected);
|
||||
|
||||
if (msg_->size () < 33) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (message, "\x07MESSAGE", 8)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGES", 16);
|
||||
memcpy (message_nonce + 16, message + 8, 8);
|
||||
uint64_t nonce = get_uint64(message + 8);
|
||||
if (nonce <= cn_peer_nonce) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
cn_peer_nonce = nonce;
|
||||
|
||||
const size_t clen = crypto_box_BOXZEROBYTES + (msg_->size () - 16);
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_plaintext);
|
||||
|
||||
uint8_t *message_box = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_box);
|
||||
|
||||
memset (message_box, 0, crypto_box_BOXZEROBYTES);
|
||||
memcpy (message_box + crypto_box_BOXZEROBYTES,
|
||||
message + 16, msg_->size () - 16);
|
||||
|
||||
int rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
|
||||
message_nonce, tools.cn_precom);
|
||||
if (rc == 0) {
|
||||
rc = msg_->close ();
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
|
||||
if (flags & 0x01)
|
||||
msg_->set_flags (msg_t::more);
|
||||
if (flags & 0x02)
|
||||
msg_->set_flags (msg_t::command);
|
||||
|
||||
memcpy (msg_->data (),
|
||||
message_plaintext + crypto_box_ZEROBYTES + 1,
|
||||
msg_->size ());
|
||||
}
|
||||
else
|
||||
errno = EPROTO;
|
||||
|
||||
free (message_plaintext);
|
||||
free (message_box);
|
||||
|
||||
return rc;
|
||||
return curve_mechanism_base_t::decode (msg_);
|
||||
}
|
||||
|
||||
zmq::mechanism_t::status_t zmq::curve_client_t::status () const
|
||||
@ -241,6 +140,10 @@ int zmq::curve_client_t::produce_hello (msg_t *msg_)
|
||||
|
||||
rc = tools.produce_hello (msg_->data (), cn_nonce);
|
||||
if (rc == -1) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
|
||||
// TODO this is somewhat inconsistent: we call init_size, but we may
|
||||
// not close msg_; i.e. we assume that msg_ is initialized but empty
|
||||
// (if it were non-empty, calling init_size might cause a leak!)
|
||||
@ -257,9 +160,13 @@ int zmq::curve_client_t::produce_hello (msg_t *msg_)
|
||||
int zmq::curve_client_t::process_welcome (const uint8_t *msg_data,
|
||||
size_t msg_size)
|
||||
{
|
||||
int rc = tools.process_welcome (msg_data, msg_size);
|
||||
int rc = tools.process_welcome (msg_data, msg_size, cn_precom);
|
||||
|
||||
if (rc == -1) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -288,6 +195,10 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_)
|
||||
free (metadata_plaintext);
|
||||
|
||||
if (-1 == rc) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
|
||||
// TODO see comment in produce_hello
|
||||
return -1;
|
||||
}
|
||||
@ -301,6 +212,9 @@ int zmq::curve_client_t::process_ready (
|
||||
const uint8_t *msg_data, size_t msg_size)
|
||||
{
|
||||
if (msg_size < 30) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -323,10 +237,13 @@ int zmq::curve_client_t::process_ready (
|
||||
cn_peer_nonce = get_uint64(msg_data + 6);
|
||||
|
||||
int rc = crypto_box_open_afternm (ready_plaintext, ready_box,
|
||||
clen, ready_nonce, tools.cn_precom);
|
||||
clen, ready_nonce, cn_precom);
|
||||
free (ready_box);
|
||||
|
||||
if (rc != 0) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -337,6 +254,12 @@ int zmq::curve_client_t::process_ready (
|
||||
|
||||
if (rc == 0)
|
||||
state = connected;
|
||||
else
|
||||
{
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA);
|
||||
errno = EPROTO;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -345,15 +268,21 @@ int zmq::curve_client_t::process_error (
|
||||
const uint8_t *msg_data, size_t msg_size)
|
||||
{
|
||||
if (state != expect_welcome && state != expect_ready) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
if (msg_size < 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
const size_t error_reason_len = static_cast <size_t> (msg_data [6]);
|
||||
if (error_reason_len > msg_size - 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#ifdef ZMQ_HAVE_CURVE
|
||||
|
||||
#include "mechanism.hpp"
|
||||
#include "curve_mechanism_base.hpp"
|
||||
#include "options.hpp"
|
||||
#include "curve_client_tools.hpp"
|
||||
|
||||
@ -42,11 +42,11 @@ namespace zmq
|
||||
class msg_t;
|
||||
class session_base_t;
|
||||
|
||||
class curve_client_t : public mechanism_t
|
||||
class curve_client_t : public curve_mechanism_base_t
|
||||
{
|
||||
public:
|
||||
|
||||
curve_client_t (const options_t &options_);
|
||||
curve_client_t (session_base_t *session_, const options_t &options_);
|
||||
virtual ~curve_client_t ();
|
||||
|
||||
// mechanism implementation
|
||||
@ -72,11 +72,7 @@ namespace zmq
|
||||
|
||||
// CURVE protocol tools
|
||||
curve_client_tools_t tools;
|
||||
|
||||
// Nonce
|
||||
uint64_t cn_nonce;
|
||||
uint64_t cn_peer_nonce;
|
||||
|
||||
|
||||
int produce_hello (msg_t *msg_);
|
||||
int process_welcome (const uint8_t *cmd_data, size_t data_size);
|
||||
int produce_initiate (msg_t *msg_);
|
||||
|
@ -251,7 +251,9 @@ struct curve_client_tools_t
|
||||
return produce_hello (data, server_key, cn_nonce, cn_public, cn_secret);
|
||||
}
|
||||
|
||||
int process_welcome (const uint8_t *msg_data, size_t msg_size)
|
||||
int process_welcome (const uint8_t *msg_data,
|
||||
size_t msg_size,
|
||||
uint8_t *cn_precom)
|
||||
{
|
||||
return process_welcome (msg_data, msg_size, server_key, cn_secret,
|
||||
cn_server, cn_cookie, cn_precom);
|
||||
@ -289,10 +291,6 @@ struct curve_client_tools_t
|
||||
// Cookie received from server
|
||||
uint8_t cn_cookie[16 + 80];
|
||||
|
||||
// Intermediary buffer used to speed up boxing and unboxing.
|
||||
uint8_t cn_precom[crypto_box_BEFORENMBYTES];
|
||||
|
||||
|
||||
private:
|
||||
template <size_t N>
|
||||
static bool is_handshake_command (const uint8_t *msg_data,
|
||||
|
181
src/curve_mechanism_base.cpp
Normal file
181
src/curve_mechanism_base.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "curve_mechanism_base.hpp"
|
||||
#include "msg.hpp"
|
||||
#include "wire.hpp"
|
||||
#include "session_base.hpp"
|
||||
|
||||
#ifdef ZMQ_HAVE_CURVE
|
||||
|
||||
zmq::curve_mechanism_base_t::curve_mechanism_base_t (
|
||||
session_base_t *session_,
|
||||
const options_t &options_,
|
||||
const char *encode_nonce_prefix_,
|
||||
const char *decode_nonce_prefix_) :
|
||||
mechanism_base_t (session_, options_),
|
||||
encode_nonce_prefix (encode_nonce_prefix_),
|
||||
decode_nonce_prefix (decode_nonce_prefix_),
|
||||
cn_nonce (1),
|
||||
cn_peer_nonce (1)
|
||||
{
|
||||
}
|
||||
|
||||
int zmq::curve_mechanism_base_t::encode (msg_t *msg_)
|
||||
{
|
||||
const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, encode_nonce_prefix, 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;
|
||||
}
|
||||
|
||||
int zmq::curve_mechanism_base_t::decode (msg_t *msg_)
|
||||
{
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
const size_t size = msg_->size ();
|
||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||
|
||||
if (size < 8 || memcmp (message, "\x07MESSAGE", 8)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size < 33) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, decode_nonce_prefix, 16);
|
||||
memcpy (message_nonce + 16, message + 8, 8);
|
||||
uint64_t nonce = get_uint64(message + 8);
|
||||
if (nonce <= cn_peer_nonce) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
cn_peer_nonce = nonce;
|
||||
|
||||
const size_t clen = crypto_box_BOXZEROBYTES + msg_->size () - 16;
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_plaintext);
|
||||
|
||||
uint8_t *message_box = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_box);
|
||||
|
||||
memset (message_box, 0, crypto_box_BOXZEROBYTES);
|
||||
memcpy (message_box + crypto_box_BOXZEROBYTES,
|
||||
message + 16, msg_->size () - 16);
|
||||
|
||||
rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
|
||||
message_nonce, cn_precom);
|
||||
if (rc == 0) {
|
||||
rc = msg_->close ();
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
|
||||
if (flags & 0x01)
|
||||
msg_->set_flags (msg_t::more);
|
||||
if (flags & 0x02)
|
||||
msg_->set_flags (msg_t::command);
|
||||
|
||||
memcpy (msg_->data (),
|
||||
message_plaintext + crypto_box_ZEROBYTES + 1,
|
||||
msg_->size ());
|
||||
}
|
||||
else {
|
||||
// CURVE I : connection key used for MESSAGE is wrong
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
}
|
||||
free (message_plaintext);
|
||||
free (message_box);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
79
src/curve_mechanism_base.hpp
Normal file
79
src/curve_mechanism_base.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ZMQ_CURVE_MECHANISM_BASE_HPP_INCLUDED__
|
||||
#define __ZMQ_CURVE_MECHANISM_BASE_HPP_INCLUDED__
|
||||
|
||||
#ifdef ZMQ_HAVE_CURVE
|
||||
|
||||
#if defined(ZMQ_USE_TWEETNACL)
|
||||
#include "tweetnacl.h"
|
||||
#elif defined(ZMQ_USE_LIBSODIUM)
|
||||
#include "sodium.h"
|
||||
#endif
|
||||
|
||||
#if crypto_box_NONCEBYTES != 24 || crypto_box_PUBLICKEYBYTES != 32 \
|
||||
|| crypto_box_SECRETKEYBYTES != 32 || crypto_box_ZEROBYTES != 32 \
|
||||
|| crypto_box_BOXZEROBYTES != 16 || crypto_secretbox_NONCEBYTES != 24 \
|
||||
|| crypto_secretbox_ZEROBYTES != 32 || crypto_secretbox_BOXZEROBYTES != 16
|
||||
#error "CURVE library not built properly"
|
||||
#endif
|
||||
|
||||
#include "mechanism_base.hpp"
|
||||
#include "options.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
class curve_mechanism_base_t : public virtual mechanism_base_t
|
||||
{
|
||||
public:
|
||||
curve_mechanism_base_t (session_base_t *session_,
|
||||
const options_t &options_,
|
||||
const char *encode_nonce_prefix_,
|
||||
const char *decode_nonce_prefix_);
|
||||
|
||||
// mechanism implementation
|
||||
virtual int encode (msg_t *msg_);
|
||||
virtual int decode (msg_t *msg_);
|
||||
|
||||
protected:
|
||||
const char *encode_nonce_prefix;
|
||||
const char *decode_nonce_prefix;
|
||||
|
||||
uint64_t cn_nonce;
|
||||
uint64_t cn_peer_nonce;
|
||||
|
||||
// Intermediary buffer used to speed up boxing and unboxing.
|
||||
uint8_t cn_precom [crypto_box_BEFORENMBYTES];
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -41,11 +41,11 @@
|
||||
zmq::curve_server_t::curve_server_t (session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
mechanism_base_t (session_, options_),
|
||||
zap_client_common_handshake_t (
|
||||
session_, peer_address_, options_, sending_ready),
|
||||
cn_nonce (1),
|
||||
cn_peer_nonce (1)
|
||||
curve_mechanism_base_t (
|
||||
session_, options_, "CurveZMQMESSAGES", "CurveZMQMESSAGEC")
|
||||
{
|
||||
int rc;
|
||||
// Fetch our secret key from socket options
|
||||
@ -107,7 +107,8 @@ int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
|
||||
// Therefore, it should be changed to zmq_assert (false);
|
||||
|
||||
// CURVE I: invalid handshake command
|
||||
current_error_detail = zmtp;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED);
|
||||
errno = EPROTO;
|
||||
rc = -1;
|
||||
break;
|
||||
@ -124,139 +125,34 @@ int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
|
||||
int zmq::curve_server_t::encode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == ready);
|
||||
|
||||
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;
|
||||
return curve_mechanism_base_t::encode (msg_);
|
||||
}
|
||||
|
||||
int zmq::curve_server_t::decode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == ready);
|
||||
|
||||
if (msg_->size () < 33) {
|
||||
// CURVE I : invalid CURVE client, sent malformed command
|
||||
current_error_detail = zmtp;
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (message, "\x07MESSAGE", 8)) {
|
||||
// CURVE I: invalid CURVE client, did not send MESSAGE
|
||||
current_error_detail = zmtp;
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
|
||||
memcpy (message_nonce + 16, message + 8, 8);
|
||||
uint64_t nonce = get_uint64(message + 8);
|
||||
if (nonce <= cn_peer_nonce) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
cn_peer_nonce = nonce;
|
||||
|
||||
const size_t clen = crypto_box_BOXZEROBYTES + msg_->size () - 16;
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_plaintext);
|
||||
|
||||
uint8_t *message_box = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_box);
|
||||
|
||||
memset (message_box, 0, crypto_box_BOXZEROBYTES);
|
||||
memcpy (message_box + crypto_box_BOXZEROBYTES,
|
||||
message + 16, msg_->size () - 16);
|
||||
|
||||
int rc = crypto_box_open_afternm (message_plaintext, message_box,
|
||||
clen, message_nonce, cn_precom);
|
||||
if (rc == 0) {
|
||||
rc = msg_->close ();
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
|
||||
if (flags & 0x01)
|
||||
msg_->set_flags (msg_t::more);
|
||||
if (flags & 0x02)
|
||||
msg_->set_flags (msg_t::command);
|
||||
|
||||
memcpy (msg_->data (),
|
||||
message_plaintext + crypto_box_ZEROBYTES + 1,
|
||||
msg_->size ());
|
||||
}
|
||||
else {
|
||||
// CURVE I : connection key used for MESSAGE is wrong
|
||||
current_error_detail = encryption;
|
||||
errno = EPROTO;
|
||||
}
|
||||
free (message_plaintext);
|
||||
free (message_box);
|
||||
|
||||
return rc;
|
||||
return curve_mechanism_base_t::decode (msg_);
|
||||
}
|
||||
|
||||
int zmq::curve_server_t::process_hello (msg_t *msg_)
|
||||
{
|
||||
if (msg_->size () != 200) {
|
||||
// CURVE I: client HELLO is not correct size
|
||||
current_error_detail = zmtp;
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
const size_t size = msg_->size ();
|
||||
const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
|
||||
|
||||
if (size < 6 || memcmp (hello, "\x05HELLO", 6)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t * const hello = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (hello, "\x05HELLO", 6)) {
|
||||
// CURVE I: client HELLO has invalid command name
|
||||
current_error_detail = zmtp;
|
||||
if (size != 200) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -266,7 +162,8 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
|
||||
|
||||
if (major != 1 || minor != 0) {
|
||||
// CURVE I: client HELLO has unknown version number
|
||||
current_error_detail = zmtp;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -286,12 +183,12 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
|
||||
memcpy (hello_box + crypto_box_BOXZEROBYTES, hello + 120, 80);
|
||||
|
||||
// Open Box [64 * %x0](C'->S)
|
||||
int rc = crypto_box_open (hello_plaintext, hello_box,
|
||||
sizeof hello_box,
|
||||
hello_nonce, cn_client, secret_key);
|
||||
rc = crypto_box_open (hello_plaintext, hello_box, sizeof hello_box,
|
||||
hello_nonce, cn_client, secret_key);
|
||||
if (rc != 0) {
|
||||
// CURVE I: cannot open client HELLO -- wrong server key?
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -345,8 +242,8 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_)
|
||||
cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80);
|
||||
|
||||
rc = crypto_box (welcome_ciphertext, welcome_plaintext,
|
||||
sizeof welcome_plaintext,
|
||||
welcome_nonce, cn_client, secret_key);
|
||||
sizeof welcome_plaintext, welcome_nonce, cn_client,
|
||||
secret_key);
|
||||
|
||||
// TODO I think we should change this back to zmq_assert (rc == 0);
|
||||
// as it was before https://github.com/zeromq/libzmq/pull/1832
|
||||
@ -370,17 +267,24 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_)
|
||||
|
||||
int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
{
|
||||
if (msg_->size () < 257) {
|
||||
// CURVE I: client INITIATE is not correct size
|
||||
current_error_detail = zmtp;
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
const size_t size = msg_->size ();
|
||||
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
||||
|
||||
if (size < 9 || memcmp (initiate, "\x08INITIATE", 9)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *initiate = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (initiate, "\x08INITIATE", 9)) {
|
||||
// CURVE I: client INITIATE has invalid command name
|
||||
current_error_detail = zmtp;
|
||||
if (size < 257) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -396,12 +300,12 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
memcpy (cookie_nonce, "COOKIE--", 8);
|
||||
memcpy (cookie_nonce + 8, initiate + 9, 16);
|
||||
|
||||
int rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
|
||||
sizeof cookie_box,
|
||||
cookie_nonce, cookie_key);
|
||||
rc = crypto_secretbox_open (cookie_plaintext, cookie_box, sizeof cookie_box,
|
||||
cookie_nonce, cookie_key);
|
||||
if (rc != 0) {
|
||||
// CURVE I: cannot open client INITIATE cookie
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -413,12 +317,13 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
// client that knows the server's secret temporary cookie key
|
||||
|
||||
// CURVE I: client INITIATE cookie is not valid
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
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_plaintext [crypto_box_ZEROBYTES + 128 + 256];
|
||||
@ -437,7 +342,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
clen, initiate_nonce, cn_client, cn_secret);
|
||||
if (rc != 0) {
|
||||
// CURVE I: cannot open client INITIATE
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -462,7 +368,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
vouch_nonce, client_key, cn_secret);
|
||||
if (rc != 0) {
|
||||
// CURVE I: cannot open client INITIATE vouch
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -473,7 +380,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
|
||||
// client that knows the server's secret short-term key
|
||||
|
||||
// CURVE I: invalid handshake from client (public key)
|
||||
current_error_detail = encryption;
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -32,34 +32,18 @@
|
||||
|
||||
#ifdef ZMQ_HAVE_CURVE
|
||||
|
||||
#if defined (ZMQ_USE_TWEETNACL)
|
||||
# include "tweetnacl.h"
|
||||
#elif defined (ZMQ_USE_LIBSODIUM)
|
||||
# include "sodium.h"
|
||||
#endif
|
||||
|
||||
#if crypto_box_NONCEBYTES != 24 \
|
||||
|| crypto_box_PUBLICKEYBYTES != 32 \
|
||||
|| crypto_box_SECRETKEYBYTES != 32 \
|
||||
|| crypto_box_ZEROBYTES != 32 \
|
||||
|| crypto_box_BOXZEROBYTES != 16 \
|
||||
|| crypto_secretbox_NONCEBYTES != 24 \
|
||||
|| crypto_secretbox_ZEROBYTES != 32 \
|
||||
|| crypto_secretbox_BOXZEROBYTES != 16
|
||||
# error "CURVE library not built properly"
|
||||
#endif
|
||||
|
||||
#include "mechanism.hpp"
|
||||
#include "curve_mechanism_base.hpp"
|
||||
#include "options.hpp"
|
||||
#include "zap_client.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
|
||||
class msg_t;
|
||||
class session_base_t;
|
||||
|
||||
class curve_server_t : public zap_client_common_handshake_t
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4250)
|
||||
#endif
|
||||
class curve_server_t : public zap_client_common_handshake_t,
|
||||
public curve_mechanism_base_t
|
||||
{
|
||||
public:
|
||||
|
||||
@ -76,9 +60,6 @@ namespace zmq
|
||||
|
||||
private:
|
||||
|
||||
uint64_t cn_nonce;
|
||||
uint64_t cn_peer_nonce;
|
||||
|
||||
// Our secret key (s)
|
||||
uint8_t secret_key [crypto_box_SECRETKEYBYTES];
|
||||
|
||||
@ -94,9 +75,6 @@ namespace zmq
|
||||
// Key used to produce cookie
|
||||
uint8_t cookie_key [crypto_secretbox_KEYBYTES];
|
||||
|
||||
// Intermediary buffer used to speed up boxing and unboxing.
|
||||
uint8_t cn_precom [crypto_box_BEFORENMBYTES];
|
||||
|
||||
int process_hello (msg_t *msg_);
|
||||
int produce_welcome (msg_t *msg_);
|
||||
int process_initiate (msg_t *msg_);
|
||||
@ -105,6 +83,9 @@ namespace zmq
|
||||
|
||||
void send_zap_request (const uint8_t *key);
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,9 @@
|
||||
#include "gssapi_client.hpp"
|
||||
#include "wire.hpp"
|
||||
|
||||
zmq::gssapi_client_t::gssapi_client_t (const options_t &options_) :
|
||||
zmq::gssapi_client_t::gssapi_client_t (session_base_t *session_,
|
||||
const options_t &options_) :
|
||||
mechanism_base_t (session_, options_),
|
||||
gssapi_mechanism_base_t (options_),
|
||||
state (call_next_init),
|
||||
token_ptr (GSS_C_NO_BUFFER),
|
||||
@ -123,6 +125,9 @@ int zmq::gssapi_client_t::process_handshake_command (msg_t *msg_)
|
||||
}
|
||||
|
||||
if (state != recv_next_token) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -38,13 +38,12 @@ namespace zmq
|
||||
{
|
||||
|
||||
class msg_t;
|
||||
class session_base_t;
|
||||
|
||||
class gssapi_client_t :
|
||||
public gssapi_mechanism_base_t
|
||||
class gssapi_client_t : public gssapi_mechanism_base_t
|
||||
{
|
||||
public:
|
||||
|
||||
gssapi_client_t (const options_t &options_);
|
||||
public:
|
||||
gssapi_client_t (session_base_t *session_, const options_t &options_);
|
||||
virtual ~gssapi_client_t ();
|
||||
|
||||
// mechanism implementation
|
||||
|
@ -40,8 +40,11 @@
|
||||
#include "gssapi_mechanism_base.hpp"
|
||||
#include "wire.hpp"
|
||||
|
||||
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (const options_t & options_) :
|
||||
mechanism_t(options_),
|
||||
zmq::gssapi_mechanism_base_t::gssapi_mechanism_base_t (
|
||||
session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_base_t (session_, options_),
|
||||
send_tok (),
|
||||
recv_tok (),
|
||||
/// FIXME remove? in_buf (),
|
||||
@ -125,8 +128,15 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
|
||||
const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
|
||||
size_t bytes_left = msg_->size ();
|
||||
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return rc;
|
||||
|
||||
// Get command string
|
||||
if (bytes_left < 8 || memcmp (ptr, "\x07MESSAGE", 8)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -135,6 +145,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
|
||||
|
||||
// Get token length
|
||||
if (bytes_left < 4) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -145,6 +158,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
|
||||
|
||||
// Get token value
|
||||
if (bytes_left < wrapped.length) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -165,11 +181,16 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
|
||||
maj_stat = gss_unwrap(&min_stat, context, &wrapped, &plaintext,
|
||||
&state, (gss_qop_t *) NULL);
|
||||
|
||||
// TODO I don't think it is a good idea to use zmq_assert here. If
|
||||
// decryption fails, gss_unwrap returns GSS_S_BAD_SIG. This opens up
|
||||
// to DoS attacks by clients! Instead, a
|
||||
// ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC event should be emitted.
|
||||
|
||||
zmq_assert(maj_stat == GSS_S_COMPLETE);
|
||||
zmq_assert(state);
|
||||
|
||||
// Re-initialize msg_ for plaintext
|
||||
int rc = msg_->close ();
|
||||
rc = msg_->close ();
|
||||
zmq_assert (rc == 0);
|
||||
|
||||
rc = msg_->init_size (plaintext.length-1);
|
||||
@ -187,6 +208,9 @@ int zmq::gssapi_mechanism_base_t::decode_message (msg_t *msg_)
|
||||
free(wrapped.value);
|
||||
|
||||
if (bytes_left > 0) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -228,8 +252,15 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
|
||||
const uint8_t *ptr = static_cast <uint8_t *> (msg_->data ());
|
||||
size_t bytes_left = msg_->size ();
|
||||
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return rc;
|
||||
|
||||
// Get command string
|
||||
if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -238,6 +269,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
|
||||
|
||||
// Get token length
|
||||
if (bytes_left < 4) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -247,6 +281,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
|
||||
|
||||
// Get token value
|
||||
if (bytes_left < token_length_) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -261,6 +298,9 @@ int zmq::gssapi_mechanism_base_t::process_initiate (msg_t *msg_, void **token_va
|
||||
}
|
||||
|
||||
if (bytes_left > 0) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -314,14 +354,28 @@ int zmq::gssapi_mechanism_base_t::process_ready (msg_t *msg_)
|
||||
const unsigned char *ptr = static_cast <unsigned char *> (msg_->data ());
|
||||
size_t bytes_left = msg_->size ();
|
||||
|
||||
int rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return rc;
|
||||
|
||||
if (bytes_left < 6 || memcmp (ptr, "\x05READY", 6)) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
ptr += 6;
|
||||
bytes_left -= 6;
|
||||
return parse_metadata (ptr, bytes_left);
|
||||
rc = parse_metadata (ptr, bytes_left);
|
||||
if (rc == -1)
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
const gss_OID zmq::gssapi_mechanism_base_t::convert_nametype (int zmq_nametype)
|
||||
{
|
||||
switch (zmq_nametype) {
|
||||
|
@ -49,14 +49,15 @@ namespace zmq
|
||||
/// For example, clients and servers both need to produce and
|
||||
/// process context-level GSSAPI tokens (via INITIATE commands)
|
||||
/// and per-message GSSAPI tokens (via MESSAGE commands).
|
||||
class gssapi_mechanism_base_t:
|
||||
public virtual mechanism_t
|
||||
class gssapi_mechanism_base_t : public virtual mechanism_base_t
|
||||
{
|
||||
public:
|
||||
gssapi_mechanism_base_t (const options_t &options_);
|
||||
public:
|
||||
gssapi_mechanism_base_t (session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_);
|
||||
virtual ~gssapi_mechanism_base_t () = 0;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
// Produce a context-level GSSAPI token (INITIATE command)
|
||||
// during security context initialization.
|
||||
int produce_initiate (msg_t *msg_, void *data_, size_t data_len_);
|
||||
|
@ -45,7 +45,7 @@
|
||||
zmq::gssapi_server_t::gssapi_server_t (session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
mechanism_base_t (session_, options_),
|
||||
gssapi_mechanism_base_t (options_),
|
||||
zap_client_t (session_, peer_address_, options_),
|
||||
state (recv_next_token),
|
||||
@ -114,6 +114,9 @@ int zmq::gssapi_server_t::process_handshake_command (msg_t *msg_)
|
||||
}
|
||||
|
||||
if (state != recv_next_token) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,19 +45,18 @@ namespace zmq
|
||||
: public gssapi_mechanism_base_t, public zap_client_t
|
||||
{
|
||||
public:
|
||||
gssapi_server_t (session_base_t *session_,
|
||||
const std::string &peer_address,
|
||||
const options_t &options_);
|
||||
virtual ~gssapi_server_t ();
|
||||
|
||||
gssapi_server_t (session_base_t *session_,
|
||||
const std::string &peer_address,
|
||||
const options_t &options_);
|
||||
virtual ~gssapi_server_t ();
|
||||
|
||||
// mechanism implementation
|
||||
virtual int next_handshake_command (msg_t *msg_);
|
||||
virtual int process_handshake_command (msg_t *msg_);
|
||||
virtual int encode (msg_t *msg_);
|
||||
virtual int decode (msg_t *msg_);
|
||||
virtual int zap_msg_available ();
|
||||
virtual status_t status () const;
|
||||
// mechanism implementation
|
||||
virtual int next_handshake_command (msg_t *msg_);
|
||||
virtual int process_handshake_command (msg_t *msg_);
|
||||
virtual int encode (msg_t *msg_);
|
||||
virtual int decode (msg_t *msg_);
|
||||
virtual int zap_msg_available ();
|
||||
virtual status_t status () const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "msg.hpp"
|
||||
#include "err.hpp"
|
||||
#include "wire.hpp"
|
||||
#include "session_base.hpp"
|
||||
|
||||
zmq::mechanism_t::mechanism_t (const options_t &options_) :
|
||||
options (options_)
|
||||
|
@ -38,11 +38,12 @@
|
||||
namespace zmq
|
||||
{
|
||||
|
||||
class msg_t;
|
||||
class session_base_t;
|
||||
|
||||
// Abstract class representing security mechanism.
|
||||
// Different mechanism extends this class.
|
||||
|
||||
class msg_t;
|
||||
|
||||
class mechanism_t
|
||||
{
|
||||
public:
|
||||
@ -53,14 +54,6 @@ namespace zmq
|
||||
error
|
||||
};
|
||||
|
||||
// Provides more details when in status_t::error
|
||||
enum error_detail_t {
|
||||
no_detail,
|
||||
zmtp,
|
||||
zap,
|
||||
encryption
|
||||
};
|
||||
|
||||
mechanism_t (const options_t &options_);
|
||||
|
||||
virtual ~mechanism_t ();
|
||||
@ -81,10 +74,6 @@ namespace zmq
|
||||
// Returns the status of this mechanism.
|
||||
virtual status_t status () const = 0;
|
||||
|
||||
// Returns details about of the current error of the mechanism.
|
||||
// Returned value does not makes sense if the current status is not error.
|
||||
virtual error_detail_t error_detail () const { return no_detail; }
|
||||
|
||||
void set_peer_identity (const void *id_ptr, size_t id_size);
|
||||
|
||||
void peer_identity (msg_t *msg_);
|
||||
|
54
src/mechanism_base.cpp
Normal file
54
src/mechanism_base.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
|
||||
#include "mechanism_base.hpp"
|
||||
#include "session_base.hpp"
|
||||
|
||||
zmq::mechanism_base_t::mechanism_base_t (session_base_t *const session_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
session (session_)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int zmq::mechanism_base_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;
|
||||
}
|
||||
|
49
src/mechanism_base.hpp
Normal file
49
src/mechanism_base.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of libzmq, the ZeroMQ core engine in C++.
|
||||
|
||||
libzmq is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License (LGPL) as published
|
||||
by the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
As a special exception, the Contributors give you permission to link
|
||||
this library with independent modules to produce an executable,
|
||||
regardless of the license terms of these independent modules, and to
|
||||
copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the
|
||||
terms and conditions of the license of that module. An independent
|
||||
module is a module which is not derived from or based on this library.
|
||||
If you modify this library, you must extend this exception to your
|
||||
version of the library.
|
||||
|
||||
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ZMQ_MECHANISM_BASE_HPP_INCLUDED__
|
||||
#define __ZMQ_MECHANISM_BASE_HPP_INCLUDED__
|
||||
|
||||
#include "mechanism.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
class mechanism_base_t : public mechanism_t
|
||||
{
|
||||
protected:
|
||||
mechanism_base_t (session_base_t *const session_,
|
||||
const options_t &options_);
|
||||
|
||||
session_base_t *const session;
|
||||
|
||||
int check_basic_command_structure (msg_t *msg_);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -42,7 +42,7 @@
|
||||
zmq::null_mechanism_t::null_mechanism_t (session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
mechanism_base_t (session_, options_),
|
||||
zap_client_t (session_, peer_address_, options_),
|
||||
ready_command_sent (false),
|
||||
error_command_sent (false),
|
||||
@ -104,8 +104,9 @@ int zmq::null_mechanism_t::next_handshake_command (msg_t *msg_)
|
||||
int zmq::null_mechanism_t::process_handshake_command (msg_t *msg_)
|
||||
{
|
||||
if (ready_command_received || error_command_received) {
|
||||
// Temporary support for security debugging
|
||||
puts ("NULL I: client sent invalid NULL handshake (duplicate READY)");
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -121,8 +122,9 @@ int zmq::null_mechanism_t::process_handshake_command (msg_t *msg_)
|
||||
if (data_size >= 6 && !memcmp (cmd_data, "\5ERROR", 6))
|
||||
rc = process_error_command (cmd_data, data_size);
|
||||
else {
|
||||
// Temporary support for security debugging
|
||||
puts ("NULL I: client sent invalid NULL handshake (not READY)");
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
rc = -1;
|
||||
}
|
||||
@ -147,11 +149,19 @@ int zmq::null_mechanism_t::process_error_command (
|
||||
const unsigned char *cmd_data, size_t data_size)
|
||||
{
|
||||
if (data_size < 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
const size_t error_reason_len = static_cast <size_t> (cmd_data [6]);
|
||||
if (error_reason_len > data_size - 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -191,4 +201,3 @@ void zmq::null_mechanism_t::send_zap_request ()
|
||||
{
|
||||
zap_client_t::send_zap_request ("NULL", 4, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,11 @@
|
||||
#include "msg.hpp"
|
||||
#include "err.hpp"
|
||||
#include "plain_client.hpp"
|
||||
#include "session_base.hpp"
|
||||
|
||||
zmq::plain_client_t::plain_client_t (const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
zmq::plain_client_t::plain_client_t (session_base_t *const session_,
|
||||
const options_t &options_) :
|
||||
mechanism_base_t (session_, options_),
|
||||
state (sending_hello)
|
||||
{
|
||||
}
|
||||
@ -84,8 +86,9 @@ int zmq::plain_client_t::process_handshake_command (msg_t *msg_)
|
||||
if (data_size >= 6 && !memcmp (cmd_data, "\5ERROR", 6))
|
||||
rc = process_error (cmd_data, data_size);
|
||||
else {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid handshake command");
|
||||
// TODO see comment in curve_server_t::process_handshake_command
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED);
|
||||
errno = EPROTO;
|
||||
rc = -1;
|
||||
}
|
||||
@ -146,10 +149,15 @@ int zmq::plain_client_t::process_welcome (
|
||||
LIBZMQ_UNUSED (cmd_data);
|
||||
|
||||
if (state != waiting_for_welcome) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
if (data_size != 8) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -168,12 +176,18 @@ int zmq::plain_client_t::process_ready (
|
||||
const unsigned char *cmd_data, size_t data_size)
|
||||
{
|
||||
if (state != waiting_for_ready) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
const int rc = parse_metadata (cmd_data + 6, data_size - 6);
|
||||
if (rc == 0)
|
||||
state = ready;
|
||||
else
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -181,15 +195,23 @@ 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) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
if (data_size < 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
const size_t error_reason_len = static_cast <size_t> (cmd_data [6]);
|
||||
if (error_reason_len > data_size - 7) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (),
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
#ifndef __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__
|
||||
#define __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__
|
||||
|
||||
#include "mechanism.hpp"
|
||||
#include "mechanism_base.hpp"
|
||||
#include "options.hpp"
|
||||
|
||||
namespace zmq
|
||||
@ -38,11 +38,11 @@ namespace zmq
|
||||
|
||||
class msg_t;
|
||||
|
||||
class plain_client_t : public mechanism_t
|
||||
class plain_client_t : public mechanism_base_t
|
||||
{
|
||||
public:
|
||||
|
||||
plain_client_t (const options_t &options_);
|
||||
public:
|
||||
plain_client_t (session_base_t *const session_,
|
||||
const options_t &options_);
|
||||
virtual ~plain_client_t ();
|
||||
|
||||
// mechanism implementation
|
||||
@ -50,7 +50,7 @@ namespace zmq
|
||||
virtual int process_handshake_command (msg_t *msg_);
|
||||
virtual status_t status () const;
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
enum state_t {
|
||||
sending_hello,
|
||||
|
@ -40,7 +40,7 @@
|
||||
zmq::plain_server_t::plain_server_t (session_base_t *session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
mechanism_base_t (session_, options_),
|
||||
zap_client_common_handshake_t (
|
||||
session_, peer_address_, options_, sending_welcome)
|
||||
{
|
||||
@ -89,8 +89,9 @@ int zmq::plain_server_t::process_handshake_command (msg_t *msg_)
|
||||
rc = process_initiate (msg_);
|
||||
break;
|
||||
default:
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid handshake command");
|
||||
// TODO see comment in curve_server_t::process_handshake_command
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED);
|
||||
errno = EPROTO;
|
||||
rc = -1;
|
||||
break;
|
||||
@ -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 rc = check_basic_command_structure (msg_);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
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)) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, did not send HELLO");
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
@ -119,17 +124,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
|
||||
bytes_left -= 6;
|
||||
|
||||
if (bytes_left < 1) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, did not send username");
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
const size_t username_length = static_cast <size_t> (*ptr++);
|
||||
const uint8_t username_length = *ptr++;
|
||||
bytes_left -= 1;
|
||||
|
||||
if (bytes_left < username_length) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, sent malformed username");
|
||||
if (bytes_left < (int)username_length) {
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
@ -137,17 +144,19 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
|
||||
ptr += username_length;
|
||||
bytes_left -= username_length;
|
||||
if (bytes_left < 1) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, did not send password");
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const size_t password_length = static_cast <size_t> (*ptr++);
|
||||
const uint8_t password_length = *ptr++;
|
||||
bytes_left -= 1;
|
||||
if (bytes_left < password_length) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, sent malformed password");
|
||||
if (bytes_left < (int)password_length) {
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
@ -156,8 +165,9 @@ int zmq::plain_server_t::process_hello (msg_t *msg_)
|
||||
ptr += password_length;
|
||||
bytes_left -= password_length;
|
||||
if (bytes_left > 0) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, sent extraneous data");
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
@ -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
|
||||
// username and password, so if ZAP is not configured it is considered a
|
||||
// failure.
|
||||
int rc = session->zap_connect ();
|
||||
rc = session->zap_connect ();
|
||||
if (rc != 0)
|
||||
return -1;
|
||||
send_zap_request (username, password);
|
||||
@ -187,8 +197,8 @@ int zmq::plain_server_t::process_initiate (msg_t *msg_)
|
||||
const size_t bytes_left = msg_->size ();
|
||||
|
||||
if (bytes_left < 9 || memcmp (ptr, "\x08INITIATE", 9)) {
|
||||
// Temporary support for security debugging
|
||||
puts ("PLAIN I: invalid PLAIN client, did not send INITIATE");
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1692,22 +1692,16 @@ void zmq::socket_base_t::event_handshake_failed_no_detail (
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL);
|
||||
}
|
||||
|
||||
void zmq::socket_base_t::event_handshake_failed_zmtp (const std::string &addr_,
|
||||
int err_)
|
||||
{
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP);
|
||||
}
|
||||
|
||||
void zmq::socket_base_t::event_handshake_failed_zap (const std::string &addr_,
|
||||
int err_)
|
||||
{
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ZAP);
|
||||
}
|
||||
|
||||
void zmq::socket_base_t::event_handshake_failed_encryption (
|
||||
void zmq::socket_base_t::event_handshake_failed_protocol (
|
||||
const std::string &addr_, int err_)
|
||||
{
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
|
||||
}
|
||||
|
||||
void zmq::socket_base_t::event_handshake_failed_auth (const std::string &addr_,
|
||||
int err_)
|
||||
{
|
||||
event (addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH);
|
||||
}
|
||||
|
||||
void zmq::socket_base_t::event_handshake_succeeded (const std::string &addr_,
|
||||
|
@ -134,9 +134,8 @@ namespace zmq
|
||||
void event_close_failed (const std::string &addr_, int err_);
|
||||
void event_disconnected (const std::string &addr_, zmq::fd_t fd_);
|
||||
void event_handshake_failed_no_detail(const std::string &addr_, int err_);
|
||||
void event_handshake_failed_zmtp(const std::string &addr_, int err_);
|
||||
void event_handshake_failed_zap(const std::string &addr_, int err_);
|
||||
void event_handshake_failed_encryption(const std::string &addr_, int err_);
|
||||
void event_handshake_failed_protocol(const std::string &addr_, int err_);
|
||||
void event_handshake_failed_auth(const std::string &addr_, int err_);
|
||||
void event_handshake_succeeded(const std::string &addr_, int err_);
|
||||
|
||||
protected:
|
||||
|
@ -674,7 +674,7 @@ bool zmq::stream_engine_t::handshake ()
|
||||
plain_server_t (session, peer_address, options);
|
||||
else
|
||||
mechanism = new (std::nothrow)
|
||||
plain_client_t (options);
|
||||
plain_client_t (session, options);
|
||||
alloc_assert (mechanism);
|
||||
}
|
||||
#ifdef ZMQ_HAVE_CURVE
|
||||
@ -685,7 +685,8 @@ bool zmq::stream_engine_t::handshake ()
|
||||
mechanism = new (std::nothrow)
|
||||
curve_server_t (session, peer_address, options);
|
||||
else
|
||||
mechanism = new (std::nothrow) curve_client_t (options);
|
||||
mechanism =
|
||||
new (std::nothrow) curve_client_t (session, options);
|
||||
alloc_assert (mechanism);
|
||||
}
|
||||
#endif
|
||||
@ -697,11 +698,14 @@ bool zmq::stream_engine_t::handshake ()
|
||||
mechanism = new (std::nothrow)
|
||||
gssapi_server_t (session, peer_address, options);
|
||||
else
|
||||
mechanism = new (std::nothrow) gssapi_client_t (options);
|
||||
mechanism =
|
||||
new (std::nothrow) gssapi_client_t (session, options);
|
||||
alloc_assert (mechanism);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
|
||||
error (protocol_error);
|
||||
return false;
|
||||
}
|
||||
@ -979,21 +983,12 @@ void zmq::stream_engine_t::error (error_reason_t reason)
|
||||
}
|
||||
zmq_assert (session);
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
int err = errno;
|
||||
if (mechanism == NULL) {
|
||||
if (reason == protocol_error)
|
||||
socket->event_handshake_failed_zmtp (endpoint, err);
|
||||
else
|
||||
socket->event_handshake_failed_no_detail (endpoint, err);
|
||||
} else if (mechanism->status () == mechanism_t::handshaking) {
|
||||
if (mechanism->error_detail () == mechanism_t::zmtp)
|
||||
socket->event_handshake_failed_zmtp (endpoint, err);
|
||||
else if (mechanism->error_detail () == mechanism_t::zap)
|
||||
socket->event_handshake_failed_zap (endpoint, err);
|
||||
else if (mechanism->error_detail () == mechanism_t::encryption)
|
||||
socket->event_handshake_failed_encryption (endpoint, err);
|
||||
else
|
||||
socket->event_handshake_failed_no_detail (endpoint, err);
|
||||
// protocol errors have been signaled already at the point where they occurred
|
||||
if (reason != protocol_error
|
||||
&& (mechanism == NULL
|
||||
|| mechanism->status () == mechanism_t::handshaking)) {
|
||||
int err = errno;
|
||||
socket->event_handshake_failed_no_detail (endpoint, err);
|
||||
}
|
||||
#endif
|
||||
socket->event_disconnected (endpoint, (int) s);
|
||||
|
@ -38,10 +38,8 @@ namespace zmq
|
||||
zap_client_t::zap_client_t (session_base_t *const session_,
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
session (session_),
|
||||
peer_address (peer_address_),
|
||||
current_error_detail (no_detail)
|
||||
mechanism_base_t (session_, options_),
|
||||
peer_address (peer_address_)
|
||||
{
|
||||
}
|
||||
|
||||
@ -155,34 +153,35 @@ int zap_client_t::receive_and_process_zap_reply ()
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
if ((msg[i].flags () & msg_t::more) == (i < 6 ? 0 : msg_t::more)) {
|
||||
// CURVE I : ZAP handler sent incomplete reply message
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY);
|
||||
errno = EPROTO;
|
||||
current_error_detail = mechanism_t::zap;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Address delimiter frame
|
||||
if (msg[0].size () > 0) {
|
||||
// CURVE I: ZAP handler sent malformed reply message
|
||||
// TODO can a ZAP handler produce such a message at all?
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED);
|
||||
errno = EPROTO;
|
||||
current_error_detail = mechanism_t::zap;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
|
||||
// Version frame
|
||||
if (msg[1].size () != 3 || memcmp (msg[1].data (), "1.0", 3)) {
|
||||
// CURVE I: ZAP handler sent bad version number
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION);
|
||||
errno = EPROTO;
|
||||
current_error_detail = mechanism_t::zap;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
|
||||
// Request id frame
|
||||
if (msg[2].size () != 1 || memcmp (msg[2].data (), "1", 1)) {
|
||||
// CURVE I: ZAP handler sent bad request ID
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID);
|
||||
errno = EPROTO;
|
||||
current_error_detail = mechanism_t::zap;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
|
||||
@ -191,9 +190,9 @@ int zap_client_t::receive_and_process_zap_reply ()
|
||||
if (msg[3].size () != 3 || status_code_data[0] < '2'
|
||||
|| status_code_data[0] > '5' || status_code_data[1] != '0'
|
||||
|| status_code_data[2] != '0') {
|
||||
// CURVE I: ZAP handler sent invalid status code
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE);
|
||||
errno = EPROTO;
|
||||
current_error_detail = mechanism_t::zap;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
|
||||
@ -208,6 +207,9 @@ int zap_client_t::receive_and_process_zap_reply ()
|
||||
msg[6].size (), true);
|
||||
|
||||
if (rc != 0) {
|
||||
session->get_socket ()->event_handshake_failed_protocol (
|
||||
session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA);
|
||||
errno = EPROTO;
|
||||
return close_and_return (msg, -1);
|
||||
}
|
||||
|
||||
@ -226,30 +228,23 @@ void zap_client_t::handle_zap_status_code ()
|
||||
{
|
||||
// we can assume here that status_code is a valid ZAP status code,
|
||||
// i.e. 200, 300, 400 or 500
|
||||
int err = 0;
|
||||
int status_code_numeric = 0;
|
||||
switch (status_code[0]) {
|
||||
case '2':
|
||||
return;
|
||||
case '3':
|
||||
err = EAGAIN;
|
||||
status_code_numeric = 300;
|
||||
break;
|
||||
case '4':
|
||||
err = EACCES;
|
||||
status_code_numeric = 400;
|
||||
break;
|
||||
case '5':
|
||||
err = EFAULT;
|
||||
status_code_numeric = 500;
|
||||
break;
|
||||
}
|
||||
// TODO use event_handshake_failed_zap here? but this is not a ZAP
|
||||
// protocol error
|
||||
|
||||
session->get_socket ()->event_handshake_failed_no_detail (
|
||||
session->get_endpoint (), err);
|
||||
}
|
||||
|
||||
mechanism_t::error_detail_t zap_client_t::error_detail () const
|
||||
{
|
||||
return current_error_detail;
|
||||
session->get_socket ()->event_handshake_failed_auth (
|
||||
session->get_endpoint (), status_code_numeric);
|
||||
}
|
||||
|
||||
zap_client_common_handshake_t::zap_client_common_handshake_t (
|
||||
@ -257,7 +252,7 @@ zap_client_common_handshake_t::zap_client_common_handshake_t (
|
||||
const std::string &peer_address_,
|
||||
const options_t &options_,
|
||||
state_t zap_reply_ok_state_) :
|
||||
mechanism_t (options_),
|
||||
mechanism_base_t (session_, options_),
|
||||
zap_client_t (session_, peer_address_, options_),
|
||||
state (waiting_for_hello),
|
||||
zap_reply_ok_state (zap_reply_ok_state_)
|
||||
|
@ -30,13 +30,11 @@
|
||||
#ifndef __ZMQ_ZAP_CLIENT_HPP_INCLUDED__
|
||||
#define __ZMQ_ZAP_CLIENT_HPP_INCLUDED__
|
||||
|
||||
#include "mechanism.hpp"
|
||||
#include "mechanism_base.hpp"
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
class session_base_t;
|
||||
|
||||
class zap_client_t : public virtual mechanism_t
|
||||
class zap_client_t : public virtual mechanism_base_t
|
||||
{
|
||||
public:
|
||||
zap_client_t (session_base_t *const session_,
|
||||
@ -56,20 +54,11 @@ class zap_client_t : public virtual mechanism_t
|
||||
|
||||
virtual int receive_and_process_zap_reply ();
|
||||
virtual void handle_zap_status_code ();
|
||||
|
||||
// methods from mechanism_t
|
||||
error_detail_t error_detail () const;
|
||||
|
||||
protected:
|
||||
session_base_t *const session;
|
||||
const std::string peer_address;
|
||||
|
||||
// Status code as received from ZAP handler
|
||||
std::string status_code;
|
||||
|
||||
// Details about the current error state
|
||||
// TODO remove this
|
||||
error_detail_t current_error_detail;
|
||||
};
|
||||
|
||||
class zap_client_common_handshake_t : public zap_client_t
|
||||
|
@ -50,11 +50,41 @@
|
||||
#define ZMQ_BINDTODEVICE 90
|
||||
|
||||
/* DRAFT 0MQ socket events and monitoring */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
|
||||
/* Unspecified system errors during handshake. Event value is an errno. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL 0x0800
|
||||
/* Handshake complete successfully with successful authentication (if *
|
||||
* enabled). Event value is unused. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_SUCCEEDED 0x1000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION 0x2000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP 0x4000
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_ZAP 0x8000
|
||||
/* Protocol errors between ZMTP peers or between server and ZAP handler. *
|
||||
* Event value is one of ZMQ_PROTOCOL_ERROR_* */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL 0x2000
|
||||
/* Failed authentication requests. Event value is the numeric ZAP status *
|
||||
* code, i.e. 300, 400 or 500. */
|
||||
#define ZMQ_EVENT_HANDSHAKE_FAILED_AUTH 0x4000
|
||||
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNSPECIFIED 0x10000000
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND 0x10000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE 0x10000002
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_KEY_EXCHANGE 0x10000003
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED 0x10000011
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE 0x10000012
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO 0x10000013
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE 0x10000014
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_ERROR 0x10000015
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_READY 0x10000016
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_WELCOME 0x10000017
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_METADATA 0x10000018
|
||||
|
||||
// the following two may be due to erroneous configuration of a peer
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC 0x11000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH 0x11000002
|
||||
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_UNSPECIFIED 0x20000000
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY 0x20000001
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID 0x20000002
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION 0x20000003
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE 0x20000004
|
||||
#define ZMQ_PROTOCOL_ERROR_ZAP_INVALID_METADATA 0x20000005
|
||||
|
||||
/* DRAFT Context options */
|
||||
#define ZMQ_MSG_T_SIZE 6
|
||||
|
@ -103,7 +103,8 @@ void test_garbage_key(void *ctx,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
int handshake_failed_encryption_event_count =
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
|
||||
// handshake_failed_encryption_event_count should be at least two because
|
||||
// expect_bounce_fail involves two exchanges
|
||||
@ -149,9 +150,8 @@ void test_curve_security_with_bogus_client_credentials (
|
||||
|
||||
int event_count = 0;
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
// TODO add another event type ZMQ_EVENT_HANDSHAKE_FAILED_AUTH for this case?
|
||||
event_count = expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EACCES);
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400);
|
||||
assert (event_count <= 1);
|
||||
#endif
|
||||
|
||||
@ -160,7 +160,10 @@ void test_curve_security_with_bogus_client_credentials (
|
||||
|| 1 <= zmq_atomic_counter_value (zap_requests_handled));
|
||||
}
|
||||
|
||||
void expect_zmtp_failure (void *client, char *my_endpoint, void *server, void *server_mon)
|
||||
void expect_zmtp_mechanism_mismatch (void *client,
|
||||
char *my_endpoint,
|
||||
void *server,
|
||||
void *server_mon)
|
||||
{
|
||||
// This must be caught by the curve_server class, not passed to ZAP
|
||||
int rc = zmq_connect (client, my_endpoint);
|
||||
@ -169,7 +172,9 @@ void expect_zmtp_failure (void *client, char *my_endpoint, void *server, void *s
|
||||
close_zero_linger (client);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP);
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
|
||||
#endif
|
||||
|
||||
assert (0 == zmq_atomic_counter_value (zap_requests_handled));
|
||||
@ -183,7 +188,7 @@ void test_curve_security_with_null_client_credentials (void *ctx,
|
||||
void *client = zmq_socket (ctx, ZMQ_DEALER);
|
||||
assert (client);
|
||||
|
||||
expect_zmtp_failure (client, my_endpoint, server, server_mon);
|
||||
expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
|
||||
}
|
||||
|
||||
void test_curve_security_with_plain_client_credentials (void *ctx,
|
||||
@ -198,7 +203,7 @@ void test_curve_security_with_plain_client_credentials (void *ctx,
|
||||
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
|
||||
assert (rc == 0);
|
||||
|
||||
expect_zmtp_failure (client, my_endpoint, server, server_mon);
|
||||
expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
|
||||
}
|
||||
|
||||
int connect_vanilla_socket (char *my_endpoint)
|
||||
@ -279,11 +284,12 @@ void test_curve_security_invalid_hello_wrong_length (char *my_endpoint,
|
||||
send_greeting (s);
|
||||
|
||||
// send CURVE HELLO of wrong size
|
||||
send(s, "\x04\x05HELLO");
|
||||
send(s, "\x04\x06\x05HELLO");
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
|
||||
EPROTO);
|
||||
expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -361,8 +367,9 @@ void test_curve_security_invalid_hello_command_name (char *my_endpoint,
|
||||
send_command(s, hello);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
|
||||
EPROTO);
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -388,8 +395,9 @@ void test_curve_security_invalid_hello_version (char *my_endpoint,
|
||||
send_command (s, hello);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
|
||||
EPROTO);
|
||||
expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -459,11 +467,12 @@ void test_curve_security_invalid_initiate_length (char *my_endpoint,
|
||||
assert (res == -1);
|
||||
#endif
|
||||
|
||||
send(s, "\x04\x08INITIATE");
|
||||
send(s, "\x04\x09\x08INITIATE");
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
|
||||
EPROTO);
|
||||
expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -482,7 +491,8 @@ int connect_exchange_greeting_and_hello_welcome (
|
||||
uint8_t welcome[welcome_length + 2];
|
||||
recv_all (s, welcome, welcome_length + 2);
|
||||
|
||||
int res = tools.process_welcome (welcome + 2, welcome_length);
|
||||
uint8_t cn_precom [crypto_box_BEFORENMBYTES];
|
||||
int res = tools.process_welcome (welcome + 2, welcome_length, cn_precom);
|
||||
assert (res == 0);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
@ -510,8 +520,9 @@ void test_curve_security_invalid_initiate_command_name (char *my_endpoint,
|
||||
send_command (s, initiate);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP,
|
||||
EPROTO);
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -532,8 +543,9 @@ void test_curve_security_invalid_initiate_command_encrypted_cookie (
|
||||
send_command (s, initiate);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION, EPROTO);
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -554,8 +566,9 @@ void test_curve_security_invalid_initiate_command_encrypted_content (
|
||||
send_command (s, initiate);
|
||||
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
expect_monitor_event_multiple (
|
||||
server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION, EPROTO);
|
||||
expect_monitor_event_multiple (server_mon,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
|
||||
ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
|
||||
#endif
|
||||
|
||||
close (s);
|
||||
@ -648,7 +661,6 @@ int main (void)
|
||||
server_mon, timeout);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
fprintf (stderr, "test_curve_security_with_null_client_credentials\n");
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
@ -664,7 +676,6 @@ int main (void)
|
||||
server_mon);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
fprintf (stderr, "test_curve_security_unauthenticated_message\n");
|
||||
setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
|
||||
&server_mon, my_endpoint);
|
||||
|
@ -87,11 +87,12 @@ void test_zap_protocol_error (void *ctx,
|
||||
void *server,
|
||||
void *server_mon,
|
||||
socket_config_fn socket_config_,
|
||||
void *socket_config_data_)
|
||||
void *socket_config_data_,
|
||||
int expected_error)
|
||||
{
|
||||
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_ZAP, EPROTO,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL, expected_error,
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
@ -119,7 +120,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
&zap_handler_wrong_version, server_socket_config_,
|
||||
server_socket_config_data_);
|
||||
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
|
||||
client_socket_config_, client_socket_config_data_);
|
||||
client_socket_config_, client_socket_config_data_,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_PROTOCOL_ERROR_ZAP_BAD_VERSION
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
@ -130,7 +137,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
&zap_handler_wrong_request_id, server_socket_config_,
|
||||
server_socket_config_data_);
|
||||
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
|
||||
client_socket_config_, client_socket_config_data_);
|
||||
client_socket_config_, client_socket_config_data_,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_PROTOCOL_ERROR_ZAP_BAD_REQUEST_ID
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
@ -141,7 +154,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
&zap_handler_wrong_status_invalid, server_socket_config_,
|
||||
server_socket_config_data_);
|
||||
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
|
||||
client_socket_config_, client_socket_config_data_);
|
||||
client_socket_config_, client_socket_config_data_,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_PROTOCOL_ERROR_ZAP_INVALID_STATUS_CODE
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
@ -152,7 +171,13 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
&zap_handler_too_many_parts, server_socket_config_,
|
||||
server_socket_config_data_);
|
||||
test_zap_protocol_error (ctx, my_endpoint, server, server_mon,
|
||||
client_socket_config_, client_socket_config_data_);
|
||||
client_socket_config_, client_socket_config_data_,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_PROTOCOL_ERROR_ZAP_MALFORMED_REPLY
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
);
|
||||
shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
|
||||
handler);
|
||||
|
||||
@ -169,7 +194,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
server_socket_config_data_);
|
||||
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EAGAIN,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 300,
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
@ -184,7 +209,7 @@ void test_zap_errors (socket_config_fn server_socket_config_,
|
||||
&zap_handler_wrong_status_internal_error, server_socket_config_);
|
||||
test_zap_unsuccessful (ctx, my_endpoint, server, server_mon,
|
||||
#ifdef ZMQ_BUILD_DRAFT_API
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL, EFAULT,
|
||||
ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 500,
|
||||
#else
|
||||
0, 0,
|
||||
#endif
|
||||
|
@ -331,11 +331,11 @@ void setup_context_and_server_side (
|
||||
char monitor_endpoint [] = "inproc://monitor-server";
|
||||
|
||||
// Monitor handshake events on the server
|
||||
rc = zmq_socket_monitor (
|
||||
*server, monitor_endpoint,
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED | ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_ZAP | ZMQ_EVENT_HANDSHAKE_FAILED_ZMTP
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION);
|
||||
rc = zmq_socket_monitor (*server, monitor_endpoint,
|
||||
ZMQ_EVENT_HANDSHAKE_SUCCEEDED
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_AUTH
|
||||
| ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL);
|
||||
assert (rc == 0);
|
||||
|
||||
// Create socket for collecting monitor events
|
||||
@ -514,7 +514,11 @@ int expect_monitor_event_multiple (void *server_mon,
|
||||
}
|
||||
if (event != expected_event
|
||||
|| (-1 != expected_err && err != expected_err)) {
|
||||
fprintf (stderr, "Unexpected event: %x (err = %i)\n", event, err);
|
||||
fprintf (
|
||||
stderr,
|
||||
"Unexpected event: 0x%x, value = %i/0x%x (expected: 0x%x, value "
|
||||
"= %i/0x%x)\n",
|
||||
event, err, err, expected_event, expected_err, expected_err);
|
||||
assert (false);
|
||||
}
|
||||
++count_of_expected_events;
|
||||
|
Loading…
x
Reference in New Issue
Block a user