mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +01:00
Merge remote-tracking branch 'andrea/ticket6456'
Somewhat tricky conflicts: src/or/config.c Also, s/test_assert/tt_assert in test_config.c
This commit is contained in:
commit
9619c395ac
287
src/or/config.c
287
src/or/config.c
@ -510,12 +510,6 @@ static int options_transition_affects_workers(
|
|||||||
static int options_transition_affects_descriptor(
|
static int options_transition_affects_descriptor(
|
||||||
const or_options_t *old_options, const or_options_t *new_options);
|
const or_options_t *old_options, const or_options_t *new_options);
|
||||||
static int check_nickname_list(char **lst, const char *name, char **msg);
|
static int check_nickname_list(char **lst, const char *name, char **msg);
|
||||||
|
|
||||||
static int parse_client_transport_line(const or_options_t *options,
|
|
||||||
const char *line, int validate_only);
|
|
||||||
|
|
||||||
static int parse_server_transport_line(const or_options_t *options,
|
|
||||||
const char *line, int validate_only);
|
|
||||||
static char *get_bindaddr_from_transport_listen_line(const char *line,
|
static char *get_bindaddr_from_transport_listen_line(const char *line,
|
||||||
const char *transport);
|
const char *transport);
|
||||||
static int parse_dir_authority_line(const char *line,
|
static int parse_dir_authority_line(const char *line,
|
||||||
@ -1413,7 +1407,7 @@ options_act(const or_options_t *old_options)
|
|||||||
if (!options->DisableNetwork) {
|
if (!options->DisableNetwork) {
|
||||||
if (options->ClientTransportPlugin) {
|
if (options->ClientTransportPlugin) {
|
||||||
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
||||||
if (parse_client_transport_line(options, cl->value, 0)<0) {
|
if (parse_transport_line(options, cl->value, 0, 0) < 0) {
|
||||||
log_warn(LD_BUG,
|
log_warn(LD_BUG,
|
||||||
"Previously validated ClientTransportPlugin line "
|
"Previously validated ClientTransportPlugin line "
|
||||||
"could not be added!");
|
"could not be added!");
|
||||||
@ -1424,7 +1418,7 @@ options_act(const or_options_t *old_options)
|
|||||||
|
|
||||||
if (options->ServerTransportPlugin && server_mode(options)) {
|
if (options->ServerTransportPlugin && server_mode(options)) {
|
||||||
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
||||||
if (parse_server_transport_line(options, cl->value, 0)<0) {
|
if (parse_transport_line(options, cl->value, 0, 1) < 0) {
|
||||||
log_warn(LD_BUG,
|
log_warn(LD_BUG,
|
||||||
"Previously validated ServerTransportPlugin line "
|
"Previously validated ServerTransportPlugin line "
|
||||||
"could not be added!");
|
"could not be added!");
|
||||||
@ -3299,12 +3293,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
|
||||||
if (parse_client_transport_line(options, cl->value, 1)<0)
|
if (parse_transport_line(options, cl->value, 1, 0) < 0)
|
||||||
REJECT("Invalid client transport line. See logs for details.");
|
REJECT("Invalid client transport line. See logs for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
for (cl = options->ServerTransportPlugin; cl; cl = cl->next) {
|
||||||
if (parse_server_transport_line(options, cl->value, 1)<0)
|
if (parse_transport_line(options, cl->value, 1, 1) < 0)
|
||||||
REJECT("Invalid server transport line. See logs for details.");
|
REJECT("Invalid server transport line. See logs for details.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4760,46 +4754,52 @@ parse_bridge_line(const char *line)
|
|||||||
return bridge_line;
|
return bridge_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read the contents of a ClientTransportPlugin line from
|
/** Read the contents of a ClientTransportPlugin or ServerTransportPlugin
|
||||||
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
* line from <b>line</b>, depending on the value of <b>server</b>. Return 0
|
||||||
* isn't.
|
* if the line is well-formed, and -1 if it isn't.
|
||||||
*
|
*
|
||||||
* If <b>validate_only</b> is 0, the line is well-formed, and the
|
* If <b>validate_only</b> is 0, the line is well-formed, and the transport is
|
||||||
* transport is needed by some bridge:
|
* needed by some bridge:
|
||||||
* - If it's an external proxy line, add the transport described in the line to
|
* - If it's an external proxy line, add the transport described in the line to
|
||||||
* our internal transport list.
|
* our internal transport list.
|
||||||
* - If it's a managed proxy line, launch the managed proxy. */
|
* - If it's a managed proxy line, launch the managed proxy.
|
||||||
static int
|
*/
|
||||||
parse_client_transport_line(const or_options_t *options,
|
|
||||||
const char *line, int validate_only)
|
STATIC int
|
||||||
|
parse_transport_line(const or_options_t *options,
|
||||||
|
const char *line, int validate_only,
|
||||||
|
int server)
|
||||||
{
|
{
|
||||||
|
|
||||||
smartlist_t *items = NULL;
|
smartlist_t *items = NULL;
|
||||||
int r;
|
int r;
|
||||||
char *field2=NULL;
|
const char *transports = NULL;
|
||||||
|
smartlist_t *transport_list = NULL;
|
||||||
const char *transports=NULL;
|
char *type = NULL;
|
||||||
smartlist_t *transport_list=NULL;
|
char *addrport = NULL;
|
||||||
char *addrport=NULL;
|
|
||||||
tor_addr_t addr;
|
tor_addr_t addr;
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
int socks_ver=PROXY_NONE;
|
int socks_ver = PROXY_NONE;
|
||||||
|
|
||||||
/* managed proxy options */
|
/* managed proxy options */
|
||||||
int is_managed=0;
|
int is_managed = 0;
|
||||||
char **proxy_argv=NULL;
|
char **proxy_argv = NULL;
|
||||||
char **tmp=NULL;
|
char **tmp = NULL;
|
||||||
int proxy_argc, i;
|
int proxy_argc, i;
|
||||||
int is_useless_proxy=1;
|
int is_useless_proxy = 1;
|
||||||
|
|
||||||
int line_length;
|
int line_length;
|
||||||
|
|
||||||
|
/* Split the line into space-separated tokens */
|
||||||
items = smartlist_new();
|
items = smartlist_new();
|
||||||
smartlist_split_string(items, line, NULL,
|
smartlist_split_string(items, line, NULL,
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
||||||
|
line_length = smartlist_len(items);
|
||||||
|
|
||||||
line_length = smartlist_len(items);
|
|
||||||
if (line_length < 3) {
|
if (line_length < 3) {
|
||||||
log_warn(LD_CONFIG, "Too few arguments on ClientTransportPlugin line.");
|
log_warn(LD_CONFIG,
|
||||||
|
"Too few arguments on %sTransportPlugin line.",
|
||||||
|
server ? "Server" : "Client");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4823,71 +4823,97 @@ parse_client_transport_line(const or_options_t *options,
|
|||||||
is_useless_proxy = 0;
|
is_useless_proxy = 0;
|
||||||
} SMARTLIST_FOREACH_END(transport_name);
|
} SMARTLIST_FOREACH_END(transport_name);
|
||||||
|
|
||||||
/* field2 is either a SOCKS version or "exec" */
|
type = smartlist_get(items, 1);
|
||||||
field2 = smartlist_get(items, 1);
|
if (!strcmp(type, "exec")) {
|
||||||
|
is_managed = 1;
|
||||||
if (!strcmp(field2,"socks4")) {
|
} else if (server && !strcmp(type, "proxy")) {
|
||||||
|
/* 'proxy' syntax only with ServerTransportPlugin */
|
||||||
|
is_managed = 0;
|
||||||
|
} else if (!server && !strcmp(type, "socks4")) {
|
||||||
|
/* 'socks4' syntax only with ClientTransportPlugin */
|
||||||
|
is_managed = 0;
|
||||||
socks_ver = PROXY_SOCKS4;
|
socks_ver = PROXY_SOCKS4;
|
||||||
} else if (!strcmp(field2,"socks5")) {
|
} else if (!server && !strcmp(type, "socks5")) {
|
||||||
|
/* 'socks5' syntax only with ClientTransportPlugin */
|
||||||
|
is_managed = 0;
|
||||||
socks_ver = PROXY_SOCKS5;
|
socks_ver = PROXY_SOCKS5;
|
||||||
} else if (!strcmp(field2,"exec")) {
|
|
||||||
is_managed=1;
|
|
||||||
} else {
|
} else {
|
||||||
log_warn(LD_CONFIG, "Strange ClientTransportPlugin field '%s'.",
|
log_warn(LD_CONFIG,
|
||||||
field2);
|
"Strange %sTransportPlugin type '%s'",
|
||||||
|
server ? "Server" : "Client", type);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_managed && options->Sandbox) {
|
if (is_managed && options->Sandbox) {
|
||||||
log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
|
log_warn(LD_CONFIG,
|
||||||
"(ClientTransportPlugin line was %s)", escaped(line));
|
"Managed proxies are not compatible with Sandbox mode."
|
||||||
|
"(%sTransportPlugin line was %s)",
|
||||||
|
server ? "Server" : "Client", escaped(line));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_managed) { /* managed */
|
if (is_managed) {
|
||||||
if (!validate_only && is_useless_proxy) {
|
/* managed */
|
||||||
log_info(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
|
|
||||||
"any needed transports and will not be launched.", line);
|
if (!server && !validate_only && is_useless_proxy) {
|
||||||
|
log_info(LD_GENERAL,
|
||||||
|
"Pluggable transport proxy (%s) does not provide "
|
||||||
|
"any needed transports and will not be launched.",
|
||||||
|
line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are not just validating, use the rest of the line as the
|
/*
|
||||||
argv of the proxy to be launched. Also, make sure that we are
|
* If we are not just validating, use the rest of the line as the
|
||||||
only launching proxies that contribute useful transports. */
|
* argv of the proxy to be launched. Also, make sure that we are
|
||||||
if (!validate_only && !is_useless_proxy) {
|
* only launching proxies that contribute useful transports.
|
||||||
proxy_argc = line_length-2;
|
*/
|
||||||
|
|
||||||
|
if (!validate_only && (server || !is_useless_proxy)) {
|
||||||
|
proxy_argc = line_length - 2;
|
||||||
tor_assert(proxy_argc > 0);
|
tor_assert(proxy_argc > 0);
|
||||||
proxy_argv = tor_calloc((proxy_argc + 1), sizeof(char *));
|
proxy_argv = tor_calloc((proxy_argc + 1), sizeof(char *));
|
||||||
tmp = proxy_argv;
|
tmp = proxy_argv;
|
||||||
for (i=0;i<proxy_argc;i++) { /* store arguments */
|
|
||||||
|
for (i = 0; i < proxy_argc; i++) {
|
||||||
|
/* store arguments */
|
||||||
*tmp++ = smartlist_get(items, 2);
|
*tmp++ = smartlist_get(items, 2);
|
||||||
smartlist_del_keeporder(items, 2);
|
smartlist_del_keeporder(items, 2);
|
||||||
}
|
}
|
||||||
*tmp = NULL; /*terminated with NULL, just like execve() likes it*/
|
*tmp = NULL; /* terminated with NULL, just like execve() likes it */
|
||||||
|
|
||||||
/* kickstart the thing */
|
/* kickstart the thing */
|
||||||
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
if (server) {
|
||||||
|
pt_kickstart_server_proxy(transport_list, proxy_argv);
|
||||||
|
} else {
|
||||||
|
pt_kickstart_client_proxy(transport_list, proxy_argv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { /* external */
|
} else {
|
||||||
|
/* external */
|
||||||
|
|
||||||
/* ClientTransportPlugins connecting through a proxy is managed only. */
|
/* ClientTransportPlugins connecting through a proxy is managed only. */
|
||||||
if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
|
if (!server &&
|
||||||
|
(options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy)) {
|
||||||
log_warn(LD_CONFIG, "You have configured an external proxy with another "
|
log_warn(LD_CONFIG, "You have configured an external proxy with another "
|
||||||
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
"proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smartlist_len(transport_list) != 1) {
|
if (smartlist_len(transport_list) != 1) {
|
||||||
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
log_warn(LD_CONFIG,
|
||||||
"more than one transports.");
|
"You can't have an external proxy with more than "
|
||||||
|
"one transport.");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
addrport = smartlist_get(items, 2);
|
addrport = smartlist_get(items, 2);
|
||||||
|
|
||||||
if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
|
if (tor_addr_port_lookup(addrport, &addr, &port) < 0) {
|
||||||
log_warn(LD_CONFIG, "Error parsing transport "
|
log_warn(LD_CONFIG,
|
||||||
"address '%s'", addrport);
|
"Error parsing transport address '%s'", addrport);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port) {
|
if (!port) {
|
||||||
log_warn(LD_CONFIG,
|
log_warn(LD_CONFIG,
|
||||||
"Transport address '%s' has no port.", addrport);
|
"Transport address '%s' has no port.", addrport);
|
||||||
@ -4895,11 +4921,15 @@ parse_client_transport_line(const or_options_t *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!validate_only) {
|
if (!validate_only) {
|
||||||
transport_add_from_config(&addr, port, smartlist_get(transport_list, 0),
|
log_info(LD_DIR, "%s '%s' at %s.",
|
||||||
socks_ver);
|
server ? "Server transport" : "Transport",
|
||||||
|
|
||||||
log_info(LD_DIR, "Transport '%s' found at %s",
|
|
||||||
transports, fmt_addrport(&addr, port));
|
transports, fmt_addrport(&addr, port));
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
transport_add_from_config(&addr, port,
|
||||||
|
smartlist_get(transport_list, 0),
|
||||||
|
socks_ver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5071,133 +5101,6 @@ get_options_for_server_transport(const char *transport)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read the contents of a ServerTransportPlugin line from
|
|
||||||
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
|
||||||
* isn't.
|
|
||||||
* If <b>validate_only</b> is 0, the line is well-formed, and it's a
|
|
||||||
* managed proxy line, launch the managed proxy. */
|
|
||||||
static int
|
|
||||||
parse_server_transport_line(const or_options_t *options,
|
|
||||||
const char *line, int validate_only)
|
|
||||||
{
|
|
||||||
smartlist_t *items = NULL;
|
|
||||||
int r;
|
|
||||||
const char *transports=NULL;
|
|
||||||
smartlist_t *transport_list=NULL;
|
|
||||||
char *type=NULL;
|
|
||||||
char *addrport=NULL;
|
|
||||||
tor_addr_t addr;
|
|
||||||
uint16_t port = 0;
|
|
||||||
|
|
||||||
/* managed proxy options */
|
|
||||||
int is_managed=0;
|
|
||||||
char **proxy_argv=NULL;
|
|
||||||
char **tmp=NULL;
|
|
||||||
int proxy_argc,i;
|
|
||||||
|
|
||||||
int line_length;
|
|
||||||
|
|
||||||
items = smartlist_new();
|
|
||||||
smartlist_split_string(items, line, NULL,
|
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
|
||||||
|
|
||||||
line_length = smartlist_len(items);
|
|
||||||
if (line_length < 3) {
|
|
||||||
log_warn(LD_CONFIG, "Too few arguments on ServerTransportPlugin line.");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the first line element, split it to commas into
|
|
||||||
transport_list (in case it's multiple transports) and validate
|
|
||||||
the transport names. */
|
|
||||||
transports = smartlist_get(items, 0);
|
|
||||||
transport_list = smartlist_new();
|
|
||||||
smartlist_split_string(transport_list, transports, ",",
|
|
||||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
|
||||||
SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
|
|
||||||
if (!string_is_C_identifier(transport_name)) {
|
|
||||||
log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
|
|
||||||
transport_name);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
} SMARTLIST_FOREACH_END(transport_name);
|
|
||||||
|
|
||||||
type = smartlist_get(items, 1);
|
|
||||||
|
|
||||||
if (!strcmp(type, "exec")) {
|
|
||||||
is_managed=1;
|
|
||||||
} else if (!strcmp(type, "proxy")) {
|
|
||||||
is_managed=0;
|
|
||||||
} else {
|
|
||||||
log_warn(LD_CONFIG, "Strange ServerTransportPlugin type '%s'", type);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_managed && options->Sandbox) {
|
|
||||||
log_warn(LD_CONFIG, "Managed proxies are not compatible with Sandbox mode."
|
|
||||||
"(ServerTransportPlugin line was %s)", escaped(line));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_managed) { /* managed */
|
|
||||||
if (!validate_only) {
|
|
||||||
proxy_argc = line_length-2;
|
|
||||||
tor_assert(proxy_argc > 0);
|
|
||||||
proxy_argv = tor_calloc((proxy_argc + 1), sizeof(char *));
|
|
||||||
tmp = proxy_argv;
|
|
||||||
|
|
||||||
for (i=0;i<proxy_argc;i++) { /* store arguments */
|
|
||||||
*tmp++ = smartlist_get(items, 2);
|
|
||||||
smartlist_del_keeporder(items, 2);
|
|
||||||
}
|
|
||||||
*tmp = NULL; /*terminated with NULL, just like execve() likes it*/
|
|
||||||
|
|
||||||
/* kickstart the thing */
|
|
||||||
pt_kickstart_server_proxy(transport_list, proxy_argv);
|
|
||||||
}
|
|
||||||
} else { /* external */
|
|
||||||
if (smartlist_len(transport_list) != 1) {
|
|
||||||
log_warn(LD_CONFIG, "You can't have an external proxy with "
|
|
||||||
"more than one transports.");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
addrport = smartlist_get(items, 2);
|
|
||||||
|
|
||||||
if (tor_addr_port_lookup(addrport, &addr, &port)<0) {
|
|
||||||
log_warn(LD_CONFIG, "Error parsing transport "
|
|
||||||
"address '%s'", addrport);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!port) {
|
|
||||||
log_warn(LD_CONFIG,
|
|
||||||
"Transport address '%s' has no port.", addrport);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validate_only) {
|
|
||||||
log_info(LD_DIR, "Server transport '%s' at %s.",
|
|
||||||
transports, fmt_addrport(&addr, port));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
err:
|
|
||||||
r = -1;
|
|
||||||
|
|
||||||
done:
|
|
||||||
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
|
|
||||||
smartlist_free(items);
|
|
||||||
if (transport_list) {
|
|
||||||
SMARTLIST_FOREACH(transport_list, char*, s, tor_free(s));
|
|
||||||
smartlist_free(transport_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Read the contents of a DirAuthority line from <b>line</b>. If
|
/** Read the contents of a DirAuthority line from <b>line</b>. If
|
||||||
* <b>validate_only</b> is 0, and the line is well-formed, and it
|
* <b>validate_only</b> is 0, and the line is well-formed, and it
|
||||||
* shares any bits with <b>required_type</b> or <b>required_type</b>
|
* shares any bits with <b>required_type</b> or <b>required_type</b>
|
||||||
|
@ -141,6 +141,9 @@ STATIC int options_validate(or_options_t *old_options,
|
|||||||
or_options_t *options,
|
or_options_t *options,
|
||||||
or_options_t *default_options,
|
or_options_t *default_options,
|
||||||
int from_setconf, char **msg);
|
int from_setconf, char **msg);
|
||||||
|
STATIC int parse_transport_line(const or_options_t *options,
|
||||||
|
const char *line, int validate_only,
|
||||||
|
int server);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1919,8 +1919,8 @@ bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
|
|||||||
|
|
||||||
/** Return True if we have a bridge that uses a transport with name
|
/** Return True if we have a bridge that uses a transport with name
|
||||||
* <b>transport_name</b>. */
|
* <b>transport_name</b>. */
|
||||||
int
|
MOCK_IMPL(int,
|
||||||
transport_is_needed(const char *transport_name)
|
transport_is_needed, (const char *transport_name))
|
||||||
{
|
{
|
||||||
if (!bridge_list)
|
if (!bridge_list)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,7 +154,7 @@ struct transport_t;
|
|||||||
int get_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
|
int get_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
|
||||||
const struct transport_t **transport);
|
const struct transport_t **transport);
|
||||||
|
|
||||||
int transport_is_needed(const char *transport_name);
|
MOCK_DECL(int, transport_is_needed, (const char *transport_name));
|
||||||
int validate_pluggable_transports_config(void);
|
int validate_pluggable_transports_config(void);
|
||||||
|
|
||||||
double pathbias_get_close_success_count(entry_guard_t *guard);
|
double pathbias_get_close_success_count(entry_guard_t *guard);
|
||||||
|
@ -326,9 +326,9 @@ transport_add(transport_t *t)
|
|||||||
/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
|
/** Remember a new pluggable transport proxy at <b>addr</b>:<b>port</b>.
|
||||||
* <b>name</b> is set to the name of the protocol this proxy uses.
|
* <b>name</b> is set to the name of the protocol this proxy uses.
|
||||||
* <b>socks_ver</b> is set to the SOCKS version of the proxy. */
|
* <b>socks_ver</b> is set to the SOCKS version of the proxy. */
|
||||||
int
|
MOCK_IMPL(int,
|
||||||
transport_add_from_config(const tor_addr_t *addr, uint16_t port,
|
transport_add_from_config, (const tor_addr_t *addr, uint16_t port,
|
||||||
const char *name, int socks_ver)
|
const char *name, int socks_ver))
|
||||||
{
|
{
|
||||||
transport_t *t = transport_new(addr, port, name, socks_ver, NULL);
|
transport_t *t = transport_new(addr, port, name, socks_ver, NULL);
|
||||||
|
|
||||||
@ -1456,9 +1456,9 @@ managed_proxy_create(const smartlist_t *transport_list,
|
|||||||
* Requires that proxy_argv be a NULL-terminated array of command-line
|
* Requires that proxy_argv be a NULL-terminated array of command-line
|
||||||
* elements, containing at least one element.
|
* elements, containing at least one element.
|
||||||
**/
|
**/
|
||||||
void
|
MOCK_IMPL(void,
|
||||||
pt_kickstart_proxy(const smartlist_t *transport_list,
|
pt_kickstart_proxy, (const smartlist_t *transport_list,
|
||||||
char **proxy_argv, int is_server)
|
char **proxy_argv, int is_server))
|
||||||
{
|
{
|
||||||
managed_proxy_t *mp=NULL;
|
managed_proxy_t *mp=NULL;
|
||||||
transport_t *old_transport = NULL;
|
transport_t *old_transport = NULL;
|
||||||
|
@ -32,14 +32,16 @@ typedef struct transport_t {
|
|||||||
|
|
||||||
void mark_transport_list(void);
|
void mark_transport_list(void);
|
||||||
void sweep_transport_list(void);
|
void sweep_transport_list(void);
|
||||||
int transport_add_from_config(const tor_addr_t *addr, uint16_t port,
|
MOCK_DECL(int, transport_add_from_config,
|
||||||
const char *name, int socks_ver);
|
(const tor_addr_t *addr, uint16_t port,
|
||||||
|
const char *name, int socks_ver));
|
||||||
void transport_free(transport_t *transport);
|
void transport_free(transport_t *transport);
|
||||||
|
|
||||||
transport_t *transport_get_by_name(const char *name);
|
transport_t *transport_get_by_name(const char *name);
|
||||||
|
|
||||||
void pt_kickstart_proxy(const smartlist_t *transport_list, char **proxy_argv,
|
MOCK_DECL(void, pt_kickstart_proxy,
|
||||||
int is_server);
|
(const smartlist_t *transport_list, char **proxy_argv,
|
||||||
|
int is_server));
|
||||||
|
|
||||||
#define pt_kickstart_client_proxy(tl, pa) \
|
#define pt_kickstart_client_proxy(tl, pa) \
|
||||||
pt_kickstart_proxy(tl, pa, 0)
|
pt_kickstart_proxy(tl, pa, 0)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
|
#include "entrynodes.h"
|
||||||
|
#include "transports.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_config_addressmap(void *arg)
|
test_config_addressmap(void *arg)
|
||||||
@ -552,6 +554,251 @@ test_config_parse_transport_options_line(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mocks needed for the transport plugin line test */
|
||||||
|
|
||||||
|
static void pt_kickstart_proxy_mock(const smartlist_t *transport_list,
|
||||||
|
char **proxy_argv, int is_server);
|
||||||
|
static int transport_add_from_config_mock(const tor_addr_t *addr,
|
||||||
|
uint16_t port, const char *name,
|
||||||
|
int socks_ver);
|
||||||
|
static int transport_is_needed_mock(const char *transport_name);
|
||||||
|
|
||||||
|
static int pt_kickstart_proxy_mock_call_count = 0;
|
||||||
|
static int transport_add_from_config_mock_call_count = 0;
|
||||||
|
static int transport_is_needed_mock_call_count = 0;
|
||||||
|
static int transport_is_needed_mock_return = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
pt_kickstart_proxy_mock(const smartlist_t *transport_list,
|
||||||
|
char **proxy_argv, int is_server)
|
||||||
|
{
|
||||||
|
++pt_kickstart_proxy_mock_call_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
transport_add_from_config_mock(const tor_addr_t *addr,
|
||||||
|
uint16_t port, const char *name,
|
||||||
|
int socks_ver)
|
||||||
|
{
|
||||||
|
++transport_add_from_config_mock_call_count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
transport_is_needed_mock(const char *transport_name)
|
||||||
|
{
|
||||||
|
++transport_is_needed_mock_call_count;
|
||||||
|
|
||||||
|
return transport_is_needed_mock_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test parsing for the ClientTransportPlugin and ServerTransportPlugin config
|
||||||
|
* options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_config_parse_transport_plugin_line(void *arg)
|
||||||
|
{
|
||||||
|
or_options_t *options = get_options_mutable();
|
||||||
|
int r, tmp;
|
||||||
|
int old_pt_kickstart_proxy_mock_call_count;
|
||||||
|
int old_transport_add_from_config_mock_call_count;
|
||||||
|
int old_transport_is_needed_mock_call_count;
|
||||||
|
|
||||||
|
/* Bad transport lines - too short */
|
||||||
|
r = parse_transport_line(options, "bad", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options, "bad", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options, "bad bad", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options, "bad bad", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
|
||||||
|
/* Test transport list parsing */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 1, 0);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 1, 1);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1,transport_2 exec /usr/bin/fake-transport", 1, 0);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1,transport_2 exec /usr/bin/fake-transport", 1, 1);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/* Bad transport identifiers */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_* exec /usr/bin/fake-transport", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_* exec /usr/bin/fake-transport", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
|
||||||
|
/* Check SOCKS cases for client transport */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 socks4 1.2.3.4:567", 1, 0);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 socks5 1.2.3.4:567", 1, 0);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/* Proxy case for server transport */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 proxy 1.2.3.4:567", 1, 1);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/* Multiple-transport error exit */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1,transport_2 socks5 1.2.3.4:567", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1,transport_2 proxy 1.2.3.4:567", 1, 1);
|
||||||
|
/* No port error exit */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 socks5 1.2.3.4", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 proxy 1.2.3.4", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
/* Unparsable address error exit */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 socks5 1.2.3:6x7", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 proxy 1.2.3:6x7", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
|
||||||
|
/* "Strange {Client|Server}TransportPlugin field" error exit */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 foo bar", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 foo bar", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
|
||||||
|
/* No sandbox mode error exit */
|
||||||
|
tmp = options->Sandbox;
|
||||||
|
options->Sandbox = 1;
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 1, 0);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 1, 1);
|
||||||
|
tt_assert(r < 0);
|
||||||
|
options->Sandbox = tmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These final test cases cover code paths that only activate without
|
||||||
|
* validate_only, so they need mocks in place.
|
||||||
|
*/
|
||||||
|
MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
|
||||||
|
old_pt_kickstart_proxy_mock_call_count =
|
||||||
|
pt_kickstart_proxy_mock_call_count;
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 0, 1);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||||
|
old_pt_kickstart_proxy_mock_call_count + 1);
|
||||||
|
UNMOCK(pt_kickstart_proxy);
|
||||||
|
|
||||||
|
/* This one hits a log line in the !validate_only case only */
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 proxy 1.2.3.4:567", 0, 1);
|
||||||
|
tt_assert(r == 0);
|
||||||
|
|
||||||
|
/* Check mocked client transport cases */
|
||||||
|
MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
|
||||||
|
MOCK(transport_add_from_config, transport_add_from_config_mock);
|
||||||
|
MOCK(transport_is_needed, transport_is_needed_mock);
|
||||||
|
|
||||||
|
/* Unnecessary transport case */
|
||||||
|
transport_is_needed_mock_return = 0;
|
||||||
|
old_pt_kickstart_proxy_mock_call_count =
|
||||||
|
pt_kickstart_proxy_mock_call_count;
|
||||||
|
old_transport_add_from_config_mock_call_count =
|
||||||
|
transport_add_from_config_mock_call_count;
|
||||||
|
old_transport_is_needed_mock_call_count =
|
||||||
|
transport_is_needed_mock_call_count;
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 0, 0);
|
||||||
|
/* Should have succeeded */
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/* transport_is_needed() should have been called */
|
||||||
|
tt_assert(transport_is_needed_mock_call_count ==
|
||||||
|
old_transport_is_needed_mock_call_count + 1);
|
||||||
|
/*
|
||||||
|
* pt_kickstart_proxy() and transport_add_from_config() should
|
||||||
|
* not have been called.
|
||||||
|
*/
|
||||||
|
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||||
|
old_pt_kickstart_proxy_mock_call_count);
|
||||||
|
tt_assert(transport_add_from_config_mock_call_count ==
|
||||||
|
old_transport_add_from_config_mock_call_count);
|
||||||
|
|
||||||
|
/* Necessary transport case */
|
||||||
|
transport_is_needed_mock_return = 1;
|
||||||
|
old_pt_kickstart_proxy_mock_call_count =
|
||||||
|
pt_kickstart_proxy_mock_call_count;
|
||||||
|
old_transport_add_from_config_mock_call_count =
|
||||||
|
transport_add_from_config_mock_call_count;
|
||||||
|
old_transport_is_needed_mock_call_count =
|
||||||
|
transport_is_needed_mock_call_count;
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 exec /usr/bin/fake-transport", 0, 0);
|
||||||
|
/* Should have succeeded */
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/*
|
||||||
|
* transport_is_needed() and pt_kickstart_proxy() should have been
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||||
|
old_pt_kickstart_proxy_mock_call_count + 1);
|
||||||
|
tt_assert(transport_is_needed_mock_call_count ==
|
||||||
|
old_transport_is_needed_mock_call_count + 1);
|
||||||
|
/* transport_add_from_config() should not have been called. */
|
||||||
|
tt_assert(transport_add_from_config_mock_call_count ==
|
||||||
|
old_transport_add_from_config_mock_call_count);
|
||||||
|
|
||||||
|
/* proxy case */
|
||||||
|
transport_is_needed_mock_return = 1;
|
||||||
|
old_pt_kickstart_proxy_mock_call_count =
|
||||||
|
pt_kickstart_proxy_mock_call_count;
|
||||||
|
old_transport_add_from_config_mock_call_count =
|
||||||
|
transport_add_from_config_mock_call_count;
|
||||||
|
old_transport_is_needed_mock_call_count =
|
||||||
|
transport_is_needed_mock_call_count;
|
||||||
|
r = parse_transport_line(options,
|
||||||
|
"transport_1 socks5 1.2.3.4:567", 0, 0);
|
||||||
|
/* Should have succeeded */
|
||||||
|
tt_assert(r == 0);
|
||||||
|
/*
|
||||||
|
* transport_is_needed() and transport_add_from_config() should have
|
||||||
|
* been called.
|
||||||
|
*/
|
||||||
|
tt_assert(transport_add_from_config_mock_call_count ==
|
||||||
|
old_transport_add_from_config_mock_call_count + 1);
|
||||||
|
tt_assert(transport_is_needed_mock_call_count ==
|
||||||
|
old_transport_is_needed_mock_call_count + 1);
|
||||||
|
/* pt_kickstart_proxy() should not have been called. */
|
||||||
|
tt_assert(pt_kickstart_proxy_mock_call_count ==
|
||||||
|
old_pt_kickstart_proxy_mock_call_count);
|
||||||
|
|
||||||
|
/* Done with mocked client transport cases */
|
||||||
|
UNMOCK(transport_is_needed);
|
||||||
|
UNMOCK(transport_add_from_config);
|
||||||
|
UNMOCK(pt_kickstart_proxy);
|
||||||
|
|
||||||
|
done:
|
||||||
|
/* Make sure we undo all mocks */
|
||||||
|
UNMOCK(pt_kickstart_proxy);
|
||||||
|
UNMOCK(transport_add_from_config);
|
||||||
|
UNMOCK(transport_is_needed);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Tests if an options with MyFamily fingerprints missing '$' normalises
|
// Tests if an options with MyFamily fingerprints missing '$' normalises
|
||||||
// them correctly and also ensure it also works with multiple fingerprints
|
// them correctly and also ensure it also works with multiple fingerprints
|
||||||
static void
|
static void
|
||||||
@ -596,6 +843,7 @@ struct testcase_t config_tests[] = {
|
|||||||
CONFIG_TEST(addressmap, 0),
|
CONFIG_TEST(addressmap, 0),
|
||||||
CONFIG_TEST(parse_bridge_line, 0),
|
CONFIG_TEST(parse_bridge_line, 0),
|
||||||
CONFIG_TEST(parse_transport_options_line, 0),
|
CONFIG_TEST(parse_transport_options_line, 0),
|
||||||
|
CONFIG_TEST(parse_transport_plugin_line, TT_FORK),
|
||||||
CONFIG_TEST(check_or_create_data_subdir, TT_FORK),
|
CONFIG_TEST(check_or_create_data_subdir, TT_FORK),
|
||||||
CONFIG_TEST(write_to_data_subdir, TT_FORK),
|
CONFIG_TEST(write_to_data_subdir, TT_FORK),
|
||||||
CONFIG_TEST(fix_my_family, 0),
|
CONFIG_TEST(fix_my_family, 0),
|
||||||
|
Loading…
Reference in New Issue
Block a user