[tor-commits] [tor/master] test: Add v3 service config and registration test

nickm at torproject.org nickm at torproject.org
Thu Jul 13 21:26:47 UTC 2017


commit 418059dd96f5f427eceffff1daeb2a2f6c4adbeb
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Jan 17 12:09:54 2017 -0500

    test: Add v3 service config and registration test
    
    This tests our hs_config.c API to properly load v3 services and register them
    to the global map. It does NOT test the service object validity, that will be
    the hs service unit test later on.
    
    At this commit, we have 100% code coverage of hs_config.c.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/hs_service.c       |  20 +++
 src/or/hs_service.h       |  11 ++
 src/test/test_hs_config.c | 349 +++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 345 insertions(+), 35 deletions(-)

diff --git a/src/or/hs_service.c b/src/or/hs_service.c
index eb58c76..854ce9e 100644
--- a/src/or/hs_service.c
+++ b/src/or/hs_service.c
@@ -6,6 +6,8 @@
  * \brief Implement next generation hidden service functionality
  **/
 
+#define HS_SERVICE_PRIVATE
+
 #include "or.h"
 #include "circuitlist.h"
 #include "config.h"
@@ -786,3 +788,21 @@ generate_establish_intro_cell(const uint8_t *circuit_key_material,
   return NULL;
 }
 
+#ifdef TOR_UNIT_TESTS
+
+/* Return the global service map size. Only used by unit test. */
+STATIC unsigned int
+get_hs_service_map_size(void)
+{
+  return HT_SIZE(hs_service_map);
+}
+
+/* Return the staging list size. Only used by unit test. */
+STATIC int
+get_hs_service_staging_list_size(void)
+{
+  return smartlist_len(hs_service_staging_list);
+}
+
+#endif /* TOR_UNIT_TESTS */
+
diff --git a/src/or/hs_service.h b/src/or/hs_service.h
index 90606ac..cd154d3 100644
--- a/src/or/hs_service.h
+++ b/src/or/hs_service.h
@@ -224,5 +224,16 @@ ssize_t
 get_establish_intro_payload(uint8_t *buf, size_t buf_len,
                             const trn_cell_establish_intro_t *cell);
 
+#ifdef HS_SERVICE_PRIVATE
+
+#ifdef TOR_UNIT_TESTS
+
+STATIC unsigned int get_hs_service_map_size(void);
+STATIC int get_hs_service_staging_list_size(void);
+
+#endif /* TOR_UNIT_TESTS */
+
+#endif /* HS_SERVICE_PRIVATE */
+
 #endif /* TOR_HS_SERVICE_H */
 
diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c
index 18b1194..343ce9f 100644
--- a/src/test/test_hs_config.c
+++ b/src/test/test_hs_config.c
@@ -7,15 +7,20 @@
  */
 
 #define CONFIG_PRIVATE
+#define HS_SERVICE_PRIVATE
 
 #include "test.h"
 #include "test_helpers.h"
 #include "log_test_helpers.h"
-#include "hs_config.h"
+
 #include "config.h"
+#include "hs_common.h"
+#include "hs_config.h"
+#include "hs_service.h"
+#include "rendservice.h"
 
 static int
-helper_config_service_v2(const char *conf, int validate_only)
+helper_config_service(const char *conf, int validate_only)
 {
   int ret = 0;
   or_options_t *options = NULL;
@@ -29,9 +34,9 @@ helper_config_service_v2(const char *conf, int validate_only)
 }
 
 static void
-test_invalid_service_v2(void *arg)
+test_invalid_service(void *arg)
 {
-  int validate_only = 1, ret;
+  int ret;
 
   (void) arg;
 
@@ -39,11 +44,98 @@ test_invalid_service_v2(void *arg)
   {
     const char *conf =
       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
-      "HiddenServiceVersion 2\n";
+      "HiddenServiceVersion 1\n"; /* Wrong not supported version. */
     setup_full_capture_of_logs(LOG_WARN);
-    ret = helper_config_service_v2(conf, validate_only);
+    ret = helper_config_service(conf, 1);
     tt_int_op(ret, OP_EQ, -1);
-    expect_log_msg_containing("with no ports configured.");
+    expect_log_msg_containing("HiddenServiceVersion must be between 2 and 3");
+    teardown_capture_of_logs();
+  }
+
+  /* Bad value of HiddenServiceAllowUnknownPorts. */
+  {
+    const char *conf =
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+      "HiddenServiceVersion 2\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("HiddenServiceAllowUnknownPorts must be "
+                              "between 0 and 1, not 2");
+    teardown_capture_of_logs();
+  }
+
+  /* Bad value of HiddenServiceDirGroupReadable */
+  {
+    const char *conf =
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+      "HiddenServiceVersion 2\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("HiddenServiceDirGroupReadable must be "
+                              "between 0 and 1, not 2");
+    teardown_capture_of_logs();
+  }
+
+  /* Bad value of HiddenServiceMaxStreamsCloseCircuit */
+  {
+    const char *conf =
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+      "HiddenServiceVersion 2\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("HiddenServiceMaxStreamsCloseCircuit must "
+                              "be between 0 and 1, not 2");
+    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(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 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(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 2\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();
   }
 
@@ -54,23 +146,60 @@ test_invalid_service_v2(void *arg)
       "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);
+    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();
   }
 
-  /* Bad port. */
+ done:
+  ;
+}
+
+static void
+test_valid_service(void *arg)
+{
+  int ret;
+
+  (void) arg;
+
+  /* Mix of v2 and v3. Still valid. */
   {
     const char *conf =
       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
       "HiddenServiceVersion 2\n"
-      "HiddenServicePort 65536\n";
+      "HiddenServicePort 80\n"
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
+      "HiddenServiceVersion 3\n"
+      "HiddenServicePort 81\n"
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
+      "HiddenServiceVersion 2\n"
+      "HiddenServicePort 82\n";
+    ret = helper_config_service(conf, 1);
+    tt_int_op(ret, OP_EQ, 0);
+  }
+
+ done:
+  ;
+}
+
+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);
+    ret = helper_config_service(conf, validate_only);
     tt_int_op(ret, OP_EQ, -1);
-    expect_log_msg_containing("Missing or invalid port");
+    expect_log_msg_containing("with no ports configured.");
     teardown_capture_of_logs();
   }
 
@@ -82,25 +211,25 @@ test_invalid_service_v2(void *arg)
       "HiddenServicePort 80\n"
       "HiddenServiceNumIntroductionPoints 11\n"; /* One too many. */
     setup_full_capture_of_logs(LOG_WARN);
-    ret = helper_config_service_v2(conf, validate_only);
+    ret = helper_config_service(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. */
+  /* Too little introduction points. */
   {
     const char *conf =
       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
       "HiddenServiceVersion 2\n"
       "HiddenServicePort 80\n"
-      "HiddenServiceMaxStreams 65536\n"; /* One too many. */
+      "HiddenServiceNumIntroductionPoints -1\n";
     setup_full_capture_of_logs(LOG_WARN);
-    ret = helper_config_service_v2(conf, validate_only);
+    ret = helper_config_service(conf, validate_only);
     tt_int_op(ret, OP_EQ, -1);
-    expect_log_msg_containing("HiddenServiceMaxStreams should be between "
-                              "0 and 65535, not 65536");
+    expect_log_msg_containing("HiddenServiceNumIntroductionPoints should "
+                              "be between 0 and 10, not -1");
     teardown_capture_of_logs();
   }
 
@@ -112,27 +241,110 @@ test_invalid_service_v2(void *arg)
       "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);
+    ret = helper_config_service(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. */
+ 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"
-      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\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(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 81\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(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_v2(conf, validate_only);
+    ret = helper_config_service(conf, validate_only);
     tt_int_op(ret, OP_EQ, -1);
-    expect_log_msg_containing("Another hidden service is already "
-                              "configured for directory");
+    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();
   }
 
@@ -141,45 +353,59 @@ test_invalid_service_v2(void *arg)
 }
 
 static void
-test_valid_service_v2(void *arg)
+test_valid_service_v3(void *arg)
 {
   int ret;
 
   (void) arg;
 
-  /* Valid complex configuration. Basic client authorization. */
+  /* Valid complex configuration. */
   {
     const char *conf =
       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
-      "HiddenServiceVersion 2\n"
+      "HiddenServiceVersion 3\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);
+    ret = helper_config_service(conf, 1);
     tt_int_op(ret, OP_EQ, 0);
   }
 
-  /* Valid complex configuration. Stealth client authorization. */
+  /* Valid complex configuration. */
   {
     const char *conf =
       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
-      "HiddenServiceVersion 2\n"
+      "HiddenServiceVersion 3\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);
+      "HiddenServiceNumIntroductionPoints 20\n";
+    ret = helper_config_service(conf, 1);
+    tt_int_op(ret, OP_EQ, 0);
+  }
+
+  /* Mix of v2 and v3. Still valid. */
+  {
+    const char *conf =
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+      "HiddenServiceVersion 2\n"
+      "HiddenServicePort 80\n"
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
+      "HiddenServiceVersion 3\n"
+      "HiddenServicePort 81\n"
+      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
+      "HiddenServiceVersion 2\n"
+      "HiddenServicePort 82\n";
+    ret = helper_config_service(conf, 1);
     tt_int_op(ret, OP_EQ, 0);
   }
 
@@ -187,12 +413,65 @@ test_valid_service_v2(void *arg)
   ;
 }
 
+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"
+    "HiddenServicePort 9000 unix:/path/to/socket\n"
+    "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);
+  /* Make sure we don't have a magic v2 service out of this. */
+  tt_int_op(num_rend_services(), OP_EQ, 0);
+
+ 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 2. */
   { "invalid_service_v2", test_invalid_service_v2, TT_FORK,
     NULL, NULL },
   { "valid_service_v2", test_valid_service_v2, 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 },
+
   END_OF_TESTCASES
 };
 





More information about the tor-commits mailing list