mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-01 08:03:31 +01:00
Merge branch 'bug9288_rebased'
Conflicts: src/test/test_pt.c
This commit is contained in:
commit
904a58d10f
4
changes/bug9288
Normal file
4
changes/bug9288
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
o Minor bugfixes:
|
||||||
|
- Fix an invalid memory read that occured when a pluggable
|
||||||
|
transport proxy failed its configuration protocol.
|
||||||
|
Fixes bug 9288.
|
@ -3966,9 +3966,9 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|||||||
* <b>process_handle</b>.
|
* <b>process_handle</b>.
|
||||||
* If <b>also_terminate_process</b> is true, also terminate the
|
* If <b>also_terminate_process</b> is true, also terminate the
|
||||||
* process of the process handle. */
|
* process of the process handle. */
|
||||||
void
|
MOCK_IMPL(void,
|
||||||
tor_process_handle_destroy(process_handle_t *process_handle,
|
tor_process_handle_destroy,(process_handle_t *process_handle,
|
||||||
int also_terminate_process)
|
int also_terminate_process))
|
||||||
{
|
{
|
||||||
if (!process_handle)
|
if (!process_handle)
|
||||||
return;
|
return;
|
||||||
@ -4567,8 +4567,8 @@ log_from_handle(HANDLE *pipe, int severity)
|
|||||||
/** Return a smartlist containing lines outputted from
|
/** Return a smartlist containing lines outputted from
|
||||||
* <b>handle</b>. Return NULL on error, and set
|
* <b>handle</b>. Return NULL on error, and set
|
||||||
* <b>stream_status_out</b> appropriately. */
|
* <b>stream_status_out</b> appropriately. */
|
||||||
smartlist_t *
|
MOCK_IMPL(smartlist_t *,
|
||||||
tor_get_lines_from_handle(FILE *handle, enum stream_status *stream_status_out)
|
tor_get_lines_from_handle,(FILE *handle, enum stream_status *stream_status_out))
|
||||||
{
|
{
|
||||||
enum stream_status stream_status;
|
enum stream_status stream_status;
|
||||||
char stdout_buf[400];
|
char stdout_buf[400];
|
||||||
|
@ -492,18 +492,21 @@ FILE *tor_process_get_stdout_pipe(process_handle_t *process_handle);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct smartlist_t *
|
MOCK_DECL(struct smartlist_t *,
|
||||||
tor_get_lines_from_handle(HANDLE *handle,
|
tor_get_lines_from_handle,(HANDLE *handle,
|
||||||
enum stream_status *stream_status);
|
enum stream_status *stream_status));
|
||||||
#else
|
#else
|
||||||
struct smartlist_t *
|
MOCK_DECL(struct smartlist_t *,
|
||||||
tor_get_lines_from_handle(FILE *handle,
|
tor_get_lines_from_handle,(FILE *handle,
|
||||||
enum stream_status *stream_status);
|
enum stream_status *stream_status));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int tor_terminate_process(process_handle_t *process_handle);
|
int
|
||||||
void tor_process_handle_destroy(process_handle_t *process_handle,
|
tor_terminate_process(process_handle_t *process_handle);
|
||||||
int also_terminate_process);
|
|
||||||
|
MOCK_DECL(void,
|
||||||
|
tor_process_handle_destroy,(process_handle_t *process_handle,
|
||||||
|
int also_terminate_process));
|
||||||
|
|
||||||
/* ===== Insecure rng */
|
/* ===== Insecure rng */
|
||||||
typedef struct tor_weak_rng_t {
|
typedef struct tor_weak_rng_t {
|
||||||
|
@ -117,8 +117,8 @@ static const config_format_t state_format = {
|
|||||||
static or_state_t *global_state = NULL;
|
static or_state_t *global_state = NULL;
|
||||||
|
|
||||||
/** Return the persistent state struct for this Tor. */
|
/** Return the persistent state struct for this Tor. */
|
||||||
or_state_t *
|
MOCK_IMPL(or_state_t *,
|
||||||
get_or_state(void)
|
get_or_state, (void))
|
||||||
{
|
{
|
||||||
tor_assert(global_state);
|
tor_assert(global_state);
|
||||||
return global_state;
|
return global_state;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#ifndef TOR_STATEFILE_H
|
#ifndef TOR_STATEFILE_H
|
||||||
#define TOR_STATEFILE_H
|
#define TOR_STATEFILE_H
|
||||||
|
|
||||||
or_state_t *get_or_state(void);
|
MOCK_DECL(or_state_t *,get_or_state,(void));
|
||||||
int did_last_state_file_write_fail(void);
|
int did_last_state_file_write_fail(void);
|
||||||
int or_state_save(time_t now);
|
int or_state_save(time_t now);
|
||||||
|
|
||||||
|
@ -103,8 +103,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 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 parse_method_error(const char *line, int is_server_method);
|
static void parse_method_error(const char *line, int is_server_method);
|
||||||
#define parse_server_method_error(l) parse_method_error(l, 1)
|
#define parse_server_method_error(l) parse_method_error(l, 1)
|
||||||
#define parse_client_method_error(l) parse_method_error(l, 0)
|
#define parse_client_method_error(l) parse_method_error(l, 0)
|
||||||
@ -574,10 +572,8 @@ pt_configure_remaining_proxies(void)
|
|||||||
/* If the proxy is not fully configured, try to configure it
|
/* If the proxy is not fully configured, try to configure it
|
||||||
futher. */
|
futher. */
|
||||||
if (!proxy_configuration_finished(mp))
|
if (!proxy_configuration_finished(mp))
|
||||||
configure_proxy(mp);
|
if (configure_proxy(mp) == 1)
|
||||||
|
at_least_a_proxy_config_finished = 1;
|
||||||
if (proxy_configuration_finished(mp))
|
|
||||||
at_least_a_proxy_config_finished = 1;
|
|
||||||
|
|
||||||
} SMARTLIST_FOREACH_END(mp);
|
} SMARTLIST_FOREACH_END(mp);
|
||||||
|
|
||||||
@ -589,10 +585,14 @@ pt_configure_remaining_proxies(void)
|
|||||||
mark_my_descriptor_dirty("configured managed proxies");
|
mark_my_descriptor_dirty("configured managed proxies");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Attempt to continue configuring managed proxy <b>mp</b>. */
|
/** Attempt to continue configuring managed proxy <b>mp</b>.
|
||||||
static void
|
* Return 1 if the transport configuration finished, and return 0
|
||||||
|
* otherwise (if we still have more configuring to do for this
|
||||||
|
* proxy). */
|
||||||
|
STATIC int
|
||||||
configure_proxy(managed_proxy_t *mp)
|
configure_proxy(managed_proxy_t *mp)
|
||||||
{
|
{
|
||||||
|
int configuration_finished = 0;
|
||||||
smartlist_t *proxy_output = NULL;
|
smartlist_t *proxy_output = NULL;
|
||||||
enum stream_status stream_status = 0;
|
enum stream_status stream_status = 0;
|
||||||
|
|
||||||
@ -602,7 +602,7 @@ configure_proxy(managed_proxy_t *mp)
|
|||||||
mp->conf_state = PT_PROTO_FAILED_LAUNCH;
|
mp->conf_state = PT_PROTO_FAILED_LAUNCH;
|
||||||
handle_finished_proxy(mp);
|
handle_finished_proxy(mp);
|
||||||
}
|
}
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tor_assert(mp->conf_state != PT_PROTO_INFANT);
|
tor_assert(mp->conf_state != PT_PROTO_INFANT);
|
||||||
@ -634,13 +634,17 @@ configure_proxy(managed_proxy_t *mp)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
/* if the proxy finished configuring, exit the loop. */
|
/* if the proxy finished configuring, exit the loop. */
|
||||||
if (proxy_configuration_finished(mp))
|
if (proxy_configuration_finished(mp)) {
|
||||||
handle_finished_proxy(mp);
|
handle_finished_proxy(mp);
|
||||||
|
configuration_finished = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (proxy_output) {
|
if (proxy_output) {
|
||||||
SMARTLIST_FOREACH(proxy_output, char *, cp, tor_free(cp));
|
SMARTLIST_FOREACH(proxy_output, char *, cp, tor_free(cp));
|
||||||
smartlist_free(proxy_output);
|
smartlist_free(proxy_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return configuration_finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register server managed proxy <b>mp</b> transports to state */
|
/** Register server managed proxy <b>mp</b> transports to state */
|
||||||
@ -709,7 +713,8 @@ managed_proxy_destroy(managed_proxy_t *mp,
|
|||||||
smartlist_free(mp->transports_to_launch);
|
smartlist_free(mp->transports_to_launch);
|
||||||
|
|
||||||
/* remove it from the list of managed proxies */
|
/* remove it from the list of managed proxies */
|
||||||
smartlist_remove(managed_proxy_list, mp);
|
if (managed_proxy_list)
|
||||||
|
smartlist_remove(managed_proxy_list, mp);
|
||||||
|
|
||||||
/* free the argv */
|
/* free the argv */
|
||||||
free_execve_args(mp->argv);
|
free_execve_args(mp->argv);
|
||||||
@ -746,7 +751,6 @@ handle_finished_proxy(managed_proxy_t *mp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unconfigured_proxies_n--;
|
unconfigured_proxies_n--;
|
||||||
tor_assert(unconfigured_proxies_n >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if the configuration of the managed proxy <b>mp</b> is
|
/** Return true if the configuration of the managed proxy <b>mp</b> is
|
||||||
|
@ -121,6 +121,8 @@ STATIC void managed_proxy_destroy(managed_proxy_t *mp,
|
|||||||
STATIC managed_proxy_t *managed_proxy_create(const smartlist_t *transport_list,
|
STATIC managed_proxy_t *managed_proxy_create(const smartlist_t *transport_list,
|
||||||
char **proxy_argv, int is_server);
|
char **proxy_argv, int is_server);
|
||||||
|
|
||||||
|
STATIC int configure_proxy(managed_proxy_t *mp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
|
|
||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#define PT_PRIVATE
|
#define PT_PRIVATE
|
||||||
|
#define UTIL_PRIVATE
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "confparse.h"
|
#include "confparse.h"
|
||||||
#include "transports.h"
|
#include "transports.h"
|
||||||
#include "circuitbuild.h"
|
#include "circuitbuild.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "statefile.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -269,6 +272,90 @@ test_pt_get_extrainfo_string(void *arg)
|
|||||||
tor_free(s);
|
tor_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define STDIN_HANDLE HANDLE
|
||||||
|
#else
|
||||||
|
#define STDIN_HANDLE FILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static smartlist_t *
|
||||||
|
tor_get_lines_from_handle_replacement(STDIN_HANDLE *handle,
|
||||||
|
enum stream_status *stream_status_out)
|
||||||
|
{
|
||||||
|
static int times_called = 0;
|
||||||
|
smartlist_t *retval_sl = smartlist_new();
|
||||||
|
|
||||||
|
(void) handle;
|
||||||
|
(void) stream_status_out;
|
||||||
|
|
||||||
|
/* Generate some dummy CMETHOD lines the first 5 times. The 6th
|
||||||
|
time, send 'CMETHODS DONE' to finish configuring the proxy. */
|
||||||
|
if (times_called++ != 5) {
|
||||||
|
smartlist_add_asprintf(retval_sl, "CMETHOD mock%d socks5 127.0.0.1:555%d",
|
||||||
|
times_called, times_called);
|
||||||
|
} else {
|
||||||
|
smartlist_add(retval_sl, tor_strdup("CMETHODS DONE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval_sl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOP mock */
|
||||||
|
static void
|
||||||
|
tor_process_handle_destroy_replacement(process_handle_t *process_handle,
|
||||||
|
int also_terminate_process)
|
||||||
|
{
|
||||||
|
(void) process_handle;
|
||||||
|
(void) also_terminate_process;
|
||||||
|
}
|
||||||
|
|
||||||
|
static or_state_t *dummy_state = NULL;
|
||||||
|
|
||||||
|
static or_state_t *
|
||||||
|
get_or_state_replacement(void)
|
||||||
|
{
|
||||||
|
return dummy_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test the configure_proxy() function. */
|
||||||
|
static void
|
||||||
|
test_pt_configure_proxy(void *arg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
managed_proxy_t *mp = NULL;
|
||||||
|
(void) arg;
|
||||||
|
|
||||||
|
dummy_state = tor_malloc_zero(sizeof(or_state_t));
|
||||||
|
|
||||||
|
MOCK(tor_get_lines_from_handle,
|
||||||
|
tor_get_lines_from_handle_replacement);
|
||||||
|
MOCK(tor_process_handle_destroy,
|
||||||
|
tor_process_handle_destroy_replacement);
|
||||||
|
MOCK(get_or_state,
|
||||||
|
get_or_state_replacement);
|
||||||
|
|
||||||
|
mp = tor_malloc(sizeof(managed_proxy_t));
|
||||||
|
mp->conf_state = PT_PROTO_ACCEPTING_METHODS;
|
||||||
|
mp->transports = smartlist_new();
|
||||||
|
mp->transports_to_launch = smartlist_new();
|
||||||
|
mp->process_handle = tor_malloc_zero(sizeof(process_handle_t));
|
||||||
|
mp->argv = tor_malloc_zero(sizeof(char*)*2);
|
||||||
|
mp->argv[0] = tor_strdup("<testcase>");
|
||||||
|
|
||||||
|
/* Test the return value of configure_proxy() by calling it some
|
||||||
|
times while it is uninitialized and then finally finalizing its
|
||||||
|
configuration. */
|
||||||
|
for (i = 0 ; i < 5 ; i++) {
|
||||||
|
test_assert(configure_proxy(mp) == 0);
|
||||||
|
}
|
||||||
|
test_assert(configure_proxy(mp) == 1);
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_free(dummy_state);
|
||||||
|
UNMOCK(tor_get_lines_from_handle);
|
||||||
|
UNMOCK(tor_process_handle_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
#define PT_LEGACY(name) \
|
#define PT_LEGACY(name) \
|
||||||
{ #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
|
{ #name, legacy_test_helper, 0, &legacy_setup, test_pt_ ## name }
|
||||||
|
|
||||||
@ -279,6 +366,8 @@ struct testcase_t pt_tests[] = {
|
|||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
{ "get_extrainfo_string", test_pt_get_extrainfo_string, TT_FORK,
|
{ "get_extrainfo_string", test_pt_get_extrainfo_string, TT_FORK,
|
||||||
NULL, NULL },
|
NULL, NULL },
|
||||||
|
{ "configure_proxy",test_pt_configure_proxy, TT_FORK,
|
||||||
|
NULL, NULL },
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user