Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
David Goulet
Tor
Commits
05aed5b6
Commit
05aed5b6
authored
Oct 03, 2016
by
Nick Mathewson
🎨
Browse files
Allow a unix: address to contain a C-style quoted string.
Feature 18753 -- all this to allow spaces.
parent
68450051
Changes
9
Hide whitespace changes
Inline
Side-by-side
changes/feature18753
0 → 100644
View file @
05aed5b6
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.
doc/tor.1.txt
View file @
05aed5b6
...
...
@@ -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.
...
...
src/common/util.c
View file @
05aed5b6
...
...
@@ -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
;
...
...
src/common/util.h
View file @
05aed5b6
...
...
@@ -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
);
...
...
src/or/config.c
View file @
05aed5b6
...
...
@@ -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,54 +6291,61 @@ 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). */
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
;
}
if
(
strlen
(
addrport
+
strlen
(
unix_socket_prefix
))
==
0
)
{
/* Empty socket path, not very usable. */
return
-
EINVAL
;
}
*
path_out
=
tor_strdup
(
addrport
+
strlen
(
unix_socket_prefix
));
return
0
;
}
#else
/* defined(HAVE_SYS_UN_H) */
/**
* 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
);
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
(
strcmpstart
(
addrport
,
unix_socket_prefix
))
{
/* Not a Unix socket path. */
return
-
ENOENT
;
const
char
*
end
=
find_whitespace
(
line
);
if
(
BUG
(
!
end
))
{
end
=
strchr
(
line
,
'\0'
);
// LCOV_EXCL_LINE -- this can't be NULL
}
tor_assert
(
end
&&
end
>=
line
);
*
addrport_out
=
tor_strndup
(
line
,
end
-
line
);
*
rest_out
=
eat_whitespace
(
end
);
return
0
;
}
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
;
}
...
...
src/or/config.h
View file @
05aed5b6
...
...
@@ -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
{
...
...
src/or/rendservice.c
View file @
05aed5b6
...
...
@@ -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
;
addrpor
t
=
smartlist_get
(
sl
,
1
);
ret
=
config_parse_unix_port
(
addrport
,
&
socket_path
)
;
i
f
(
ret
<
0
&&
ret
!=
-
ENOENT
)
{
if
(
ret
==
-
EINVAL
)
if
(
err_msg_ou
t
)
err_msg
=
tor_strdup
(
"Empty socket path in hidden service port "
"configuration."
);
const
char
*
addrport_elemen
t
=
smartlist_get
(
sl
,
1
);
const
char
*
rest
=
NULL
;
i
nt
is_unix
;
ret
=
port_cfg_line_extract_addrport
(
addrport_element
,
&
addrport
,
&
is_unix
,
&
res
t
)
;
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
;
}
...
...
src/test/test_config.c
View file @
05aed5b6
...
...
@@ -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
),
...
...
src/test/test_controller.c
View file @
05aed5b6
...
...
@@ -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> "