mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge branch 'bug8929_rebase_2'
This commit is contained in:
commit
b551988ef4
4
changes/bug8929
Normal file
4
changes/bug8929
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor features:
|
||||||
|
- Add a new torrc option "ServerTransportOptions" that allows
|
||||||
|
bridge operators to pass configuration parameters to their
|
||||||
|
pluggable transports. Resolves ticket 8929.
|
@ -186,6 +186,11 @@ GENERAL OPTIONS
|
|||||||
listening address of any pluggable transport proxy that tries to
|
listening address of any pluggable transport proxy that tries to
|
||||||
launch __transport__.
|
launch __transport__.
|
||||||
|
|
||||||
|
**ServerTransportOptions** __transport__ __k=v__ __k=v__ ...::
|
||||||
|
When this option is set, Tor will pass the __k=v__ parameters to
|
||||||
|
any pluggable transport proxy that tries to launch __transport__. +
|
||||||
|
(Example: ServerTransportOptions obfs45 shared-secret=bridgepasswd cache=/var/lib/tor/cache)
|
||||||
|
|
||||||
**ConnLimit** __NUM__::
|
**ConnLimit** __NUM__::
|
||||||
The minimum number of file descriptors that must be available to the Tor
|
The minimum number of file descriptors that must be available to the Tor
|
||||||
process before it will start. Tor will ask the OS for as many file
|
process before it will start. Tor will ask the OS for as many file
|
||||||
|
@ -1223,17 +1223,14 @@ escaped(const char *s)
|
|||||||
return escaped_val_;
|
return escaped_val_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Escape every ";" or "\" character of <b>string</b>. Use
|
/** Return a newly allocated string equal to <b>string</b>, except that every
|
||||||
* <b>escape_char</b> as the character to use for escaping.
|
* character in <b>chars_to_escape</b> is preceded by a backslash. */
|
||||||
* The returned string is allocated on the heap and it's the
|
|
||||||
* responsibility of the caller to free it. */
|
|
||||||
char *
|
char *
|
||||||
tor_escape_str_for_socks_arg(const char *string)
|
tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape)
|
||||||
{
|
{
|
||||||
char *new_string = NULL;
|
char *new_string = NULL;
|
||||||
char *new_cp = NULL;
|
char *new_cp = NULL;
|
||||||
size_t length, new_length;
|
size_t length, new_length;
|
||||||
static const char *chars_to_escape = ";\\";
|
|
||||||
|
|
||||||
tor_assert(string);
|
tor_assert(string);
|
||||||
|
|
||||||
|
@ -231,7 +231,8 @@ int tor_digest256_is_zero(const char *digest);
|
|||||||
char *esc_for_log(const char *string) ATTR_MALLOC;
|
char *esc_for_log(const char *string) ATTR_MALLOC;
|
||||||
const char *escaped(const char *string);
|
const char *escaped(const char *string);
|
||||||
|
|
||||||
char *tor_escape_str_for_socks_arg(const char *string);
|
char *tor_escape_str_for_pt_args(const char *string,
|
||||||
|
const char *chars_to_escape);
|
||||||
|
|
||||||
struct smartlist_t;
|
struct smartlist_t;
|
||||||
int tor_vsscanf(const char *buf, const char *pattern, va_list ap) \
|
int tor_vsscanf(const char *buf, const char *pattern, va_list ap) \
|
||||||
|
@ -280,6 +280,7 @@ static config_var_t option_vars_[] = {
|
|||||||
V(IPv6Exit, BOOL, "0"),
|
V(IPv6Exit, BOOL, "0"),
|
||||||
VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
|
VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
|
||||||
V(ServerTransportListenAddr, LINELIST, NULL),
|
V(ServerTransportListenAddr, LINELIST, NULL),
|
||||||
|
V(ServerTransportOptions, LINELIST, NULL),
|
||||||
V(Socks4Proxy, STRING, NULL),
|
V(Socks4Proxy, STRING, NULL),
|
||||||
V(Socks5Proxy, STRING, NULL),
|
V(Socks5Proxy, STRING, NULL),
|
||||||
V(Socks5ProxyUsername, STRING, NULL),
|
V(Socks5ProxyUsername, STRING, NULL),
|
||||||
@ -3147,6 +3148,19 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
|||||||
"ServerTransportListenAddr line will be ignored.");
|
"ServerTransportListenAddr line will be ignored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
|
||||||
|
/** If get_options_from_transport_options_line() fails with
|
||||||
|
'transport' being NULL, it means that something went wrong
|
||||||
|
while parsing the ServerTransportOptions line. */
|
||||||
|
smartlist_t *options_sl =
|
||||||
|
get_options_from_transport_options_line(cl->value, NULL);
|
||||||
|
if (!options_sl)
|
||||||
|
REJECT("ServerTransportOptions did not parse. See logs for details.");
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH(options_sl, char *, cp, tor_free(cp));
|
||||||
|
smartlist_free(options_sl);
|
||||||
|
}
|
||||||
|
|
||||||
if (options->ConstrainedSockets) {
|
if (options->ConstrainedSockets) {
|
||||||
/* If the user wants to constrain socket buffer use, make sure the desired
|
/* If the user wants to constrain socket buffer use, make sure the desired
|
||||||
* limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
|
* limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
|
||||||
@ -4580,6 +4594,63 @@ get_bindaddr_from_transport_listen_line(const char *line,const char *transport)
|
|||||||
return addrport;
|
return addrport;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Given a ServerTransportOptions <b>line</b>, return a smartlist
|
||||||
|
* with the options. Return NULL if the line was not well-formed.
|
||||||
|
*
|
||||||
|
* If <b>transport</b> is set, return NULL if the line is not
|
||||||
|
* referring to <b>transport</b>.
|
||||||
|
*
|
||||||
|
* The returned smartlist and its strings are allocated on the heap
|
||||||
|
* and it's the responsibility of the caller to free it. */
|
||||||
|
smartlist_t *
|
||||||
|
get_options_from_transport_options_line(const char *line,const char *transport)
|
||||||
|
{
|
||||||
|
smartlist_t *items = smartlist_new();
|
||||||
|
smartlist_t *options = smartlist_new();
|
||||||
|
const char *parsed_transport = NULL;
|
||||||
|
|
||||||
|
smartlist_split_string(items, line, NULL,
|
||||||
|
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
|
||||||
|
|
||||||
|
if (smartlist_len(items) < 2) {
|
||||||
|
log_warn(LD_CONFIG,"Too few arguments on ServerTransportOptions line.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed_transport = smartlist_get(items, 0);
|
||||||
|
/* If 'transport' is given, check if it matches the one on the line */
|
||||||
|
if (transport && strcmp(transport, parsed_transport))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH_BEGIN(items, const char *, option) {
|
||||||
|
if (option_sl_idx == 0) /* skip the transport field (first field)*/
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* validate that it's a k=v value */
|
||||||
|
if (!string_is_key_value(LOG_WARN, option)) {
|
||||||
|
log_warn(LD_CONFIG, "%s is not a k=v value.", escaped(option));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add it to the options smartlist */
|
||||||
|
smartlist_add(options, tor_strdup(option));
|
||||||
|
log_debug(LD_CONFIG, "Added %s to the list of options", escaped(option));
|
||||||
|
} SMARTLIST_FOREACH_END(option);
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
err:
|
||||||
|
SMARTLIST_FOREACH(options, char*, s, tor_free(s));
|
||||||
|
smartlist_free(options);
|
||||||
|
options = NULL;
|
||||||
|
|
||||||
|
done:
|
||||||
|
SMARTLIST_FOREACH(items, char*, s, tor_free(s));
|
||||||
|
smartlist_free(items);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
/** Given the name of a pluggable transport in <b>transport</b>, check
|
/** Given the name of a pluggable transport in <b>transport</b>, check
|
||||||
* the configuration file to see if the user has explicitly asked for
|
* the configuration file to see if the user has explicitly asked for
|
||||||
* it to listen on a specific port. Return a <address:port> string if
|
* it to listen on a specific port. Return a <address:port> string if
|
||||||
@ -4600,6 +4671,26 @@ get_transport_bindaddr_from_config(const char *transport)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Given the name of a pluggable transport in <b>transport</b>, check
|
||||||
|
* the configuration file to see if the user has asked us to pass any
|
||||||
|
* parameters to the pluggable transport. Return a smartlist
|
||||||
|
* containing the parameters, otherwise NULL. */
|
||||||
|
smartlist_t *
|
||||||
|
get_options_for_server_transport(const char *transport)
|
||||||
|
{
|
||||||
|
config_line_t *cl;
|
||||||
|
const or_options_t *options = get_options();
|
||||||
|
|
||||||
|
for (cl = options->ServerTransportOptions; cl; cl = cl->next) {
|
||||||
|
smartlist_t *options_sl =
|
||||||
|
get_options_from_transport_options_line(cl->value, transport);
|
||||||
|
if (options_sl)
|
||||||
|
return options_sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/** Read the contents of a ServerTransportPlugin line from
|
/** Read the contents of a ServerTransportPlugin line from
|
||||||
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
* <b>line</b>. Return 0 if the line is well-formed, and -1 if it
|
||||||
* isn't.
|
* isn't.
|
||||||
|
@ -112,6 +112,9 @@ typedef struct bridge_line_t {
|
|||||||
|
|
||||||
void bridge_line_free(bridge_line_t *bridge_line);
|
void bridge_line_free(bridge_line_t *bridge_line);
|
||||||
bridge_line_t *parse_bridge_line(const char *line);
|
bridge_line_t *parse_bridge_line(const char *line);
|
||||||
|
smartlist_t *get_options_from_transport_options_line(const char *line,
|
||||||
|
const char *transport);
|
||||||
|
smartlist_t *get_options_for_server_transport(const char *transport);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3500,6 +3500,9 @@ typedef struct {
|
|||||||
/** List of TCP/IP addresses that transports should listen at. */
|
/** List of TCP/IP addresses that transports should listen at. */
|
||||||
config_line_t *ServerTransportListenAddr;
|
config_line_t *ServerTransportListenAddr;
|
||||||
|
|
||||||
|
/** List of options that must be passed to pluggable transports. */
|
||||||
|
config_line_t *ServerTransportOptions;
|
||||||
|
|
||||||
int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
|
int BridgeRelay; /**< Boolean: are we acting as a bridge relay? We make
|
||||||
* this explicit so we can change how we behave in the
|
* this explicit so we can change how we behave in the
|
||||||
* future. */
|
* future. */
|
||||||
|
@ -102,9 +102,6 @@ create_managed_proxy_environment(const managed_proxy_t *mp);
|
|||||||
|
|
||||||
static INLINE int proxy_configuration_finished(const managed_proxy_t *mp);
|
static INLINE int proxy_configuration_finished(const managed_proxy_t *mp);
|
||||||
|
|
||||||
static void managed_proxy_destroy(managed_proxy_t *mp,
|
|
||||||
int also_terminate_process);
|
|
||||||
|
|
||||||
static void handle_finished_proxy(managed_proxy_t *mp);
|
static void handle_finished_proxy(managed_proxy_t *mp);
|
||||||
static void configure_proxy(managed_proxy_t *mp);
|
static void configure_proxy(managed_proxy_t *mp);
|
||||||
|
|
||||||
@ -694,7 +691,7 @@ register_proxy(const managed_proxy_t *mp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Free memory allocated by managed proxy <b>mp</b>. */
|
/** Free memory allocated by managed proxy <b>mp</b>. */
|
||||||
static void
|
STATIC void
|
||||||
managed_proxy_destroy(managed_proxy_t *mp,
|
managed_proxy_destroy(managed_proxy_t *mp,
|
||||||
int also_terminate_process)
|
int also_terminate_process)
|
||||||
{
|
{
|
||||||
@ -1100,6 +1097,50 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return a newly allocated string that tor should place in
|
||||||
|
* TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server
|
||||||
|
* manged proxy in <b>mp</b>. Return NULL if no such options are found. */
|
||||||
|
STATIC char *
|
||||||
|
get_transport_options_for_server_proxy(const managed_proxy_t *mp)
|
||||||
|
{
|
||||||
|
char *options_string = NULL;
|
||||||
|
smartlist_t *string_sl = smartlist_new();
|
||||||
|
|
||||||
|
tor_assert(mp->is_server);
|
||||||
|
|
||||||
|
/** Loop over the transports of the proxy. If we have options for
|
||||||
|
any of them, format them appropriately and place them in our
|
||||||
|
smartlist. Finally, join our smartlist to get the final
|
||||||
|
string. */
|
||||||
|
SMARTLIST_FOREACH_BEGIN(mp->transports_to_launch, const char *, transport) {
|
||||||
|
smartlist_t *options_tmp_sl = NULL;
|
||||||
|
options_tmp_sl = get_options_for_server_transport(transport);
|
||||||
|
if (!options_tmp_sl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/** Loop over the options of this transport, escape them, and
|
||||||
|
place them in the smartlist. */
|
||||||
|
SMARTLIST_FOREACH_BEGIN(options_tmp_sl, const char *, options) {
|
||||||
|
char *escaped_opts = tor_escape_str_for_pt_args(options, ":;\\");
|
||||||
|
smartlist_add_asprintf(string_sl, "%s:%s",
|
||||||
|
transport, escaped_opts);
|
||||||
|
tor_free(escaped_opts);
|
||||||
|
} SMARTLIST_FOREACH_END(options);
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH(options_tmp_sl, char *, c, tor_free(c));
|
||||||
|
smartlist_free(options_tmp_sl);
|
||||||
|
} SMARTLIST_FOREACH_END(transport);
|
||||||
|
|
||||||
|
if (smartlist_len(string_sl)) {
|
||||||
|
options_string = smartlist_join_strings(string_sl, ";", 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH(string_sl, char *, t, tor_free(t));
|
||||||
|
smartlist_free(string_sl);
|
||||||
|
|
||||||
|
return options_string;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return the string that tor should place in TOR_PT_SERVER_BINDADDR
|
/** Return the string that tor should place in TOR_PT_SERVER_BINDADDR
|
||||||
* while configuring the server managed proxy in <b>mp</b>. The
|
* while configuring the server managed proxy in <b>mp</b>. The
|
||||||
* string is stored in the heap, and it's the the responsibility of
|
* string is stored in the heap, and it's the the responsibility of
|
||||||
@ -1181,6 +1222,16 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
|
|||||||
tor_free(bindaddr_tmp);
|
tor_free(bindaddr_tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *server_transport_options =
|
||||||
|
get_transport_options_for_server_proxy(mp);
|
||||||
|
if (server_transport_options) {
|
||||||
|
smartlist_add_asprintf(envs, "TOR_PT_SERVER_TRANSPORT_OPTIONS=%s",
|
||||||
|
server_transport_options);
|
||||||
|
tor_free(server_transport_options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX024 Remove the '=' here once versions of obfsproxy which
|
/* XXX024 Remove the '=' here once versions of obfsproxy which
|
||||||
* assert that this env var exists are sufficiently dead.
|
* assert that this env var exists are sufficiently dead.
|
||||||
*
|
*
|
||||||
@ -1211,7 +1262,7 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
|
|||||||
* <b>proxy_argv</b>.
|
* <b>proxy_argv</b>.
|
||||||
*
|
*
|
||||||
* Requires that proxy_argv have at least one element. */
|
* Requires that proxy_argv have at least one element. */
|
||||||
static managed_proxy_t *
|
STATIC managed_proxy_t *
|
||||||
managed_proxy_create(const smartlist_t *transport_list,
|
managed_proxy_create(const smartlist_t *transport_list,
|
||||||
char **proxy_argv, int is_server)
|
char **proxy_argv, int is_server)
|
||||||
{
|
{
|
||||||
@ -1440,7 +1491,7 @@ pt_stringify_socks_args(const smartlist_t *socks_args)
|
|||||||
|
|
||||||
SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) {
|
SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) {
|
||||||
/* Escape ';' and '\'. */
|
/* Escape ';' and '\'. */
|
||||||
escaped_string = tor_escape_str_for_socks_arg(s);
|
escaped_string = tor_escape_str_for_pt_args(s, ";\\");
|
||||||
if (!escaped_string)
|
if (!escaped_string)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -110,6 +110,12 @@ STATIC int parse_smethod_line(const char *line, managed_proxy_t *mp);
|
|||||||
STATIC int parse_version(const char *line, managed_proxy_t *mp);
|
STATIC int parse_version(const char *line, managed_proxy_t *mp);
|
||||||
STATIC void parse_env_error(const char *line);
|
STATIC void parse_env_error(const char *line);
|
||||||
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
|
STATIC void handle_proxy_line(const char *line, managed_proxy_t *mp);
|
||||||
|
STATIC char *get_transport_options_for_server_proxy(const managed_proxy_t *mp);
|
||||||
|
|
||||||
|
STATIC void managed_proxy_destroy(managed_proxy_t *mp,
|
||||||
|
int also_terminate_process);
|
||||||
|
STATIC managed_proxy_t *managed_proxy_create(const smartlist_t *transport_list,
|
||||||
|
char **proxy_argv, int is_server);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -438,12 +438,84 @@ test_config_parse_bridge_line(void *arg)
|
|||||||
"aa=b");
|
"aa=b");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_config_parse_transport_options_line(void *arg)
|
||||||
|
{
|
||||||
|
smartlist_t *options_sl = NULL, *sl_tmp = NULL;
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
{ /* too small line */
|
||||||
|
options_sl = get_options_from_transport_options_line("valley", NULL);
|
||||||
|
test_assert(!options_sl);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* no k=v values */
|
||||||
|
options_sl = get_options_from_transport_options_line("hit it!", NULL);
|
||||||
|
test_assert(!options_sl);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* correct line, but wrong transport specified */
|
||||||
|
options_sl =
|
||||||
|
get_options_from_transport_options_line("trebuchet k=v", "rook");
|
||||||
|
test_assert(!options_sl);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* correct -- no transport specified */
|
||||||
|
sl_tmp = smartlist_new();
|
||||||
|
smartlist_add_asprintf(sl_tmp, "ladi=dadi");
|
||||||
|
smartlist_add_asprintf(sl_tmp, "weliketo=party");
|
||||||
|
|
||||||
|
options_sl =
|
||||||
|
get_options_from_transport_options_line("rook ladi=dadi weliketo=party",
|
||||||
|
NULL);
|
||||||
|
test_assert(options_sl);
|
||||||
|
test_assert(smartlist_strings_eq(options_sl, sl_tmp));
|
||||||
|
|
||||||
|
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
|
||||||
|
smartlist_free(sl_tmp);
|
||||||
|
sl_tmp = NULL;
|
||||||
|
SMARTLIST_FOREACH(options_sl, char *, s, tor_free(s));
|
||||||
|
smartlist_free(options_sl);
|
||||||
|
options_sl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* correct -- correct transport specified */
|
||||||
|
sl_tmp = smartlist_new();
|
||||||
|
smartlist_add_asprintf(sl_tmp, "ladi=dadi");
|
||||||
|
smartlist_add_asprintf(sl_tmp, "weliketo=party");
|
||||||
|
|
||||||
|
options_sl =
|
||||||
|
get_options_from_transport_options_line("rook ladi=dadi weliketo=party",
|
||||||
|
"rook");
|
||||||
|
test_assert(options_sl);
|
||||||
|
test_assert(smartlist_strings_eq(options_sl, sl_tmp));
|
||||||
|
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
|
||||||
|
smartlist_free(sl_tmp);
|
||||||
|
sl_tmp = NULL;
|
||||||
|
SMARTLIST_FOREACH(options_sl, char *, s, tor_free(s));
|
||||||
|
smartlist_free(options_sl);
|
||||||
|
options_sl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (options_sl) {
|
||||||
|
SMARTLIST_FOREACH(options_sl, char *, s, tor_free(s));
|
||||||
|
smartlist_free(options_sl);
|
||||||
|
}
|
||||||
|
if (sl_tmp) {
|
||||||
|
SMARTLIST_FOREACH(sl_tmp, char *, s, tor_free(s));
|
||||||
|
smartlist_free(sl_tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define CONFIG_TEST(name, flags) \
|
#define CONFIG_TEST(name, flags) \
|
||||||
{ #name, test_config_ ## name, flags, NULL, NULL }
|
{ #name, test_config_ ## name, flags, NULL, NULL }
|
||||||
|
|
||||||
struct testcase_t config_tests[] = {
|
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(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),
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#define PT_PRIVATE
|
#define PT_PRIVATE
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "confparse.h"
|
||||||
#include "transports.h"
|
#include "transports.h"
|
||||||
#include "circuitbuild.h"
|
#include "circuitbuild.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
@ -107,6 +109,58 @@ test_pt_parsing(void)
|
|||||||
tor_free(mp);
|
tor_free(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_pt_get_transport_options(void *arg)
|
||||||
|
{
|
||||||
|
char **execve_args;
|
||||||
|
smartlist_t *transport_list = smartlist_new();
|
||||||
|
managed_proxy_t *mp;
|
||||||
|
or_options_t *options = get_options_mutable();
|
||||||
|
char *opt_str = NULL;
|
||||||
|
config_line_t *cl = NULL;
|
||||||
|
(void)arg;
|
||||||
|
|
||||||
|
execve_args = tor_malloc(sizeof(char*)*2);
|
||||||
|
execve_args[0] = tor_strdup("cheeseshop");
|
||||||
|
execve_args[1] = NULL;
|
||||||
|
|
||||||
|
mp = managed_proxy_create(transport_list, execve_args, 1);
|
||||||
|
tt_ptr_op(mp, !=, NULL);
|
||||||
|
opt_str = get_transport_options_for_server_proxy(mp);
|
||||||
|
tt_ptr_op(opt_str, ==, NULL);
|
||||||
|
|
||||||
|
smartlist_add(mp->transports_to_launch, tor_strdup("gruyere"));
|
||||||
|
smartlist_add(mp->transports_to_launch, tor_strdup("roquefort"));
|
||||||
|
smartlist_add(mp->transports_to_launch, tor_strdup("stnectaire"));
|
||||||
|
|
||||||
|
tt_assert(options);
|
||||||
|
|
||||||
|
cl = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
cl->value = tor_strdup("gruyere melty=10 hardness=se;ven");
|
||||||
|
options->ServerTransportOptions = cl;
|
||||||
|
|
||||||
|
cl = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
cl->value = tor_strdup("stnectaire melty=4 hardness=three");
|
||||||
|
cl->next = options->ServerTransportOptions;
|
||||||
|
options->ServerTransportOptions = cl;
|
||||||
|
|
||||||
|
cl = tor_malloc_zero(sizeof(config_line_t));
|
||||||
|
cl->value = tor_strdup("pepperjack melty=12 hardness=five");
|
||||||
|
cl->next = options->ServerTransportOptions;
|
||||||
|
options->ServerTransportOptions = cl;
|
||||||
|
|
||||||
|
opt_str = get_transport_options_for_server_proxy(mp);
|
||||||
|
tt_str_op(opt_str, ==,
|
||||||
|
"gruyere:melty=10;gruyere:hardness=se\\;ven;"
|
||||||
|
"stnectaire:melty=4;stnectaire:hardness=three");
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_free(opt_str);
|
||||||
|
config_free_lines(cl);
|
||||||
|
managed_proxy_destroy(mp, 0);
|
||||||
|
smartlist_free(transport_list);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_pt_protocol(void)
|
test_pt_protocol(void)
|
||||||
{
|
{
|
||||||
@ -159,6 +213,8 @@ test_pt_protocol(void)
|
|||||||
struct testcase_t pt_tests[] = {
|
struct testcase_t pt_tests[] = {
|
||||||
PT_LEGACY(parsing),
|
PT_LEGACY(parsing),
|
||||||
PT_LEGACY(protocol),
|
PT_LEGACY(protocol),
|
||||||
|
{ "get_transport_options", test_pt_get_transport_options, TT_FORK,
|
||||||
|
NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -796,37 +796,37 @@ test_util_expand_filename(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Test tor_escape_str_for_socks_arg(). */
|
/** Test tor_escape_str_for_pt_args(). */
|
||||||
static void
|
static void
|
||||||
test_util_escape_string_socks(void)
|
test_util_escape_string_socks(void)
|
||||||
{
|
{
|
||||||
char *escaped_string = NULL;
|
char *escaped_string = NULL;
|
||||||
|
|
||||||
/** Simple backslash escape. */
|
/** Simple backslash escape. */
|
||||||
escaped_string = tor_escape_str_for_socks_arg("This is a backslash: \\");
|
escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
|
||||||
test_assert(escaped_string);
|
test_assert(escaped_string);
|
||||||
test_streq(escaped_string, "This is a backslash: \\\\");
|
test_streq(escaped_string, "This is a backslash: \\\\");
|
||||||
tor_free(escaped_string);
|
tor_free(escaped_string);
|
||||||
|
|
||||||
/** Simple semicolon escape. */
|
/** Simple semicolon escape. */
|
||||||
escaped_string = tor_escape_str_for_socks_arg("First rule: Do not use ;");
|
escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
|
||||||
test_assert(escaped_string);
|
test_assert(escaped_string);
|
||||||
test_streq(escaped_string, "First rule:Do not use \\;");
|
test_streq(escaped_string, "First rule:Do not use \\;");
|
||||||
tor_free(escaped_string);
|
tor_free(escaped_string);
|
||||||
|
|
||||||
/** Empty string. */
|
/** Empty string. */
|
||||||
escaped_string = tor_escape_str_for_socks_arg("");
|
escaped_string = tor_escape_str_for_pt_args("", ";\\");
|
||||||
test_assert(escaped_string);
|
test_assert(escaped_string);
|
||||||
test_streq(escaped_string, "");
|
test_streq(escaped_string, "");
|
||||||
tor_free(escaped_string);
|
tor_free(escaped_string);
|
||||||
|
|
||||||
/** Escape all characters. */
|
/** Escape all characters. */
|
||||||
escaped_string = tor_escape_str_for_socks_arg(";\\;\\");
|
escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\");
|
||||||
test_assert(escaped_string);
|
test_assert(escaped_string);
|
||||||
test_streq(escaped_string, "\\;\\\\\\;\\\\");
|
test_streq(escaped_string, "\\;\\\\\\;\\\\");
|
||||||
tor_free(escaped_string);
|
tor_free(escaped_string);
|
||||||
|
|
||||||
escaped_string = tor_escape_str_for_socks_arg(";");
|
escaped_string = tor_escape_str_for_pt_args(";", ";\\");
|
||||||
test_assert(escaped_string);
|
test_assert(escaped_string);
|
||||||
test_streq(escaped_string, "\\;");
|
test_streq(escaped_string, "\\;");
|
||||||
tor_free(escaped_string);
|
tor_free(escaped_string);
|
||||||
|
Loading…
Reference in New Issue
Block a user