Merge branch 'maint-0.4.8'
[tor.git] / src / test / test_hs_config.c
blob74f823f897f6b8d4254abf4c15cc39b3785a1975
1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file test_hs_config.c
6 * \brief Test hidden service configuration functionality.
7 */
9 #define CONFIG_PRIVATE
10 #define HS_SERVICE_PRIVATE
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"
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"
22 static int
23 helper_config_service(const char *conf, int validate_only)
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;
36 static void
37 test_invalid_service(void *arg)
39 int ret;
41 (void) arg;
43 /* Try with a missing port configuration. */
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();
55 /* Bad value of HiddenServiceAllowUnknownPorts. */
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();
70 /* Bad value of HiddenServiceDirGroupReadable */
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();
85 /* Bad value of HiddenServiceMaxStreamsCloseCircuit */
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();
100 /* Too much max streams. */
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();
115 /* Duplicate directory directive. */
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();
132 /* Bad port. */
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();
145 /* Bad target addr:port separation. */
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();
159 /* Out of order directives. */
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();
173 done:
177 static void
178 test_valid_service(void *arg)
180 int ret;
182 (void) arg;
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);
193 done:
197 static void
198 test_invalid_service_v3(void *arg)
200 int validate_only = 1, ret;
202 (void) arg;
204 /* Try with a missing port configuration. */
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();
216 /* Too many introduction points. */
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();
231 /* Too little introduction points. */
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();
246 done:
250 static void
251 test_valid_service_v3(void *arg)
253 int ret;
255 (void) arg;
256 mock_hostname_resolver();
258 /* Valid complex configuration. */
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);
277 /* Valid complex configuration. */
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);
296 done:
297 unmock_hostname_resolver();
300 static void
301 test_staging_service_v3(void *arg)
303 int ret;
305 (void) arg;
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. */
311 hs_init();
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);
332 done:
333 hs_free_all();
336 static void
337 test_dos_parameters(void *arg)
339 int ret;
341 (void) arg;
343 hs_init();
345 /* Valid configuration. */
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";
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();
363 /* Invalid rate. Value of 2^37. Max allowed is 2^31. */
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";
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();
383 /* Invalid burst. Value of 2^38. Max allowed is 2^31. */
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";
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();
403 /* Burst is smaller than rate. */
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";
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();
421 /* Negative value. */
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";
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();
440 done:
441 hs_free_all();
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 },
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 },
457 /* Test service staging. */
458 { "staging_service_v3", test_staging_service_v3, TT_FORK,
459 NULL, NULL },
461 /* Test HS DoS parameters. */
462 { "dos_parameters", test_dos_parameters, TT_FORK,
463 NULL, NULL },
465 END_OF_TESTCASES