From ea72958f25f6326d6947c8cd4ef185912582d436 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 12 Jun 2013 16:23:16 +0300 Subject: Pass characters to be escaped to tor_escape_str_for_socks_arg(). This is in preparation for using tor_escape_str_for_socks_arg() to escape server-side pluggable transport parameters. --- src/or/transports.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/or/transports.c') diff --git a/src/or/transports.c b/src/or/transports.c index cfec70340c..6f17702386 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1440,7 +1440,7 @@ pt_stringify_socks_args(const smartlist_t *socks_args) SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) { /* Escape ';' and '\'. */ - escaped_string = tor_escape_str_for_socks_arg(s); + escaped_string = tor_escape_str_for_socks_arg(s, ";\\"); if (!escaped_string) goto done; -- cgit v1.2.3-54-g00ecf From 1a0cf08841904940ed46b2fcfd79cf65c65a1a6c Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 12 Jun 2013 16:36:13 +0300 Subject: Rename tor_escape_str_for_socks_arg() to something more generic. Since we are going to be using that function to also escape parameters passed to transport proxies using environment variables. --- src/common/util.c | 2 +- src/common/util.h | 4 ++-- src/or/transports.c | 2 +- src/test/test_util.c | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/or/transports.c') diff --git a/src/common/util.c b/src/common/util.c index bd38a62800..eb932f3054 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1227,7 +1227,7 @@ escaped(const char *s) * chars_to_escape. The returned string is allocated on the * heap and it's the responsibility of the caller to free it. */ char * -tor_escape_str_for_socks_arg(const char *string, const char *chars_to_escape) +tor_escape_str_for_pt_args(const char *string, const char *chars_to_escape) { char *new_string = NULL; char *new_cp = NULL; diff --git a/src/common/util.h b/src/common/util.h index ba0ec98685..0a8e4a23fc 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -231,8 +231,8 @@ int tor_digest256_is_zero(const char *digest); char *esc_for_log(const char *string) ATTR_MALLOC; const char *escaped(const char *string); -char *tor_escape_str_for_socks_arg(const char *string, - const char *chars_to_escape); +char *tor_escape_str_for_pt_args(const char *string, + const char *chars_to_escape); struct smartlist_t; int tor_vsscanf(const char *buf, const char *pattern, va_list ap) \ diff --git a/src/or/transports.c b/src/or/transports.c index 6f17702386..6b6882ae73 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1440,7 +1440,7 @@ pt_stringify_socks_args(const smartlist_t *socks_args) SMARTLIST_FOREACH_BEGIN(socks_args, const char *, s) { /* Escape ';' and '\'. */ - escaped_string = tor_escape_str_for_socks_arg(s, ";\\"); + escaped_string = tor_escape_str_for_pt_args(s, ";\\"); if (!escaped_string) goto done; diff --git a/src/test/test_util.c b/src/test/test_util.c index 54a089b368..f7513c0f31 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -796,37 +796,37 @@ test_util_expand_filename(void) } #endif -/** Test tor_escape_str_for_socks_arg(). */ +/** Test tor_escape_str_for_pt_args(). */ static void test_util_escape_string_socks(void) { char *escaped_string = NULL; /** 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_streq(escaped_string, "This is a backslash: \\\\"); tor_free(escaped_string); /** 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_streq(escaped_string, "First rule: Do not use \\;"); + test_streq(escaped_string, "First rule:Do not use \\;"); tor_free(escaped_string); /** Empty string. */ - escaped_string = tor_escape_str_for_socks_arg("", ";\\"); + escaped_string = tor_escape_str_for_pt_args("", ";\\"); test_assert(escaped_string); test_streq(escaped_string, ""); tor_free(escaped_string); /** Escape all characters. */ - escaped_string = tor_escape_str_for_socks_arg(";\\;\\", ";\\"); + escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\"); test_assert(escaped_string); test_streq(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_streq(escaped_string, "\\;"); tor_free(escaped_string); -- cgit v1.2.3-54-g00ecf From 1ee3a0cf4440f34c024ff61a320e0b16553a3558 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Wed, 12 Jun 2013 17:12:39 +0300 Subject: Place the options in the environment after processing them properly. --- src/or/config.c | 20 ++++++++++++++++++++ src/or/config.h | 2 +- src/or/transports.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) (limited to 'src/or/transports.c') diff --git a/src/or/config.c b/src/or/config.c index 1f6d1db1c5..4ddced8a68 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4671,6 +4671,26 @@ get_transport_bindaddr_from_config(const char *transport) return NULL; } +/** Given the name of a pluggable transport in transport, 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 * line. Return 0 if the line is well-formed, and -1 if it * isn't. diff --git a/src/or/config.h b/src/or/config.h index 11e8109d93..9910f18736 100644 --- a/src/or/config.h +++ b/src/or/config.h @@ -114,7 +114,7 @@ void bridge_line_free(bridge_line_t *bridge_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 diff --git a/src/or/transports.c b/src/or/transports.c index 6b6882ae73..2b129cb0ff 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1100,6 +1100,48 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp) return r; } +/** Return a newly allocated string that tor should place in + * TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server + * manged proxy in mp. 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); + + 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 * while configuring the server managed proxy in mp. The * string is stored in the heap, and it's the the responsibility of @@ -1181,6 +1223,14 @@ create_managed_proxy_environment(const managed_proxy_t *mp) tor_free(bindaddr_tmp); } + { + char *server_transport_options = + get_transport_options_for_server_proxy(mp); + 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 * assert that this env var exists are sufficiently dead. * -- cgit v1.2.3-54-g00ecf From c71809d403f1fe84105748583ef0f66b6c778db2 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 13 Jun 2013 12:18:07 +0300 Subject: Insert the environment variable only if we have options to pass. --- src/or/transports.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/or/transports.c') diff --git a/src/or/transports.c b/src/or/transports.c index 2b129cb0ff..39cb872c23 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -1134,7 +1134,9 @@ get_transport_options_for_server_proxy(const managed_proxy_t *mp) smartlist_free(options_tmp_sl); } SMARTLIST_FOREACH_END(transport); - options_string = smartlist_join_strings(string_sl, ";", 0, NULL); + 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); @@ -1226,9 +1228,11 @@ create_managed_proxy_environment(const managed_proxy_t *mp) { char *server_transport_options = get_transport_options_for_server_proxy(mp); - smartlist_add_asprintf(envs, "TOR_PT_SERVER_TRANSPORT_OPTIONS=%s", - server_transport_options); - tor_free(server_transport_options); + 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 -- cgit v1.2.3-54-g00ecf From 8a01a7c35b422a2c22fad2ee71f0268aa1b28b85 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 15 Jul 2013 17:32:08 -0400 Subject: Improve test coverage of 8929 code --- src/or/transports.c | 9 +++------ src/or/transports.h | 6 ++++++ src/test/test_pt.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) (limited to 'src/or/transports.c') diff --git a/src/or/transports.c b/src/or/transports.c index 39cb872c23..5941560cc7 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -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 void managed_proxy_destroy(managed_proxy_t *mp, - int also_terminate_process); - static void handle_finished_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 mp. */ -static void +STATIC void managed_proxy_destroy(managed_proxy_t *mp, int also_terminate_process) { @@ -1103,7 +1100,7 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp) /** Return a newly allocated string that tor should place in * TOR_PT_SERVER_TRANSPORT_OPTIONS while configuring the server * manged proxy in mp. Return NULL if no such options are found. */ -static char * +STATIC char * get_transport_options_for_server_proxy(const managed_proxy_t *mp) { char *options_string = NULL; @@ -1265,7 +1262,7 @@ create_managed_proxy_environment(const managed_proxy_t *mp) * proxy_argv. * * 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, char **proxy_argv, int is_server) { diff --git a/src/or/transports.h b/src/or/transports.h index cc3e018d6d..dc68e946f2 100644 --- a/src/or/transports.h +++ b/src/or/transports.h @@ -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 void parse_env_error(const char *line); 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 diff --git a/src/test/test_pt.c b/src/test/test_pt.c index d4cc0ae97b..6aa345d568 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -6,6 +6,8 @@ #include "orconfig.h" #define PT_PRIVATE #include "or.h" +#include "config.h" +#include "confparse.h" #include "transports.h" #include "circuitbuild.h" #include "test.h" @@ -86,6 +88,58 @@ test_pt_parsing(void) 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 test_pt_protocol(void) { @@ -138,6 +192,8 @@ test_pt_protocol(void) struct testcase_t pt_tests[] = { PT_LEGACY(parsing), PT_LEGACY(protocol), + { "get_transport_options", test_pt_get_transport_options, TT_FORK, + NULL, NULL }, END_OF_TESTCASES }; -- cgit v1.2.3-54-g00ecf