mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
test: Add HS onion balance tests
Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
faada6af8d
commit
7c18860c3e
@ -167,6 +167,7 @@ src_test_test_SOURCES += \
|
||||
src/test/test_hs_client.c \
|
||||
src/test/test_hs_intropoint.c \
|
||||
src/test/test_hs_control.c \
|
||||
src/test/test_hs_ob.c \
|
||||
src/test/test_handles.c \
|
||||
src/test/test_hs_cache.c \
|
||||
src/test/test_hs_descriptor.c \
|
||||
|
@ -721,6 +721,7 @@ struct testgroup_t testgroups[] = {
|
||||
{ "hs_dos/", hs_dos_tests },
|
||||
{ "hs_intropoint/", hs_intropoint_tests },
|
||||
{ "hs_ntor/", hs_ntor_tests },
|
||||
{ "hs_ob/", hs_ob_tests },
|
||||
{ "hs_service/", hs_service_tests },
|
||||
{ "introduce/", introduce_tests },
|
||||
{ "keypin/", keypin_tests },
|
||||
|
@ -141,6 +141,7 @@ extern struct testcase_t hs_descriptor[];
|
||||
extern struct testcase_t hs_dos_tests[];
|
||||
extern struct testcase_t hs_intropoint_tests[];
|
||||
extern struct testcase_t hs_ntor_tests[];
|
||||
extern struct testcase_t hs_ob_tests[];
|
||||
extern struct testcase_t hs_service_tests[];
|
||||
extern struct testcase_t hs_tests[];
|
||||
extern struct testcase_t introduce_tests[];
|
||||
|
231
src/test/test_hs_ob.c
Normal file
231
src/test/test_hs_ob.c
Normal file
@ -0,0 +1,231 @@
|
||||
/* Copyright (c) 2020, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file test_hs_ob.c
|
||||
* \brief Test hidden service onion balance functionality.
|
||||
*/
|
||||
|
||||
#define CONFIG_PRIVATE
|
||||
#define HS_SERVICE_PRIVATE
|
||||
|
||||
#include "test/test.h"
|
||||
#include "test/test_helpers.h"
|
||||
#include "test/log_test_helpers.h"
|
||||
|
||||
#include "app/config/config.h"
|
||||
#include "feature/hs/hs_config.h"
|
||||
#include "feature/hs/hs_ob.h"
|
||||
#include "feature/hs/hs_service.h"
|
||||
#include "feature/nodelist/networkstatus.h"
|
||||
#include "feature/nodelist/networkstatus_st.h"
|
||||
|
||||
static ed25519_keypair_t onion_addr_kp_1;
|
||||
static char onion_addr_1[HS_SERVICE_ADDR_LEN_BASE32 + 1];
|
||||
|
||||
static ed25519_keypair_t onion_addr_kp_2;
|
||||
static char onion_addr_2[HS_SERVICE_ADDR_LEN_BASE32 + 1];
|
||||
|
||||
static bool config_is_good = true;
|
||||
|
||||
static int
|
||||
helper_tor_config(const char *conf)
|
||||
{
|
||||
int ret = -1;
|
||||
or_options_t *options = helper_parse_options(conf);
|
||||
tt_assert(options);
|
||||
ret = hs_config_service_all(options, 0);
|
||||
done:
|
||||
or_options_free(options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static networkstatus_t mock_ns;
|
||||
|
||||
static networkstatus_t *
|
||||
mock_networkstatus_get_live_consensus(time_t now)
|
||||
{
|
||||
(void) now;
|
||||
return &mock_ns;
|
||||
}
|
||||
|
||||
static char *
|
||||
mock_read_file_to_str(const char *filename, int flags, struct stat *stat_out)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
(void) flags;
|
||||
(void) stat_out;
|
||||
|
||||
if (!strcmp(filename, get_fname("hs3" PATH_SEPARATOR "ob_config"))) {
|
||||
if (config_is_good) {
|
||||
tor_asprintf(&ret, "MasterOnionAddress %s.onion\n"
|
||||
"MasterOnionAddress %s.onion\n",
|
||||
onion_addr_1, onion_addr_2);
|
||||
} else {
|
||||
tor_asprintf(&ret, "MasterOnionAddress JUNKJUNKJUNK.onion\n"
|
||||
"UnknownOption BLAH\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
test_parse_config_file(void *arg)
|
||||
{
|
||||
int ret;
|
||||
char *conf = NULL;
|
||||
const ed25519_public_key_t *pkey;
|
||||
|
||||
(void) arg;
|
||||
|
||||
hs_init();
|
||||
|
||||
MOCK(read_file_to_str, mock_read_file_to_str);
|
||||
|
||||
#define fmt_conf \
|
||||
"HiddenServiceDir %s\n" \
|
||||
"HiddenServicePort 22\n" \
|
||||
"HiddenServiceOnionBalanceInstance 1\n"
|
||||
tor_asprintf(&conf, fmt_conf, get_fname("hs3"));
|
||||
#undef fmt_conf
|
||||
|
||||
/* Build the OB frontend onion addresses. */
|
||||
ed25519_keypair_generate(&onion_addr_kp_1, 0);
|
||||
hs_build_address(&onion_addr_kp_1.pubkey, HS_VERSION_THREE, onion_addr_1);
|
||||
ed25519_keypair_generate(&onion_addr_kp_2, 0);
|
||||
hs_build_address(&onion_addr_kp_2.pubkey, HS_VERSION_THREE, onion_addr_2);
|
||||
|
||||
ret = helper_tor_config(conf);
|
||||
tor_free(conf);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
|
||||
/* Load the keys for the service. After that, the v3 service should be
|
||||
* registered in the global map and we'll be able to access it. */
|
||||
tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
|
||||
hs_service_load_all_keys();
|
||||
tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
|
||||
const hs_service_t *s = get_first_service();
|
||||
tt_assert(s);
|
||||
tt_assert(s->config.ob_master_pubkeys);
|
||||
tt_assert(hs_ob_service_is_instance(s));
|
||||
tt_assert(smartlist_len(s->config.ob_master_pubkeys) == 2);
|
||||
|
||||
/* Test the public keys we've added. */
|
||||
pkey = smartlist_get(s->config.ob_master_pubkeys, 0);
|
||||
tt_mem_op(&onion_addr_kp_1.pubkey, OP_EQ, pkey, ED25519_PUBKEY_LEN);
|
||||
pkey = smartlist_get(s->config.ob_master_pubkeys, 1);
|
||||
tt_mem_op(&onion_addr_kp_2.pubkey, OP_EQ, pkey, ED25519_PUBKEY_LEN);
|
||||
|
||||
done:
|
||||
hs_free_all();
|
||||
|
||||
UNMOCK(read_file_to_str);
|
||||
}
|
||||
|
||||
static void
|
||||
test_parse_config_file_bad(void *arg)
|
||||
{
|
||||
int ret;
|
||||
char *conf = NULL;
|
||||
|
||||
(void) arg;
|
||||
|
||||
hs_init();
|
||||
|
||||
MOCK(read_file_to_str, mock_read_file_to_str);
|
||||
|
||||
/* Indicate mock_read_file_to_str() to use the bad config. */
|
||||
config_is_good = false;
|
||||
|
||||
#define fmt_conf \
|
||||
"HiddenServiceDir %s\n" \
|
||||
"HiddenServicePort 22\n" \
|
||||
"HiddenServiceOnionBalanceInstance 1\n"
|
||||
tor_asprintf(&conf, fmt_conf, get_fname("hs3"));
|
||||
#undef fmt_conf
|
||||
|
||||
setup_full_capture_of_logs(LOG_INFO);
|
||||
ret = helper_tor_config(conf);
|
||||
tor_free(conf);
|
||||
tt_int_op(ret, OP_EQ, -1);
|
||||
expect_log_msg_containing("OnionBalance: MasterOnionAddress "
|
||||
"JUNKJUNKJUNK.onion is invalid");
|
||||
expect_log_msg_containing("Found unrecognized option \'UnknownOption\'; "
|
||||
"saving it.");
|
||||
teardown_capture_of_logs();
|
||||
|
||||
done:
|
||||
hs_free_all();
|
||||
|
||||
UNMOCK(read_file_to_str);
|
||||
}
|
||||
|
||||
static void
|
||||
test_get_subcredentials(void *arg)
|
||||
{
|
||||
int ret;
|
||||
hs_service_config_t config;
|
||||
|
||||
(void) arg;
|
||||
|
||||
MOCK(networkstatus_get_live_consensus,
|
||||
mock_networkstatus_get_live_consensus);
|
||||
|
||||
/* Setup consensus with proper time so we can compute the time period. */
|
||||
ret = parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
|
||||
&mock_ns.valid_after);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
ret = parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
|
||||
&mock_ns.fresh_until);
|
||||
tt_int_op(ret, OP_EQ, 0);
|
||||
|
||||
config.ob_master_pubkeys = smartlist_new();
|
||||
tt_assert(config.ob_master_pubkeys);
|
||||
|
||||
/* Generate a keypair to add to the list. */
|
||||
ed25519_keypair_generate(&onion_addr_kp_1, 0);
|
||||
smartlist_add(config.ob_master_pubkeys, &onion_addr_kp_1.pubkey);
|
||||
|
||||
uint8_t *subcreds = NULL;
|
||||
size_t num = hs_ob_get_subcredentials(&config, &subcreds);
|
||||
tt_uint_op(num, OP_EQ, 3);
|
||||
|
||||
/* Validate the subcredentials we just got. We'll build them oursevles with
|
||||
* the right time period steps and compare. */
|
||||
const uint64_t tp = hs_get_time_period_num(0);
|
||||
const int steps[3] = {0, -1, 1};
|
||||
|
||||
for (unsigned int i = 0; i < num; i++) {
|
||||
uint8_t subcredential[DIGEST256_LEN];
|
||||
ed25519_public_key_t blinded_pubkey;
|
||||
hs_build_blinded_pubkey(&onion_addr_kp_1.pubkey, NULL, 0, tp + steps[i],
|
||||
&blinded_pubkey);
|
||||
hs_get_subcredential(&onion_addr_kp_1.pubkey, &blinded_pubkey,
|
||||
subcredential);
|
||||
tt_mem_op(&(subcreds[i * sizeof(subcredential)]), OP_EQ, subcredential,
|
||||
sizeof(subcredential));
|
||||
}
|
||||
|
||||
done:
|
||||
tor_free(subcreds);
|
||||
smartlist_free(config.ob_master_pubkeys);
|
||||
|
||||
UNMOCK(networkstatus_get_live_consensus);
|
||||
}
|
||||
|
||||
struct testcase_t hs_ob_tests[] = {
|
||||
{ "parse_config_file", test_parse_config_file, TT_FORK,
|
||||
NULL, NULL },
|
||||
{ "parse_config_file_bad", test_parse_config_file_bad, TT_FORK,
|
||||
NULL, NULL },
|
||||
|
||||
{ "get_subcredentials", test_get_subcredentials, TT_FORK,
|
||||
NULL, NULL },
|
||||
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user