mirror of
https://github.com/zeromq/libzmq.git
synced 2025-09-20 21:09:34 +02:00
Problem: zmq_connect() does not validate TCP addresses
Since https://github.com/zeromq/libzmq/commit/350a1a, TCP addresses get resolved asynchronously, so zmq_connect no longer returned an error on incorrect addresses. This is troublesome since we rely on some error checking to catch blatant errors. Solution add some upfront syntax checking that catches at least the obvious kinds of errors (invalid characters, wrong or missing port number).
This commit is contained in:
parent
407843374d
commit
deaad00ad9
@ -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
|
||||
|
@ -466,7 +466,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user