Commit 4494286e authored by Pieter Hintjens's avatar Pieter Hintjens

Merge pull request #1272 from minrk/security-old-zmtp

reject old ZMTP connections if auth enabled
parents c57d5574 5385a515
......@@ -331,6 +331,14 @@ int zmq::session_base_t::zap_connect ()
return 0;
}
bool zmq::session_base_t::zap_enabled ()
{
return (
options.mechanism != ZMQ_NULL ||
(options.mechanism == ZMQ_NULL && options.zap_domain.length() > 0)
);
}
void zmq::session_base_t::process_attach (i_engine *engine_)
{
zmq_assert (engine_ != NULL);
......
......@@ -69,6 +69,7 @@ namespace zmq
int push_msg (msg_t *msg_);
int zap_connect ();
bool zap_enabled ();
// Fetches a message. Returns 0 if successful; -1 otherwise.
// The caller is responsible for freeing the message when no
......
......@@ -534,6 +534,12 @@ bool zmq::stream_engine_t::handshake ()
// Is the peer using ZMTP/1.0 with no revision number?
// If so, we send and receive rest of identity message
if (greeting_recv [0] != 0xff || !(greeting_recv [9] & 0x01)) {
if (session->zap_enabled ()) {
// reject ZMTP 1.0 connections if ZAP is enabled
error (protocol_error);
return false;
}
encoder = new (std::nothrow) v1_encoder_t (out_batch_size);
alloc_assert (encoder);
......@@ -575,6 +581,12 @@ bool zmq::stream_engine_t::handshake ()
}
else
if (greeting_recv [revision_pos] == ZMTP_1_0) {
if (session->zap_enabled ()) {
// reject ZMTP 1.0 connections if ZAP is enabled
error (protocol_error);
return false;
}
encoder = new (std::nothrow) v1_encoder_t (
out_batch_size);
alloc_assert (encoder);
......@@ -585,6 +597,12 @@ bool zmq::stream_engine_t::handshake ()
}
else
if (greeting_recv [revision_pos] == ZMTP_2_0) {
if (session->zap_enabled ()) {
// reject ZMTP 2.0 connections if ZAP is enabled
error (protocol_error);
return false;
}
encoder = new (std::nothrow) v2_encoder_t (out_batch_size);
alloc_assert (encoder);
......
......@@ -18,6 +18,17 @@
*/
#include "testutil.hpp"
#if defined (ZMQ_HAVE_WINDOWS)
# include <winsock2.h>
# include <ws2tcpip.h>
# include <stdexcept>
# define close closesocket
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <unistd.h>
#endif
// We'll generate random test keys at startup
static char client_public [41];
......@@ -218,6 +229,30 @@ int main (void)
expect_bounce_fail (server, client);
close_zero_linger (client);
// Unauthenticated messages from a vanilla socket shouldn't be received
struct sockaddr_in ip4addr;
int s;
ip4addr.sin_family = AF_INET;
ip4addr.sin_port = htons (9998);
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr));
assert (rc > -1);
// send anonymous ZMTP/1.0 greeting
send (s, "\x01\x00", 2, 0);
// send sneaky message that shouldn't be received
send (s, "\x08\x00sneaky\0", 9, 0);
int timeout = 150;
zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
char *buf = s_recv (server);
if (buf != NULL) {
printf ("Received unauthenticated message: %s\n", buf);
assert (buf == NULL);
}
close (s);
// Check return codes for invalid buffer sizes
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);
......
......@@ -18,6 +18,17 @@
*/
#include "testutil.hpp"
#if defined (ZMQ_HAVE_WINDOWS)
# include <winsock2.h>
# include <ws2tcpip.h>
# include <stdexcept>
# define close closesocket
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <unistd.h>
#endif
static void
zap_handler (void *handler)
......@@ -124,6 +135,38 @@ int main (void)
close_zero_linger (client);
close_zero_linger (server);
// Unauthenticated messages from a vanilla socket shouldn't be received
server = zmq_socket (ctx, ZMQ_DEALER);
assert (server);
rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5);
assert (rc == 0);
rc = zmq_bind (server, "tcp://127.0.0.1:9003");
assert (rc == 0);
struct sockaddr_in ip4addr;
int s;
ip4addr.sin_family = AF_INET;
ip4addr.sin_port = htons(9003);
inet_pton(AF_INET, "127.0.0.1", &ip4addr.sin_addr);
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
rc = connect (s, (struct sockaddr*) &ip4addr, sizeof ip4addr);
assert (rc > -1);
// send anonymous ZMTP/1.0 greeting
send (s, "\x01\x00", 2, 0);
// send sneaky message that shouldn't be received
send (s, "\x08\x00sneaky\0", 9, 0);
int timeout = 150;
zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
char *buf = s_recv (server);
if (buf != NULL) {
printf ("Received unauthenticated message: %s\n", buf);
assert (buf == NULL);
}
close (s);
close_zero_linger (server);
// Shutdown
rc = zmq_ctx_term (ctx);
assert (rc == 0);
......
......@@ -18,6 +18,17 @@
*/
#include "testutil.hpp"
#if defined (ZMQ_HAVE_WINDOWS)
# include <winsock2.h>
# include <ws2tcpip.h>
# include <stdexcept>
# define close closesocket
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <unistd.h>
#endif
static void
zap_handler (void *ctx)
......@@ -137,6 +148,30 @@ int main (void)
expect_bounce_fail (server, client);
close_zero_linger (client);
// Unauthenticated messages from a vanilla socket shouldn't be received
struct sockaddr_in ip4addr;
int s;
ip4addr.sin_family = AF_INET;
ip4addr.sin_port = htons (9998);
inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr));
assert (rc > -1);
// send anonymous ZMTP/1.0 greeting
send (s, "\x01\x00", 2, 0);
// send sneaky message that shouldn't be received
send (s, "\x08\x00sneaky\0", 9, 0);
int timeout = 150;
zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
char *buf = s_recv (server);
if (buf != NULL) {
printf ("Received unauthenticated message: %s\n", buf);
assert (buf == NULL);
}
close (s);
// Shutdown
rc = zmq_close (server);
assert (rc == 0);
......
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