LCOV - code coverage report
Current view: top level - test - test_hs_config.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 178 178 100.0 %
Date: 2021-11-24 03:28:48 Functions: 7 7 100.0 %

          Line data    Source code
       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          21 : helper_config_service(const char *conf, int validate_only)
      24             : {
      25          21 :   int ret = 0;
      26          21 :   or_options_t *options = NULL;
      27          21 :   tt_assert(conf);
      28          21 :   options = helper_parse_options(conf);
      29          21 :   tt_assert(options);
      30          21 :   ret = hs_config_service_all(options, validate_only);
      31          21 :  done:
      32          21 :   or_options_free(options);
      33          21 :   return ret;
      34             : }
      35             : 
      36             : static void
      37           1 : test_invalid_service(void *arg)
      38             : {
      39           1 :   int ret;
      40             : 
      41           1 :   (void) arg;
      42             : 
      43             :   /* Try with a missing port configuration. */
      44             :   {
      45           1 :     const char *conf =
      46             :       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
      47             :       "HiddenServiceVersion 1\n"; /* Wrong not supported version. */
      48           1 :     setup_full_capture_of_logs(LOG_WARN);
      49           1 :     ret = helper_config_service(conf, 1);
      50           1 :     tt_int_op(ret, OP_EQ, -1);
      51           1 :     expect_log_msg_containing("HiddenServiceVersion must be between 3 and 3");
      52           1 :     teardown_capture_of_logs();
      53             :   }
      54             : 
      55             :   /* Bad value of HiddenServiceAllowUnknownPorts. */
      56             :   {
      57           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
      62           1 :     ret = helper_config_service(conf, 1);
      63           1 :     tt_int_op(ret, OP_EQ, -1);
      64           1 :     expect_log_msg_containing("Could not parse "
      65             :                               "HiddenServiceAllowUnknownPorts: Unrecognized "
      66           1 :                               "value 2. Allowed values are 0 and 1.");
      67           1 :     teardown_capture_of_logs();
      68             :   }
      69             : 
      70             :   /* Bad value of HiddenServiceDirGroupReadable */
      71             :   {
      72           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
      77           1 :     ret = helper_config_service(conf, 1);
      78           1 :     tt_int_op(ret, OP_EQ, -1);
      79           1 :     expect_log_msg_containing("Could not parse "
      80             :                               "HiddenServiceDirGroupReadable: "
      81           1 :                               "Unrecognized value 2.");
      82           1 :     teardown_capture_of_logs();
      83             :   }
      84             : 
      85             :   /* Bad value of HiddenServiceMaxStreamsCloseCircuit */
      86             :   {
      87           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
      92           1 :     ret = helper_config_service(conf, 1);
      93           1 :     tt_int_op(ret, OP_EQ, -1);
      94           1 :     expect_log_msg_containing("Could not parse "
      95             :                               "HiddenServiceMaxStreamsCloseCircuit: "
      96           1 :                               "Unrecognized value 2");
      97           1 :     teardown_capture_of_logs();
      98             :   }
      99             : 
     100             :   /* Too much max streams. */
     101             :   {
     102           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     108           1 :     ret = helper_config_service(conf, 1);
     109           1 :     tt_int_op(ret, OP_EQ, -1);
     110           1 :     expect_log_msg_containing("HiddenServiceMaxStreams must be between "
     111           1 :                               "0 and 65535, not 65536");
     112           1 :     teardown_capture_of_logs();
     113             :   }
     114             : 
     115             :   /* Duplicate directory directive. */
     116             :   {
     117           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     125           1 :     ret = helper_config_service(conf, 1);
     126           1 :     tt_int_op(ret, OP_EQ, -1);
     127           1 :     expect_log_msg_containing("Another hidden service is already "
     128           1 :                               "configured for directory");
     129           1 :     teardown_capture_of_logs();
     130             :   }
     131             : 
     132             :   /* Bad port. */
     133             :   {
     134           1 :     const char *conf =
     135             :       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     136             :       "HiddenServiceVersion 3\n"
     137             :       "HiddenServicePort 65536\n";
     138           1 :     setup_full_capture_of_logs(LOG_WARN);
     139           1 :     ret = helper_config_service(conf, 1);
     140           1 :     tt_int_op(ret, OP_EQ, -1);
     141           1 :     expect_log_msg_containing("Missing or invalid port");
     142           1 :     teardown_capture_of_logs();
     143             :   }
     144             : 
     145             :   /* Bad target addr:port separation. */
     146             :   {
     147           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     152           1 :     ret = helper_config_service(conf, 1);
     153           1 :     tt_int_op(ret, OP_EQ, -1);
     154           1 :     expect_log_msg_containing("HiddenServicePort parse error: "
     155           1 :                               "invalid port mapping");
     156           1 :     teardown_capture_of_logs();
     157             :   }
     158             : 
     159             :   /* Out of order directives. */
     160             :   {
     161           1 :     const char *conf =
     162             :       "HiddenServiceVersion 3\n"
     163             :       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     164             :       "HiddenServicePort 80\n";
     165           1 :     setup_full_capture_of_logs(LOG_WARN);
     166           1 :     ret = helper_config_service(conf, 1);
     167           1 :     tt_int_op(ret, OP_EQ, -1);
     168           1 :     expect_log_msg_containing("HiddenServiceVersion with no preceding "
     169           1 :                               "HiddenServiceDir directive");
     170           1 :     teardown_capture_of_logs();
     171             :   }
     172             : 
     173           1 :  done:
     174           1 :   ;
     175           1 : }
     176             : 
     177             : static void
     178           1 : test_valid_service(void *arg)
     179             : {
     180           1 :   int ret;
     181             : 
     182           1 :   (void) arg;
     183             : 
     184             :   {
     185           1 :     const char *conf =
     186             :       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n"
     187             :       "HiddenServiceVersion 3\n"
     188             :       "HiddenServicePort 81\n";
     189           1 :     ret = helper_config_service(conf, 1);
     190           1 :     tt_int_op(ret, OP_EQ, 0);
     191             :   }
     192             : 
     193           1 :  done:
     194           1 :   ;
     195           1 : }
     196             : 
     197             : static void
     198           1 : test_invalid_service_v3(void *arg)
     199             : {
     200           1 :   int validate_only = 1, ret;
     201             : 
     202           1 :   (void) arg;
     203             : 
     204             :   /* Try with a missing port configuration. */
     205             :   {
     206           1 :     const char *conf =
     207             :       "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
     208             :       "HiddenServiceVersion 3\n";
     209           1 :     setup_full_capture_of_logs(LOG_WARN);
     210           1 :     ret = helper_config_service(conf, validate_only);
     211           1 :     tt_int_op(ret, OP_EQ, -1);
     212           1 :     expect_log_msg_containing("with no ports configured.");
     213           1 :     teardown_capture_of_logs();
     214             :   }
     215             : 
     216             :   /* Too many introduction points. */
     217             :   {
     218           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     224           1 :     ret = helper_config_service(conf, validate_only);
     225           1 :     tt_int_op(ret, OP_EQ, -1);
     226           1 :     expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
     227           1 :                               "be between 3 and 20, not 21.");
     228           1 :     teardown_capture_of_logs();
     229             :   }
     230             : 
     231             :   /* Too little introduction points. */
     232             :   {
     233           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     239           1 :     ret = helper_config_service(conf, validate_only);
     240           1 :     tt_int_op(ret, OP_EQ, -1);
     241           1 :     expect_log_msg_containing("HiddenServiceNumIntroductionPoints must "
     242           1 :                               "be between 3 and 20, not 1.");
     243           1 :     teardown_capture_of_logs();
     244             :   }
     245             : 
     246           1 :  done:
     247           1 :   ;
     248           1 : }
     249             : 
     250             : static void
     251           1 : test_valid_service_v3(void *arg)
     252             : {
     253           1 :   int ret;
     254             : 
     255           1 :   (void) arg;
     256           1 :   mock_hostname_resolver();
     257             : 
     258             :   /* Valid complex configuration. */
     259             :   {
     260           1 :     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           1 :     ret = helper_config_service(conf, 1);
     274           1 :     tt_int_op(ret, OP_EQ, 0);
     275             :   }
     276             : 
     277             :   /* Valid complex configuration. */
     278             :   {
     279           1 :     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           1 :     ret = helper_config_service(conf, 1);
     293           1 :     tt_int_op(ret, OP_EQ, 0);
     294             :   }
     295             : 
     296           1 :  done:
     297           1 :   unmock_hostname_resolver();
     298           1 : }
     299             : 
     300             : static void
     301           1 : test_staging_service_v3(void *arg)
     302             : {
     303           1 :   int ret;
     304             : 
     305           1 :   (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           1 :   hs_init();
     312             : 
     313             :   /* Time for a valid v3 service that should get staged. */
     314           1 :   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           1 :   ret = helper_config_service(conf, 0);
     328           1 :   tt_int_op(ret, OP_EQ, 0);
     329             :   /* Ok, we have a service in our map! Registration went well. */
     330           1 :   tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 1);
     331             : 
     332           1 :  done:
     333           1 :   hs_free_all();
     334           1 : }
     335             : 
     336             : static void
     337           1 : test_dos_parameters(void *arg)
     338             : {
     339           1 :   int ret;
     340             : 
     341           1 :   (void) arg;
     342             : 
     343           1 :   hs_init();
     344             : 
     345             :   /* Valid configuration. */
     346             :   {
     347           1 :     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           1 :     setup_full_capture_of_logs(LOG_INFO);
     356           1 :     ret = helper_config_service(conf, 0);
     357           1 :     tt_int_op(ret, OP_EQ, 0);
     358           1 :     expect_log_msg_containing("Service INTRO2 DoS defenses rate set to: 42");
     359           1 :     expect_log_msg_containing("Service INTRO2 DoS defenses burst set to: 87");
     360           1 :     teardown_capture_of_logs();
     361             :   }
     362             : 
     363             :   /* Invalid rate. Value of 2^37. Max allowed is 2^31. */
     364             :   {
     365           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     374           1 :     ret = helper_config_service(conf, 0);
     375           1 :     tt_int_op(ret, OP_EQ, -1);
     376           1 :     expect_log_msg_containing("Could not parse "
     377             :                               "HiddenServiceEnableIntroDoSRatePerSec: "
     378             :                               "Integer 137438953472 is malformed or out of "
     379           1 :                               "bounds.");
     380           1 :     teardown_capture_of_logs();
     381             :   }
     382             : 
     383             :   /* Invalid burst. Value of 2^38. Max allowed is 2^31. */
     384             :   {
     385           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     394           1 :     ret = helper_config_service(conf, 0);
     395           1 :     tt_int_op(ret, OP_EQ, -1);
     396           1 :     expect_log_msg_containing("Could not parse "
     397             :                               "HiddenServiceEnableIntroDoSBurstPerSec: "
     398             :                               "Integer 274877906944 is malformed or out "
     399           1 :                               "of bounds.");
     400           1 :     teardown_capture_of_logs();
     401             :   }
     402             : 
     403             :   /* Burst is smaller than rate. */
     404             :   {
     405           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     414           1 :     ret = helper_config_service(conf, 0);
     415           1 :     tt_int_op(ret, OP_EQ, -1);
     416           1 :     expect_log_msg_containing("Hidden service DoS defenses burst (27) can "
     417           1 :                               "not be smaller than the rate value (42).");
     418           1 :     teardown_capture_of_logs();
     419             :   }
     420             : 
     421             :   /* Negative value. */
     422             :   {
     423           1 :     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           1 :     setup_full_capture_of_logs(LOG_WARN);
     432           1 :     ret = helper_config_service(conf, 0);
     433           1 :     tt_int_op(ret, OP_EQ, -1);
     434           1 :     expect_log_msg_containing("Could not parse "
     435             :                               "HiddenServiceEnableIntroDoSRatePerSec: "
     436           1 :                               "Integer -1 is malformed or out of bounds.");
     437           1 :     teardown_capture_of_logs();
     438             :   }
     439             : 
     440           1 :  done:
     441           1 :   hs_free_all();
     442           1 : }
     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             : };

Generated by: LCOV version 1.14