mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Allow a unix: address to contain a C-style quoted string.
Feature 18753 -- all this to allow spaces.
This commit is contained in:
parent
684500519d
commit
05aed5b635
6
changes/feature18753
Normal file
6
changes/feature18753
Normal file
@ -0,0 +1,6 @@
|
||||
o Minor features (unix domain sockets):
|
||||
- When configuring a unix domain socket for a SocksPort,
|
||||
ControlPort, or Hidden service, you can now wrap the address
|
||||
in quotes, using C-style escapes inside the quotes. This
|
||||
allows unix domain socket paths to contain spaces.
|
||||
|
@ -323,6 +323,8 @@ GENERAL OPTIONS
|
||||
any process on the local host to control it. (Setting both authentication
|
||||
methods means either method is sufficient to authenticate to Tor.) This
|
||||
option is required for many Tor controllers; most use the value of 9051.
|
||||
If a unix domain socket is used, you may quote the path using standard
|
||||
C escape sequences.
|
||||
Set it to "auto" to have Tor pick a port for you. (Default: 0) +
|
||||
+
|
||||
Recognized flags are...
|
||||
@ -1032,7 +1034,9 @@ The following options are useful only for clients (that is, if
|
||||
applications. Set this to 0 if you don't want to allow application
|
||||
connections via SOCKS. Set it to "auto" to have Tor pick a port for
|
||||
you. This directive can be specified multiple times to bind
|
||||
to multiple addresses/ports. (Default: 9050) +
|
||||
to multiple addresses/ports. If a unix domain socket is used, you may
|
||||
quote the path using standard C escape sequences.
|
||||
(Default: 9050) +
|
||||
+
|
||||
NOTE: Although this option allows you to specify an IP address
|
||||
other than localhost, you should do so only with extreme caution.
|
||||
@ -2342,7 +2346,8 @@ The following options are used to configure a hidden service.
|
||||
recent HiddenServiceDir. By default, this option maps the virtual port to
|
||||
the same port on 127.0.0.1 over TCP. You may override the target port,
|
||||
address, or both by specifying a target of addr, port, addr:port, or
|
||||
**unix:**__path__. (You can specify an IPv6 target as [addr]:port.)
|
||||
**unix:**__path__. (You can specify an IPv6 target as [addr]:port. Unix
|
||||
paths may be quoted, and may use standard C escapes.)
|
||||
You may also have multiple lines with the same VIRTPORT: when a user
|
||||
connects to that VIRTPORT, one of the TARGETs from those lines will be
|
||||
chosen at random.
|
||||
|
@ -2906,7 +2906,7 @@ read_file_to_str, (const char *filename, int flags, struct stat *stat_out))
|
||||
* provided), and return a pointer to the position in <b>s</b> immediately
|
||||
* after the string. On failure, return NULL.
|
||||
*/
|
||||
static const char *
|
||||
const char *
|
||||
unescape_string(const char *s, char **result, size_t *size_out)
|
||||
{
|
||||
const char *cp;
|
||||
|
@ -385,6 +385,7 @@ MOCK_DECL_ATTR(char *, read_file_to_str,
|
||||
char *read_file_to_str_until_eof(int fd, size_t max_bytes_to_read,
|
||||
size_t *sz_out)
|
||||
ATTR_MALLOC;
|
||||
const char *unescape_string(const char *s, char **result, size_t *size_out);
|
||||
const char *parse_config_line_from_str_verbose(const char *line,
|
||||
char **key_out, char **value_out,
|
||||
const char **err_out);
|
||||
|
129
src/or/config.c
129
src/or/config.c
@ -68,6 +68,9 @@
|
||||
|
||||
/* Prefix used to indicate a Unix socket in a FooPort configuration. */
|
||||
static const char unix_socket_prefix[] = "unix:";
|
||||
/* Prefix used to indicate a Unix socket with spaces in it, in a FooPort
|
||||
* configuration. */
|
||||
static const char unix_q_socket_prefix[] = "unix:\"";
|
||||
|
||||
/** A list of abbreviations and aliases to map command-line options, obsolete
|
||||
* option names, or alternative option names, to their current values. */
|
||||
@ -6288,55 +6291,62 @@ warn_nonlocal_controller_ports(smartlist_t *ports, unsigned forbid_nonlocal)
|
||||
} SMARTLIST_FOREACH_END(port);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
||||
/** Parse the given <b>addrport</b> and set <b>path_out</b> if a Unix socket
|
||||
* path is found. Return 0 on success. On error, a negative value is
|
||||
* returned, -ENOENT if no Unix statement found, -EINVAL if the socket path
|
||||
* is empty and -ENOSYS if AF_UNIX is not supported (see function in the
|
||||
* #else statement below). */
|
||||
|
||||
/**
|
||||
* Take a string (<b>line</b>) that begins with either an address:port, a
|
||||
* port, or an AF_UNIX address, optionally quoted, prefixed with
|
||||
* "unix:". Parse that line, and on success, set <b>addrport_out</b> to a new
|
||||
* string containing the beginning portion (without prefix). Iff there was a
|
||||
* unix: prefix, set <b>is_unix_out</b> to true. On success, also set
|
||||
* <b>rest_out</b> to point to the part of the line after the address portion.
|
||||
*
|
||||
* Return 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
config_parse_unix_port(const char *addrport, char **path_out)
|
||||
port_cfg_line_extract_addrport(const char *line,
|
||||
char **addrport_out,
|
||||
int *is_unix_out,
|
||||
const char **rest_out)
|
||||
{
|
||||
tor_assert(path_out);
|
||||
tor_assert(addrport);
|
||||
tor_assert(line);
|
||||
tor_assert(addrport_out);
|
||||
tor_assert(is_unix_out);
|
||||
tor_assert(rest_out);
|
||||
|
||||
if (strcmpstart(addrport, unix_socket_prefix)) {
|
||||
/* Not a Unix socket path. */
|
||||
return -ENOENT;
|
||||
line = eat_whitespace(line);
|
||||
|
||||
if (!strcmpstart(line, unix_q_socket_prefix)) {
|
||||
// It starts with unix:"
|
||||
size_t sz;
|
||||
*is_unix_out = 1;
|
||||
*addrport_out = NULL;
|
||||
line += strlen(unix_socket_prefix); /*No q: Keep the quote */
|
||||
*rest_out = unescape_string(line, addrport_out, &sz);
|
||||
if (!*rest_out || (*addrport_out && sz != strlen(*addrport_out))) {
|
||||
tor_free(*addrport_out);
|
||||
return -1;
|
||||
}
|
||||
*rest_out = eat_whitespace(*rest_out);
|
||||
return 0;
|
||||
} else {
|
||||
// Is there a unix: prefix?
|
||||
if (!strcmpstart(line, unix_socket_prefix)) {
|
||||
line += strlen(unix_socket_prefix);
|
||||
*is_unix_out = 1;
|
||||
} else {
|
||||
*is_unix_out = 0;
|
||||
}
|
||||
|
||||
if (strlen(addrport + strlen(unix_socket_prefix)) == 0) {
|
||||
/* Empty socket path, not very usable. */
|
||||
return -EINVAL;
|
||||
const char *end = find_whitespace(line);
|
||||
if (BUG(!end)) {
|
||||
end = strchr(line, '\0'); // LCOV_EXCL_LINE -- this can't be NULL
|
||||
}
|
||||
|
||||
*path_out = tor_strdup(addrport + strlen(unix_socket_prefix));
|
||||
tor_assert(end && end >= line);
|
||||
*addrport_out = tor_strndup(line, end - line);
|
||||
*rest_out = eat_whitespace(end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* defined(HAVE_SYS_UN_H) */
|
||||
|
||||
int
|
||||
config_parse_unix_port(const char *addrport, char **path_out)
|
||||
{
|
||||
tor_assert(path_out);
|
||||
tor_assert(addrport);
|
||||
|
||||
if (strcmpstart(addrport, unix_socket_prefix)) {
|
||||
/* Not a Unix socket path. */
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
log_warn(LD_CONFIG,
|
||||
"Port configuration %s is for an AF_UNIX socket, but we have no"
|
||||
"support available on this platform",
|
||||
escaped(addrport));
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif /* defined(HAVE_SYS_UN_H) */
|
||||
|
||||
static void
|
||||
warn_client_dns_cache(const char *option, int disabling)
|
||||
{
|
||||
@ -6515,16 +6525,16 @@ parse_port_config(smartlist_t *out,
|
||||
/* At last we can actually parse the FooPort lines. The syntax is:
|
||||
* [Addr:](Port|auto) [Options].*/
|
||||
elts = smartlist_new();
|
||||
char *addrport = NULL;
|
||||
|
||||
for (; ports; ports = ports->next) {
|
||||
tor_addr_t addr;
|
||||
int port, ret;
|
||||
int port;
|
||||
int sessiongroup = SESSION_GROUP_UNSET;
|
||||
unsigned isolation = ISO_DEFAULT;
|
||||
int prefer_no_auth = 0;
|
||||
int socks_iso_keep_alive = 0;
|
||||
|
||||
char *addrport;
|
||||
uint16_t ptmp=0;
|
||||
int ok;
|
||||
/* This must be kept in sync with port_cfg_new's defaults */
|
||||
@ -6538,23 +6548,31 @@ parse_port_config(smartlist_t *out,
|
||||
relax_dirmode_check = 0,
|
||||
has_used_unix_socket_only_option = 0;
|
||||
|
||||
smartlist_split_string(elts, ports->value, NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
if (smartlist_len(elts) == 0) {
|
||||
log_warn(LD_CONFIG, "Invalid %sPort line with no value", portname);
|
||||
int is_unix_tagged_addr = 0;
|
||||
const char *rest_of_line = NULL;
|
||||
if (port_cfg_line_extract_addrport(ports->value,
|
||||
&addrport, &is_unix_tagged_addr, &rest_of_line)<0) {
|
||||
log_warn(LD_CONFIG, "Invalid %sPort line with unparsable address",
|
||||
portname);
|
||||
goto err;
|
||||
}
|
||||
if (strlen(addrport) == 0) {
|
||||
log_warn(LD_CONFIG, "Invalid %sPort line with no address", portname);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Now parse the addr/port value */
|
||||
addrport = smartlist_get(elts, 0);
|
||||
/* Split the remainder... */
|
||||
smartlist_split_string(elts, rest_of_line, NULL,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
|
||||
/* Let's start to check if it's a Unix socket path. */
|
||||
ret = config_parse_unix_port(addrport, &unix_socket_path);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
if (ret == -EINVAL) {
|
||||
log_warn(LD_CONFIG, "Empty Unix socket path.");
|
||||
}
|
||||
if (is_unix_tagged_addr) {
|
||||
#ifndef HAVE_SYS_UN_H
|
||||
log_warn(LD_CONFIG, "Unix sockets not supported on this system.");
|
||||
goto err;
|
||||
#endif
|
||||
unix_socket_path = addrport;
|
||||
addrport = NULL;
|
||||
}
|
||||
|
||||
if (unix_socket_path &&
|
||||
@ -6612,9 +6630,6 @@ parse_port_config(smartlist_t *out,
|
||||
if (use_server_options) {
|
||||
/* This is a server port; parse advertising options */
|
||||
SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
|
||||
if (elt_sl_idx == 0)
|
||||
continue; /* Skip addr:port */
|
||||
|
||||
if (!strcasecmp(elt, "NoAdvertise")) {
|
||||
no_advertise = 1;
|
||||
} else if (!strcasecmp(elt, "NoListen")) {
|
||||
@ -6662,8 +6677,6 @@ parse_port_config(smartlist_t *out,
|
||||
SMARTLIST_FOREACH_BEGIN(elts, char *, elt) {
|
||||
int no = 0, isoflag = 0;
|
||||
const char *elt_orig = elt;
|
||||
if (elt_sl_idx == 0)
|
||||
continue; /* Skip addr:port */
|
||||
|
||||
if (!strcasecmpstart(elt, "SessionGroup=")) {
|
||||
int group = (int)tor_parse_long(elt+strlen("SessionGroup="),
|
||||
@ -6880,6 +6893,7 @@ parse_port_config(smartlist_t *out,
|
||||
}
|
||||
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
|
||||
smartlist_clear(elts);
|
||||
tor_free(addrport);
|
||||
}
|
||||
|
||||
if (warn_nonlocal && out) {
|
||||
@ -6903,6 +6917,7 @@ parse_port_config(smartlist_t *out,
|
||||
SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
|
||||
smartlist_free(elts);
|
||||
tor_free(unix_socket_path);
|
||||
tor_free(addrport);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,11 @@ int addressmap_register_auto(const char *from, const char *to,
|
||||
time_t expires,
|
||||
addressmap_entry_source_t addrmap_source,
|
||||
const char **msg);
|
||||
int config_parse_unix_port(const char *addrport, char **path_out);
|
||||
|
||||
int port_cfg_line_extract_addrport(const char *line,
|
||||
char **addrport_out,
|
||||
int *is_unix_out,
|
||||
const char **rest_out);
|
||||
|
||||
/** Represents the information stored in a torrc Bridge line. */
|
||||
typedef struct bridge_line_t {
|
||||
|
@ -347,22 +347,20 @@ rend_service_parse_port_config(const char *string, const char *sep,
|
||||
int realport = 0;
|
||||
uint16_t p;
|
||||
tor_addr_t addr;
|
||||
const char *addrport;
|
||||
rend_service_port_config_t *result = NULL;
|
||||
unsigned int is_unix_addr = 0;
|
||||
char *socket_path = NULL;
|
||||
const char *socket_path = NULL;
|
||||
char *err_msg = NULL;
|
||||
char *addrport = NULL;
|
||||
|
||||
sl = smartlist_new();
|
||||
smartlist_split_string(sl, string, sep,
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
if (smartlist_len(sl) < 1 || smartlist_len(sl) > 2) {
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
|
||||
if (smartlist_len(sl) < 1 || BUG(smartlist_len(sl) > 2)) {
|
||||
if (err_msg_out)
|
||||
err_msg = tor_strdup("Bad syntax in hidden service port configuration.");
|
||||
|
||||
goto err;
|
||||
}
|
||||
|
||||
virtport = (int)tor_parse_long(smartlist_get(sl,0), 10, 1, 65535, NULL,NULL);
|
||||
if (!virtport) {
|
||||
if (err_msg_out)
|
||||
@ -371,7 +369,6 @@ rend_service_parse_port_config(const char *string, const char *sep,
|
||||
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (smartlist_len(sl) == 1) {
|
||||
/* No addr:port part; use default. */
|
||||
realport = virtport;
|
||||
@ -379,17 +376,18 @@ rend_service_parse_port_config(const char *string, const char *sep,
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
addrport = smartlist_get(sl,1);
|
||||
ret = config_parse_unix_port(addrport, &socket_path);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
if (ret == -EINVAL)
|
||||
if (err_msg_out)
|
||||
err_msg = tor_strdup("Empty socket path in hidden service port "
|
||||
"configuration.");
|
||||
|
||||
const char *addrport_element = smartlist_get(sl,1);
|
||||
const char *rest = NULL;
|
||||
int is_unix;
|
||||
ret = port_cfg_line_extract_addrport(addrport_element, &addrport,
|
||||
&is_unix, &rest);
|
||||
if (ret < 0) {
|
||||
tor_asprintf(&err_msg, "Couldn't process address <%s> from hidden service "
|
||||
"configuration", addrport_element);
|
||||
goto err;
|
||||
}
|
||||
if (socket_path) {
|
||||
if (is_unix) {
|
||||
socket_path = addrport;
|
||||
is_unix_addr = 1;
|
||||
} else if (strchr(addrport, ':') || strchr(addrport, '.')) {
|
||||
/* else try it as an IP:port pair if it has a : or . in it */
|
||||
@ -427,10 +425,10 @@ rend_service_parse_port_config(const char *string, const char *sep,
|
||||
}
|
||||
|
||||
err:
|
||||
tor_free(addrport);
|
||||
if (err_msg_out) *err_msg_out = err_msg;
|
||||
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
|
||||
smartlist_free(sl);
|
||||
if (socket_path) tor_free(socket_path);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -3710,6 +3710,145 @@ test_config_default_fallback_dirs(void *arg)
|
||||
clear_dir_servers();
|
||||
}
|
||||
|
||||
static void
|
||||
test_config_port_cfg_line_extract_addrport(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
int unixy = 0;
|
||||
const char *rest = NULL;
|
||||
char *a = NULL;
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("", &a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("hello", &a, &unixy, &rest),
|
||||
OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "hello");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport(" flipperwalt gersplut",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "flipperwalt");;
|
||||
tt_str_op(rest, OP_EQ, "gersplut");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport(" flipperwalt \t gersplut",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "flipperwalt");;
|
||||
tt_str_op(rest, OP_EQ, "gersplut");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("flipperwalt \t gersplut",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "flipperwalt");;
|
||||
tt_str_op(rest, OP_EQ, "gersplut");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:flipperwalt \t gersplut",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "flipperwalt");;
|
||||
tt_str_op(rest, OP_EQ, "gersplut");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("lolol",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:lolol",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:lolol ",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport(" unix:lolol",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("foobar:lolol",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, "foobar:lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport(":lolol",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 0);
|
||||
tt_str_op(a, OP_EQ, ":lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\"",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\" ",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lolol\" foo ",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lolol");;
|
||||
tt_str_op(rest, OP_EQ, "foo ");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lol ol\" foo ",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lol ol");;
|
||||
tt_str_op(rest, OP_EQ, "foo ");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\\" ol\" foo ",
|
||||
&a, &unixy, &rest), OP_EQ, 0);
|
||||
tt_int_op(unixy, OP_EQ, 1);
|
||||
tt_str_op(a, OP_EQ, "lol\" ol");;
|
||||
tt_str_op(rest, OP_EQ, "foo ");
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\\" ol foo ",
|
||||
&a, &unixy, &rest), OP_EQ, -1);
|
||||
tor_free(a);
|
||||
|
||||
tt_int_op(port_cfg_line_extract_addrport("unix:\"lol\\0\" ol foo ",
|
||||
&a, &unixy, &rest), OP_EQ, -1);
|
||||
tor_free(a);
|
||||
|
||||
done:
|
||||
tor_free(a);
|
||||
}
|
||||
|
||||
|
||||
static config_line_t *
|
||||
mock_config_line(const char *key, const char *val)
|
||||
{
|
||||
@ -4050,6 +4189,49 @@ test_config_parse_port_config__ports__ports_given(void *data)
|
||||
tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
|
||||
#endif
|
||||
|
||||
// Test success with quoted unix: address.
|
||||
config_free_lines(config_port_valid); config_port_valid = NULL;
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
smartlist_clear(slout);
|
||||
config_port_valid = mock_config_line("SOCKSPort", "unix:\"/tmp/foo/ bar\" "
|
||||
"NoDNSRequest NoIPv4Traffic");
|
||||
ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
|
||||
CONN_TYPE_AP_LISTENER, NULL, 0,
|
||||
CL_PORT_TAKES_HOSTNAMES);
|
||||
#ifdef _WIN32
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
#else
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
tt_int_op(smartlist_len(slout), OP_EQ, 1);
|
||||
port_cfg = (port_cfg_t *)smartlist_get(slout, 0);
|
||||
tt_int_op(port_cfg->entry_cfg.dns_request, OP_EQ, 0);
|
||||
tt_int_op(port_cfg->entry_cfg.ipv4_traffic, OP_EQ, 0);
|
||||
tt_int_op(port_cfg->entry_cfg.ipv6_traffic, OP_EQ, 0);
|
||||
tt_int_op(port_cfg->entry_cfg.onion_traffic, OP_EQ, 1);
|
||||
#endif
|
||||
|
||||
// Test failure with broken quoted unix: address.
|
||||
config_free_lines(config_port_valid); config_port_valid = NULL;
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
smartlist_clear(slout);
|
||||
config_port_valid = mock_config_line("SOCKSPort", "unix:\"/tmp/foo/ bar "
|
||||
"NoDNSRequest NoIPv4Traffic");
|
||||
ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
|
||||
CONN_TYPE_AP_LISTENER, NULL, 0,
|
||||
CL_PORT_TAKES_HOSTNAMES);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
|
||||
// Test failure with empty quoted unix: address.
|
||||
config_free_lines(config_port_valid); config_port_valid = NULL;
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
smartlist_clear(slout);
|
||||
config_port_valid = mock_config_line("SOCKSPort", "unix:\"\" "
|
||||
"NoDNSRequest NoIPv4Traffic");
|
||||
ret = parse_port_config(slout, config_port_valid, NULL, "SOCKS",
|
||||
CONN_TYPE_AP_LISTENER, NULL, 0,
|
||||
CL_PORT_TAKES_HOSTNAMES);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
|
||||
// Test success with OnionTrafficOnly (no DNS, no ipv4, no ipv6)
|
||||
config_free_lines(config_port_valid); config_port_valid = NULL;
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
@ -4690,6 +4872,15 @@ test_config_parse_port_config__ports__server_options(void *data)
|
||||
0, CL_PORT_SERVER_OPTIONS);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
|
||||
// Check for failure with empty unix: address.
|
||||
config_free_lines(config_port_invalid); config_port_invalid = NULL;
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
smartlist_clear(slout);
|
||||
config_port_invalid = mock_config_line("ORPort", "unix:\"\"");
|
||||
ret = parse_port_config(slout, config_port_invalid, NULL, "ORPort", 0, NULL,
|
||||
0, CL_PORT_SERVER_OPTIONS);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
|
||||
done:
|
||||
if (slout)
|
||||
SMARTLIST_FOREACH(slout,port_cfg_t *,pf,port_cfg_free(pf));
|
||||
@ -4719,6 +4910,7 @@ struct testcase_t config_tests[] = {
|
||||
CONFIG_TEST(write_to_data_subdir, TT_FORK),
|
||||
CONFIG_TEST(fix_my_family, 0),
|
||||
CONFIG_TEST(directory_fetch, 0),
|
||||
CONFIG_TEST(port_cfg_line_extract_addrport, 0),
|
||||
CONFIG_TEST(parse_port_config__listenaddress, 0),
|
||||
CONFIG_TEST(parse_port_config__ports__no_ports_given, 0),
|
||||
CONFIG_TEST(parse_port_config__ports__server_options, 0),
|
||||
|
@ -137,6 +137,8 @@ test_rend_service_parse_port_config(void *arg)
|
||||
cfg = rend_service_parse_port_config("80,[2001:db8::1]:8080", sep, &err_msg);
|
||||
tt_assert(cfg);
|
||||
tt_assert(!err_msg);
|
||||
rend_service_port_config_free(cfg);
|
||||
cfg = NULL;
|
||||
|
||||
/* XXX: Someone should add tests for AF_UNIX targets if supported. */
|
||||
|
||||
@ -151,6 +153,53 @@ test_rend_service_parse_port_config(void *arg)
|
||||
cfg = rend_service_parse_port_config("90001", sep, &err_msg);
|
||||
tt_assert(!cfg);
|
||||
tt_assert(err_msg);
|
||||
tor_free(err_msg);
|
||||
|
||||
/* unix port */
|
||||
cfg = NULL;
|
||||
|
||||
/* quoted unix port */
|
||||
tor_free(err_msg);
|
||||
cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"",
|
||||
" ", &err_msg);
|
||||
tt_assert(cfg);
|
||||
tt_assert(!err_msg);
|
||||
rend_service_port_config_free(cfg);
|
||||
cfg = NULL;
|
||||
|
||||
/* quoted unix port */
|
||||
tor_free(err_msg);
|
||||
cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar\"",
|
||||
" ", &err_msg);
|
||||
tt_assert(cfg);
|
||||
tt_assert(!err_msg);
|
||||
rend_service_port_config_free(cfg);
|
||||
cfg = NULL;
|
||||
|
||||
/* quoted unix port, missing end quote */
|
||||
cfg = rend_service_parse_port_config("100 unix:\"/tmp/foo bar",
|
||||
" ", &err_msg);
|
||||
tt_assert(!cfg);
|
||||
tt_str_op(err_msg, OP_EQ, "Couldn't process address <unix:\"/tmp/foo bar> "
|
||||
"from hidden service configuration");
|
||||
tor_free(err_msg);
|
||||
|
||||
/* bogus IP address */
|
||||
cfg = rend_service_parse_port_config("100 1.2.3.4.5:9000",
|
||||
" ", &err_msg);
|
||||
tt_assert(!cfg);
|
||||
tt_str_op(err_msg, OP_EQ, "Unparseable address in hidden service port "
|
||||
"configuration.");
|
||||
tor_free(err_msg);
|
||||
|
||||
/* bogus port port */
|
||||
cfg = rend_service_parse_port_config("100 99999",
|
||||
" ", &err_msg);
|
||||
tt_assert(!cfg);
|
||||
tt_str_op(err_msg, OP_EQ, "Unparseable or out-of-range port \"99999\" "
|
||||
"in hidden service port configuration.");
|
||||
tor_free(err_msg);
|
||||
|
||||
|
||||
done:
|
||||
rend_service_port_config_free(cfg);
|
||||
|
Loading…
Reference in New Issue
Block a user