diff options
Diffstat (limited to 'src')
47 files changed, 516 insertions, 99 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index 5f59ce32ff..a19ca13f57 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -2755,6 +2755,7 @@ list_deprecated_options(void) static void list_enabled_modules(void) { + printf("%s: %s\n", "relay", have_module_relay() ? "yes" : "no"); printf("%s: %s\n", "dirauth", have_module_dirauth() ? "yes" : "no"); } diff --git a/src/core/include.am b/src/core/include.am index fb2f93d81e..565668abe3 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -72,6 +72,7 @@ LIBTOR_APP_A_SOURCES = \ src/feature/client/circpathbias.c \ src/feature/client/dnsserv.c \ src/feature/client/entrynodes.c \ + src/feature/client/proxymode.c \ src/feature/client/transports.c \ src/feature/control/btrack.c \ src/feature/control/btrack_circuit.c \ @@ -146,7 +147,6 @@ LIBTOR_APP_A_SOURCES = \ src/feature/relay/relay_sys.c \ src/feature/relay/router.c \ src/feature/relay/routerkeys.c \ - src/feature/relay/routermode.c \ src/feature/relay/selftest.c \ src/feature/rend/rendcache.c \ src/feature/rend/rendclient.c \ @@ -170,6 +170,10 @@ endif # LIBTOR_APP_TESTING_A_SOURCES = $(LIBTOR_APP_A_SOURCES) +# The Relay module. +MODULE_RELAY_SOURCES = \ + src/feature/relay/routermode.c + # The Directory Authority module. MODULE_DIRAUTH_SOURCES = \ src/feature/dirauth/authmode.c \ @@ -189,6 +193,10 @@ MODULE_DIRAUTH_SOURCES = \ src/feature/dirauth/shared_random_state.c \ src/feature/dirauth/voteflags.c +if BUILD_MODULE_RELAY +LIBTOR_APP_A_SOURCES += $(MODULE_RELAY_SOURCES) +endif + if BUILD_MODULE_DIRAUTH LIBTOR_APP_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) endif @@ -197,6 +205,7 @@ src_core_libtor_app_a_SOURCES = $(LIBTOR_APP_A_SOURCES) if UNITTESTS_ENABLED # Add the sources of the modules that are needed for tests to work here. +LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_RELAY_SOURCES) LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES) src_core_libtor_app_testing_a_SOURCES = $(LIBTOR_APP_TESTING_A_SOURCES) @@ -306,6 +315,7 @@ noinst_HEADERS += \ src/feature/client/circpathbias.h \ src/feature/client/dnsserv.h \ src/feature/client/entrynodes.h \ + src/feature/client/proxymode.h \ src/feature/client/transports.h \ src/feature/control/btrack_circuit.h \ src/feature/control/btrack_orconn.h \ @@ -324,7 +334,7 @@ noinst_HEADERS += \ src/feature/control/fmt_serverstatus.h \ src/feature/control/getinfo_geoip.h \ src/feature/dirauth/authmode.h \ - src/feature/dirauth/bridgeauth.h \ + src/feature/dirauth/bridgeauth.h \ src/feature/dirauth/bwauth.h \ src/feature/dirauth/dirauth_periodic.h \ src/feature/dirauth/dirauth_sys.h \ diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 2f8be9961d..d58f263bdc 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -71,6 +71,7 @@ #include "feature/client/bridges.h" #include "feature/client/dnsserv.h" #include "feature/client/entrynodes.h" +#include "feature/client/proxymode.h" #include "feature/client/transports.h" #include "feature/control/control.h" #include "feature/control/control_events.h" diff --git a/src/core/mainloop/periodic.c b/src/core/mainloop/periodic.c index 51a0165d19..efc6a63165 100644 --- a/src/core/mainloop/periodic.c +++ b/src/core/mainloop/periodic.c @@ -153,6 +153,11 @@ periodic_event_disconnect(periodic_event_item_t *event) { if (!event) return; + + /* First disable the event so we first cancel the event and set its enabled + * flag properly. */ + periodic_event_disable(event); + mainloop_event_free(event->ev); event->last_action_time = 0; } diff --git a/src/core/or/circuitpadding.c b/src/core/or/circuitpadding.c index 99c68d5f6b..178f066baf 100644 --- a/src/core/or/circuitpadding.c +++ b/src/core/or/circuitpadding.c @@ -2179,8 +2179,8 @@ circpad_add_matching_machines(origin_circuit_t *on_circ, circ->padding_machine[i] = NULL; on_circ->padding_negotiation_failed = 1; } else { - /* Success. Don't try any more machines */ - return; + /* Success. Don't try any more machines on this index */ + break; } } } SMARTLIST_FOREACH_END(machine); diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 606c5e2dd2..a74ecbfd54 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -42,6 +42,7 @@ #include "feature/client/bridges.h" #include "feature/client/circpathbias.h" #include "feature/client/entrynodes.h" +#include "feature/client/proxymode.h" #include "feature/control/control_events.h" #include "feature/dircommon/directory.h" #include "feature/hs/hs_circuit.h" diff --git a/src/feature/client/proxymode.c b/src/feature/client/proxymode.c new file mode 100644 index 0000000000..3b5fba5cda --- /dev/null +++ b/src/feature/client/proxymode.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "core/or/or.h" + +#include "app/config/config.h" +#include "core/mainloop/connection.h" +#include "core/or/port_cfg_st.h" +#include "feature/client/proxymode.h" + +/** Return true iff we are trying to proxy client connections. */ +int +proxy_mode(const or_options_t *options) +{ + (void)options; + SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { + if (p->type == CONN_TYPE_AP_LISTENER || + p->type == CONN_TYPE_AP_TRANS_LISTENER || + p->type == CONN_TYPE_AP_DNS_LISTENER || + p->type == CONN_TYPE_AP_NATD_LISTENER) + return 1; + } SMARTLIST_FOREACH_END(p); + return 0; +} diff --git a/src/feature/client/proxymode.h b/src/feature/client/proxymode.h new file mode 100644 index 0000000000..f8352922c7 --- /dev/null +++ b/src/feature/client/proxymode.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file proxymode.h + * \brief Header file for proxymode.c. + **/ + +#ifndef TOR_PROXYMODE_H +#define TOR_PROXYMODE_H + +int proxy_mode(const or_options_t *options); + +#endif diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c index 97bfc8ae30..3f731ac7d4 100644 --- a/src/feature/client/transports.c +++ b/src/feature/client/transports.c @@ -1826,15 +1826,13 @@ managed_proxy_stdout_callback(process_t *process, managed_proxy_t *mp = process_get_data(process); - if (BUG(mp == NULL)) + if (mp == NULL) return; handle_proxy_line(line, mp); - if (proxy_configuration_finished(mp)) { + if (proxy_configuration_finished(mp)) handle_finished_proxy(mp); - tor_assert(mp->conf_state == PT_PROTO_COMPLETED); - } } /** Callback function that is called when our PT process have data on its diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c index 3e31bb9e8f..979fa4480d 100644 --- a/src/feature/control/control_getinfo.c +++ b/src/feature/control/control_getinfo.c @@ -325,6 +325,41 @@ getinfo_helper_current_time(control_connection_t *control_conn, return 0; } +/** GETINFO helper for dumping different consensus flavors + * returns: 0 on success -1 on error. */ +STATIC int +getinfo_helper_current_consensus(consensus_flavor_t flavor, + char** answer, + const char** errmsg) +{ + const char *flavor_name = networkstatus_get_flavor_name(flavor); + if (BUG(!strcmp(flavor_name, "??"))) { + *errmsg = "Internal error: unrecognized flavor name."; + return -1; + } + if (we_want_to_fetch_flavor(get_options(), flavor)) { + /** Check from the cache */ + const cached_dir_t *consensus = dirserv_get_consensus(flavor_name); + if (consensus) { + *answer = tor_strdup(consensus->dir); + } + } + if (!*answer) { /* try loading it from disk */ + + tor_mmap_t *mapped = networkstatus_map_cached_consensus(flavor_name); + if (mapped) { + *answer = tor_memdup_nulterm(mapped->data, mapped->size); + tor_munmap_file(mapped); + } + if (!*answer) { /* generate an error */ + *errmsg = "Could not open cached consensus. " + "Make sure FetchUselessDescriptors is set to 1."; + return -1; + } + } + return 0; +} + /** Implementation helper for GETINFO: knows the answers for questions about * directory information. */ STATIC int @@ -576,23 +611,18 @@ getinfo_helper_dir(control_connection_t *control_conn, smartlist_free(descs); } else if (!strcmpstart(question, "dir/status/")) { *answer = tor_strdup(""); - } else if (!strcmp(question, "dir/status-vote/current/consensus")) { /* v3 */ - if (we_want_to_fetch_flavor(get_options(), FLAV_NS)) { - const cached_dir_t *consensus = dirserv_get_consensus("ns"); - if (consensus) - *answer = tor_strdup(consensus->dir); + } else if (!strcmp(question, "dir/status-vote/current/consensus")) { + int consensus_result = getinfo_helper_current_consensus(FLAV_NS, + answer, errmsg); + if (consensus_result < 0) { + return -1; } - if (!*answer) { /* try loading it from disk */ - tor_mmap_t *mapped = networkstatus_map_cached_consensus("ns"); - if (mapped) { - *answer = tor_memdup_nulterm(mapped->data, mapped->size); - tor_munmap_file(mapped); - } - if (!*answer) { /* generate an error */ - *errmsg = "Could not open cached consensus. " - "Make sure FetchUselessDescriptors is set to 1."; - return -1; - } + } else if (!strcmp(question, + "dir/status-vote/current/consensus-microdesc")) { + int consensus_result = getinfo_helper_current_consensus(FLAV_MICRODESC, + answer, errmsg); + if (consensus_result < 0) { + return -1; } } else if (!strcmp(question, "network-status")) { /* v1 */ static int network_status_warned = 0; @@ -1513,6 +1543,8 @@ static const getinfo_item_t getinfo_items[] = { "v2 networkstatus docs as retrieved from a DirPort."), ITEM("dir/status-vote/current/consensus", dir, "v3 Networkstatus consensus as retrieved from a DirPort."), + ITEM("dir/status-vote/current/consensus-microdesc", dir, + "v3 Microdescriptor consensus as retrieved from a DirPort."), ITEM("exit-policy/default", policies, "The default value appended to the configured exit policy."), ITEM("exit-policy/reject-private/default", policies, diff --git a/src/feature/control/control_getinfo.h b/src/feature/control/control_getinfo.h index 52978686d8..86aaf7c4f7 100644 --- a/src/feature/control/control_getinfo.h +++ b/src/feature/control/control_getinfo.h @@ -48,6 +48,10 @@ STATIC int getinfo_helper_downloads( control_connection_t *control_conn, const char *question, char **answer, const char **errmsg); +STATIC int getinfo_helper_current_consensus( + consensus_flavor_t flavor, + char **answer, + const char **errmsg); STATIC int getinfo_helper_dir( control_connection_t *control_conn, const char *question, char **answer, diff --git a/src/feature/dirauth/authmode.h b/src/feature/dirauth/authmode.h index bfd5f4dc04..11bc40d8d1 100644 --- a/src/feature/dirauth/authmode.h +++ b/src/feature/dirauth/authmode.h @@ -27,6 +27,7 @@ authdir_mode_v3(const or_options_t *options) return authdir_mode(options) && options->V3AuthoritativeDir != 0; } +/* Is the dirauth module enabled? */ #define have_module_dirauth() (1) #else /* !defined(HAVE_MODULE_DIRAUTH) */ diff --git a/src/feature/dircache/dirserv.c b/src/feature/dircache/dirserv.c index 79400bf15f..85331bfeaa 100644 --- a/src/feature/dircache/dirserv.c +++ b/src/feature/dircache/dirserv.c @@ -259,8 +259,8 @@ dirserv_set_cached_consensus_networkstatus(const char *networkstatus, /** Return the latest downloaded consensus networkstatus in encoded, signed, * optionally compressed format, suitable for sending to clients. */ -cached_dir_t * -dirserv_get_consensus(const char *flavor_name) +MOCK_IMPL(cached_dir_t *, +dirserv_get_consensus,(const char *flavor_name)) { if (!cached_consensuses) return NULL; diff --git a/src/feature/dircache/dirserv.h b/src/feature/dircache/dirserv.h index 7f944459da..0c15c9ad19 100644 --- a/src/feature/dircache/dirserv.h +++ b/src/feature/dircache/dirserv.h @@ -82,7 +82,7 @@ int directory_permits_begindir_requests(const or_options_t *options); int directory_too_idle_to_fetch_descriptors(const or_options_t *options, time_t now); -cached_dir_t *dirserv_get_consensus(const char *flavor_name); +MOCK_DECL(cached_dir_t *, dirserv_get_consensus, (const char *flavor_name)); void dirserv_set_cached_consensus_networkstatus(const char *consensus, size_t consensus_len, const char *flavor_name, diff --git a/src/feature/hibernate/hibernate.c b/src/feature/hibernate/hibernate.c index 674fe3c813..f7847d9a16 100644 --- a/src/feature/hibernate/hibernate.c +++ b/src/feature/hibernate/hibernate.c @@ -67,7 +67,7 @@ static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL; /** If are hibernating, when do we plan to wake up? Set to 0 if we * aren't hibernating. */ static time_t hibernate_end_time = 0; -/** If we are shutting down, when do we plan finally exit? Set to 0 if we +/** If we are shutting down, when do we plan to finally exit? Set to 0 if we * aren't shutting down. (This is obsolete; scheduled shutdowns are supposed * to happen from mainloop_schedule_shutdown() now.) */ static time_t shutdown_time = 0; @@ -562,7 +562,7 @@ time_to_record_bandwidth_usage(time_t now) /* Note every 600 sec */ #define NOTE_INTERVAL (600) /* Or every 20 megabytes */ -#define NOTE_BYTES 20*(1024*1024) +#define NOTE_BYTES (20*1024*1024) static uint64_t last_read_bytes_noted = 0; static uint64_t last_written_bytes_noted = 0; static time_t last_time_noted = 0; @@ -815,7 +815,7 @@ hibernate_soft_limit_reached(void) * We want to stop accepting connections when ALL of the following are true: * - We expect to use up the remaining bytes in under 3 hours * - We have used up 95% of our bytes. - * - We have less than 500MB of bytes left. + * - We have less than 500MBytes left. */ uint64_t soft_limit = (uint64_t) (acct_max * SOFT_LIM_PCT); if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) { diff --git a/src/feature/hs/hs_cell.c b/src/feature/hs/hs_cell.c index 2d4a761eb9..eaf8820e9f 100644 --- a/src/feature/hs/hs_cell.c +++ b/src/feature/hs/hs_cell.c @@ -503,8 +503,8 @@ build_establish_intro_dos_extension(const hs_service_config_t *service_config, ssize_t ret; size_t dos_ext_encoded_len; uint8_t *field_array; - trn_cell_extension_field_t *field; - trn_cell_extension_dos_t *dos_ext; + trn_cell_extension_field_t *field = NULL; + trn_cell_extension_dos_t *dos_ext = NULL; tor_assert(service_config); tor_assert(extensions); @@ -530,7 +530,7 @@ build_establish_intro_dos_extension(const hs_service_config_t *service_config, /* Set the field with the encoded DoS extension. */ ret = trn_cell_extension_dos_encoded_len(dos_ext); if (BUG(ret <= 0)) { - return -1; + goto err; } dos_ext_encoded_len = ret; /* Set length field and the field array size length. */ @@ -541,7 +541,7 @@ build_establish_intro_dos_extension(const hs_service_config_t *service_config, ret = trn_cell_extension_dos_encode(field_array, trn_cell_extension_field_getlen_field(field), dos_ext); if (BUG(ret <= 0)) { - return -1; + goto err; } tor_assert(ret == (ssize_t) dos_ext_encoded_len); @@ -557,6 +557,11 @@ build_establish_intro_dos_extension(const hs_service_config_t *service_config, trn_cell_extension_dos_free(dos_ext); return 0; + + err: + trn_cell_extension_field_free(field); + trn_cell_extension_dos_free(dos_ext); + return -1; } /* ========== */ diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c index 496bafb865..b4b98301b0 100644 --- a/src/feature/nodelist/networkstatus.c +++ b/src/feature/nodelist/networkstatus.c @@ -216,10 +216,10 @@ networkstatus_reset_download_failures(void) } /** Return the filename used to cache the consensus of a given flavor */ -static char * -networkstatus_get_cache_fname(int flav, - const char *flavorname, - int unverified_consensus) +MOCK_IMPL(char *, +networkstatus_get_cache_fname,(int flav, + const char *flavorname, + int unverified_consensus)) { char buf[128]; const char *prefix; diff --git a/src/feature/nodelist/networkstatus.h b/src/feature/nodelist/networkstatus.h index 600fd7fbd5..e2c6ba611a 100644 --- a/src/feature/nodelist/networkstatus.h +++ b/src/feature/nodelist/networkstatus.h @@ -16,6 +16,9 @@ void networkstatus_reset_warnings(void); void networkstatus_reset_download_failures(void); +MOCK_DECL(char *,networkstatus_get_cache_fname,(int flav, + const char *flavorname, + int unverified_consensus)); tor_mmap_t *networkstatus_map_cached_consensus(const char *flavorname); int router_reload_consensus_networkstatus(void); void routerstatus_free_(routerstatus_t *rs); diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index ab0762e17e..92803f88a9 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -372,6 +372,8 @@ assert_identity_keys_ok(void) } } +#ifdef HAVE_MODULE_RELAY + /** Returns the current server identity key; requires that the key has * been set, and that we are running as a Tor server. */ @@ -384,6 +386,8 @@ get_server_identity_key,(void)) return server_identitykey; } +#endif + /** Return true iff we are a server and the server identity key * has been set. */ int diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index 55b9ef9e68..a708b24889 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -28,7 +28,13 @@ struct ed25519_keypair_t; MOCK_DECL(crypto_pk_t *,get_onion_key,(void)); time_t get_onion_key_set_at(void); void set_server_identity_key(crypto_pk_t *k); +/* Some compilers are clever enough to know that when relay mode is disabled, + * this function never returns. */ +#ifdef HAVE_MODULE_RELAY MOCK_DECL(crypto_pk_t *,get_server_identity_key,(void)); +#else +#define get_server_identity_key() (tor_abort_(),NULL) +#endif int server_identity_key_is_set(void); void set_client_identity_key(crypto_pk_t *k); crypto_pk_t *get_tlsclient_identity_key(void); diff --git a/src/feature/relay/routermode.c b/src/feature/relay/routermode.c index 2a9ddeac4d..3613841b1e 100644 --- a/src/feature/relay/routermode.c +++ b/src/feature/relay/routermode.c @@ -7,8 +7,6 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "core/mainloop/connection.h" -#include "core/or/port_cfg_st.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" @@ -25,21 +23,6 @@ dir_server_mode(const or_options_t *options) (server_mode(options) && router_has_bandwidth_to_be_dirserver(options)); } -/** Return true iff we are trying to proxy client connections. */ -int -proxy_mode(const or_options_t *options) -{ - (void)options; - SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) { - if (p->type == CONN_TYPE_AP_LISTENER || - p->type == CONN_TYPE_AP_TRANS_LISTENER || - p->type == CONN_TYPE_AP_DNS_LISTENER || - p->type == CONN_TYPE_AP_NATD_LISTENER) - return 1; - } SMARTLIST_FOREACH_END(p); - return 0; -} - /** Return true iff we are trying to be a server. */ MOCK_IMPL(int, diff --git a/src/feature/relay/routermode.h b/src/feature/relay/routermode.h index be535af478..f6195a8698 100644 --- a/src/feature/relay/routermode.h +++ b/src/feature/relay/routermode.h @@ -12,13 +12,31 @@ #ifndef TOR_ROUTERMODE_H #define TOR_ROUTERMODE_H +#ifdef HAVE_MODULE_RELAY + int dir_server_mode(const or_options_t *options); MOCK_DECL(int, server_mode, (const or_options_t *options)); MOCK_DECL(int, public_server_mode, (const or_options_t *options)); MOCK_DECL(int, advertised_server_mode, (void)); -int proxy_mode(const or_options_t *options); void set_server_advertised(int s); +/** Is the relay module enabled? */ +#define have_module_relay() (1) + +#else + +#define dir_server_mode(options) (((void)(options)),0) +#define server_mode(options) (((void)(options)),0) +#define public_server_mode(options) (((void)(options)),0) +#define advertised_server_mode() (0) + +/* We shouldn't be publishing descriptors when relay mode is disabled. */ +#define set_server_advertised(s) tor_assert_nonfatal(!(s)) + +#define have_module_relay() (0) + +#endif + #endif /* !defined(TOR_ROUTERMODE_H) */ diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c index 4d8a21e6a1..e0cf06b9df 100644 --- a/src/feature/rend/rendservice.c +++ b/src/feature/rend/rendservice.c @@ -3999,7 +3999,7 @@ remove_invalid_intro_points(rend_service_t *service, * accounted for when considiring uploading a descriptor. */ intro->circuit_established = 0; - /* Node is gone or we've reached our maximum circuit creationg retry + /* Node is gone or we've reached our maximum circuit creation retry * count, clean up everything, we'll find a new one. */ if (node == NULL || intro->circuit_retries >= MAX_INTRO_POINT_CIRCUIT_RETRIES) { diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index bc3ca286ec..ce8ddcd7c0 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -85,7 +85,7 @@ static pthread_mutex_t cb_buf_mutex = PTHREAD_MUTEX_INITIALIZER; /** Lock and return a static stack pointer buffer that can hold up to * MAX_DEPTH function pointers. */ -static void * +static void ** lock_cb_buf(void) { /* Lock the mutex first, before even declaring the buffer. */ @@ -102,7 +102,7 @@ lock_cb_buf(void) /** Unlock the static stack pointer buffer. */ static void -unlock_cb_buf(void *cb_buf) +unlock_cb_buf(void **cb_buf) { memset(cb_buf, 0, SIZEOF_CB_BUF); pthread_mutex_unlock(&cb_buf_mutex); @@ -149,7 +149,7 @@ log_backtrace_impl(int severity, log_domain_mask_t domain, const char *msg, char **symbols; size_t i; - void *cb_buf = lock_cb_buf(); + void **cb_buf = lock_cb_buf(); depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, (int)depth); @@ -183,7 +183,7 @@ crash_handler(int sig, siginfo_t *si, void *ctx_) int n_fds, i; const int *fds = NULL; - void *cb_buf = lock_cb_buf(); + void **cb_buf = lock_cb_buf(); (void) si; @@ -214,7 +214,7 @@ dump_stack_symbols_to_error_fds(void) const int *fds = NULL; size_t depth; - void *cb_buf = lock_cb_buf(); + void **cb_buf = lock_cb_buf(); depth = backtrace(cb_buf, MAX_DEPTH); @@ -256,7 +256,7 @@ install_bt_handler(void) * libc has pre-loaded the symbols we need to dump things, so that later * reads won't be denied by the sandbox code */ char **symbols; - void *cb_buf = lock_cb_buf(); + void **cb_buf = lock_cb_buf(); size_t depth = backtrace(cb_buf, MAX_DEPTH); symbols = backtrace_symbols(cb_buf, (int) depth); if (symbols) diff --git a/src/lib/fs/mmap.c b/src/lib/fs/mmap.c index f71c0cff7a..9d50a476bd 100644 --- a/src/lib/fs/mmap.c +++ b/src/lib/fs/mmap.c @@ -42,8 +42,8 @@ * failure, return NULL. Sets errno properly, using ERANGE to mean * "empty file". Must only be called on trusted Tor-owned files, as changing * the underlying file's size causes unspecified behavior. */ -tor_mmap_t * -tor_mmap_file(const char *filename) +MOCK_IMPL(tor_mmap_t *, +tor_mmap_file,(const char *filename)) { int fd; /* router file */ char *string; @@ -111,8 +111,8 @@ tor_mmap_file(const char *filename) } /** Release storage held for a memory mapping; returns 0 on success, * or -1 on failure (and logs a warning). */ -int -tor_munmap_file(tor_mmap_t *handle) +MOCK_IMPL(int, +tor_munmap_file,(tor_mmap_t *handle)) { int res; @@ -132,8 +132,8 @@ tor_munmap_file(tor_mmap_t *handle) return res; } #elif defined(_WIN32) -tor_mmap_t * -tor_mmap_file(const char *filename) +MOCK_IMPL(tor_mmap_t *, +tor_mmap_file,(const char *filename)) { TCHAR tfilename[MAX_PATH]= {0}; tor_mmap_t *res = tor_malloc_zero(sizeof(tor_mmap_t)); @@ -213,8 +213,8 @@ tor_mmap_file(const char *filename) } /* Unmap the file, and return 0 for success or -1 for failure */ -int -tor_munmap_file(tor_mmap_t *handle) +MOCK_IMPL(int, +tor_munmap_file,(tor_mmap_t *handle)) { if (handle == NULL) return 0; diff --git a/src/lib/fs/mmap.h b/src/lib/fs/mmap.h index 61aad544b2..beb0535109 100644 --- a/src/lib/fs/mmap.h +++ b/src/lib/fs/mmap.h @@ -13,6 +13,7 @@ #define TOR_MMAP_H #include "lib/cc/compat_compiler.h" +#include "lib/testsupport/testsupport.h" #include <stddef.h> #ifdef _WIN32 @@ -35,7 +36,7 @@ typedef struct tor_mmap_t { } tor_mmap_t; -tor_mmap_t *tor_mmap_file(const char *filename); -int tor_munmap_file(tor_mmap_t *handle); +MOCK_DECL(tor_mmap_t *, tor_mmap_file, (const char *filename)); +MOCK_DECL(int, tor_munmap_file, (tor_mmap_t *handle)); #endif /* !defined(TOR_MMAP_H) */ diff --git a/src/lib/process/process_unix.c b/src/lib/process/process_unix.c index 332b432c54..8191bdc1f0 100644 --- a/src/lib/process/process_unix.c +++ b/src/lib/process/process_unix.c @@ -253,22 +253,15 @@ process_unix_exec(process_t *process) process_environment_t *env = process_get_environment(process); /* Call the requested program. */ - retval = execve(argv[0], argv, env->unixoid_environment_block); + execve(argv[0], argv, env->unixoid_environment_block); /* If we made it here it is because execve failed :-( */ - if (-1 == retval) - fprintf(stderr, "Call to execve() failed: %s", strerror(errno)); - tor_free(argv); process_environment_free(env); - tor_assert_unreached(); - error: - /* LCOV_EXCL_START */ fprintf(stderr, "Error from child process: %s", strerror(errno)); _exit(1); - /* LCOV_EXCL_STOP */ } /* We are in the parent process. */ diff --git a/src/lib/process/process_win32.c b/src/lib/process/process_win32.c index 624333d4a3..7e4082ad13 100644 --- a/src/lib/process/process_win32.c +++ b/src/lib/process/process_win32.c @@ -234,6 +234,24 @@ process_win32_exec(process_t *process) CloseHandle(stdin_pipe_read); CloseHandle(stdin_pipe_write); + /* In the Unix backend, we do not get an error in the Tor process when a + * child process fails to spawn its target executable since we need to + * first do the fork() call in the Tor process and then the child process + * is responsible for doing the call to execve(). + * + * This means that the user of the process_exec() API must check for + * whether it returns PROCESS_STATUS_ERROR, which will rarely happen on + * Unix, but will happen for error cases on Windows where it does not + * happen on Unix. For example: when the target executable does not exist + * on the file system. + * + * To have somewhat feature compatibility between the Unix and the Windows + * backend, we here notify the process_t owner that the process have exited + * (even though it never managed to run) to ensure that the exit callback + * is executed. + */ + process_notify_event_exit(process, 0); + return PROCESS_STATUS_ERROR; } diff --git a/src/test/conf_examples/bridgeauth_1/expected b/src/test/conf_examples/bridgeauth_1/expected new file mode 100644 index 0000000000..d43aaf2c8b --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected @@ -0,0 +1,7 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +Nickname Unnamed +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/expected_no_dirauth b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth new file mode 100644 index 0000000000..d43aaf2c8b --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth @@ -0,0 +1,7 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +Nickname Unnamed +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..e059d79971 --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/expected_no_dirauth_relay @@ -0,0 +1,6 @@ +Address 198.51.100.123 +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 +ContactInfo tor_parse_test@example.com +DirPort 80 +ORPort 443 diff --git a/src/test/conf_examples/bridgeauth_1/torrc b/src/test/conf_examples/bridgeauth_1/torrc new file mode 100644 index 0000000000..740bc6c2eb --- /dev/null +++ b/src/test/conf_examples/bridgeauth_1/torrc @@ -0,0 +1,8 @@ +AuthoritativeDirectory 1 +BridgeAuthoritativeDir 1 + +ContactInfo tor_parse_test@example.com + +Address 198.51.100.123 +ORPort 443 +DirPort 80 diff --git a/src/test/conf_examples/dirauth_1/expected b/src/test/conf_examples/dirauth_1/expected new file mode 100644 index 0000000000..901f7d947f --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected @@ -0,0 +1,8 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +DownloadExtraInfo 1 +Nickname Unnamed +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/expected_no_dirauth b/src/test/conf_examples/dirauth_1/expected_no_dirauth new file mode 100644 index 0000000000..f006c6f8f2 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected_no_dirauth @@ -0,0 +1,7 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +Nickname Unnamed +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay b/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..4b9ad49bb2 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/expected_no_dirauth_relay @@ -0,0 +1,6 @@ +Address 192.0.2.1 +AuthoritativeDirectory 1 +ContactInfo tor_parse_test@example.net +DirPort 9030 +ORPort 9001 +V3AuthoritativeDirectory 1 diff --git a/src/test/conf_examples/dirauth_1/torrc b/src/test/conf_examples/dirauth_1/torrc new file mode 100644 index 0000000000..b870e6e8e0 --- /dev/null +++ b/src/test/conf_examples/dirauth_1/torrc @@ -0,0 +1,8 @@ +AuthoritativeDirectory 1 +V3AuthoritativeDirectory 1 + +ContactInfo tor_parse_test@example.net + +Address 192.0.2.1 +ORPort 9001 +DirPort 9030 diff --git a/src/test/conf_examples/ops_1/expected_no_dirauth_relay b/src/test/conf_examples/ops_1/expected_no_dirauth_relay new file mode 100644 index 0000000000..2bb9bfa132 --- /dev/null +++ b/src/test/conf_examples/ops_1/expected_no_dirauth_relay @@ -0,0 +1 @@ +ORPort 1000 diff --git a/src/test/conf_examples/ops_3/expected_no_dirauth_relay b/src/test/conf_examples/ops_3/expected_no_dirauth_relay new file mode 100644 index 0000000000..93dea50eeb --- /dev/null +++ b/src/test/conf_examples/ops_3/expected_no_dirauth_relay @@ -0,0 +1,2 @@ +ORPort 9999 +ORPort 1000 diff --git a/src/test/conf_examples/ops_4/expected_no_dirauth_relay b/src/test/conf_examples/ops_4/expected_no_dirauth_relay new file mode 100644 index 0000000000..56b3a5b71f --- /dev/null +++ b/src/test/conf_examples/ops_4/expected_no_dirauth_relay @@ -0,0 +1 @@ +ORPort 9099 diff --git a/src/test/conf_examples/ops_5/expected_no_dirauth_relay b/src/test/conf_examples/ops_5/expected_no_dirauth_relay new file mode 100644 index 0000000000..834a785090 --- /dev/null +++ b/src/test/conf_examples/ops_5/expected_no_dirauth_relay @@ -0,0 +1,2 @@ +ORPort 9000 +ORPort 9099 diff --git a/src/test/test_controller.c b/src/test/test_controller.c index 55eb79e448..8d9c3e8eaf 100644 --- a/src/test/test_controller.c +++ b/src/test/test_controller.c @@ -27,6 +27,7 @@ #include "feature/dirclient/download_status_st.h" #include "feature/nodelist/microdesc_st.h" #include "feature/nodelist/node_st.h" +#include "feature/dircache/dirserv.c" typedef struct { const char *input; @@ -1691,6 +1692,138 @@ test_download_status_bridge(void *arg) return; } +/** Mock cached consensus */ +static cached_dir_t *mock_ns_consensus_cache; +static cached_dir_t *mock_microdesc_consensus_cache; + +/** Mock the function that retrieves consensus from cache. These use a + * global variable so that they can be cleared from within the test. + * The actual code retains the pointer to the consensus data, but + * we are doing this here, to prevent memory leaks + * from within the tests */ +static cached_dir_t * +mock_dirserv_get_consensus(const char *flavor_name) +{ + if (!strcmp(flavor_name, "ns")) { + mock_ns_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); + mock_ns_consensus_cache->dir = tor_strdup("mock_ns_consensus"); + return mock_ns_consensus_cache; + } else { + mock_microdesc_consensus_cache = tor_malloc_zero(sizeof(cached_dir_t)); + mock_microdesc_consensus_cache->dir = tor_strdup( + "mock_microdesc_consensus"); + return mock_microdesc_consensus_cache; + } +} + +/** Mock the function that retrieves consensuses + * from a files in the directory. */ +static tor_mmap_t * +mock_tor_mmap_file(const char* filename) +{ + tor_mmap_t *res; + res = tor_malloc_zero(sizeof(tor_mmap_t)); + if (strstr(filename, "cached-consensus") != NULL) { + res->data = "mock_ns_consensus"; + } else if (strstr(filename, "cached-microdesc-consensus") != NULL) { + res->data = "mock_microdesc_consensus"; + } else { + res->data = "."; + } + res->size = strlen(res->data); + return res; +} + +/** Mock the function that clears file data + * loaded into the memory */ +static int +mock_tor_munmap_file(tor_mmap_t *handle) +{ + tor_free(handle); + return 0; +} + +static void +test_getinfo_helper_current_consensus_from_file(void *arg) +{ + /* We just need one of these to pass, it doesn't matter what's in it */ + control_connection_t dummy; + /* Get results out */ + char *answer = NULL; + const char *errmsg = NULL; + + (void)arg; + + MOCK(tor_mmap_file, mock_tor_mmap_file); + MOCK(tor_munmap_file, mock_tor_munmap_file); + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_ns_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(answer); + errmsg = NULL; + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus-microdesc", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + errmsg = NULL; + + done: + tor_free(answer); + UNMOCK(tor_mmap_file); + UNMOCK(tor_munmap_file); + return; +} + +static void +test_getinfo_helper_current_consensus_from_cache(void *arg) +{ + /* We just need one of these to pass, it doesn't matter what's in it */ + control_connection_t dummy; + /* Get results out */ + char *answer = NULL; + const char *errmsg = NULL; + + (void)arg; + or_options_t *options = get_options_mutable(); + options->FetchUselessDescriptors = 1; + MOCK(dirserv_get_consensus, mock_dirserv_get_consensus); + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_ns_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(answer); + tor_free(mock_ns_consensus_cache->dir); + tor_free(mock_ns_consensus_cache); + errmsg = NULL; + + getinfo_helper_dir(&dummy, + "dir/status-vote/current/consensus-microdesc", + &answer, + &errmsg); + tt_str_op(answer, OP_EQ, "mock_microdesc_consensus"); + tt_ptr_op(errmsg, OP_EQ, NULL); + tor_free(mock_microdesc_consensus_cache->dir); + tor_free(answer); + errmsg = NULL; + + done: + options->FetchUselessDescriptors = 0; + tor_free(answer); + tor_free(mock_microdesc_consensus_cache); + UNMOCK(dirserv_get_consensus); + return; +} + /** Set timeval to a mock date and time. This is necessary * to make tor_gettimeofday() mockable. */ static void @@ -1840,6 +1973,10 @@ struct testcase_t controller_tests[] = { NULL }, { "download_status_consensus", test_download_status_consensus, 0, NULL, NULL }, + {"getinfo_helper_current_consensus_from_cache", + test_getinfo_helper_current_consensus_from_cache, 0, NULL, NULL }, + {"getinfo_helper_current_consensus_from_file", + test_getinfo_helper_current_consensus_from_file, 0, NULL, NULL }, { "download_status_cert", test_download_status_cert, 0, NULL, NULL }, { "download_status_desc", test_download_status_desc, 0, NULL, NULL }, diff --git a/src/test/test_key_expiration.sh b/src/test/test_key_expiration.sh index 54abb4a2fa..9d42c1cc4c 100755 --- a/src/test/test_key_expiration.sh +++ b/src/test/test_key_expiration.sh @@ -28,6 +28,11 @@ else TOR_BINARY="${TESTING_TOR_BINARY}" fi +if "$TOR_BINARY" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi + if [ $# -ge 1 ]; then dflt=0 else diff --git a/src/test/test_keygen.sh b/src/test/test_keygen.sh index cbdfd1909c..57df888274 100755 --- a/src/test/test_keygen.sh +++ b/src/test/test_keygen.sh @@ -28,7 +28,10 @@ else TOR_BINARY="${TESTING_TOR_BINARY}" fi - +if "$TOR_BINARY" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi if [ $# -ge 1 ]; then dflt=0 diff --git a/src/test/test_parseconf.sh b/src/test/test_parseconf.sh index eeb80cdfa7..d46be5e5cd 100755 --- a/src/test/test_parseconf.sh +++ b/src/test/test_parseconf.sh @@ -36,6 +36,27 @@ # matched by some line in the output of "--verify-config", which must # fail. Exactly one of "expected" or "error" must be present, or the # test will fail. +# +# {expected,error}_no_${TOR_MODULES_DISABLED} -- If this file is present, +# then the outcome is different when some modules are disabled. If there +# is no result file matching the exact list of disabled modules, the +# standard result file is used. +# +# For example: +# A test that succeeds, regardless of any disabled modules: +# - expected +# A test that has a different result if the relay module is disabled +# (but the same result if just the dirauth module is disabled): +# - expected +# - expected_no_relay_dirauth +# A test that fails if the dirauth module is disabled: +# - expected +# - error_no_dirauth +# - error_no_relay_dirauth +# (Disabling the relay module also disables dirauth module. But we don't +# want to encode that knowledge in this test script, so we supply a +# separate result file for every combination of disabled modules that +# has a different result.) umask 077 set -e @@ -64,6 +85,11 @@ fi TOR_BINARY="$(abspath "$TOR_BINARY")" +TOR_MODULES_DISABLED="$("$TOR_BINARY" --list-modules | grep ": no" \ + | cut -d ":" -f1 | sort | tr "\n" "_")" +# Remove the last underscore, if there is one +TOR_MODULES_DISABLED=${TOR_MODULES_DISABLED%_} + # make a safe space for temporary files DATA_DIR=$(mktemp -d -t tor_parseconf_tests.XXXXXX) trap 'rm -rf "$DATA_DIR"' 0 @@ -125,12 +151,30 @@ for dir in "${EXAMPLEDIR}"/*; do CMDLINE="" fi - if test -f "./expected"; then - if test -f "./error"; then - echo "FAIL: Found both ${dir}/expected and ${dir}/error." - echo "(Only one of these files should exist.)" - exit $EXITCODE + # If tor has some modules disabled, search for a custom result file for + # the disabled modules + for suffix in "_no_$TOR_MODULES_DISABLED" ""; do + + if test -f "./expected${suffix}"; then + + # Check for broken configs + if test -f "./error${suffix}"; then + echo "FAIL: Found both ${dir}/expected${suffix}" + echo "and ${dir}/error${suffix}." + echo "(Only one of these files should exist.)" + exit $EXITCODE + fi + + EXPECTED="./expected${suffix}" + break + + elif test -f "./error${suffix}"; then + ERROR="./error${suffix}" + break fi + done + + if test -f "$EXPECTED"; then # This case should succeed: run dump-config and see if it does. @@ -141,7 +185,7 @@ for dir in "${EXAMPLEDIR}"/*; do | "${FILTER}" > "${DATA_DIR}/output.${testname}" \ || die "Failure: Tor exited." - if cmp "./expected" "${DATA_DIR}/output.${testname}">/dev/null ; then + if cmp "$EXPECTED" "${DATA_DIR}/output.${testname}">/dev/null ; then # Check round-trip. "${TOR_BINARY}" -f "${DATA_DIR}/output.${testname}" \ --defaults-torrc "${DATA_DIR}/empty" \ @@ -166,11 +210,11 @@ for dir in "${EXAMPLEDIR}"/*; do --verify-config \ ${CMDLINE} || true fi - diff -u "./expected" "${DATA_DIR}/output.${testname}" || /bin/true + diff -u "$EXPECTED" "${DATA_DIR}/output.${testname}" || /bin/true exit $EXITCODE fi - elif test -f "./error"; then + elif test -f "$ERROR"; then # This case should fail: run verify-config and see if it does. "${TOR_BINARY}" --verify-config \ @@ -180,7 +224,7 @@ for dir in "${EXAMPLEDIR}"/*; do > "${DATA_DIR}/output.${testname}" \ && die "Failure: Tor did not report an error." - expect_err="$(cat ./error)" + expect_err="$(cat $ERROR)" if grep "${expect_err}" "${DATA_DIR}/output.${testname}" >/dev/null; then echo "OK" else @@ -195,7 +239,7 @@ for dir in "${EXAMPLEDIR}"/*; do # This case is not actually configured with a success or a failure. # call that an error. - echo "FAIL: Did not find ${dir}/expected or ${dir}/error." + echo "FAIL: Did not find ${dir}/*expected or ${dir}/*error." exit $EXITCODE fi diff --git a/src/test/test_process_slow.c b/src/test/test_process_slow.c index 91252c725d..f311e8b293 100644 --- a/src/test/test_process_slow.c +++ b/src/test/test_process_slow.c @@ -328,8 +328,38 @@ test_callbacks_terminate(void *arg) process_free(process); } +static void +test_nonexistent_executable(void *arg) +{ + (void)arg; + + /* Process callback data. */ + process_data_t *process_data = process_data_new(); + + /* Setup our process. */ + process_t *process = process_new("binary-does-not-exist"); + process_set_data(process, process_data); + process_set_exit_callback(process, process_exit_callback); + + /* Run our process. */ + process_exec(process); + + /* Start our main loop. */ + run_main_loop(process_data); + + /* Ensure that the exit callback was actually called even though the binary + * did not exist. + */ + tt_assert(process_data->did_exit); + + done: + process_data_free(process_data); + process_free(process); +} + struct testcase_t slow_process_tests[] = { { "callbacks", test_callbacks, 0, NULL, NULL }, { "callbacks_terminate", test_callbacks_terminate, 0, NULL, NULL }, + { "nonexistent_executable", test_nonexistent_executable, 0, NULL, NULL }, END_OF_TESTCASES }; diff --git a/src/test/test_rebind.py b/src/test/test_rebind.py index 232b200326..c9b9200b2d 100644 --- a/src/test/test_rebind.py +++ b/src/test/test_rebind.py @@ -32,15 +32,17 @@ def wait_for_log(s): cutoff = time.time() + LOG_TIMEOUT while time.time() < cutoff: l = tor_process.stdout.readline() - l = l.decode('utf8') + l = l.decode('utf8', 'backslashreplace') if s in l: logging.info('Tor logged: "{}"'.format(l.strip())) return - logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) # readline() returns a blank string when there is no output # avoid busy-waiting - if len(s) == 0: + if len(l) == 0: + logging.debug('Tor has not logged anything, waiting for "{}"'.format(s)) time.sleep(LOG_WAIT) + else: + logging.info('Tor logged: "{}", waiting for "{}"'.format(l.strip(), s)) fail('Could not find "{}" in logs after {} seconds'.format(s, LOG_TIMEOUT)) def pick_random_port(): @@ -120,18 +122,18 @@ if control_socket.connect_ex(('127.0.0.1', control_port)): tor_process.terminate() fail('Cannot connect to ControlPort') -control_socket.sendall('AUTHENTICATE \r\n'.encode('utf8')) -control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('AUTHENTICATE \r\n'.encode('ascii')) +control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('utf8')) +control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('ascii')) wait_for_log('Opened Socks listener') try_connecting_to_socksport() -control_socket.sendall('SIGNAL HALT\r\n'.encode('utf8')) +control_socket.sendall('SIGNAL HALT\r\n'.encode('ascii')) wait_for_log('exiting cleanly') logging.info('OK') diff --git a/src/test/test_zero_length_keys.sh b/src/test/test_zero_length_keys.sh index 84ca513b0a..eeabab352d 100755 --- a/src/test/test_zero_length_keys.sh +++ b/src/test/test_zero_length_keys.sh @@ -1,6 +1,11 @@ #!/bin/sh # Check that tor regenerates keys when key files are zero-length +if "${builddir:-.}/src/app/tor" --list-modules | grep -q "relay: no"; then + echo "This test requires the relay module. Skipping." >&2 + exit 77 +fi + exitcode=0 "${SHELL:-sh}" "${abs_top_srcdir:-.}/src/test/zero_length_keys.sh" "${builddir:-.}/src/app/tor" -z || exitcode=1 |