mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
hs_pow: Make proof-of-work support optional in configure
This adds a new "pow" module for the user-visible proof of work support in ./configure, and this disables src/feature/hs/hs_pow at compile-time. Signed-off-by: Micah Elizabeth Scott <beth@torproject.org>
This commit is contained in:
parent
9d1a573977
commit
dcb9c4df67
37
configure.ac
37
configure.ac
@ -373,7 +373,7 @@ dnl Tor modules options. These options are namespaced with --disable-module-XXX
|
||||
dnl ---
|
||||
|
||||
dnl All our modules.
|
||||
m4_define(MODULES, relay dirauth dircache)
|
||||
m4_define([MODULES], [relay dirauth dircache pow])
|
||||
|
||||
# Some modules are only disabled through another option. For those, we don't
|
||||
# want to print the help in the summary at the end of the configure. Any entry
|
||||
@ -382,6 +382,9 @@ m4_define(MODULES, relay dirauth dircache)
|
||||
m4_set_add_all([MODULES_WITH_NO_OPTIONS], [dircache])
|
||||
|
||||
dnl Relay module.
|
||||
m4_define([module_option_hints(relay)],
|
||||
[AS_IF([test "x$value" = x1], [HINT_OPT([--disable-module-relay])],
|
||||
[HINT_NONE])])
|
||||
AC_ARG_ENABLE([module-relay],
|
||||
AS_HELP_STRING([--disable-module-relay],
|
||||
[Build tor without the Relay modules: tor can not run as a relay, bridge, or authority. Implies --disable-module-dirauth]))
|
||||
@ -399,6 +402,9 @@ AM_COND_IF(BUILD_MODULE_DIRCACHE,
|
||||
[Compile with directory cache support]))
|
||||
|
||||
dnl Directory Authority module.
|
||||
m4_define([module_option_hints(dirauth)],
|
||||
[AS_IF([test "x$value" = x1], [HINT_OPT([--disable-module-dirauth])],
|
||||
[HINT_NONE])])
|
||||
AC_ARG_ENABLE([module-dirauth],
|
||||
AS_HELP_STRING([--disable-module-dirauth],
|
||||
[Build tor without the Directory Authority module: tor can not run as a directory authority or bridge authority]))
|
||||
@ -407,6 +413,19 @@ AM_COND_IF(BUILD_MODULE_DIRAUTH,
|
||||
AC_DEFINE([HAVE_MODULE_DIRAUTH], [1],
|
||||
[Compile with Directory Authority feature support]))
|
||||
|
||||
dnl Hidden Service Proof-of-Work module.
|
||||
m4_define([module_option_hints(pow)],
|
||||
[AS_IF([test "x$value" = x1], [HINT_OPT([--disable-module-pow])],
|
||||
[AS_IF([test "x$license_option" != "xGPL"], [HINT_OPT([requires --enable-gpl])],
|
||||
[HINT_NONE])])])
|
||||
AC_ARG_ENABLE([module-pow],
|
||||
AS_HELP_STRING([--disable-module-pow],
|
||||
[Build tor without proof-of-work denial of service mitigation, normally available when building with --enable-gpl]))
|
||||
AM_CONDITIONAL(BUILD_MODULE_POW,
|
||||
[test "x$license_option" = "xGPL" && test "x$enable_module_pow" != "xno"])
|
||||
AM_COND_IF(BUILD_MODULE_POW,
|
||||
AC_DEFINE([HAVE_MODULE_POW], [1], [Compile with proof-of-work support]))
|
||||
|
||||
dnl Helper variables.
|
||||
TOR_MODULES_ALL_ENABLED=
|
||||
AC_DEFUN([ADD_MODULE], [
|
||||
@ -2733,12 +2752,22 @@ PPRINT_PROP_BOOL([Fragile Hardening (--enable-fragile-hardening, dev only)], $va
|
||||
AS_ECHO
|
||||
PPRINT_SUBTITLE([Modules])
|
||||
|
||||
# Modules have documentation hints indicating how they can be enabled
|
||||
# or disabled, and those hints can select which version of our message
|
||||
# to show based on variables at configure-time.
|
||||
#
|
||||
# Each "module_option_hints(<name>)" macro, if it exists, must
|
||||
# visit exactly one HINT_* macro using shell conditionals.
|
||||
|
||||
m4_foreach_w([mname], MODULES,
|
||||
[
|
||||
AM_COND_IF(m4_join([], [BUILD_MODULE_], m4_toupper([]mname[])), value=1, value=0)
|
||||
m4_set_contains([MODULES_WITH_NO_OPTIONS], mname,
|
||||
PPRINT_PROP_BOOL([mname], $value),
|
||||
PPRINT_PROP_BOOL([mname (--disable-module-mname)], $value))
|
||||
m4_pushdef([HINT_OPT], [PPRINT_PROP_BOOL](mname ($1), [[$value]]))
|
||||
m4_pushdef([HINT_NONE], [PPRINT_PROP_BOOL](mname, [[$value]]))
|
||||
m4_ifdef([module_option_hints](mname),
|
||||
[m4_indir([module_option_hints](mname))],
|
||||
[HINT_NONE])
|
||||
m4_popdef([HINT_OPT], [HINT_NONE])
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -88,9 +88,11 @@
|
||||
#include "feature/control/control.h"
|
||||
#include "feature/control/control_auth.h"
|
||||
#include "feature/control/control_events.h"
|
||||
#include "feature/dircache/dirserv.h"
|
||||
#include "feature/dirclient/dirclient_modes.h"
|
||||
#include "feature/hibernate/hibernate.h"
|
||||
#include "feature/hs/hs_config.h"
|
||||
#include "feature/hs/hs_pow.h"
|
||||
#include "feature/metrics/metrics.h"
|
||||
#include "feature/nodelist/dirlist.h"
|
||||
#include "feature/nodelist/networkstatus.h"
|
||||
@ -2731,11 +2733,19 @@ 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");
|
||||
// We don't list dircache, because it cannot be enabled or disabled
|
||||
// independently from relay. Listing it here would proliferate
|
||||
// test variants in test_parseconf.sh to no useful purpose.
|
||||
static const struct {
|
||||
const char *name;
|
||||
bool have;
|
||||
} list[] = {
|
||||
{ "relay", have_module_relay() },
|
||||
{ "dirauth", have_module_dirauth() },
|
||||
{ "dircache", have_module_dircache() },
|
||||
{ "pow", have_module_pow() }
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof list / sizeof list[0]; i++) {
|
||||
printf("%s: %s\n", list[i].name, list[i].have ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
/** Prints compile-time and runtime library versions. */
|
||||
|
@ -17,6 +17,7 @@ if UNITTESTS_ENABLED
|
||||
LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_RELAY_SOURCES)
|
||||
LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRCACHE_SOURCES)
|
||||
LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_DIRAUTH_SOURCES)
|
||||
LIBTOR_APP_TESTING_A_SOURCES += $(MODULE_POW_SOURCES)
|
||||
|
||||
src_core_libtor_app_testing_a_SOURCES = $(LIBTOR_APP_TESTING_A_SOURCES)
|
||||
else
|
||||
|
@ -1369,7 +1369,7 @@ hs_circ_handle_introduce2(const hs_service_t *service,
|
||||
|
||||
/* Add the rendezvous request to the priority queue if PoW defenses are
|
||||
* enabled, otherwise rendezvous as usual. */
|
||||
if (service->config.has_pow_defenses_enabled) {
|
||||
if (have_module_pow() && service->config.has_pow_defenses_enabled) {
|
||||
log_notice(LD_REND,
|
||||
"Adding introduction request to pqueue with effort: %u",
|
||||
data.rdv_data.pow_effort);
|
||||
|
@ -733,7 +733,8 @@ consider_sending_introduce1(origin_circuit_t *intro_circ,
|
||||
|
||||
/* If the descriptor contains PoW parameters then the service is
|
||||
* expecting a PoW solution in the INTRODUCE cell, which we solve here. */
|
||||
if (desc->encrypted_data.pow_params &&
|
||||
if (have_module_pow() &&
|
||||
desc->encrypted_data.pow_params &&
|
||||
desc->encrypted_data.pow_params->suggested_effort > 0) {
|
||||
log_debug(LD_REND, "PoW params present in descriptor.");
|
||||
|
||||
@ -752,9 +753,11 @@ consider_sending_introduce1(origin_circuit_t *intro_circ,
|
||||
|
||||
/* send it to the client-side pow cpuworker for solving. */
|
||||
intro_circ->hs_currently_solving_pow = 1;
|
||||
pow_queue_work(intro_circ->global_identifier,
|
||||
rend_circ->global_identifier,
|
||||
desc->encrypted_data.pow_params);
|
||||
if (0 != hs_pow_queue_work(intro_circ->global_identifier,
|
||||
rend_circ->global_identifier,
|
||||
desc->encrypted_data.pow_params)) {
|
||||
log_debug(LD_REND, "Failed to enqueue PoW request");
|
||||
}
|
||||
|
||||
/* can't proceed with the intro1 cell yet, so yield back to the
|
||||
* main loop */
|
||||
|
@ -327,6 +327,12 @@ config_validate_service(const hs_service_config_t *config)
|
||||
config->pow_queue_burst, config->pow_queue_rate);
|
||||
goto invalid;
|
||||
}
|
||||
if (config->has_pow_defenses_enabled && !have_module_pow()) {
|
||||
log_warn(LD_CONFIG, "Hidden service proof-of-work defenses are enabled "
|
||||
"in our configuration but this build of tor does not "
|
||||
"include the required 'pow' module.");
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
/* Valid. */
|
||||
return 0;
|
||||
|
@ -410,9 +410,9 @@ pow_worker_replyfn(void *work_)
|
||||
* Queue the job of solving the pow in a worker thread.
|
||||
*/
|
||||
int
|
||||
pow_queue_work(uint32_t intro_circ_identifier,
|
||||
uint32_t rend_circ_identifier,
|
||||
const hs_pow_desc_params_t *pow_params)
|
||||
hs_pow_queue_work(uint32_t intro_circ_identifier,
|
||||
uint32_t rend_circ_identifier,
|
||||
const hs_pow_desc_params_t *pow_params)
|
||||
{
|
||||
tor_assert(in_main_thread());
|
||||
|
||||
|
@ -127,6 +127,9 @@ typedef struct hs_pow_solution_t {
|
||||
equix_solution equix_solution;
|
||||
} hs_pow_solution_t;
|
||||
|
||||
#ifdef HAVE_MODULE_POW
|
||||
#define have_module_pow() (1)
|
||||
|
||||
/* API */
|
||||
int hs_pow_solve(const hs_pow_desc_params_t *pow_params,
|
||||
hs_pow_solution_t *pow_solution_out);
|
||||
@ -137,8 +140,54 @@ int hs_pow_verify(const hs_pow_service_state_t *pow_state,
|
||||
void hs_pow_remove_seed_from_cache(uint32_t seed);
|
||||
void hs_pow_free_service_state(hs_pow_service_state_t *state);
|
||||
|
||||
int pow_queue_work(uint32_t intro_circ_identifier,
|
||||
uint32_t rend_circ_identifier,
|
||||
const hs_pow_desc_params_t *pow_params);
|
||||
int hs_pow_queue_work(uint32_t intro_circ_identifier,
|
||||
uint32_t rend_circ_identifier,
|
||||
const hs_pow_desc_params_t *pow_params);
|
||||
|
||||
#else /* !defined(HAVE_MODULE_POW) */
|
||||
#define have_module_pow() (0)
|
||||
|
||||
static inline int
|
||||
hs_pow_solve(const hs_pow_desc_params_t *pow_params,
|
||||
hs_pow_solution_t *pow_solution_out)
|
||||
{
|
||||
(void)pow_params;
|
||||
(void)pow_solution_out;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hs_pow_verify(const hs_pow_service_state_t *pow_state,
|
||||
const hs_pow_solution_t *pow_solution)
|
||||
{
|
||||
(void)pow_state;
|
||||
(void)pow_solution;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hs_pow_remove_seed_from_cache(uint32_t seed)
|
||||
{
|
||||
(void)seed;
|
||||
}
|
||||
|
||||
static inline void
|
||||
hs_pow_free_service_state(hs_pow_service_state_t *state)
|
||||
{
|
||||
(void)state;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hs_pow_queue_work(uint32_t intro_circ_identifier,
|
||||
uint32_t rend_circ_identifier,
|
||||
const hs_pow_desc_params_t *pow_params)
|
||||
{
|
||||
(void)intro_circ_identifier;
|
||||
(void)rend_circ_identifier;
|
||||
(void)pow_params;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_MODULE_POW) */
|
||||
|
||||
#endif /* !defined(TOR_HS_POW_H) */
|
||||
|
@ -2899,7 +2899,7 @@ run_housekeeping_event(time_t now)
|
||||
|
||||
/* Check if we need to initialize or update PoW parameters, if the
|
||||
* defenses are enabled. */
|
||||
if (service->config.has_pow_defenses_enabled) {
|
||||
if (have_module_pow() && service->config.has_pow_defenses_enabled) {
|
||||
pow_housekeeping(service, now);
|
||||
}
|
||||
|
||||
@ -2937,8 +2937,10 @@ run_build_descriptor_event(time_t now)
|
||||
* is useful for newly built descriptors. */
|
||||
update_all_descriptors_intro_points(now);
|
||||
|
||||
/* Update the PoW params if needed. */
|
||||
update_all_descriptors_pow_params(now);
|
||||
if (have_module_pow()) {
|
||||
/* Update the PoW params if needed. */
|
||||
update_all_descriptors_pow_params(now);
|
||||
}
|
||||
}
|
||||
|
||||
/** For the given service, launch any intro point circuits that could be
|
||||
|
@ -15,12 +15,19 @@ LIBTOR_APP_A_SOURCES += \
|
||||
src/feature/hs/hs_intropoint.c \
|
||||
src/feature/hs/hs_metrics.c \
|
||||
src/feature/hs/hs_ob.c \
|
||||
src/feature/hs/hs_pow.c \
|
||||
src/feature/hs/hs_service.c \
|
||||
src/feature/hs/hs_stats.c \
|
||||
src/feature/hs/hs_sys.c \
|
||||
src/feature/hs/hs_metrics_entry.c
|
||||
|
||||
# Proof of Work module
|
||||
MODULE_POW_SOURCES = \
|
||||
src/feature/hs/hs_pow.c
|
||||
|
||||
if BUILD_MODULE_POW
|
||||
LIBTOR_APP_A_SOURCES += $(MODULE_POW_SOURCES)
|
||||
endif
|
||||
|
||||
# ADD_C_FILE: INSERT HEADERS HERE.
|
||||
noinst_HEADERS += \
|
||||
src/feature/hs/hs_cache.h \
|
||||
|
@ -98,6 +98,9 @@
|
||||
# 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.)
|
||||
#
|
||||
# This logic ignores modules that are not listed by --list-modules
|
||||
# (dircache) and some that do not currently affect config parsing (pow).
|
||||
|
||||
umask 077
|
||||
set -e
|
||||
@ -197,6 +200,8 @@ echo "This pattern should not match any log messages" \
|
||||
"$NON_EMPTY"
|
||||
|
||||
STANDARD_LIBS="libevent\\|openssl\\|zlib"
|
||||
MODULES_WITHOUT_CONFIG_TESTS="dircache\\|pow"
|
||||
|
||||
# Lib names are restricted to [a-z0-9]* at the moment
|
||||
# We don't actually want to support foreign accents here
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
@ -229,6 +234,7 @@ TOR_LIBS_ENABLED_SEARCH="$(echo "$TOR_LIBS_ENABLED_SEARCH" | tr ' ' '\n' \
|
||||
| grep -v '^_*$' | tr '\n' ' ')"
|
||||
|
||||
TOR_MODULES_DISABLED="$("$TOR_BINARY" --list-modules | grep ': no' \
|
||||
| grep -v "$MODULES_WITHOUT_CONFIG_TESTS" \
|
||||
| cut -d ':' -f1 | sort | tr '\n' '_')"
|
||||
# Remove the last underscore, if there is one
|
||||
TOR_MODULES_DISABLED=${TOR_MODULES_DISABLED%_}
|
||||
|
Loading…
Reference in New Issue
Block a user