tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

test_hs_config.c (13986B)


      1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
      2 /* See LICENSE for licensing information */
      3 
      4 /**
      5 * \file test_hs_config.c
      6 * \brief Test hidden service configuration functionality.
      7 */
      8 
      9 #define CONFIG_PRIVATE
     10 #define HS_SERVICE_PRIVATE
     11 
     12 #include "test/test.h"
     13 #include "test/test_helpers.h"
     14 #include "test/log_test_helpers.h"
     15 #include "test/resolve_test_helpers.h"
     16 
     17 #include "app/config/config.h"
     18 #include "feature/hs/hs_common.h"
     19 #include "feature/hs/hs_config.h"
     20 #include "feature/hs/hs_service.h"
     21 
     22 static int
     23 helper_config_service(const char *conf, int validate_only)
     24 {
     25  int ret = 0;
     26  or_options_t *options = NULL;
     27  tt_assert(conf);
     28  options = helper_parse_options(conf);
     29  tt_assert(options);
     30  ret = hs_config_service_all(options, validate_only);
     31 done:
     32  or_options_free(options);
     33  return ret;
     34 }
     35 
     36 static void
     37 test_invalid_service(void *arg)
     38 {
     39  int ret;
     40 
     41  (void) arg;
     42 
     43  /* Try with a missing port configuration. */
     44  {
     45    const char *conf =
     46      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     47      "HiddenServiceVersion 1\n"; /* Wrong not supported version. */
     48    setup_full_capture_of_logs(LOG_WARN);
     49    ret = helper_config_service(conf, 1);
     50    tt_int_op(ret, OP_EQ, -1);
     51    expect_log_msg_containing("HiddenServiceVersion must be 3, not 1");
     52    teardown_capture_of_logs();
     53  }
     54 
     55  /* Bad value of HiddenServiceAllowUnknownPorts. */
     56  {
     57    const char *conf =
     58      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     59      "HiddenServiceVersion 3\n"
     60      "HiddenServiceAllowUnknownPorts 2\n"; /* Should be 0 or 1. */
     61    setup_full_capture_of_logs(LOG_WARN);
     62    ret = helper_config_service(conf, 1);
     63    tt_int_op(ret, OP_EQ, -1);
     64    expect_log_msg_containing("Could not parse "
     65                              "HiddenServiceAllowUnknownPorts: Unrecognized "
     66                              "value 2. Allowed values are 0 and 1.");
     67    teardown_capture_of_logs();
     68  }
     69 
     70  /* Bad value of HiddenServiceDirGroupReadable */
     71  {
     72    const char *conf =
     73      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     74      "HiddenServiceVersion 3\n"
     75      "HiddenServiceDirGroupReadable 2\n"; /* Should be 0 or 1. */
     76    setup_full_capture_of_logs(LOG_WARN);
     77    ret = helper_config_service(conf, 1);
     78    tt_int_op(ret, OP_EQ, -1);
     79    expect_log_msg_containing("Could not parse "
     80                              "HiddenServiceDirGroupReadable: "
     81                              "Unrecognized value 2.");
     82    teardown_capture_of_logs();
     83  }
     84 
     85  /* Bad value of HiddenServiceMaxStreamsCloseCircuit */
     86  {
     87    const char *conf =
     88      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     89      "HiddenServiceVersion 3\n"
     90      "HiddenServiceMaxStreamsCloseCircuit 2\n"; /* Should be 0 or 1. */
     91    setup_full_capture_of_logs(LOG_WARN);
     92    ret = helper_config_service(conf, 1);
     93    tt_int_op(ret, OP_EQ, -1);
     94    expect_log_msg_containing("Could not parse "
     95                              "HiddenServiceMaxStreamsCloseCircuit: "
     96                              "Unrecognized value 2");
     97    teardown_capture_of_logs();
     98  }
     99 
    100  /* Too much max streams. */
    101  {
    102    const char *conf =
    103      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    104      "HiddenServiceVersion 3\n"
    105      "HiddenServicePort 80\n"
    106      "HiddenServiceMaxStreams 65536\n"; /* One too many. */
    107    setup_full_capture_of_logs(LOG_WARN);
    108    ret = helper_config_service(conf, 1);
    109    tt_int_op(ret, OP_EQ, -1);
    110    expect_log_msg_containing("HiddenServiceMaxStreams must be between "
    111                              "0 and 65535, not 65536");
    112    teardown_capture_of_logs();
    113  }
    114 
    115  /* Duplicate directory directive. */
    116  {
    117    const char *conf =
    118      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    119      "HiddenServiceVersion 3\n"
    120      "HiddenServicePort 80\n"
    121      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    122      "HiddenServiceVersion 3\n"
    123      "HiddenServicePort 81\n";
    124    setup_full_capture_of_logs(LOG_WARN);
    125    ret = helper_config_service(conf, 1);
    126    tt_int_op(ret, OP_EQ, -1);
    127    expect_log_msg_containing("Another hidden service is already "
    128                              "configured for directory");
    129    teardown_capture_of_logs();
    130  }
    131 
    132  /* Bad port. */
    133  {
    134    const char *conf =
    135      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    136      "HiddenServiceVersion 3\n"
    137      "HiddenServicePort 65536\n";
    138    setup_full_capture_of_logs(LOG_WARN);
    139    ret = helper_config_service(conf, 1);
    140    tt_int_op(ret, OP_EQ, -1);
    141    expect_log_msg_containing("Missing or invalid port");
    142    teardown_capture_of_logs();
    143  }
    144 
    145  /* Bad target addr:port separation. */
    146  {
    147    const char *conf =
    148      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    149      "HiddenServiceVersion 3\n"
    150      "HiddenServicePort 80 127.0.0.1 8000\n";
    151    setup_full_capture_of_logs(LOG_WARN);
    152    ret = helper_config_service(conf, 1);
    153    tt_int_op(ret, OP_EQ, -1);
    154    expect_log_msg_containing("HiddenServicePort parse error: "
    155                              "invalid port mapping");
    156    teardown_capture_of_logs();
    157  }
    158 
    159  /* Out of order directives. */
    160  {
    161    const char *conf =
    162      "HiddenServiceVersion 3\n"
    163      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    164      "HiddenServicePort 80\n";
    165    setup_full_capture_of_logs(LOG_WARN);
    166    ret = helper_config_service(conf, 1);
    167    tt_int_op(ret, OP_EQ, -1);
    168    expect_log_msg_containing("HiddenServiceVersion with no preceding "
    169                              "HiddenServiceDir directive");
    170    teardown_capture_of_logs();
    171  }
    172 
    173 done:
    174  ;
    175 }
    176 
    177 static void
    178 test_valid_service(void *arg)
    179 {
    180  int ret;
    181 
    182  (void) arg;
    183 
    184  {
    185    const char *conf =
    186      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
    187      "HiddenServiceVersion 3\n"
    188      "HiddenServicePort 81\n";
    189    ret = helper_config_service(conf, 1);
    190    tt_int_op(ret, OP_EQ, 0);
    191  }
    192 
    193 done:
    194  ;
    195 }
    196 
    197 static void
    198 test_invalid_service_v3(void *arg)
    199 {
    200  int validate_only = 1, ret;
    201 
    202  (void) arg;
    203 
    204  /* Try with a missing port configuration. */
    205  {
    206    const char *conf =
    207      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    208      "HiddenServiceVersion 3\n";
    209    setup_full_capture_of_logs(LOG_WARN);
    210    ret = helper_config_service(conf, validate_only);
    211    tt_int_op(ret, OP_EQ, -1);
    212    expect_log_msg_containing("with no ports configured.");
    213    teardown_capture_of_logs();
    214  }
    215 
    216  /* Too many introduction points. */
    217  {
    218    const char *conf =
    219      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    220      "HiddenServiceVersion 3\n"
    221      "HiddenServicePort 80\n"
    222      "HiddenServiceNumIntroductionPoints 21\n"; /* One too many. */
    223    setup_full_capture_of_logs(LOG_WARN);
    224    ret = helper_config_service(conf, validate_only);
    225    tt_int_op(ret, OP_EQ, -1);
    226    expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
    227                              "be between 3 and 20, not 21.");
    228    teardown_capture_of_logs();
    229  }
    230 
    231  /* Too little introduction points. */
    232  {
    233    const char *conf =
    234      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    235      "HiddenServiceVersion 3\n"
    236      "HiddenServicePort 80\n"
    237      "HiddenServiceNumIntroductionPoints 1\n";
    238    setup_full_capture_of_logs(LOG_WARN);
    239    ret = helper_config_service(conf, validate_only);
    240    tt_int_op(ret, OP_EQ, -1);
    241    expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
    242                              "be between 3 and 20, not 1.");
    243    teardown_capture_of_logs();
    244  }
    245 
    246 done:
    247  ;
    248 }
    249 
    250 static void
    251 test_valid_service_v3(void *arg)
    252 {
    253  int ret;
    254 
    255  (void) arg;
    256  mock_hostname_resolver();
    257 
    258  /* Valid complex configuration. */
    259  {
    260    const char *conf =
    261      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
    262      "HiddenServiceVersion 3\n"
    263      "HiddenServicePort 80\n"
    264      "HiddenServicePort 22 localhost:22\n"
    265 #ifdef HAVE_SYS_UN_H
    266      "HiddenServicePort 42 unix:/path/to/socket\n"
    267 #endif
    268      "HiddenServiceAllowUnknownPorts 1\n"
    269      "HiddenServiceMaxStreams 42\n"
    270      "HiddenServiceMaxStreamsCloseCircuit 0\n"
    271      "HiddenServiceDirGroupReadable 1\n"
    272      "HiddenServiceNumIntroductionPoints 7\n";
    273    ret = helper_config_service(conf, 1);
    274    tt_int_op(ret, OP_EQ, 0);
    275  }
    276 
    277  /* Valid complex configuration. */
    278  {
    279    const char *conf =
    280      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
    281      "HiddenServiceVersion 3\n"
    282      "HiddenServicePort 65535\n"
    283      "HiddenServicePort 22 1.1.1.1:22\n"
    284 #ifdef HAVE_SYS_UN_H
    285      "HiddenServicePort 9000 unix:/path/to/socket\n"
    286 #endif
    287      "HiddenServiceAllowUnknownPorts 0\n"
    288      "HiddenServiceMaxStreams 42\n"
    289      "HiddenServiceMaxStreamsCloseCircuit 0\n"
    290      "HiddenServiceDirGroupReadable 1\n"
    291      "HiddenServiceNumIntroductionPoints 20\n";
    292    ret = helper_config_service(conf, 1);
    293    tt_int_op(ret, OP_EQ, 0);
    294  }
    295 
    296 done:
    297  unmock_hostname_resolver();
    298 }
    299 
    300 static void
    301 test_staging_service_v3(void *arg)
    302 {
    303  int ret;
    304 
    305  (void) arg;
    306 
    307  /* We don't validate a service object, this is the service test that are in
    308   * charge of doing so. We just check for the stable state after
    309   * registration. */
    310 
    311  hs_init();
    312 
    313  /* Time for a valid v3 service that should get staged. */
    314  const char *conf =
    315    "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
    316    "HiddenServiceVersion 3\n"
    317    "HiddenServicePort 65535\n"
    318    "HiddenServicePort 22 1.1.1.1:22\n"
    319 #ifdef HAVE_SYS_UN_H
    320    "HiddenServicePort 9000 unix:/path/to/socket\n"
    321 #endif
    322    "HiddenServiceAllowUnknownPorts 0\n"
    323    "HiddenServiceMaxStreams 42\n"
    324    "HiddenServiceMaxStreamsCloseCircuit 0\n"
    325    "HiddenServiceDirGroupReadable 1\n"
    326    "HiddenServiceNumIntroductionPoints 20\n";
    327  ret = helper_config_service(conf, 0);
    328  tt_int_op(ret, OP_EQ, 0);
    329  /* Ok, we have a service in our map! Registration went well. */
    330  tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
    331 
    332 done:
    333  hs_free_all();
    334 }
    335 
    336 static void
    337 test_dos_parameters(void *arg)
    338 {
    339  int ret;
    340 
    341  (void) arg;
    342 
    343  hs_init();
    344 
    345  /* Valid configuration. */
    346  {
    347    const char *conf =
    348      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
    349      "HiddenServiceVersion 3\n"
    350      "HiddenServicePort 22 1.1.1.1:22\n"
    351      "HiddenServiceEnableIntroDoSDefense 1\n"
    352      "HiddenServiceEnableIntroDoSRatePerSec 42\n"
    353      "HiddenServiceEnableIntroDoSBurstPerSec 87\n";
    354 
    355    setup_full_capture_of_logs(LOG_INFO);
    356    ret = helper_config_service(conf, 0);
    357    tt_int_op(ret, OP_EQ, 0);
    358    expect_log_msg_containing("Service INTRO2 DoS defenses rate set to: 42");
    359    expect_log_msg_containing("Service INTRO2 DoS defenses burst set to: 87");
    360    teardown_capture_of_logs();
    361  }
    362 
    363  /* Invalid rate. Value of 2^37. Max allowed is 2^31. */
    364  {
    365    const char *conf =
    366      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
    367      "HiddenServiceVersion 3\n"
    368      "HiddenServicePort 22 1.1.1.1:22\n"
    369      "HiddenServiceEnableIntroDoSDefense 1\n"
    370      "HiddenServiceEnableIntroDoSRatePerSec 137438953472\n"
    371      "HiddenServiceEnableIntroDoSBurstPerSec 87\n";
    372 
    373    setup_full_capture_of_logs(LOG_WARN);
    374    ret = helper_config_service(conf, 0);
    375    tt_int_op(ret, OP_EQ, -1);
    376    expect_log_msg_containing("Could not parse "
    377                              "HiddenServiceEnableIntroDoSRatePerSec: "
    378                              "Integer 137438953472 is malformed or out of "
    379                              "bounds.");
    380    teardown_capture_of_logs();
    381  }
    382 
    383  /* Invalid burst. Value of 2^38. Max allowed is 2^31. */
    384  {
    385    const char *conf =
    386      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
    387      "HiddenServiceVersion 3\n"
    388      "HiddenServicePort 22 1.1.1.1:22\n"
    389      "HiddenServiceEnableIntroDoSDefense 1\n"
    390      "HiddenServiceEnableIntroDoSRatePerSec 42\n"
    391      "HiddenServiceEnableIntroDoSBurstPerSec 274877906944\n";
    392 
    393    setup_full_capture_of_logs(LOG_WARN);
    394    ret = helper_config_service(conf, 0);
    395    tt_int_op(ret, OP_EQ, -1);
    396    expect_log_msg_containing("Could not parse "
    397                              "HiddenServiceEnableIntroDoSBurstPerSec: "
    398                              "Integer 274877906944 is malformed or out "
    399                              "of bounds.");
    400    teardown_capture_of_logs();
    401  }
    402 
    403  /* Burst is smaller than rate. */
    404  {
    405    const char *conf =
    406      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
    407      "HiddenServiceVersion 3\n"
    408      "HiddenServicePort 22 1.1.1.1:22\n"
    409      "HiddenServiceEnableIntroDoSDefense 1\n"
    410      "HiddenServiceEnableIntroDoSRatePerSec 42\n"
    411      "HiddenServiceEnableIntroDoSBurstPerSec 27\n";
    412 
    413    setup_full_capture_of_logs(LOG_WARN);
    414    ret = helper_config_service(conf, 0);
    415    tt_int_op(ret, OP_EQ, -1);
    416    expect_log_msg_containing("Hidden service DoS defenses burst (27) can "
    417                              "not be smaller than the rate value (42).");
    418    teardown_capture_of_logs();
    419  }
    420 
    421  /* Negative value. */
    422  {
    423    const char *conf =
    424      "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n"
    425      "HiddenServiceVersion 3\n"
    426      "HiddenServicePort 22 1.1.1.1:22\n"
    427      "HiddenServiceEnableIntroDoSDefense 1\n"
    428      "HiddenServiceEnableIntroDoSRatePerSec -1\n"
    429      "HiddenServiceEnableIntroDoSBurstPerSec 42\n";
    430 
    431    setup_full_capture_of_logs(LOG_WARN);
    432    ret = helper_config_service(conf, 0);
    433    tt_int_op(ret, OP_EQ, -1);
    434    expect_log_msg_containing("Could not parse "
    435                              "HiddenServiceEnableIntroDoSRatePerSec: "
    436                              "Integer -1 is malformed or out of bounds.");
    437    teardown_capture_of_logs();
    438  }
    439 
    440 done:
    441  hs_free_all();
    442 }
    443 
    444 struct testcase_t hs_config_tests[] = {
    445  /* Invalid service not specific to any version. */
    446  { "invalid_service", test_invalid_service, TT_FORK,
    447    NULL, NULL },
    448  { "valid_service", test_valid_service, TT_FORK,
    449    NULL, NULL },
    450 
    451  /* Test case only for version 3. */
    452  { "invalid_service_v3", test_invalid_service_v3, TT_FORK,
    453    NULL, NULL },
    454  { "valid_service_v3", test_valid_service_v3, TT_FORK,
    455    NULL, NULL },
    456 
    457  /* Test service staging. */
    458  { "staging_service_v3", test_staging_service_v3, TT_FORK,
    459    NULL, NULL },
    460 
    461  /* Test HS DoS parameters. */
    462  { "dos_parameters", test_dos_parameters, TT_FORK,
    463    NULL, NULL },
    464 
    465  END_OF_TESTCASES
    466 };