mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
9a6c6e8ec5
Some tests were removed because they were testing something not usable anymore. Some tests remains to make sure that things are indeed disabled. Part of #40476 Signed-off-by: David Goulet <dgoulet@torproject.org>
467 lines
14 KiB
C
467 lines
14 KiB
C
/* Copyright (c) 2016-2021, The Tor Project, Inc. */
|
|
/* See LICENSE for licensing information */
|
|
|
|
/**
|
|
* \file test_hs_config.c
|
|
* \brief Test hidden service configuration functionality.
|
|
*/
|
|
|
|
#define CONFIG_PRIVATE
|
|
#define HS_SERVICE_PRIVATE
|
|
|
|
#include "test/test.h"
|
|
#include "test/test_helpers.h"
|
|
#include "test/log_test_helpers.h"
|
|
#include "test/resolve_test_helpers.h"
|
|
|
|
#include "app/config/config.h"
|
|
#include "feature/hs/hs_common.h"
|
|
#include "feature/hs/hs_config.h"
|
|
#include "feature/hs/hs_service.h"
|
|
|
|
static int
|
|
helper_config_service(const char *conf, int validate_only)
|
|
{
|
|
int ret = 0;
|
|
or_options_t *options = NULL;
|
|
tt_assert(conf);
|
|
options = helper_parse_options(conf);
|
|
tt_assert(options);
|
|
ret = hs_config_service_all(options, validate_only);
|
|
done:
|
|
or_options_free(options);
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
test_invalid_service(void *arg)
|
|
{
|
|
int ret;
|
|
|
|
(void) arg;
|
|
|
|
/* Try with a missing port configuration. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 1\n"; /* Wrong not supported version. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServiceVersion must be 3, not 1");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Bad value of HiddenServiceAllowUnknownPorts. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServiceAllowUnknownPorts 2\n"; /* Should be 0 or 1. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceAllowUnknownPorts: Unrecognized "
|
|
"value 2. Allowed values are 0 and 1.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Bad value of HiddenServiceDirGroupReadable */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServiceDirGroupReadable 2\n"; /* Should be 0 or 1. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceDirGroupReadable: "
|
|
"Unrecognized value 2.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Bad value of HiddenServiceMaxStreamsCloseCircuit */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServiceMaxStreamsCloseCircuit 2\n"; /* Should be 0 or 1. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceMaxStreamsCloseCircuit: "
|
|
"Unrecognized value 2");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Too much max streams. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80\n"
|
|
"HiddenServiceMaxStreams 65536\n"; /* One too many. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServiceMaxStreams must be between "
|
|
"0 and 65535, not 65536");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Duplicate directory directive. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80\n"
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 81\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Another hidden service is already "
|
|
"configured for directory");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Bad port. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 65536\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Missing or invalid port");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Bad target addr:port separation. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80 127.0.0.1 8000\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServicePort parse error: "
|
|
"invalid port mapping");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Out of order directives. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServicePort 80\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServiceVersion with no preceding "
|
|
"HiddenServiceDir directive");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_valid_service(void *arg)
|
|
{
|
|
int ret;
|
|
|
|
(void) arg;
|
|
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 81\n";
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, 0);
|
|
}
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_invalid_service_v3(void *arg)
|
|
{
|
|
int validate_only = 1, ret;
|
|
|
|
(void) arg;
|
|
|
|
/* Try with a missing port configuration. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, validate_only);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("with no ports configured.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Too many introduction points. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80\n"
|
|
"HiddenServiceNumIntroductionPoints 21\n"; /* One too many. */
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, validate_only);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
|
|
"be between 3 and 20, not 21.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Too little introduction points. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80\n"
|
|
"HiddenServiceNumIntroductionPoints 1\n";
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, validate_only);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
|
|
"be between 3 and 20, not 1.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
done:
|
|
;
|
|
}
|
|
|
|
static void
|
|
test_valid_service_v3(void *arg)
|
|
{
|
|
int ret;
|
|
|
|
(void) arg;
|
|
mock_hostname_resolver();
|
|
|
|
/* Valid complex configuration. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 80\n"
|
|
"HiddenServicePort 22 localhost:22\n"
|
|
#ifdef HAVE_SYS_UN_H
|
|
"HiddenServicePort 42 unix:/path/to/socket\n"
|
|
#endif
|
|
"HiddenServiceAllowUnknownPorts 1\n"
|
|
"HiddenServiceMaxStreams 42\n"
|
|
"HiddenServiceMaxStreamsCloseCircuit 0\n"
|
|
"HiddenServiceDirGroupReadable 1\n"
|
|
"HiddenServiceNumIntroductionPoints 7\n";
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, 0);
|
|
}
|
|
|
|
/* Valid complex configuration. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 65535\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
#ifdef HAVE_SYS_UN_H
|
|
"HiddenServicePort 9000 unix:/path/to/socket\n"
|
|
#endif
|
|
"HiddenServiceAllowUnknownPorts 0\n"
|
|
"HiddenServiceMaxStreams 42\n"
|
|
"HiddenServiceMaxStreamsCloseCircuit 0\n"
|
|
"HiddenServiceDirGroupReadable 1\n"
|
|
"HiddenServiceNumIntroductionPoints 20\n";
|
|
ret = helper_config_service(conf, 1);
|
|
tt_int_op(ret, OP_EQ, 0);
|
|
}
|
|
|
|
done:
|
|
unmock_hostname_resolver();
|
|
}
|
|
|
|
static void
|
|
test_staging_service_v3(void *arg)
|
|
{
|
|
int ret;
|
|
|
|
(void) arg;
|
|
|
|
/* We don't validate a service object, this is the service test that are in
|
|
* charge of doing so. We just check for the stable state after
|
|
* registration. */
|
|
|
|
hs_init();
|
|
|
|
/* Time for a valid v3 service that should get staged. */
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 65535\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
#ifdef HAVE_SYS_UN_H
|
|
"HiddenServicePort 9000 unix:/path/to/socket\n"
|
|
#endif
|
|
"HiddenServiceAllowUnknownPorts 0\n"
|
|
"HiddenServiceMaxStreams 42\n"
|
|
"HiddenServiceMaxStreamsCloseCircuit 0\n"
|
|
"HiddenServiceDirGroupReadable 1\n"
|
|
"HiddenServiceNumIntroductionPoints 20\n";
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, 0);
|
|
/* Ok, we have a service in our map! Registration went well. */
|
|
tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
|
|
|
|
done:
|
|
hs_free_all();
|
|
}
|
|
|
|
static void
|
|
test_dos_parameters(void *arg)
|
|
{
|
|
int ret;
|
|
|
|
(void) arg;
|
|
|
|
hs_init();
|
|
|
|
/* Valid configuration. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
"HiddenServiceEnableIntroDoSDefense 1\n"
|
|
"HiddenServiceEnableIntroDoSRatePerSec 42\n"
|
|
"HiddenServiceEnableIntroDoSBurstPerSec 87\n";
|
|
|
|
setup_full_capture_of_logs(LOG_INFO);
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, 0);
|
|
expect_log_msg_containing("Service INTRO2 DoS defenses rate set to: 42");
|
|
expect_log_msg_containing("Service INTRO2 DoS defenses burst set to: 87");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Invalid rate. Value of 2^37. Max allowed is 2^31. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
"HiddenServiceEnableIntroDoSDefense 1\n"
|
|
"HiddenServiceEnableIntroDoSRatePerSec 137438953472\n"
|
|
"HiddenServiceEnableIntroDoSBurstPerSec 87\n";
|
|
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceEnableIntroDoSRatePerSec: "
|
|
"Integer 137438953472 is malformed or out of "
|
|
"bounds.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Invalid burst. Value of 2^38. Max allowed is 2^31. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
"HiddenServiceEnableIntroDoSDefense 1\n"
|
|
"HiddenServiceEnableIntroDoSRatePerSec 42\n"
|
|
"HiddenServiceEnableIntroDoSBurstPerSec 274877906944\n";
|
|
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceEnableIntroDoSBurstPerSec: "
|
|
"Integer 274877906944 is malformed or out "
|
|
"of bounds.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Burst is smaller than rate. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
"HiddenServiceEnableIntroDoSDefense 1\n"
|
|
"HiddenServiceEnableIntroDoSRatePerSec 42\n"
|
|
"HiddenServiceEnableIntroDoSBurstPerSec 27\n";
|
|
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Hidden service DoS defenses burst (27) can "
|
|
"not be smaller than the rate value (42).");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
/* Negative value. */
|
|
{
|
|
const char *conf =
|
|
"HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
|
|
"HiddenServiceVersion 3\n"
|
|
"HiddenServicePort 22 1.1.1.1:22\n"
|
|
"HiddenServiceEnableIntroDoSDefense 1\n"
|
|
"HiddenServiceEnableIntroDoSRatePerSec -1\n"
|
|
"HiddenServiceEnableIntroDoSBurstPerSec 42\n";
|
|
|
|
setup_full_capture_of_logs(LOG_WARN);
|
|
ret = helper_config_service(conf, 0);
|
|
tt_int_op(ret, OP_EQ, -1);
|
|
expect_log_msg_containing("Could not parse "
|
|
"HiddenServiceEnableIntroDoSRatePerSec: "
|
|
"Integer -1 is malformed or out of bounds.");
|
|
teardown_capture_of_logs();
|
|
}
|
|
|
|
done:
|
|
hs_free_all();
|
|
}
|
|
|
|
struct testcase_t hs_config_tests[] = {
|
|
/* Invalid service not specific to any version. */
|
|
{ "invalid_service", test_invalid_service, TT_FORK,
|
|
NULL, NULL },
|
|
{ "valid_service", test_valid_service, TT_FORK,
|
|
NULL, NULL },
|
|
|
|
/* Test case only for version 3. */
|
|
{ "invalid_service_v3", test_invalid_service_v3, TT_FORK,
|
|
NULL, NULL },
|
|
{ "valid_service_v3", test_valid_service_v3, TT_FORK,
|
|
NULL, NULL },
|
|
|
|
/* Test service staging. */
|
|
{ "staging_service_v3", test_staging_service_v3, TT_FORK,
|
|
NULL, NULL },
|
|
|
|
/* Test HS DoS parameters. */
|
|
{ "dos_parameters", test_dos_parameters, TT_FORK,
|
|
NULL, NULL },
|
|
|
|
END_OF_TESTCASES
|
|
};
|