Commit 64513d85 authored by Richard Newton's avatar Richard Newton

Merge pull request #1106 from hintjens/master

Problem: zmq_connect() does not validate TCP addresses
parents 40784337 78a7b469
......@@ -596,7 +596,39 @@ int zmq::socket_base_t::connect (const char *addr_)
// Resolve address (if needed by the protocol)
if (protocol == "tcp") {
// Defer resolution until a socket is opened
// Do some basic sanity checks on tcp:// address syntax
// - hostname starts with digit or letter, with embedded '-' or '.'
// - IPv6 address may contain hex chars and colons.
// - IPv4 address may contain decimal digits and dots.
// - Address must end in ":port" where port is *, or numeric
// - Address may contain two parts separated by ':'
// Following code is quick and dirty check to catch obvious errors,
// without trying to be fully accurate.
const char *check = address.c_str ();
if (isalnum (*check) || isxdigit (*check)) {
check++;
while (isalnum (*check)
|| isxdigit (*check)
|| *check == '.' || *check == '-' || *check == ':'|| *check == ';')
check++;
}
// Assume the worst, now look for success
rc = -1;
// Did we reach the end of the address safely?
if (*check == 0) {
// Do we have a valid port string? (cannot be '*' in connect
check = strrchr (address.c_str (), ':');
if (check) {
check++;
if (*check && (isdigit (*check)))
rc = 0; // Valid
}
}
if (rc == -1) {
delete paddr;
return -1;
}
// Defer resolution until a socket is opened
paddr->resolved.tcp_addr = NULL;
}
#if !defined ZMQ_HAVE_WINDOWS && !defined ZMQ_HAVE_OPENVMS
......
......@@ -413,11 +413,6 @@ int zmq::tcp_address_t::resolve (const char *name_, bool local_, bool ipv6_, boo
std::string addr_str (name_, delimiter - name_);
std::string port_str (delimiter + 1);
// Remove square brackets around the address, if any.
if (addr_str.size () >= 2 && addr_str [0] == '[' &&
addr_str [addr_str.size () - 1] == ']')
addr_str = addr_str.substr (1, addr_str.size () - 2);
// Allow 0 specifically, to detect invalid port error in atoi if not
uint16_t port;
if (port_str == "*" || port_str == "0")
......@@ -466,7 +461,8 @@ int zmq::tcp_address_t::to_string (std::string &addr_)
return -1;
}
// not using service resolv because of https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4
// Not using service resolv because of
// https://github.com/zeromq/libzmq/commit/1824574f9b5a8ce786853320e3ea09fe1f822bc4
char hbuf [NI_MAXHOST];
int rc = getnameinfo (addr (), addrlen (), hbuf, sizeof hbuf, NULL, 0, NI_NUMERICHOST);
if (rc != 0) {
......
......@@ -31,14 +31,18 @@ int main (void)
int rc = zmq_connect (sock, "tcp://localhost:1234");
assert (rc == 0);
// Because of lazy resolution of TCP names, this will succeed
rc = zmq_connect (sock, "tcp://localhost:invalid");
assert (rc == 0);
assert (rc == -1);
// Because of lazy resolution of TCP names, this will succeed
rc = zmq_connect (sock, "tcp://in val id:1234");
assert (rc == 0);
assert (rc == -1);
rc = zmq_connect (sock, "tcp://");
assert (rc == -1);
rc = zmq_connect (sock, "tcp://192.168.0.200:*");
assert (rc == -1);
rc = zmq_connect (sock, "invalid://localhost:1234");
assert (rc == -1);
assert (errno == EPROTONOSUPPORT);
......
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