diff options
author | David Goulet <dgoulet@torproject.org> | 2017-01-13 11:20:31 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2017-07-13 16:49:08 -0400 |
commit | 93774dcb5458115652e0be5cdfaf198967b8a31e (patch) | |
tree | a2a8655730a5affb08ffc478aacc57451cd9e7da /src | |
parent | 74193b932115a82417dc312721ffe0a10a7ed6dc (diff) | |
download | tor-93774dcb5458115652e0be5cdfaf198967b8a31e.tar.gz tor-93774dcb5458115652e0be5cdfaf198967b8a31e.zip |
test: Add HS v2 service configuration unit tests
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/test/include.am | 1 | ||||
-rw-r--r-- | src/test/test.c | 1 | ||||
-rw-r--r-- | src/test/test.h | 1 | ||||
-rw-r--r-- | src/test/test_helpers.c | 42 | ||||
-rw-r--r-- | src/test/test_helpers.h | 1 | ||||
-rw-r--r-- | src/test/test_hs_config.c | 198 |
6 files changed, 242 insertions, 2 deletions
diff --git a/src/test/include.am b/src/test/include.am index e7a2e0278b..2e448c8b39 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -114,6 +114,7 @@ src_test_test_SOURCES = \ src/test/test_guardfraction.c \ src/test/test_extorport.c \ src/test/test_hs.c \ + src/test/test_hs_config.c \ src/test/test_hs_service.c \ src/test/test_hs_client.c \ src/test/test_hs_intropoint.c \ diff --git a/src/test/test.c b/src/test/test.c index 31b3db3a4f..b6b11ce94a 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1213,6 +1213,7 @@ struct testgroup_t testgroups[] = { { "extorport/", extorport_tests }, { "legacy_hs/", hs_tests }, { "hs_cache/", hs_cache }, + { "hs_config/", hs_config_tests }, { "hs_descriptor/", hs_descriptor }, { "hs_service/", hs_service_tests }, { "hs_client/", hs_client_tests }, diff --git a/src/test/test.h b/src/test/test.h index 4de0da99fb..9b2a0b842f 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -207,6 +207,7 @@ extern struct testcase_t guardfraction_tests[]; extern struct testcase_t extorport_tests[]; extern struct testcase_t hs_tests[]; extern struct testcase_t hs_cache[]; +extern struct testcase_t hs_config_tests[]; extern struct testcase_t hs_descriptor[]; extern struct testcase_t hs_service_tests[]; extern struct testcase_t hs_client_tests[]; diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index 22d9de3f5b..e885d27815 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -7,18 +7,21 @@ */ #define ROUTERLIST_PRIVATE +#define CONFIG_PRIVATE #define CONNECTION_PRIVATE #define MAIN_PRIVATE #include "orconfig.h" #include "or.h" +#include "buffers.h" +#include "config.h" +#include "confparse.h" #include "connection.h" #include "main.h" +#include "nodelist.h" #include "relay.h" #include "routerlist.h" -#include "nodelist.h" -#include "buffers.h" #include "test.h" #include "test_helpers.h" @@ -239,3 +242,38 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose) return NULL; } +/* Helper function to parse a set of torrc options in a text format and return + * a newly allocated or_options_t object containing the configuration. On + * error, NULL is returned indicating that the conf couldn't be parsed + * properly. */ +or_options_t * +helper_parse_options(const char *conf) +{ + int ret = 0; + char *msg = NULL; + or_options_t *opt = NULL; + config_line_t *line = NULL; + + /* Kind of pointless to call this with a NULL value. */ + tt_assert(conf); + + opt = options_new(); + tt_assert(opt); + ret = config_get_lines(conf, &line, 1); + if (ret != 0) { + goto done; + } + ret = config_assign(&options_format, opt, line, 0, &msg); + if (ret != 0) { + goto done; + } + + done: + config_free_lines(line); + if (ret != 0) { + or_options_free(opt); + opt = NULL; + } + return opt; +} + diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h index 96a4b594eb..847104a40a 100644 --- a/src/test/test_helpers.h +++ b/src/test/test_helpers.h @@ -24,6 +24,7 @@ int mock_tor_addr_lookup__fail_on_bad_addrs(const char *name, connection_t *test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose); +or_options_t *helper_parse_options(const char *conf); extern const char TEST_DESCRIPTORS[]; diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c new file mode 100644 index 0000000000..18b11948a4 --- /dev/null +++ b/src/test/test_hs_config.c @@ -0,0 +1,198 @@ +/* Copyright (c) 2016, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file test_hs_config.c + * \brief Test hidden service configuration functionality. + */ + +#define CONFIG_PRIVATE + +#include "test.h" +#include "test_helpers.h" +#include "log_test_helpers.h" +#include "hs_config.h" +#include "config.h" + +static int +helper_config_service_v2(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_v2(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 2\n"; + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("with no ports configured."); + teardown_capture_of_logs(); + } + + /* Out of order directives. */ + { + const char *conf = + "HiddenServiceVersion 2\n" + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServicePort 80\n"; + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("HiddenServiceVersion with no preceding " + "HiddenServiceDir directive"); + teardown_capture_of_logs(); + } + + /* Bad port. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 65536\n"; + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("Missing or invalid port"); + teardown_capture_of_logs(); + } + + /* Too many introduction points. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 80\n" + "HiddenServiceNumIntroductionPoints 11\n"; /* One too many. */ + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("HiddenServiceNumIntroductionPoints should " + "be between 0 and 10, not 11"); + teardown_capture_of_logs(); + } + + /* Too much max streams. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 80\n" + "HiddenServiceMaxStreams 65536\n"; /* One too many. */ + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("HiddenServiceMaxStreams should be between " + "0 and 65535, not 65536"); + teardown_capture_of_logs(); + } + + /* Bad authorized client type. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 80\n" + "HiddenServiceAuthorizeClient blah alice,bob\n"; /* blah is no good. */ + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("HiddenServiceAuthorizeClient contains " + "unrecognized auth-type"); + teardown_capture_of_logs(); + } + + /* Duplicate directory directive. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 80\n" + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 81\n"; + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service_v2(conf, validate_only); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("Another hidden service is already " + "configured for directory"); + teardown_capture_of_logs(); + } + + done: + ; +} + +static void +test_valid_service_v2(void *arg) +{ + int ret; + + (void) arg; + + /* Valid complex configuration. Basic client authorization. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 80\n" + "HiddenServicePort 22 localhost:22\n" + "HiddenServicePort 42 unix:/path/to/socket\n" + "HiddenServiceAuthorizeClient basic alice,bob,eve\n" + "HiddenServiceAllowUnknownPorts 1\n" + "HiddenServiceMaxStreams 42\n" + "HiddenServiceMaxStreamsCloseCircuit 0\n" + "HiddenServiceDirGroupReadable 1\n" + "HiddenServiceNumIntroductionPoints 7\n"; + ret = helper_config_service_v2(conf, 1); + tt_int_op(ret, OP_EQ, 0); + } + + /* Valid complex configuration. Stealth client authorization. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n" + "HiddenServiceVersion 2\n" + "HiddenServicePort 65535\n" + "HiddenServicePort 22 1.1.1.1:22\n" + "HiddenServicePort 9000 unix:/path/to/socket\n" + "HiddenServiceAuthorizeClient stealth charlie,romeo\n" + "HiddenServiceAllowUnknownPorts 0\n" + "HiddenServiceMaxStreams 42\n" + "HiddenServiceMaxStreamsCloseCircuit 0\n" + "HiddenServiceDirGroupReadable 1\n" + "HiddenServiceNumIntroductionPoints 8\n"; + ret = helper_config_service_v2(conf, 1); + tt_int_op(ret, OP_EQ, 0); + } + + done: + ; +} + +struct testcase_t hs_config_tests[] = { + { "invalid_service_v2", test_invalid_service_v2, TT_FORK, + NULL, NULL }, + { "valid_service_v2", test_valid_service_v2, TT_FORK, + NULL, NULL }, + + END_OF_TESTCASES +}; + |