Merge remote-tracking branch 'tor-github/pr/1430'

This commit is contained in:
Nick Mathewson 2019-10-21 12:43:26 -04:00
commit 7dc78aca29
31 changed files with 252 additions and 46 deletions

View File

@ -54,6 +54,8 @@ matrix:
- env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
## We check asciidoc with distcheck, to make sure we remove doc products
- env: DISTCHECK="yes" ASCIIDOC_OPTIONS="" SKIP_MAKE_CHECK="yes"
## We check disable module relay
- env: MODULES_OPTIONS="--disable-module-relay"
## We check disable module dirauth
- env: MODULES_OPTIONS="--disable-module-dirauth"
## We run rust on macOS, because we have seen macOS rust failures before

5
changes/ticket32123 Normal file
View File

@ -0,0 +1,5 @@
o Major features (build system):
- Create an optional relay module, which can be disabled using the
--disable-module-relay configure option. When it is set, also disable
the dirauth module. Add a minimal implemention, which disables the
relay and dircache modes in tor. Closes ticket 32123.

View File

@ -255,13 +255,22 @@ dnl Tor modules options. These options are namespaced with --disable-module-XXX
dnl ---
dnl All our modules.
m4_define(MODULES, dirauth)
m4_define(MODULES, relay dirauth)
dnl Relay module.
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]))
AM_CONDITIONAL(BUILD_MODULE_RELAY, [test "x$enable_module_relay" != "xno"])
AM_COND_IF(BUILD_MODULE_RELAY,
AC_DEFINE([HAVE_MODULE_RELAY], [1],
[Compile with Relay feature support]))
dnl Directory Authority module.
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]))
AM_CONDITIONAL(BUILD_MODULE_DIRAUTH,[test "x$enable_module_dirauth" != "xno"])
AM_CONDITIONAL(BUILD_MODULE_DIRAUTH,[test "x$enable_module_dirauth" != "xno" && test "x$enable_module_relay" != "xno"])
AM_COND_IF(BUILD_MODULE_DIRAUTH,
AC_DEFINE([HAVE_MODULE_DIRAUTH], [1],
[Compile with Directory Authority feature support]))

View File

@ -8,13 +8,18 @@ module in Tor.
In the context of the tor code base, a module is a subsystem that we can
selectively enable or disable, at `configure` time.
Currently, there is only one module:
Currently, tor has these modules:
- Relay subsystem (relay)
- Directory Authority subsystem (dirauth)
It is located in its own directory in `src/feature/dirauth/`. To disable it,
one need to pass `--disable-module-dirauth` at configure time. All modules
are currently enabled by default.
dirauth is located in its own directory in `src/feature/dirauth/`.
Relay is located in directories named `src/*/*relay` and `src/*/*dircache`,
which are being progressively refactored and disabled.
To disable a module, pass `--disable-module-{dirauth,relay}` at configure
time. All modules are currently enabled by default.
## Build System ##
@ -24,7 +29,7 @@ The changes to the build system are pretty straightforward.
contains a list (white-space separated) of the module in tor. Add yours to
the list.
2. Use the `AC_ARG_ENABLE([module-dirauth]` template for your new module. We
2. Use the `AC_ARG_ENABLE([module-relay]` template for your new module. We
use the "disable module" approach instead of enabling them one by one. So,
by default, tor will build all the modules.
@ -32,7 +37,7 @@ The changes to the build system are pretty straightforward.
the C code to conditionally compile things for your module. And the
`BUILD_MODULE_<name>` is also defined for automake files (e.g: include.am).
3. In the `src/core/include.am` file, locate the `MODULE_DIRAUTH_SOURCES`
3. In the `src/core/include.am` file, locate the `MODULE_RELAY_SOURCES`
value. You need to create your own `_SOURCES` variable for your module
and then conditionally add the it to `LIBTOR_A_SOURCES` if you should
build the module.
@ -40,18 +45,14 @@ The changes to the build system are pretty straightforward.
It is then **very** important to add your SOURCES variable to
`src_or_libtor_testing_a_SOURCES` so the tests can build it.
4. Do the same for header files, locate `ORHEADERS +=` which always add all
headers of all modules so the symbol can be found for the module entry
points.
Finally, your module will automatically be included in the
`TOR_MODULES_ALL_ENABLED` variable which is used to build the unit tests. They
always build everything in order to tests everything.
`TOR_MODULES_ALL_ENABLED` variable which is used to build the unit tests.
They always build everything in order to test everything.
## Coding ##
As mentioned above, a module must be isolated in its own directory (name of
the module) in `src/feature/`.
As mentioned above, a module should be isolated in its own directories,
suffixed with the name of the module, in `src/*/`.
There are couples of "rules" you want to follow:

View File

@ -2757,6 +2757,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");
}

View File

@ -71,6 +71,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 \
@ -145,7 +146,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 \
@ -169,6 +169,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 \
@ -188,6 +192,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
@ -196,6 +204,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)
@ -305,6 +314,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 \

View File

@ -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"

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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) */

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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) */

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
Address 198.51.100.123
AuthoritativeDirectory 1
BridgeAuthoritativeDir 1
ContactInfo tor_parse_test@example.com
DirPort 80
ORPort 443

View File

@ -0,0 +1,8 @@
AuthoritativeDirectory 1
BridgeAuthoritativeDir 1
ContactInfo tor_parse_test@example.com
Address 198.51.100.123
ORPort 443
DirPort 80

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,6 @@
Address 192.0.2.1
AuthoritativeDirectory 1
ContactInfo tor_parse_test@example.net
DirPort 9030
ORPort 9001
V3AuthoritativeDirectory 1

View File

@ -0,0 +1,8 @@
AuthoritativeDirectory 1
V3AuthoritativeDirectory 1
ContactInfo tor_parse_test@example.net
Address 192.0.2.1
ORPort 9001
DirPort 9030

View File

@ -0,0 +1 @@
ORPort 1000

View File

@ -0,0 +1,2 @@
ORPort 9999
ORPort 1000

View File

@ -0,0 +1 @@
ORPort 9099

View File

@ -0,0 +1,2 @@
ORPort 9000
ORPort 9099

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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