Commit b6e9e0c2 authored by Vincent Tellier's avatar Vincent Tellier

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.
parent 64b07d81
...@@ -417,6 +417,8 @@ ZMQ_EXPORT const char *zmq_msg_gets (zmq_msg_t *msg, const char *property); ...@@ -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_CLOSE_FAILED 0x0100
#define ZMQ_EVENT_DISCONNECTED 0x0200 #define ZMQ_EVENT_DISCONNECTED 0x0200
#define ZMQ_EVENT_MONITOR_STOPPED 0x0400 #define ZMQ_EVENT_MONITOR_STOPPED 0x0400
#define ZMQ_EVENT_HANDSHAKE_FAILED 0x0800
#define ZMQ_EVENT_HANDSHAKE_SUCCEED 0x1000
#define ZMQ_EVENT_ALL 0xFFFF #define ZMQ_EVENT_ALL 0xFFFF
ZMQ_EXPORT void *zmq_socket (void *, int type); ZMQ_EXPORT void *zmq_socket (void *, int type);
......
...@@ -310,13 +310,14 @@ int zmq::curve_server_t::process_hello (msg_t *msg_) ...@@ -310,13 +310,14 @@ int zmq::curve_server_t::process_hello (msg_t *msg_)
sizeof hello_box, sizeof hello_box,
hello_nonce, cn_client, secret_key); hello_nonce, cn_client, secret_key);
if (rc != 0) { if (rc != 0) {
// Temporary support for security debugging // Hard error, the client knows a wrong server public key, it shall not try to reconnect using the same.
puts ("CURVE I: cannot open client HELLO -- wrong server key?"); status_code = "100";
errno = EPROTO; state = send_error;
return -1; rc = 0;
} }
else
state = send_welcome;
state = send_welcome;
return rc; return rc;
} }
......
...@@ -421,7 +421,8 @@ void zmq::session_base_t::engine_error ( ...@@ -421,7 +421,8 @@ void zmq::session_base_t::engine_error (
if (pipe) if (pipe)
clean_pipes (); 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::timeout_error
|| reason == stream_engine_t::protocol_error); || reason == stream_engine_t::protocol_error);
...@@ -433,6 +434,7 @@ void zmq::session_base_t::engine_error ( ...@@ -433,6 +434,7 @@ void zmq::session_base_t::engine_error (
else else
terminate (); terminate ();
break; break;
case stream_engine_t::encryption_error:
case stream_engine_t::protocol_error: case stream_engine_t::protocol_error:
terminate (); terminate ();
break; break;
......
...@@ -1678,6 +1678,16 @@ void zmq::socket_base_t::event_disconnected (const std::string &addr_, zmq::fd_t ...@@ -1678,6 +1678,16 @@ void zmq::socket_base_t::event_disconnected (const std::string &addr_, zmq::fd_t
event(addr_, fd_, ZMQ_EVENT_DISCONNECTED); 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_) void zmq::socket_base_t::event(const std::string &addr_, intptr_t value_, int type_)
{ {
scoped_lock_t lock(monitor_sync); scoped_lock_t lock(monitor_sync);
......
...@@ -133,6 +133,8 @@ namespace zmq ...@@ -133,6 +133,8 @@ namespace zmq
void event_closed (const std::string &addr_, zmq::fd_t fd_); void event_closed (const std::string &addr_, zmq::fd_t fd_);
void event_close_failed (const std::string &addr_, int err_); void event_close_failed (const std::string &addr_, int err_);
void event_disconnected (const std::string &addr_, zmq::fd_t fd_); 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: protected:
......
...@@ -356,7 +356,10 @@ void zmq::stream_engine_t::in_event () ...@@ -356,7 +356,10 @@ void zmq::stream_engine_t::in_event ()
// or the session has rejected the message. // or the session has rejected the message.
if (rc == -1) { if (rc == -1) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
error (protocol_error); if(this->process_msg == &stream_engine_t::process_handshake_command)
error(encryption_error);
else
error(protocol_error);
return; return;
} }
input_stopped = true; input_stopped = true;
...@@ -784,8 +787,12 @@ int zmq::stream_engine_t::next_handshake_command (msg_t *msg_) ...@@ -784,8 +787,12 @@ int zmq::stream_engine_t::next_handshake_command (msg_t *msg_)
} }
else { else {
const int rc = mechanism->next_handshake_command (msg_); const int rc = mechanism->next_handshake_command (msg_);
if (rc == 0) if (rc == 0)
msg_->set_flags (msg_t::command); msg_->set_flags (msg_t::command);
if(mechanism->status() == mechanism_t::error)
socket->event_handshake_failed(endpoint, 0);
return rc; return rc;
} }
} }
...@@ -863,6 +870,8 @@ void zmq::stream_engine_t::mechanism_ready () ...@@ -863,6 +870,8 @@ void zmq::stream_engine_t::mechanism_ready ()
zmq_assert (metadata == NULL); zmq_assert (metadata == NULL);
if (!properties.empty ()) if (!properties.empty ())
metadata = new (std::nothrow) metadata_t (properties); 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_) 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) ...@@ -967,6 +976,8 @@ void zmq::stream_engine_t::error (error_reason_t reason)
terminator.close(); terminator.close();
} }
zmq_assert (session); zmq_assert (session);
if(reason == encryption_error)
socket->event_handshake_failed(endpoint, (int) s);
socket->event_disconnected (endpoint, (int) s); socket->event_disconnected (endpoint, (int) s);
session->flush (); session->flush ();
session->engine_error (reason); session->engine_error (reason);
......
...@@ -65,7 +65,8 @@ namespace zmq ...@@ -65,7 +65,8 @@ namespace zmq
enum error_reason_t { enum error_reason_t {
protocol_error, protocol_error,
connection_error, connection_error,
timeout_error timeout_error,
encryption_error
}; };
stream_engine_t (fd_t fd_, const options_t &options_, stream_engine_t (fd_t fd_, const options_t &options_,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment