[tor-commits] [tor/master] test: Add HS onion balance tests

nickm at torproject.org nickm at torproject.org
Mon Feb 24 12:48:35 UTC 2020


commit 7c18860c3e0403246af0d9d79cecc79f97c7f2d6
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Jan 14 11:29:08 2020 -0500

    test: Add HS onion balance tests
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/test/include.am   |   1 +
 src/test/test.c       |   1 +
 src/test/test.h       |   1 +
 src/test/test_hs_ob.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 234 insertions(+)

diff --git a/src/test/include.am b/src/test/include.am
index 90e50752c..3590745ba 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -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 \
diff --git a/src/test/test.c b/src/test/test.c
index 1742f1d95..4b6082ce4 100644
--- a/src/test/test.c
+++ b/src/test/test.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 },
diff --git a/src/test/test.h b/src/test/test.h
index 63e2faff9..18987719d 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -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[];
diff --git a/src/test/test_hs_ob.c b/src/test/test_hs_ob.c
new file mode 100644
index 000000000..37c57f795
--- /dev/null
+++ b/src/test/test_hs_ob.c
@@ -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
+};
+





More information about the tor-commits mailing list