From b6e9e0c2d35db4e2f60d5d1c2c54e88f1588795a Mon Sep 17 00:00:00 2001 From: Vincent Tellier Date: Fri, 30 Dec 2016 16:26:42 +0100 Subject: [PATCH] Fixed issue #2227 Added two new monitoring events: - ZMQ_EVENT_HANDSHAKE_SUCCEED is raised once the encryption handshake succeed - ZMQ_EVENT_HANDSHAKE_FAILED is raised when it failed Both events are raised on server and client side. --- include/zmq.h | 2 ++ src/curve_server.cpp | 11 ++++++----- src/session_base.cpp | 4 +++- src/socket_base.cpp | 10 ++++++++++ src/socket_base.hpp | 2 ++ src/stream_engine.cpp | 13 ++++++++++++- src/stream_engine.hpp | 3 ++- 7 files changed, 37 insertions(+), 8 deletions(-) diff --git a/include/zmq.h b/include/zmq.h index d30673ce..be6f962c 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -417,6 +417,8 @@ ZMQ_EXPORT const char *zmq_msg_gets (zmq_msg_t *msg, const char *property); #define ZMQ_EVENT_CLOSE_FAILED 0x0100 #define ZMQ_EVENT_DISCONNECTED 0x0200 #define ZMQ_EVENT_MONITOR_STOPPED 0x0400 +#define ZMQ_EVENT_HANDSHAKE_FAILED 0x0800 +#define ZMQ_EVENT_HANDSHAKE_SUCCEED 0x1000 #define ZMQ_EVENT_ALL 0xFFFF ZMQ_EXPORT void *zmq_socket (void *, int type); diff --git a/src/curve_server.cpp b/src/curve_server.cpp index b5678b4e..2230cd08 100644 --- a/src/curve_server.cpp +++ b/src/curve_server.cpp @@ -310,13 +310,14 @@ int zmq::curve_server_t::process_hello (msg_t *msg_) sizeof hello_box, hello_nonce, cn_client, secret_key); if (rc != 0) { - // Temporary support for security debugging - puts ("CURVE I: cannot open client HELLO -- wrong server key?"); - errno = EPROTO; - return -1; + // Hard error, the client knows a wrong server public key, it shall not try to reconnect using the same. + status_code = "100"; + state = send_error; + rc = 0; } + else + state = send_welcome; - state = send_welcome; return rc; } diff --git a/src/session_base.cpp b/src/session_base.cpp index c74ce363..7ce1a2d6 100644 --- a/src/session_base.cpp +++ b/src/session_base.cpp @@ -421,7 +421,8 @@ void zmq::session_base_t::engine_error ( if (pipe) clean_pipes (); - zmq_assert (reason == stream_engine_t::connection_error + zmq_assert (reason == stream_engine_t::encryption_error + || reason == stream_engine_t::connection_error || reason == stream_engine_t::timeout_error || reason == stream_engine_t::protocol_error); @@ -433,6 +434,7 @@ void zmq::session_base_t::engine_error ( else terminate (); break; + case stream_engine_t::encryption_error: case stream_engine_t::protocol_error: terminate (); break; diff --git a/src/socket_base.cpp b/src/socket_base.cpp index e2b254c9..885c270d 100644 --- a/src/socket_base.cpp +++ b/src/socket_base.cpp @@ -1678,6 +1678,16 @@ void zmq::socket_base_t::event_disconnected (const std::string &addr_, zmq::fd_t event(addr_, fd_, ZMQ_EVENT_DISCONNECTED); } +void zmq::socket_base_t::event_handshake_failed(const std::string &addr_, int err_) +{ + event(addr_, err_, ZMQ_EVENT_HANDSHAKE_FAILED); +} + +void zmq::socket_base_t::event_handshake_succeed(const std::string &addr_, int err_) +{ + event(addr_, err_, ZMQ_EVENT_HANDSHAKE_SUCCEED); +} + void zmq::socket_base_t::event(const std::string &addr_, intptr_t value_, int type_) { scoped_lock_t lock(monitor_sync); diff --git a/src/socket_base.hpp b/src/socket_base.hpp index 50e5b4ae..30fb2c4b 100644 --- a/src/socket_base.hpp +++ b/src/socket_base.hpp @@ -133,6 +133,8 @@ namespace zmq void event_closed (const std::string &addr_, zmq::fd_t fd_); 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(const std::string &addr_, int err_); + void event_handshake_succeed(const std::string &addr_, int err_); protected: diff --git a/src/stream_engine.cpp b/src/stream_engine.cpp index 584d9343..31df21be 100644 --- a/src/stream_engine.cpp +++ b/src/stream_engine.cpp @@ -356,7 +356,10 @@ void zmq::stream_engine_t::in_event () // or the session has rejected the message. if (rc == -1) { if (errno != EAGAIN) { - error (protocol_error); + if(this->process_msg == &stream_engine_t::process_handshake_command) + error(encryption_error); + else + error(protocol_error); return; } input_stopped = true; @@ -784,8 +787,12 @@ int zmq::stream_engine_t::next_handshake_command (msg_t *msg_) } else { const int rc = mechanism->next_handshake_command (msg_); + if (rc == 0) msg_->set_flags (msg_t::command); + if(mechanism->status() == mechanism_t::error) + socket->event_handshake_failed(endpoint, 0); + return rc; } } @@ -863,6 +870,8 @@ void zmq::stream_engine_t::mechanism_ready () zmq_assert (metadata == NULL); if (!properties.empty ()) metadata = new (std::nothrow) metadata_t (properties); + + socket->event_handshake_succeed(endpoint, 0); } int zmq::stream_engine_t::pull_msg_from_session (msg_t *msg_) @@ -967,6 +976,8 @@ void zmq::stream_engine_t::error (error_reason_t reason) terminator.close(); } zmq_assert (session); + if(reason == encryption_error) + socket->event_handshake_failed(endpoint, (int) s); socket->event_disconnected (endpoint, (int) s); session->flush (); session->engine_error (reason); diff --git a/src/stream_engine.hpp b/src/stream_engine.hpp index 68292c53..b5163191 100644 --- a/src/stream_engine.hpp +++ b/src/stream_engine.hpp @@ -65,7 +65,8 @@ namespace zmq enum error_reason_t { protocol_error, connection_error, - timeout_error + timeout_error, + encryption_error }; stream_engine_t (fd_t fd_, const options_t &options_,