1 /* Copyright (c) 2016-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
5 * \file test_hs_service.c
6 * \brief Test hidden service functionality.
9 #define CIRCUITBUILD_PRIVATE
10 #define CIRCUITLIST_PRIVATE
11 #define CONFIG_PRIVATE
12 #define CONNECTION_PRIVATE
13 #define CONNECTION_EDGE_PRIVATE
14 #define CRYPTO_PRIVATE
15 #define HS_COMMON_PRIVATE
16 #define HS_SERVICE_PRIVATE
17 #define HS_INTROPOINT_PRIVATE
18 #define HS_CIRCUIT_PRIVATE
19 #define MAINLOOP_PRIVATE
20 #define NETWORKSTATUS_PRIVATE
21 #define STATEFILE_PRIVATE
22 #define CHANNEL_OBJECT_PRIVATE
23 #define HS_CLIENT_PRIVATE
24 #define CRYPT_PATH_PRIVATE
26 #include "test/test.h"
27 #include "test/test_helpers.h"
28 #include "test/log_test_helpers.h"
29 #include "test/rend_test_helpers.h"
30 #include "test/hs_test_helpers.h"
32 #include "core/or/or.h"
33 #include "app/config/config.h"
34 #include "app/config/statefile.h"
35 #include "core/crypto/hs_ntor.h"
36 #include "core/mainloop/connection.h"
37 #include "core/mainloop/mainloop.h"
38 #include "core/or/circuitbuild.h"
39 #include "core/or/circuitlist.h"
40 #include "core/or/circuituse.h"
41 #include "core/or/connection_edge.h"
42 #include "core/or/edge_connection_st.h"
43 #include "core/or/relay.h"
44 #include "core/or/versions.h"
45 #include "feature/dirauth/dirvote.h"
46 #include "feature/dirauth/shared_random_state.h"
47 #include "feature/dirauth/voting_schedule.h"
48 #include "feature/hs/hs_circuit.h"
49 #include "feature/hs/hs_circuitmap.h"
50 #include "feature/hs/hs_client.h"
51 #include "feature/hs/hs_common.h"
52 #include "feature/hs/hs_config.h"
53 #include "feature/hs/hs_ident.h"
54 #include "feature/hs/hs_ob.h"
55 #include "feature/hs/hs_cell.h"
56 #include "feature/hs/hs_intropoint.h"
57 #include "feature/hs/hs_metrics.h"
58 #include "feature/hs/hs_service.h"
59 #include "feature/nodelist/networkstatus.h"
60 #include "feature/nodelist/nodelist.h"
61 #include "feature/rend/rendservice.h"
62 #include "lib/crypt_ops/crypto_rand.h"
63 #include "lib/fs/dir.h"
65 #include "core/or/cpath_build_state_st.h"
66 #include "core/or/crypt_path_st.h"
67 #include "core/or/crypt_path.h"
68 #include "feature/nodelist/networkstatus_st.h"
69 #include "feature/nodelist/node_st.h"
70 #include "core/or/origin_circuit_st.h"
71 #include "app/config/or_state_st.h"
72 #include "feature/nodelist/routerinfo_st.h"
75 #include "trunnel/hs/cell_establish_intro.h"
77 #ifdef HAVE_SYS_STAT_H
84 static networkstatus_t mock_ns
;
86 static networkstatus_t
*
87 mock_networkstatus_get_reasonably_live_consensus(time_t now
, int flavor
)
94 static networkstatus_t
*
95 mock_networkstatus_get_reasonably_live_consensus_null(time_t now
, int flavor
)
102 static or_state_t
*dummy_state
= NULL
;
104 /* Mock function to get fake or state (used for rev counters) */
106 get_or_state_replacement(void)
111 /* Mock function because we are not trying to test the close circuit that does
112 * an awful lot of checks on the circuit object. */
114 mock_circuit_mark_for_close(circuit_t
*circ
, int reason
, int line
,
124 static size_t relay_payload_len
;
125 static char relay_payload
[RELAY_PAYLOAD_SIZE
];
128 mock_relay_send_command_from_edge(streamid_t stream_id
, circuit_t
*circ
,
129 uint8_t relay_command
, const char *payload
,
131 crypt_path_t
*cpath_layer
,
132 const char *filename
, int lineno
)
136 (void) relay_command
;
143 memcpy(relay_payload
, payload
, payload_len
);
144 relay_payload_len
= payload_len
;
149 static unsigned int num_intro_points
= 0;
151 mock_count_desc_circuit_established(const hs_service_descriptor_t
*desc
)
154 return num_intro_points
;
158 mock_router_have_minimum_dir_info_false(void)
163 /* Helper: from a set of options in conf, configure a service which will add
164 * it to the staging list of the HS subsystem. */
166 helper_config_service(const char *conf
)
169 or_options_t
*options
= NULL
;
171 options
= helper_parse_options(conf
);
173 ret
= hs_config_service_all(options
, 0);
175 or_options_free(options
);
179 /* Test: Ensure that setting up rendezvous circuits works correctly. */
181 test_e2e_rend_circuit_setup(void *arg
)
183 ed25519_public_key_t service_pk
;
184 origin_circuit_t
*or_circ
;
187 /** In this test we create a v3 prop224 service-side rendezvous circuit.
188 * We simulate an HS ntor key exchange with a client, and check that
189 * the circuit was setup correctly and is ready to accept rendezvous data */
193 /* Now make dummy circuit */
195 or_circ
= origin_circuit_new();
197 or_circ
->base_
.purpose
= CIRCUIT_PURPOSE_S_CONNECT_REND
;
199 or_circ
->build_state
= tor_malloc_zero(sizeof(cpath_build_state_t
));
200 or_circ
->build_state
->is_internal
= 1;
202 /* prop224: Setup hs conn identifier on the stream */
203 ed25519_secret_key_t sk
;
204 tt_int_op(0, OP_EQ
, ed25519_secret_key_generate(&sk
, 0));
205 tt_int_op(0, OP_EQ
, ed25519_public_key_generate(&service_pk
, &sk
));
207 or_circ
->hs_ident
= hs_ident_circuit_new(&service_pk
);
209 TO_CIRCUIT(or_circ
)->state
= CIRCUIT_STATE_OPEN
;
212 /* Check number of hops */
213 retval
= cpath_get_n_hops(&or_circ
->cpath
);
214 tt_int_op(retval
, OP_EQ
, 0);
216 /* Setup the circuit: do the ntor key exchange */
218 uint8_t ntor_key_seed
[DIGEST256_LEN
] = {2};
219 retval
= hs_circuit_setup_e2e_rend_circ(or_circ
, ntor_key_seed
,
220 sizeof(ntor_key_seed
), 1);
221 tt_int_op(retval
, OP_EQ
, 0);
224 /* See that a hop was added to the circuit's cpath */
225 retval
= cpath_get_n_hops(&or_circ
->cpath
);
226 tt_int_op(retval
, OP_EQ
, 1);
228 /* Check the digest algo */
229 tt_int_op(crypto_digest_get_algorithm(or_circ
->cpath
->pvt_crypto
.f_digest
),
230 OP_EQ
, DIGEST_SHA3_256
);
231 tt_int_op(crypto_digest_get_algorithm(or_circ
->cpath
->pvt_crypto
.b_digest
),
232 OP_EQ
, DIGEST_SHA3_256
);
233 tt_assert(or_circ
->cpath
->pvt_crypto
.f_crypto
);
234 tt_assert(or_circ
->cpath
->pvt_crypto
.b_crypto
);
236 /* Ensure that circ purpose was changed */
237 tt_int_op(or_circ
->base_
.purpose
, OP_EQ
, CIRCUIT_PURPOSE_S_REND_JOINED
);
240 circuit_free_(TO_CIRCUIT(or_circ
));
243 /* Helper: Return a newly allocated and initialized origin circuit with
244 * purpose and flags. A default HS identifier is set to an ed25519
245 * authentication key for introduction point. */
246 static origin_circuit_t
*
247 helper_create_origin_circuit(int purpose
, int flags
)
249 origin_circuit_t
*circ
= NULL
;
251 circ
= origin_circuit_init(purpose
, flags
);
253 circ
->cpath
= tor_malloc_zero(sizeof(crypt_path_t
));
254 circ
->cpath
->magic
= CRYPT_PATH_MAGIC
;
255 circ
->cpath
->state
= CPATH_STATE_OPEN
;
256 circ
->cpath
->package_window
= circuit_initial_package_window();
257 circ
->cpath
->deliver_window
= CIRCWINDOW_START
;
258 circ
->cpath
->prev
= circ
->cpath
;
260 crypto_rand(circ
->cpath
->prev
->rend_circ_nonce
, DIGEST_LEN
);
261 /* Create a default HS identifier. */
262 circ
->hs_ident
= tor_malloc_zero(sizeof(hs_ident_circuit_t
));
267 /* Helper: Return a newly allocated authorized client object with
268 * and a newly generated public key. */
269 static hs_service_authorized_client_t
*
270 helper_create_authorized_client(void)
273 hs_service_authorized_client_t
*client
;
274 curve25519_secret_key_t seckey
;
275 client
= tor_malloc_zero(sizeof(hs_service_authorized_client_t
));
277 ret
= curve25519_secret_key_generate(&seckey
, 0);
278 tt_int_op(ret
, OP_EQ
, 0);
279 curve25519_public_key_generate(&client
->client_pk
, &seckey
);
285 /* Helper: Return a newly allocated authorized client object with the
286 * same client name and the same public key as the given client. */
287 static hs_service_authorized_client_t
*
288 helper_clone_authorized_client(const hs_service_authorized_client_t
*client
)
290 hs_service_authorized_client_t
*client_out
;
294 client_out
= tor_malloc_zero(sizeof(hs_service_authorized_client_t
));
295 memcpy(client_out
->client_pk
.public_key
,
296 client
->client_pk
.public_key
, CURVE25519_PUBKEY_LEN
);
301 /* Helper: Return a newly allocated service object with the identity keypair
302 * sets and the current descriptor. Then register it to the global map.
303 * Caller should use hs_free_all() to free this service or remove it from the
304 * global map before freeing. */
305 static hs_service_t
*
306 helper_create_service(void)
308 /* Set a service for this circuit. */
309 hs_service_t
*service
= hs_service_new(get_options());
311 service
->config
.version
= HS_VERSION_THREE
;
312 ed25519_secret_key_generate(&service
->keys
.identity_sk
, 0);
313 ed25519_public_key_generate(&service
->keys
.identity_pk
,
314 &service
->keys
.identity_sk
);
315 service
->desc_current
= service_descriptor_new();
316 tt_assert(service
->desc_current
);
317 /* Register service to global map. */
318 int ret
= register_service(get_hs_service_map(), service
);
319 tt_int_op(ret
, OP_EQ
, 0);
325 /* Helper: Deallocate a given service object, its child objects and
326 * remove it from onion service map.
329 helper_destroy_service(hs_service_t
*service
)
334 remove_service(get_hs_service_map(), service
);
336 hs_service_free(service
);
339 /* Helper: Return a newly allocated service object with clients. */
340 static hs_service_t
*
341 helper_create_service_with_clients(int num_clients
)
344 hs_service_t
*service
= helper_create_service();
346 service
->config
.is_client_auth_enabled
= 1;
347 service
->config
.clients
= smartlist_new();
349 for (i
= 0; i
< num_clients
; i
++) {
350 hs_service_authorized_client_t
*client
;
351 client
= helper_create_authorized_client();
352 smartlist_add(service
->config
.clients
, client
);
359 /* Helper: Return a newly allocated service intro point with two link
360 * specifiers, one IPv4 and one legacy ID set to As. */
361 static hs_service_intro_point_t
*
362 helper_create_service_ip(void)
364 link_specifier_t
*ls
;
365 hs_service_intro_point_t
*ip
= service_intro_point_new(NULL
);
367 /* Add a first unused link specifier. */
368 ls
= link_specifier_new();
369 link_specifier_set_ls_type(ls
, LS_IPV4
);
370 smartlist_add(ip
->base
.link_specifiers
, ls
);
371 /* Add a second link specifier used by a test. */
372 ls
= link_specifier_new();
373 link_specifier_set_ls_type(ls
, LS_LEGACY_ID
);
374 memset(link_specifier_getarray_un_legacy_id(ls
), 'A',
375 link_specifier_getlen_un_legacy_id(ls
));
376 smartlist_add(ip
->base
.link_specifiers
, ls
);
382 test_load_keys(void *arg
)
386 char *hsdir_v2
= tor_strdup(get_fname("hs2"));
387 char *hsdir_v3
= tor_strdup(get_fname("hs3"));
388 char addr
[HS_SERVICE_ADDR_LEN_BASE32
+ 1];
392 /* We'll register two services, a v2 and a v3, then we'll load keys and
393 * validate that both are in a correct state. */
398 "HiddenServiceDir %s\n" \
399 "HiddenServiceVersion %d\n" \
400 "HiddenServicePort 65535\n"
403 tor_asprintf(&conf
, conf_fmt
, hsdir_v2
, HS_VERSION_TWO
);
404 ret
= helper_config_service(conf
);
406 tt_int_op(ret
, OP_EQ
, 0);
407 /* This one should now be registered into the v2 list. */
408 tt_int_op(get_hs_service_staging_list_size(), OP_EQ
, 0);
409 tt_int_op(rend_num_services(), OP_EQ
, 1);
412 tor_asprintf(&conf
, conf_fmt
, hsdir_v3
, HS_VERSION_THREE
);
413 ret
= helper_config_service(conf
);
415 tt_int_op(ret
, OP_EQ
, 0);
416 /* It's in staging? */
417 tt_int_op(get_hs_service_staging_list_size(), OP_EQ
, 1);
421 /* Load the keys for these. After that, the v3 service should be registered
422 * in the global map. */
423 hs_service_load_all_keys();
424 tt_int_op(get_hs_service_map_size(), OP_EQ
, 1);
425 hs_service_t
*s
= get_first_service();
428 /* Ok we have the service object. Validate few things. */
429 tt_assert(!fast_mem_is_zero(s
->onion_address
, sizeof(s
->onion_address
)));
430 tt_int_op(hs_address_is_valid(s
->onion_address
), OP_EQ
, 1);
431 tt_assert(!fast_mem_is_zero((char *) s
->keys
.identity_sk
.seckey
,
432 ED25519_SECKEY_LEN
));
433 tt_assert(!fast_mem_is_zero((char *) s
->keys
.identity_pk
.pubkey
,
434 ED25519_PUBKEY_LEN
));
435 /* Check onion address from identity key. */
436 hs_build_address(&s
->keys
.identity_pk
, s
->config
.version
, addr
);
437 tt_int_op(hs_address_is_valid(addr
), OP_EQ
, 1);
438 tt_str_op(addr
, OP_EQ
, s
->onion_address
);
440 /* Check that the is_client_auth_enabled is not set. */
441 tt_assert(!s
->config
.is_client_auth_enabled
);
450 test_client_filename_is_valid(void *arg
)
454 /* Valid file name. */
455 tt_assert(client_filename_is_valid("a.auth"));
456 /* Valid file name with special character. */
457 tt_assert(client_filename_is_valid("a-.auth"));
458 /* Invalid extension. */
459 tt_assert(!client_filename_is_valid("a.ath"));
460 /* Nothing before the extension. */
461 tt_assert(!client_filename_is_valid(".auth"));
468 test_parse_authorized_client(void *arg
)
470 hs_service_authorized_client_t
*client
= NULL
;
474 /* Valid authorized client. */
475 client
= parse_authorized_client(
476 "descriptor:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
479 /* Wrong number of fields. */
480 tt_assert(!parse_authorized_client("a:b:c:d:e"));
481 /* Wrong auth type. */
482 tt_assert(!parse_authorized_client(
483 "x:x25519:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
484 /* Wrong key type. */
485 tt_assert(!parse_authorized_client(
486 "descriptor:x:dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
487 /* Some malformed string. */
488 tt_assert(!parse_authorized_client("descriptor:x25519:aa=="));
489 tt_assert(!parse_authorized_client("descriptor:"));
490 tt_assert(!parse_authorized_client("descriptor:x25519"));
491 tt_assert(!parse_authorized_client("descriptor:x25519:"));
492 tt_assert(!parse_authorized_client(""));
495 service_authorized_client_free(client
);
499 mock_read_file_to_str(const char *filename
, int flags
, struct stat
*stat_out
)
506 if (!strcmp(filename
, get_fname("hs3" PATH_SEPARATOR
507 "authorized_clients" PATH_SEPARATOR
509 ret
= tor_strdup("descriptor:x25519:"
510 "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja");
514 if (!strcmp(filename
, get_fname("hs3" PATH_SEPARATOR
515 "authorized_clients" PATH_SEPARATOR
517 ret
= tor_strdup("descriptor:x25519:"
518 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
522 if (!strcmp(filename
, get_fname("hs3" PATH_SEPARATOR
523 "authorized_clients" PATH_SEPARATOR
525 ret
= tor_strdup("descriptor:x25519:"
526 "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta");
535 mock_tor_listdir(const char *dirname
)
537 smartlist_t
*file_list
= smartlist_new();
541 smartlist_add(file_list
, tor_strdup("client1.auth"));
542 smartlist_add(file_list
, tor_strdup("dummy.xxx"));
543 smartlist_add(file_list
, tor_strdup("client2.auth"));
549 test_load_keys_with_client_auth(void *arg
)
553 smartlist_t
*pubkey_b32_list
= smartlist_new();
554 char *hsdir_v3
= tor_strdup(get_fname("hs3"));
555 hs_service_t
*service
;
560 smartlist_add(pubkey_b32_list
, tor_strdup(
561 "dz4q5xqlb4ldnbs72iarrml4ephk3du4i7o2cgiva5lwr6wkquja"));
562 smartlist_add(pubkey_b32_list
, tor_strdup(
563 "okoi2gml3wd6x7jganlk5d66xxyjgg24sxw4y7javx4giqr66zta"));
566 "HiddenServiceDir %s\n" \
567 "HiddenServiceVersion %d\n" \
568 "HiddenServicePort 65534\n"
570 tor_asprintf(&conf
, conf_fmt
, hsdir_v3
, HS_VERSION_THREE
);
571 ret
= helper_config_service(conf
);
573 tt_int_op(ret
, OP_EQ
, 0);
574 /* It's in staging? */
575 tt_int_op(get_hs_service_staging_list_size(), OP_EQ
, 1);
579 MOCK(read_file_to_str
, mock_read_file_to_str
);
580 MOCK(tor_listdir
, mock_tor_listdir
);
582 /* Load the keys for these. After that, the v3 service should be registered
583 * in the global map. */
584 hs_service_load_all_keys();
585 tt_int_op(get_hs_service_map_size(), OP_EQ
, 1);
587 service
= get_first_service();
589 tt_assert(service
->config
.clients
);
590 tt_int_op(smartlist_len(service
->config
.clients
), OP_EQ
,
591 smartlist_len(pubkey_b32_list
));
593 /* Test that the is_client_auth_enabled flag is set. */
594 tt_assert(service
->config
.is_client_auth_enabled
);
596 /* Test that the keys in clients are correct. */
597 SMARTLIST_FOREACH_BEGIN(pubkey_b32_list
, char *, pubkey_b32
) {
599 curve25519_public_key_t pubkey
;
600 /* This flag will be set if the key is found in clients. */
602 base32_decode((char *) pubkey
.public_key
, sizeof(pubkey
.public_key
),
603 pubkey_b32
, strlen(pubkey_b32
));
605 SMARTLIST_FOREACH_BEGIN(service
->config
.clients
,
606 hs_service_authorized_client_t
*, client
) {
607 if (tor_memeq(&pubkey
, &client
->client_pk
, sizeof(pubkey
))) {
611 } SMARTLIST_FOREACH_END(client
);
615 } SMARTLIST_FOREACH_END(pubkey_b32
);
618 SMARTLIST_FOREACH(pubkey_b32_list
, char *, s
, tor_free(s
));
619 smartlist_free(pubkey_b32_list
);
622 UNMOCK(read_file_to_str
);
627 test_access_service(void *arg
)
631 char *hsdir_v3
= tor_strdup(get_fname("hs3"));
632 hs_service_ht
*global_map
;
633 hs_service_t
*s
= NULL
;
637 /* We'll register two services, a v2 and a v3, then we'll load keys and
638 * validate that both are in a correct state. */
643 "HiddenServiceDir %s\n" \
644 "HiddenServiceVersion %d\n" \
645 "HiddenServicePort 65535\n"
648 tor_asprintf(&conf
, conf_fmt
, hsdir_v3
, HS_VERSION_THREE
);
649 ret
= helper_config_service(conf
);
651 tt_int_op(ret
, OP_EQ
, 0);
652 /* It's in staging? */
653 tt_int_op(get_hs_service_staging_list_size(), OP_EQ
, 1);
655 /* Load the keys for these. After that, the v3 service should be registered
656 * in the global map. */
657 hs_service_load_all_keys();
658 tt_int_op(get_hs_service_map_size(), OP_EQ
, 1);
659 s
= get_first_service();
661 global_map
= get_hs_service_map();
662 tt_assert(global_map
);
664 /* From here, we'll try the service accessors. */
665 hs_service_t
*query
= find_service(global_map
, &s
->keys
.identity_pk
);
667 tt_mem_op(query
, OP_EQ
, s
, sizeof(hs_service_t
));
668 /* Remove service, check if it actually works and then put it back. */
669 remove_service(global_map
, s
);
670 hs_metrics_service_free(s
);
671 tt_int_op(get_hs_service_map_size(), OP_EQ
, 0);
672 query
= find_service(global_map
, &s
->keys
.identity_pk
);
673 tt_ptr_op(query
, OP_EQ
, NULL
);
675 /* Register back the service in the map. */
676 ret
= register_service(global_map
, s
);
677 tt_int_op(ret
, OP_EQ
, 0);
678 tt_int_op(get_hs_service_map_size(), OP_EQ
, 1);
679 /* Twice should fail. */
680 hs_metrics_service_free(s
); /* Avoid BUG() on metrics init. */
681 ret
= register_service(global_map
, s
);
682 tt_int_op(ret
, OP_EQ
, -1);
683 /* Remove service from map so we don't double free on cleanup. */
684 remove_service(global_map
, s
);
685 tt_int_op(get_hs_service_map_size(), OP_EQ
, 0);
686 query
= find_service(global_map
, &s
->keys
.identity_pk
);
687 tt_ptr_op(query
, OP_EQ
, NULL
);
688 /* Let's try to remove twice for fun. */
689 setup_full_capture_of_logs(LOG_WARN
);
690 remove_service(global_map
, s
);
691 expect_log_msg_containing("Could not find service in the global map");
692 teardown_capture_of_logs();
700 /** Test that we can create intro point objects, index them and find them */
702 test_service_intro_point(void *arg
)
704 hs_service_t
*service
= NULL
;
705 hs_service_intro_point_t
*ip
= NULL
;
709 update_approx_time(1481621834);
711 /* Test simple creation of an object. */
713 time_t now
= approx_time();
714 ip
= helper_create_service_ip();
716 /* Make sure the authentication keypair is not zeroes. */
717 tt_int_op(fast_mem_is_zero((const char *) &ip
->auth_key_kp
,
718 sizeof(ed25519_keypair_t
)), OP_EQ
, 0);
719 /* The introduce2_max MUST be in that range. */
720 tt_u64_op(ip
->introduce2_max
, OP_GE
,
721 INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS
);
722 tt_u64_op(ip
->introduce2_max
, OP_LE
,
723 INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS
);
724 /* Time to expire MUST also be in that range. We subtract 500 seconds
725 * because there could be a gap between setting now and the time taken in
726 * service_intro_point_new. On ARM and other older CPUs, it can be
727 * surprisingly slow... */
728 tt_u64_op(ip
->time_to_expire
, OP_GE
,
729 now
+ INTRO_POINT_LIFETIME_MIN_SECONDS
- 500);
730 /* We add 500 seconds, because this time we're testing against the
731 * maximum allowed time. */
732 tt_u64_op(ip
->time_to_expire
, OP_LE
,
733 now
+ INTRO_POINT_LIFETIME_MAX_SECONDS
+ 500);
734 tt_assert(ip
->replay_cache
);
735 tt_assert(ip
->base
.link_specifiers
);
736 /* By default, this is NOT a legacy object. */
737 tt_int_op(ip
->base
.is_only_legacy
, OP_EQ
, 0);
740 /* Test functions that uses a service intropoints map with that previously
741 * created object (non legacy). */
743 ed25519_public_key_t garbage
= { {0} };
744 hs_service_intro_point_t
*query
;
746 service
= hs_service_new(get_options());
748 service
->desc_current
= service_descriptor_new();
749 tt_assert(service
->desc_current
);
750 /* Add intropoint to descriptor map. */
751 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
752 query
= service_intro_point_find(service
, &ip
->auth_key_kp
.pubkey
);
753 tt_mem_op(query
, OP_EQ
, ip
, sizeof(hs_service_intro_point_t
));
754 query
= service_intro_point_find(service
, &garbage
);
755 tt_ptr_op(query
, OP_EQ
, NULL
);
757 /* While at it, can I find the descriptor with the intro point? */
758 hs_service_descriptor_t
*desc_lookup
=
759 service_desc_find_by_intro(service
, ip
);
760 tt_mem_op(service
->desc_current
, OP_EQ
, desc_lookup
,
761 sizeof(hs_service_descriptor_t
));
763 /* Remove object from service descriptor and make sure it is out. */
764 service_intro_point_remove(service
, ip
);
765 query
= service_intro_point_find(service
, &ip
->auth_key_kp
.pubkey
);
766 tt_ptr_op(query
, OP_EQ
, NULL
);
770 /* If the test succeed, this object is no longer referenced in the service
771 * so we can free it without use after free. Else, it might explode because
772 * it's still in the service descriptor map. */
773 service_intro_point_free(ip
);
774 hs_service_free(service
);
777 static node_t mock_node
;
778 static const node_t
*
779 mock_node_get_by_id(const char *digest
)
782 memset(mock_node
.identity
, 'A', DIGEST_LEN
);
783 /* Only return the matching identity of As */
784 if (!tor_memcmp(mock_node
.identity
, digest
, DIGEST_LEN
)) {
791 test_helper_functions(void *arg
)
794 hs_service_t
*service
= NULL
;
795 hs_service_intro_point_t
*ip
= NULL
;
796 hs_ident_circuit_t ident
;
800 MOCK(node_get_by_id
, mock_node_get_by_id
);
803 time_t now
= time(NULL
);
804 update_approx_time(now
);
806 service
= helper_create_service();
808 ip
= helper_create_service_ip();
809 /* Immediately add the intro point to the service so the free service at the
810 * end cleans it as well. */
811 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
813 /* Setup the circuit identifier. */
814 ed25519_pubkey_copy(&ident
.intro_auth_pk
, &ip
->auth_key_kp
.pubkey
);
815 ed25519_pubkey_copy(&ident
.identity_pk
, &service
->keys
.identity_pk
);
817 /* Testing get_objects_from_ident(). */
819 hs_service_t
*s_lookup
= NULL
;
820 hs_service_intro_point_t
*ip_lookup
= NULL
;
821 hs_service_descriptor_t
*desc_lookup
= NULL
;
823 get_objects_from_ident(&ident
, &s_lookup
, &ip_lookup
, &desc_lookup
);
824 tt_mem_op(s_lookup
, OP_EQ
, service
, sizeof(hs_service_t
));
825 tt_mem_op(ip_lookup
, OP_EQ
, ip
, sizeof(hs_service_intro_point_t
));
826 tt_mem_op(desc_lookup
, OP_EQ
, service
->desc_current
,
827 sizeof(hs_service_descriptor_t
));
829 s_lookup
= NULL
; ip_lookup
= NULL
; desc_lookup
= NULL
;
831 /* NULL parameter should work. */
832 get_objects_from_ident(&ident
, NULL
, &ip_lookup
, &desc_lookup
);
833 tt_mem_op(ip_lookup
, OP_EQ
, ip
, sizeof(hs_service_intro_point_t
));
834 tt_mem_op(desc_lookup
, OP_EQ
, service
->desc_current
,
835 sizeof(hs_service_descriptor_t
));
837 s_lookup
= NULL
; ip_lookup
= NULL
; desc_lookup
= NULL
;
839 /* Break the ident and we should find nothing. */
840 memset(&ident
, 0, sizeof(ident
));
841 get_objects_from_ident(&ident
, &s_lookup
, &ip_lookup
, &desc_lookup
);
842 tt_ptr_op(s_lookup
, OP_EQ
, NULL
);
843 tt_ptr_op(ip_lookup
, OP_EQ
, NULL
);
844 tt_ptr_op(desc_lookup
, OP_EQ
, NULL
);
847 /* Testing get_node_from_intro_point() */
849 const node_t
*node
= get_node_from_intro_point(ip
);
850 tt_ptr_op(node
, OP_EQ
, &mock_node
);
851 SMARTLIST_FOREACH_BEGIN(ip
->base
.link_specifiers
,
852 link_specifier_t
*, ls
) {
853 if (link_specifier_get_ls_type(ls
) == LS_LEGACY_ID
) {
854 /* Change legacy id in link specifier which is not the mock node. */
855 memset(link_specifier_getarray_un_legacy_id(ls
), 'B',
856 link_specifier_getlen_un_legacy_id(ls
));
858 } SMARTLIST_FOREACH_END(ls
);
859 node
= get_node_from_intro_point(ip
);
860 tt_ptr_op(node
, OP_EQ
, NULL
);
863 /* Testing can_service_launch_intro_circuit() */
865 /* Put the start of the retry period back in time, we should be allowed.
866 * to launch intro circuit. */
867 service
->state
.num_intro_circ_launched
= 2;
868 service
->state
.intro_circ_retry_started_time
=
869 (now
- INTRO_CIRC_RETRY_PERIOD
- 1);
870 ret
= can_service_launch_intro_circuit(service
, now
);
871 tt_int_op(ret
, OP_EQ
, 1);
872 tt_u64_op(service
->state
.intro_circ_retry_started_time
, OP_EQ
, now
);
873 tt_u64_op(service
->state
.num_intro_circ_launched
, OP_EQ
, 0);
874 /* Call it again, we should still be allowed because we are under
875 * MAX_INTRO_CIRCS_PER_PERIOD which been set to 0 previously. */
876 ret
= can_service_launch_intro_circuit(service
, now
);
877 tt_int_op(ret
, OP_EQ
, 1);
878 tt_u64_op(service
->state
.intro_circ_retry_started_time
, OP_EQ
, now
);
879 tt_u64_op(service
->state
.num_intro_circ_launched
, OP_EQ
, 0);
880 /* Too many intro circuit launched means we are not allowed. */
881 service
->state
.num_intro_circ_launched
= 20;
882 ret
= can_service_launch_intro_circuit(service
, now
);
883 tt_int_op(ret
, OP_EQ
, 0);
886 /* Testing intro_point_should_expire(). */
888 /* Just some basic test of the current state. */
889 tt_u64_op(ip
->introduce2_max
, OP_GE
,
890 INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS
);
891 tt_u64_op(ip
->introduce2_max
, OP_LE
,
892 INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS
);
893 tt_u64_op(ip
->time_to_expire
, OP_GE
,
894 now
+ INTRO_POINT_LIFETIME_MIN_SECONDS
);
895 tt_u64_op(ip
->time_to_expire
, OP_LE
,
896 now
+ INTRO_POINT_LIFETIME_MAX_SECONDS
);
898 /* This newly created IP from above shouldn't expire now. */
899 ret
= intro_point_should_expire(ip
, now
);
900 tt_int_op(ret
, OP_EQ
, 0);
901 /* Maximum number of INTRODUCE2 cell reached, it should expire. */
902 ip
->introduce2_count
= INTRO_POINT_MAX_LIFETIME_INTRODUCTIONS
+ 1;
903 ret
= intro_point_should_expire(ip
, now
);
904 tt_int_op(ret
, OP_EQ
, 1);
905 ip
->introduce2_count
= 0;
906 /* It should expire if time to expire has been reached. */
907 ip
->time_to_expire
= now
- 1000;
908 ret
= intro_point_should_expire(ip
, now
);
909 tt_int_op(ret
, OP_EQ
, 1);
913 /* This will free the service and all objects associated to it. */
915 remove_service(get_hs_service_map(), service
);
916 hs_service_free(service
);
918 hs_service_free_all();
919 UNMOCK(node_get_by_id
);
922 /** Test that we do the right operations when an intro circuit opens */
924 test_intro_circuit_opened(void *arg
)
926 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
927 hs_service_t
*service
= NULL
;
928 origin_circuit_t
*circ
= NULL
;
933 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
934 MOCK(relay_send_command_from_edge_
, mock_relay_send_command_from_edge
);
936 circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
,
939 /* No service associated with this circuit. */
940 setup_full_capture_of_logs(LOG_WARN
);
941 hs_service_circuit_has_opened(circ
);
942 expect_log_msg_containing("Unknown service identity key");
943 teardown_capture_of_logs();
945 /* Set a service for this circuit. */
947 service
= helper_create_service();
948 ed25519_pubkey_copy(&circ
->hs_ident
->identity_pk
,
949 &service
->keys
.identity_pk
);
951 /* No intro point associated with this circuit. */
952 setup_full_capture_of_logs(LOG_WARN
);
953 hs_service_circuit_has_opened(circ
);
954 expect_log_msg_containing("Unknown introduction point auth key");
955 teardown_capture_of_logs();
958 /* Set an IP object now for this circuit. */
960 hs_service_intro_point_t
*ip
= helper_create_service_ip();
961 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
962 /* Update ident to contain the intro point auth key. */
963 ed25519_pubkey_copy(&circ
->hs_ident
->intro_auth_pk
,
964 &ip
->auth_key_kp
.pubkey
);
967 /* This one should go all the way. */
968 setup_full_capture_of_logs(LOG_INFO
);
969 hs_service_circuit_has_opened(circ
);
970 expect_log_msg_containing("Introduction circuit 0 established for service");
971 teardown_capture_of_logs();
974 circuit_free_(TO_CIRCUIT(circ
));
976 remove_service(get_hs_service_map(), service
);
977 hs_service_free(service
);
980 UNMOCK(circuit_mark_for_close_
);
981 UNMOCK(relay_send_command_from_edge_
);
984 /** Test the operations we do on a circuit after we learn that we successfully
985 * established an intro point on it */
987 test_intro_established(void *arg
)
990 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
991 uint8_t payload
[RELAY_PAYLOAD_SIZE
] = {0};
992 origin_circuit_t
*circ
= NULL
;
993 hs_service_t
*service
= NULL
;
994 hs_service_intro_point_t
*ip
= NULL
;
999 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
1001 circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
,
1005 /* Test a wrong purpose. */
1006 TO_CIRCUIT(circ
)->purpose
= CIRCUIT_PURPOSE_S_INTRO
;
1007 setup_full_capture_of_logs(LOG_WARN
);
1008 ret
= hs_service_receive_intro_established(circ
, payload
, sizeof(payload
));
1009 tt_int_op(ret
, OP_EQ
, -1);
1010 expect_log_msg_containing("Received an INTRO_ESTABLISHED cell on a "
1011 "non introduction circuit of purpose");
1012 teardown_capture_of_logs();
1014 /* Back to normal. */
1015 TO_CIRCUIT(circ
)->purpose
= CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
;
1017 /* No service associated to it. */
1018 setup_full_capture_of_logs(LOG_WARN
);
1019 ret
= hs_service_receive_intro_established(circ
, payload
, sizeof(payload
));
1020 tt_int_op(ret
, OP_EQ
, -1);
1021 expect_log_msg_containing("Unknown service identity key");
1022 teardown_capture_of_logs();
1024 /* Set a service for this circuit. */
1025 service
= helper_create_service();
1026 ed25519_pubkey_copy(&circ
->hs_ident
->identity_pk
,
1027 &service
->keys
.identity_pk
);
1028 /* No introduction point associated to it. */
1029 setup_full_capture_of_logs(LOG_WARN
);
1030 ret
= hs_service_receive_intro_established(circ
, payload
, sizeof(payload
));
1031 tt_int_op(ret
, OP_EQ
, -1);
1032 expect_log_msg_containing("Introduction circuit established without an "
1033 "intro point object on circuit");
1034 teardown_capture_of_logs();
1036 /* Set an IP object now for this circuit. */
1038 ip
= helper_create_service_ip();
1039 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1040 /* Update ident to contain the intro point auth key. */
1041 ed25519_pubkey_copy(&circ
->hs_ident
->intro_auth_pk
,
1042 &ip
->auth_key_kp
.pubkey
);
1045 /* Send an empty payload. INTRO_ESTABLISHED cells are basically zeroes. */
1046 ret
= hs_service_receive_intro_established(circ
, payload
, sizeof(payload
));
1047 tt_int_op(ret
, OP_EQ
, 0);
1048 tt_int_op(TO_CIRCUIT(circ
)->purpose
, OP_EQ
, CIRCUIT_PURPOSE_S_INTRO
);
1052 circuit_free_(TO_CIRCUIT(circ
));
1054 remove_service(get_hs_service_map(), service
);
1055 hs_service_free(service
);
1058 UNMOCK(circuit_mark_for_close_
);
1061 /** Check the operations we do on a rendezvous circuit after we learn it's
1064 test_rdv_circuit_opened(void *arg
)
1066 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
1067 origin_circuit_t
*circ
= NULL
;
1068 hs_service_t
*service
= NULL
;
1073 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
1074 MOCK(relay_send_command_from_edge_
, mock_relay_send_command_from_edge
);
1076 circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_CONNECT_REND
, flags
);
1077 crypto_rand((char *) circ
->hs_ident
->rendezvous_cookie
, REND_COOKIE_LEN
);
1078 crypto_rand((char *) circ
->hs_ident
->rendezvous_handshake_info
,
1079 sizeof(circ
->hs_ident
->rendezvous_handshake_info
));
1081 /* No service associated with this circuit. */
1082 setup_full_capture_of_logs(LOG_WARN
);
1083 hs_service_circuit_has_opened(circ
);
1084 expect_log_msg_containing("Unknown service identity key");
1085 teardown_capture_of_logs();
1086 /* This should be set to a non zero timestamp. */
1087 tt_u64_op(TO_CIRCUIT(circ
)->timestamp_dirty
, OP_NE
, 0);
1089 /* Set a service for this circuit. */
1090 service
= helper_create_service();
1091 ed25519_pubkey_copy(&circ
->hs_ident
->identity_pk
,
1092 &service
->keys
.identity_pk
);
1093 /* Should be all good. */
1094 hs_service_circuit_has_opened(circ
);
1095 tt_int_op(TO_CIRCUIT(circ
)->purpose
, OP_EQ
, CIRCUIT_PURPOSE_S_REND_JOINED
);
1098 circuit_free_(TO_CIRCUIT(circ
));
1100 remove_service(get_hs_service_map(), service
);
1101 hs_service_free(service
);
1104 UNMOCK(circuit_mark_for_close_
);
1105 UNMOCK(relay_send_command_from_edge_
);
1109 mock_assert_circuit_ok(const circuit_t
*c
)
1115 /** Test for the general mechanism for closing intro circs.
1116 * Also a way to identify that #23603 has been fixed. */
1118 test_closing_intro_circs(void *arg
)
1120 hs_service_t
*service
= NULL
;
1121 hs_service_intro_point_t
*ip
= NULL
, *entry
= NULL
;
1122 origin_circuit_t
*intro_circ
= NULL
, *tmp_circ
;
1123 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
1127 MOCK(assert_circuit_ok
, mock_assert_circuit_ok
);
1131 /* Initialize service */
1132 service
= helper_create_service();
1133 /* Initialize intro point */
1134 ip
= helper_create_service_ip();
1136 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1138 /* Initialize intro circuit */
1139 intro_circ
= origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
, flags
);
1140 intro_circ
->hs_ident
= hs_ident_circuit_new(&service
->keys
.identity_pk
);
1141 /* Register circuit in the circuitmap . */
1142 hs_circuitmap_register_intro_circ_v3_service_side(intro_circ
,
1143 &ip
->auth_key_kp
.pubkey
);
1145 hs_circuitmap_get_intro_circ_v3_service_side(&ip
->auth_key_kp
.pubkey
);
1146 tt_ptr_op(tmp_circ
, OP_EQ
, intro_circ
);
1148 /* Pretend that intro point has failed too much */
1149 ip
->circuit_retries
= MAX_INTRO_POINT_CIRCUIT_RETRIES
+1;
1151 /* Now pretend we are freeing this intro circuit. We want to see that our
1152 * destructor is not gonna kill our intro point structure since that's the
1153 * job of the cleanup routine. */
1154 circuit_free_(TO_CIRCUIT(intro_circ
));
1156 entry
= service_intro_point_find(service
, &ip
->auth_key_kp
.pubkey
);
1158 /* The free should also remove the circuit from the circuitmap. */
1160 hs_circuitmap_get_intro_circ_v3_service_side(&ip
->auth_key_kp
.pubkey
);
1161 tt_assert(!tmp_circ
);
1163 /* Now pretend that a new intro point circ was launched and opened. Check
1164 * that the intro point will be established correctly. */
1165 intro_circ
= origin_circuit_init(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
, flags
);
1166 intro_circ
->hs_ident
= hs_ident_circuit_new(&service
->keys
.identity_pk
);
1167 ed25519_pubkey_copy(&intro_circ
->hs_ident
->intro_auth_pk
,
1168 &ip
->auth_key_kp
.pubkey
);
1169 /* Register circuit in the circuitmap . */
1170 hs_circuitmap_register_intro_circ_v3_service_side(intro_circ
,
1171 &ip
->auth_key_kp
.pubkey
);
1173 hs_circuitmap_get_intro_circ_v3_service_side(&ip
->auth_key_kp
.pubkey
);
1174 tt_ptr_op(tmp_circ
, OP_EQ
, intro_circ
);
1175 tt_int_op(TO_CIRCUIT(intro_circ
)->marked_for_close
, OP_EQ
, 0);
1176 circuit_mark_for_close(TO_CIRCUIT(intro_circ
), END_CIRC_REASON_INTERNAL
);
1177 tt_int_op(TO_CIRCUIT(intro_circ
)->marked_for_close
, OP_NE
, 0);
1178 /* At this point, we should not be able to find it in the circuitmap. */
1180 hs_circuitmap_get_intro_circ_v3_service_side(&ip
->auth_key_kp
.pubkey
);
1181 tt_assert(!tmp_circ
);
1185 circuit_free_(TO_CIRCUIT(intro_circ
));
1187 /* Frees the service object. */
1189 remove_service(get_hs_service_map(), service
);
1190 hs_service_free(service
);
1193 UNMOCK(assert_circuit_ok
);
1196 /** Test sending and receiving introduce2 cells */
1198 test_bad_introduce2(void *arg
)
1201 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
1202 uint8_t payload
[RELAY_PAYLOAD_SIZE
] = {0};
1203 origin_circuit_t
*circ
= NULL
;
1204 hs_service_t
*service
= NULL
;
1205 hs_service_intro_point_t
*ip
= NULL
;
1210 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
1212 get_or_state_replacement
);
1214 dummy_state
= or_state_new();
1216 circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO
, flags
);
1219 /* Test a wrong purpose. */
1220 TO_CIRCUIT(circ
)->purpose
= CIRCUIT_PURPOSE_S_ESTABLISH_INTRO
;
1221 setup_full_capture_of_logs(LOG_WARN
);
1222 ret
= hs_service_receive_introduce2(circ
, payload
, sizeof(payload
));
1223 tt_int_op(ret
, OP_EQ
, -1);
1224 expect_log_msg_containing("Received an INTRODUCE2 cell on a "
1225 "non introduction circuit of purpose");
1226 teardown_capture_of_logs();
1228 /* Back to normal. */
1229 TO_CIRCUIT(circ
)->purpose
= CIRCUIT_PURPOSE_S_INTRO
;
1231 /* No service associated to it. */
1232 setup_full_capture_of_logs(LOG_WARN
);
1233 ret
= hs_service_receive_introduce2(circ
, payload
, sizeof(payload
));
1234 tt_int_op(ret
, OP_EQ
, -1);
1235 expect_log_msg_containing("Unknown service identity key");
1236 teardown_capture_of_logs();
1238 /* Set a service for this circuit. */
1239 service
= helper_create_service();
1240 ed25519_pubkey_copy(&circ
->hs_ident
->identity_pk
,
1241 &service
->keys
.identity_pk
);
1242 /* No introduction point associated to it. */
1243 setup_full_capture_of_logs(LOG_WARN
);
1244 ret
= hs_service_receive_introduce2(circ
, payload
, sizeof(payload
));
1245 tt_int_op(ret
, OP_EQ
, -1);
1246 expect_log_msg_containing("Unknown introduction auth key when handling "
1247 "an INTRODUCE2 cell on circuit");
1248 teardown_capture_of_logs();
1250 /* Set an IP object now for this circuit. */
1252 ip
= helper_create_service_ip();
1253 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1254 /* Update ident to contain the intro point auth key. */
1255 ed25519_pubkey_copy(&circ
->hs_ident
->intro_auth_pk
,
1256 &ip
->auth_key_kp
.pubkey
);
1259 /* This will fail because receiving an INTRODUCE2 cell implies a valid cell
1260 * and then launching circuits so let's not do that and instead test that
1261 * behaviour differently. */
1262 ret
= hs_service_receive_introduce2(circ
, payload
, sizeof(payload
));
1263 tt_int_op(ret
, OP_EQ
, -1);
1264 tt_u64_op(ip
->introduce2_count
, OP_EQ
, 0);
1267 or_state_free(dummy_state
);
1270 circuit_free_(TO_CIRCUIT(circ
));
1272 remove_service(get_hs_service_map(), service
);
1273 hs_service_free(service
);
1276 UNMOCK(circuit_mark_for_close_
);
1279 /** Test basic hidden service housekeeping operations (maintaining intro
1282 test_service_event(void *arg
)
1284 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
1285 time_t now
= time(NULL
);
1286 hs_service_t
*service
;
1287 origin_circuit_t
*circ
= NULL
;
1292 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
1294 circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_INTRO
, flags
);
1296 /* Set a service for this circuit. */
1297 service
= helper_create_service();
1299 ed25519_pubkey_copy(&circ
->hs_ident
->identity_pk
,
1300 &service
->keys
.identity_pk
);
1302 /* Currently this consists of cleaning invalid intro points. So adding IPs
1303 * here that should get cleaned up. */
1305 hs_service_intro_point_t
*ip
= helper_create_service_ip();
1306 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1307 /* This run will remove the IP because we have no circuits nor node_t
1308 * associated with it. */
1309 run_housekeeping_event(now
);
1310 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1312 /* We'll trigger a removal because we've reached our maximum amount of
1313 * times we should retry a circuit. For this, we need to have a node_t
1314 * that matches the identity of this IP. */
1316 memset(&ri
, 0, sizeof(ri
));
1317 ip
= helper_create_service_ip();
1318 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1319 memset(ri
.cache_info
.identity_digest
, 'A', DIGEST_LEN
);
1320 /* This triggers a node_t creation. */
1321 tt_assert(nodelist_set_routerinfo(&ri
, NULL
));
1322 ip
->circuit_retries
= MAX_INTRO_POINT_CIRCUIT_RETRIES
+ 1;
1323 run_housekeeping_event(now
);
1324 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1326 /* No removal but no circuit so this means the IP object will stay in the
1327 * descriptor map so we can retry it. */
1328 ip
= helper_create_service_ip();
1329 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1330 run_housekeeping_event(now
);
1331 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1333 /* Remove the IP object at once for the next test. */
1334 ip
->circuit_retries
= MAX_INTRO_POINT_CIRCUIT_RETRIES
+ 1;
1335 run_housekeeping_event(now
);
1336 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1338 /* Now, we'll create an IP with a registered circuit. The IP object
1339 * shouldn't go away. */
1340 ip
= helper_create_service_ip();
1341 service_intro_point_add(service
->desc_current
->intro_points
.map
, ip
);
1342 ed25519_pubkey_copy(&circ
->hs_ident
->intro_auth_pk
,
1343 &ip
->auth_key_kp
.pubkey
);
1344 hs_circuitmap_register_intro_circ_v3_service_side(
1345 circ
, &ip
->auth_key_kp
.pubkey
);
1346 run_housekeeping_event(now
);
1347 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1349 /* We'll mangle the IP object to expire. */
1350 ip
->time_to_expire
= now
;
1351 run_housekeeping_event(now
);
1352 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1357 hs_circuitmap_remove_circuit(TO_CIRCUIT(circ
));
1358 circuit_free_(TO_CIRCUIT(circ
));
1360 remove_service(get_hs_service_map(), service
);
1361 hs_service_free(service
);
1364 UNMOCK(circuit_mark_for_close_
);
1367 /** Test that we rotate descriptors correctly. */
1369 test_rotate_descriptors(void *arg
)
1372 time_t next_rotation_time
, now
;
1373 hs_service_t
*service
= NULL
;
1374 hs_service_descriptor_t
*desc_next
;
1378 dummy_state
= or_state_new();
1381 MOCK(get_or_state
, get_or_state_replacement
);
1382 MOCK(circuit_mark_for_close_
, mock_circuit_mark_for_close
);
1383 MOCK(networkstatus_get_reasonably_live_consensus
,
1384 mock_networkstatus_get_reasonably_live_consensus
);
1386 /* Descriptor rotation happens with a consensus with a new SRV. */
1388 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
1389 &mock_ns
.valid_after
);
1390 tt_int_op(ret
, OP_EQ
, 0);
1391 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
1392 &mock_ns
.fresh_until
);
1393 tt_int_op(ret
, OP_EQ
, 0);
1394 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
1396 update_approx_time(mock_ns
.valid_after
+1);
1397 now
= mock_ns
.valid_after
+1;
1399 /* Create a service with a default descriptor and state. It's added to the
1401 service
= helper_create_service();
1402 service_descriptor_free(service
->desc_current
);
1403 service
->desc_current
= NULL
;
1404 /* This triggers a build for both descriptors. The time now is only used in
1405 * the descriptor certificate which is important to be now else the decoding
1406 * will complain that the cert has expired if we use valid_after. */
1407 build_all_descriptors(now
);
1408 tt_assert(service
->desc_current
);
1409 tt_assert(service
->desc_next
);
1411 /* Tweak our service next rotation time so we can use a custom time. */
1412 service
->state
.next_rotation_time
= next_rotation_time
=
1413 mock_ns
.valid_after
+ (11 * 60 * 60);
1415 /* Nothing should happen, we are not at a new SRV. Our next rotation time
1416 * should be untouched. */
1417 rotate_all_descriptors(mock_ns
.valid_after
);
1418 tt_u64_op(service
->state
.next_rotation_time
, OP_EQ
, next_rotation_time
);
1419 tt_assert(service
->desc_current
);
1420 tt_assert(service
->desc_next
);
1421 tt_u64_op(service
->desc_current
->time_period_num
, OP_EQ
,
1422 hs_get_previous_time_period_num(0));
1423 tt_u64_op(service
->desc_next
->time_period_num
, OP_EQ
,
1424 hs_get_time_period_num(0));
1425 /* Keep a reference so we can compare it after rotation to the current. */
1426 desc_next
= service
->desc_next
;
1428 /* Going right after a new SRV. */
1429 ret
= parse_rfc1123_time("Sat, 27 Oct 1985 01:00:00 UTC",
1430 &mock_ns
.valid_after
);
1431 tt_int_op(ret
, OP_EQ
, 0);
1432 ret
= parse_rfc1123_time("Sat, 27 Oct 1985 02:00:00 UTC",
1433 &mock_ns
.fresh_until
);
1434 tt_int_op(ret
, OP_EQ
, 0);
1435 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
1437 update_approx_time(mock_ns
.valid_after
+1);
1438 now
= mock_ns
.valid_after
+1;
1440 /* Note down what to expect for the next rotation time which is 01:00 + 23h
1441 * meaning 00:00:00. */
1442 next_rotation_time
= mock_ns
.valid_after
+ (23 * 60 * 60);
1443 /* We should have our next rotation time modified, our current descriptor
1444 * cleaned up and the next descriptor becoming the current. */
1445 rotate_all_descriptors(mock_ns
.valid_after
);
1446 tt_u64_op(service
->state
.next_rotation_time
, OP_EQ
, next_rotation_time
);
1447 tt_mem_op(service
->desc_current
, OP_EQ
, desc_next
, sizeof(*desc_next
));
1448 tt_assert(service
->desc_next
== NULL
);
1450 /* A second time should do nothing. */
1451 rotate_all_descriptors(mock_ns
.valid_after
);
1452 tt_u64_op(service
->state
.next_rotation_time
, OP_EQ
, next_rotation_time
);
1453 tt_mem_op(service
->desc_current
, OP_EQ
, desc_next
, sizeof(*desc_next
));
1454 tt_assert(service
->desc_next
== NULL
);
1456 build_all_descriptors(now
);
1457 tt_mem_op(service
->desc_current
, OP_EQ
, desc_next
, sizeof(*desc_next
));
1458 tt_u64_op(service
->desc_current
->time_period_num
, OP_EQ
,
1459 hs_get_time_period_num(0));
1460 tt_u64_op(service
->desc_next
->time_period_num
, OP_EQ
,
1461 hs_get_next_time_period_num(0));
1462 tt_assert(service
->desc_next
);
1466 remove_service(get_hs_service_map(), service
);
1467 hs_service_free(service
);
1470 UNMOCK(get_or_state
);
1471 UNMOCK(circuit_mark_for_close_
);
1472 UNMOCK(networkstatus_get_reasonably_live_consensus
);
1475 /** Test building descriptors: picking intro points, setting up their link
1476 * specifiers, etc. */
1478 test_build_update_descriptors(void *arg
)
1482 hs_service_t
*service
= NULL
;
1483 hs_service_intro_point_t
*ip_cur
, *ip_next
;
1491 get_or_state_replacement
);
1492 MOCK(networkstatus_get_reasonably_live_consensus
,
1493 mock_networkstatus_get_reasonably_live_consensus
);
1495 dummy_state
= or_state_new();
1497 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
1498 &mock_ns
.valid_after
);
1499 tt_int_op(ret
, OP_EQ
, 0);
1500 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
1501 &mock_ns
.fresh_until
);
1502 tt_int_op(ret
, OP_EQ
, 0);
1503 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
1505 update_approx_time(mock_ns
.valid_after
+1);
1507 time_t now
= mock_ns
.valid_after
+1;
1509 /* Create a service without a current descriptor to trigger a build. */
1510 service
= helper_create_service();
1512 /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
1513 service_descriptor_free(service
->desc_current
);
1514 service
->desc_current
= NULL
;
1516 /* We have a fresh service so this should trigger a build for both
1517 * descriptors for specific time period that we'll test. */
1518 build_all_descriptors(now
);
1519 /* Check *current* descriptor. */
1520 tt_assert(service
->desc_current
);
1521 tt_assert(service
->desc_current
->desc
);
1522 tt_assert(service
->desc_current
->intro_points
.map
);
1523 /* The current time period is the one expected when starting at 03:00. */
1524 tt_u64_op(service
->desc_current
->time_period_num
, OP_EQ
,
1525 hs_get_time_period_num(0));
1526 /* This should be untouched, the update descriptor process changes it. */
1527 tt_u64_op(service
->desc_current
->next_upload_time
, OP_EQ
, 0);
1529 /* Check *next* descriptor. */
1530 tt_assert(service
->desc_next
);
1531 tt_assert(service
->desc_next
->desc
);
1532 tt_assert(service
->desc_next
->intro_points
.map
);
1533 tt_assert(service
->desc_current
!= service
->desc_next
);
1534 tt_u64_op(service
->desc_next
->time_period_num
, OP_EQ
,
1535 hs_get_next_time_period_num(0));
1536 /* This should be untouched, the update descriptor process changes it. */
1537 tt_u64_op(service
->desc_next
->next_upload_time
, OP_EQ
, 0);
1539 /* Time to test the update of those descriptors. At first, we have no node
1540 * in the routerlist so this will find NO suitable node for the IPs. */
1541 setup_full_capture_of_logs(LOG_INFO
);
1542 update_all_descriptors_intro_points(now
);
1543 expect_log_msg_containing("Unable to find a suitable node to be an "
1544 "introduction point for service");
1545 teardown_capture_of_logs();
1546 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1548 tt_int_op(digest256map_size(service
->desc_next
->intro_points
.map
),
1551 /* Now, we'll setup a node_t. */
1553 curve25519_secret_key_t curve25519_secret_key
;
1555 memset(&ri
, 0, sizeof(routerinfo_t
));
1557 tor_addr_parse(&ri
.ipv4_addr
, "127.0.0.1");
1558 ri
.ipv4_orport
= 1337;
1559 ri
.purpose
= ROUTER_PURPOSE_GENERAL
;
1560 /* Ugly yes but we never free the "ri" object so this just makes things
1562 ri
.protocol_list
= (char *) "HSDir=1-2 LinkAuth=3";
1563 summarize_protover_flags(&ri
.pv
, ri
.protocol_list
, NULL
);
1564 ret
= curve25519_secret_key_generate(&curve25519_secret_key
, 0);
1565 tt_int_op(ret
, OP_EQ
, 0);
1566 ri
.onion_curve25519_pkey
=
1567 tor_malloc_zero(sizeof(curve25519_public_key_t
));
1568 ri
.onion_pkey
= tor_malloc_zero(140);
1569 curve25519_public_key_generate(ri
.onion_curve25519_pkey
,
1570 &curve25519_secret_key
);
1571 memset(ri
.cache_info
.identity_digest
, 'A', DIGEST_LEN
);
1572 /* Setup ed25519 identity */
1573 ed25519_keypair_t kp1
;
1574 ed25519_keypair_generate(&kp1
, 0);
1575 ri
.cache_info
.signing_key_cert
= tor_malloc_zero(sizeof(tor_cert_t
));
1576 tt_assert(ri
.cache_info
.signing_key_cert
);
1577 ed25519_pubkey_copy(&ri
.cache_info
.signing_key_cert
->signing_key
,
1579 nodelist_set_routerinfo(&ri
, NULL
);
1580 node
= node_get_mutable_by_id(ri
.cache_info
.identity_digest
);
1582 node
->is_running
= node
->is_valid
= node
->is_fast
= node
->is_stable
= 1;
1585 /* We have to set this, or the lack of microdescriptors for these
1586 * nodes will make them unusable. */
1587 get_options_mutable()->UseMicrodescriptors
= 0;
1589 /* We expect to pick only one intro point from the node above. */
1590 setup_full_capture_of_logs(LOG_INFO
);
1591 update_all_descriptors_intro_points(now
);
1592 tor_free(node
->ri
->onion_curve25519_pkey
); /* Avoid memleak. */
1593 tor_free(node
->ri
->cache_info
.signing_key_cert
);
1594 tor_free(node
->ri
->onion_pkey
);
1595 expect_log_msg_containing("just picked 1 intro points and wanted 3 for next "
1596 "descriptor. It currently has 0 intro points. "
1597 "Launching ESTABLISH_INTRO circuit shortly.");
1598 teardown_capture_of_logs();
1599 tt_int_op(digest256map_size(service
->desc_current
->intro_points
.map
),
1601 tt_int_op(digest256map_size(service
->desc_next
->intro_points
.map
),
1603 /* Get the IP object. Because we don't have the auth key of the IP, we can't
1604 * query it so get the first element in the map. */
1608 digest256map_iter_t
*iter
=
1609 digest256map_iter_init(service
->desc_current
->intro_points
.map
);
1610 digest256map_iter_get(iter
, &key
, &obj
);
1613 /* Get also the IP from the next descriptor. We'll make sure it's not the
1614 * same object as in the current descriptor. */
1615 iter
= digest256map_iter_init(service
->desc_next
->intro_points
.map
);
1616 digest256map_iter_get(iter
, &key
, &obj
);
1620 tt_mem_op(ip_cur
, OP_NE
, ip_next
, sizeof(hs_desc_intro_point_t
));
1622 /* We won't test the service IP object because there is a specific test
1623 * already for this but we'll make sure that the state is coherent.*/
1625 /* Three link specifiers are mandatory so make sure we do have them. */
1626 tt_int_op(smartlist_len(ip_cur
->base
.link_specifiers
), OP_EQ
, 3);
1627 /* Make sure we have a valid encryption keypair generated when we pick an
1628 * intro point in the update process. */
1629 tt_assert(!fast_mem_is_zero((char *) ip_cur
->enc_key_kp
.seckey
.secret_key
,
1630 CURVE25519_SECKEY_LEN
));
1631 tt_assert(!fast_mem_is_zero((char *) ip_cur
->enc_key_kp
.pubkey
.public_key
,
1632 CURVE25519_PUBKEY_LEN
));
1633 tt_u64_op(ip_cur
->time_to_expire
, OP_GE
, now
+
1634 INTRO_POINT_LIFETIME_MIN_SECONDS
);
1635 tt_u64_op(ip_cur
->time_to_expire
, OP_LE
, now
+
1636 INTRO_POINT_LIFETIME_MAX_SECONDS
);
1638 /* Now, we will try to set up a service after a new time period has started
1639 * and see if it behaves as expected. */
1641 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
1642 &mock_ns
.valid_after
);
1643 tt_int_op(ret
, OP_EQ
, 0);
1644 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
1645 &mock_ns
.fresh_until
);
1646 tt_int_op(ret
, OP_EQ
, 0);
1648 update_approx_time(mock_ns
.valid_after
+1);
1649 now
= mock_ns
.valid_after
+1;
1651 /* Create a service without a current descriptor to trigger a build. */
1652 service
= helper_create_service();
1654 /* Unfortunately, the helper creates a dummy descriptor so get rid of it. */
1655 service_descriptor_free(service
->desc_current
);
1656 service
->desc_current
= NULL
;
1658 /* We have a fresh service so this should trigger a build for both
1659 * descriptors for specific time period that we'll test. */
1660 build_all_descriptors(now
);
1661 /* Check *current* descriptor. */
1662 tt_assert(service
->desc_current
);
1663 tt_assert(service
->desc_current
->desc
);
1664 tt_assert(service
->desc_current
->intro_points
.map
);
1665 /* This should be for the previous time period. */
1666 tt_u64_op(service
->desc_current
->time_period_num
, OP_EQ
,
1667 hs_get_previous_time_period_num(0));
1668 /* This should be untouched, the update descriptor process changes it. */
1669 tt_u64_op(service
->desc_current
->next_upload_time
, OP_EQ
, 0);
1671 /* Check *next* descriptor. */
1672 tt_assert(service
->desc_next
);
1673 tt_assert(service
->desc_next
->desc
);
1674 tt_assert(service
->desc_next
->intro_points
.map
);
1675 tt_assert(service
->desc_current
!= service
->desc_next
);
1676 tt_u64_op(service
->desc_next
->time_period_num
, OP_EQ
,
1677 hs_get_time_period_num(0));
1678 /* This should be untouched, the update descriptor process changes it. */
1679 tt_u64_op(service
->desc_next
->next_upload_time
, OP_EQ
, 0);
1681 /* Let's remove the next descriptor to simulate a rotation. */
1682 service_descriptor_free(service
->desc_next
);
1683 service
->desc_next
= NULL
;
1685 build_all_descriptors(now
);
1686 /* Check *next* descriptor. */
1687 tt_assert(service
->desc_next
);
1688 tt_assert(service
->desc_next
->desc
);
1689 tt_assert(service
->desc_next
->intro_points
.map
);
1690 tt_assert(service
->desc_current
!= service
->desc_next
);
1691 tt_u64_op(service
->desc_next
->time_period_num
, OP_EQ
,
1692 hs_get_next_time_period_num(0));
1693 /* This should be untouched, the update descriptor process changes it. */
1694 tt_u64_op(service
->desc_next
->next_upload_time
, OP_EQ
, 0);
1698 remove_service(get_hs_service_map(), service
);
1699 hs_service_free(service
);
1702 nodelist_free_all();
1705 /** Test building descriptors. We use this separate function instead of
1706 * using test_build_update_descriptors because that function is too complex
1707 * and also too interactive. */
1709 test_build_descriptors(void *arg
)
1712 time_t now
= time(NULL
);
1713 hs_service_t
*last_service
= NULL
;
1720 get_or_state_replacement
);
1721 MOCK(networkstatus_get_reasonably_live_consensus
,
1722 mock_networkstatus_get_reasonably_live_consensus
);
1724 dummy_state
= or_state_new();
1726 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 03:00:00 UTC",
1727 &mock_ns
.valid_after
);
1728 tt_int_op(ret
, OP_EQ
, 0);
1729 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 04:00:00 UTC",
1730 &mock_ns
.fresh_until
);
1731 tt_int_op(ret
, OP_EQ
, 0);
1732 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
1734 /* Generate a valid number of fake auth clients when a client authorization
1737 hs_service_t
*service
= helper_create_service();
1738 last_service
= service
;
1739 service_descriptor_free(service
->desc_current
);
1740 service
->desc_current
= NULL
;
1742 build_all_descriptors(now
);
1743 tt_assert(service
->desc_current
);
1744 tt_assert(service
->desc_current
->desc
);
1746 hs_desc_superencrypted_data_t
*superencrypted
;
1747 superencrypted
= &service
->desc_current
->desc
->superencrypted_data
;
1748 tt_int_op(smartlist_len(superencrypted
->clients
), OP_EQ
, 16);
1750 helper_destroy_service(service
);
1751 last_service
= NULL
;
1754 /* Generate a valid number of fake auth clients when the number of
1755 * clients is zero. */
1757 hs_service_t
*service
= helper_create_service_with_clients(0);
1758 last_service
= service
;
1759 service_descriptor_free(service
->desc_current
);
1760 service
->desc_current
= NULL
;
1762 build_all_descriptors(now
);
1763 hs_desc_superencrypted_data_t
*superencrypted
;
1764 superencrypted
= &service
->desc_current
->desc
->superencrypted_data
;
1765 tt_int_op(smartlist_len(superencrypted
->clients
), OP_EQ
, 16);
1767 helper_destroy_service(service
);
1768 last_service
= NULL
;
1771 /* Generate a valid number of fake auth clients when the number of
1772 * clients is not a multiple of 16. */
1774 hs_service_t
*service
= helper_create_service_with_clients(20);
1775 last_service
= service
;
1776 service_descriptor_free(service
->desc_current
);
1777 service
->desc_current
= NULL
;
1779 build_all_descriptors(now
);
1780 hs_desc_superencrypted_data_t
*superencrypted
;
1781 superencrypted
= &service
->desc_current
->desc
->superencrypted_data
;
1782 tt_int_op(smartlist_len(superencrypted
->clients
), OP_EQ
, 32);
1784 helper_destroy_service(service
);
1785 last_service
= NULL
;
1788 /* Do not generate any fake desc client when the number of clients is
1789 * a multiple of 16 but not zero. */
1791 hs_service_t
*service
= helper_create_service_with_clients(32);
1792 last_service
= service
;
1793 service_descriptor_free(service
->desc_current
);
1794 service
->desc_current
= NULL
;
1796 build_all_descriptors(now
);
1797 hs_desc_superencrypted_data_t
*superencrypted
;
1798 superencrypted
= &service
->desc_current
->desc
->superencrypted_data
;
1799 tt_int_op(smartlist_len(superencrypted
->clients
), OP_EQ
, 32);
1801 helper_destroy_service(service
);
1802 last_service
= NULL
;
1806 helper_destroy_service(last_service
);
1811 test_upload_descriptors(void *arg
)
1815 hs_service_t
*service
;
1821 get_or_state_replacement
);
1822 MOCK(networkstatus_get_reasonably_live_consensus
,
1823 mock_networkstatus_get_reasonably_live_consensus
);
1825 dummy_state
= or_state_new();
1827 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
1828 &mock_ns
.valid_after
);
1829 tt_int_op(ret
, OP_EQ
, 0);
1830 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
1831 &mock_ns
.fresh_until
);
1832 tt_int_op(ret
, OP_EQ
, 0);
1833 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
1835 update_approx_time(mock_ns
.valid_after
+1);
1836 now
= mock_ns
.valid_after
+1;
1838 /* Create a service with no descriptor. It's added to the global map. */
1839 service
= hs_service_new(get_options());
1841 service
->config
.version
= HS_VERSION_THREE
;
1842 ed25519_secret_key_generate(&service
->keys
.identity_sk
, 0);
1843 ed25519_public_key_generate(&service
->keys
.identity_pk
,
1844 &service
->keys
.identity_sk
);
1845 /* Register service to global map. */
1846 ret
= register_service(get_hs_service_map(), service
);
1847 tt_int_op(ret
, OP_EQ
, 0);
1848 /* But first, build our descriptor. */
1849 build_all_descriptors(now
);
1851 /* Nothing should happen because we have 0 introduction circuit established
1852 * and we want (by default) 3 intro points. */
1853 run_upload_descriptor_event(now
);
1854 /* If no upload happened, this should be untouched. */
1855 tt_u64_op(service
->desc_current
->next_upload_time
, OP_EQ
, 0);
1856 /* We'll simulate that we've opened our intro point circuit and that we only
1857 * want one intro point. */
1858 service
->config
.num_intro_points
= 1;
1860 /* Set our next upload time after now which will skip the upload. */
1861 service
->desc_current
->next_upload_time
= now
+ 1000;
1862 run_upload_descriptor_event(now
);
1863 /* If no upload happened, this should be untouched. */
1864 tt_u64_op(service
->desc_current
->next_upload_time
, OP_EQ
, now
+ 1000);
1868 UNMOCK(get_or_state
);
1871 /** Global vars used by test_rendezvous1_parsing() */
1872 static char rend1_payload
[RELAY_PAYLOAD_SIZE
];
1873 static size_t rend1_payload_len
= 0;
1875 /** Mock for relay_send_command_from_edge() to send a RENDEZVOUS1 cell. Instead
1876 * of sending it to the network, instead save it to the global `rend1_payload`
1877 * variable so that we can inspect it in the test_rendezvous1_parsing()
1880 mock_relay_send_rendezvous1(streamid_t stream_id
, circuit_t
*circ
,
1881 uint8_t relay_command
, const char *payload
,
1883 crypt_path_t
*cpath_layer
,
1884 const char *filename
, int lineno
)
1888 (void) relay_command
;
1893 memcpy(rend1_payload
, payload
, payload_len
);
1894 rend1_payload_len
= payload_len
;
1899 /** Send a RENDEZVOUS1 as a service, and parse it as a client. */
1901 test_rendezvous1_parsing(void *arg
)
1904 static const char *test_addr
=
1905 "4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion";
1906 hs_service_t
*service
= NULL
;
1907 origin_circuit_t
*service_circ
= NULL
;
1908 origin_circuit_t
*client_circ
= NULL
;
1909 ed25519_keypair_t ip_auth_kp
;
1910 curve25519_keypair_t ephemeral_kp
;
1911 curve25519_keypair_t client_kp
;
1912 curve25519_keypair_t ip_enc_kp
;
1913 int flags
= CIRCLAUNCH_NEED_UPTIME
| CIRCLAUNCH_IS_INTERNAL
;
1917 MOCK(relay_send_command_from_edge_
, mock_relay_send_rendezvous1
);
1920 /* Let's start by setting up the service that will start the rend */
1921 service
= tor_malloc_zero(sizeof(hs_service_t
));
1922 ed25519_secret_key_generate(&service
->keys
.identity_sk
, 0);
1923 ed25519_public_key_generate(&service
->keys
.identity_pk
,
1924 &service
->keys
.identity_sk
);
1925 memcpy(service
->onion_address
, test_addr
, sizeof(service
->onion_address
));
1930 /* Now let's set up the service rendezvous circuit and its keys. */
1931 service_circ
= helper_create_origin_circuit(CIRCUIT_PURPOSE_S_CONNECT_REND
,
1933 tor_free(service_circ
->hs_ident
);
1934 hs_ntor_rend_cell_keys_t hs_ntor_rend_cell_keys
;
1935 uint8_t rendezvous_cookie
[HS_REND_COOKIE_LEN
];
1936 curve25519_keypair_generate(&ip_enc_kp
, 0);
1937 curve25519_keypair_generate(&ephemeral_kp
, 0);
1938 curve25519_keypair_generate(&client_kp
, 0);
1939 ed25519_keypair_generate(&ip_auth_kp
, 0);
1940 retval
= hs_ntor_service_get_rendezvous1_keys(&ip_auth_kp
.pubkey
,
1944 &hs_ntor_rend_cell_keys
);
1945 tt_int_op(retval
, OP_EQ
, 0);
1947 memset(rendezvous_cookie
, 2, sizeof(rendezvous_cookie
));
1948 service_circ
->hs_ident
=
1949 create_rp_circuit_identifier(service
, rendezvous_cookie
,
1950 &ephemeral_kp
.pubkey
,
1951 &hs_ntor_rend_cell_keys
);
1954 /* Send out the RENDEZVOUS1 and make sure that our mock func worked */
1955 tt_assert(fast_mem_is_zero(rend1_payload
, 32));
1956 hs_circ_service_rp_has_opened(service
, service_circ
);
1957 tt_assert(!fast_mem_is_zero(rend1_payload
, 32));
1958 tt_int_op(rend1_payload_len
, OP_EQ
, HS_LEGACY_RENDEZVOUS_CELL_SIZE
);
1960 /******************************/
1962 /** Now let's create the client rendezvous circuit */
1964 helper_create_origin_circuit(CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED
,
1966 /* fix up its circ ident */
1967 ed25519_pubkey_copy(&client_circ
->hs_ident
->intro_auth_pk
,
1968 &ip_auth_kp
.pubkey
);
1969 memcpy(&client_circ
->hs_ident
->rendezvous_client_kp
,
1970 &client_kp
, sizeof(client_circ
->hs_ident
->rendezvous_client_kp
));
1971 memcpy(&client_circ
->hs_ident
->intro_enc_pk
.public_key
,
1972 &ip_enc_kp
.pubkey
.public_key
,
1973 sizeof(client_circ
->hs_ident
->intro_enc_pk
.public_key
));
1975 /* Now parse the rendezvous2 circuit and make sure it was fine. We are
1976 * skipping 20 bytes off its payload, since that's the rendezvous cookie
1977 * which is only present in REND1. */
1978 retval
= handle_rendezvous2(client_circ
,
1979 (uint8_t*)rend1_payload
+20,
1980 rend1_payload_len
-20);
1981 tt_int_op(retval
, OP_EQ
, 0);
1983 /* TODO: We are only simulating client/service here. We could also simulate
1984 * the rendezvous point by plugging in rend_mid_establish_rendezvous(). We
1985 * would need an extra circuit and some more stuff but it's doable. */
1988 circuit_free_(TO_CIRCUIT(service_circ
));
1989 circuit_free_(TO_CIRCUIT(client_circ
));
1990 hs_service_free(service
);
1992 UNMOCK(relay_send_command_from_edge_
);
1996 test_authorized_client_config_equal(void *arg
)
1999 hs_service_config_t
*config1
, *config2
;
2003 config1
= tor_malloc_zero(sizeof(*config1
));
2004 config2
= tor_malloc_zero(sizeof(*config2
));
2006 /* Both configs are empty. */
2008 config1
->clients
= smartlist_new();
2009 config2
->clients
= smartlist_new();
2011 ret
= service_authorized_client_config_equal(config1
, config2
);
2012 tt_int_op(ret
, OP_EQ
, 1);
2014 service_clear_config(config1
);
2015 service_clear_config(config2
);
2018 /* Both configs have exactly the same client config. */
2020 config1
->clients
= smartlist_new();
2021 config2
->clients
= smartlist_new();
2023 hs_service_authorized_client_t
*client1
, *client2
;
2024 client1
= helper_create_authorized_client();
2025 client2
= helper_create_authorized_client();
2027 smartlist_add(config1
->clients
, client1
);
2028 smartlist_add(config1
->clients
, client2
);
2030 /* We should swap the order of clients here to test that the order
2031 * does not matter. */
2032 smartlist_add(config2
->clients
, helper_clone_authorized_client(client2
));
2033 smartlist_add(config2
->clients
, helper_clone_authorized_client(client1
));
2035 ret
= service_authorized_client_config_equal(config1
, config2
);
2036 tt_int_op(ret
, OP_EQ
, 1);
2038 service_clear_config(config1
);
2039 service_clear_config(config2
);
2042 /* The numbers of clients in both configs are not equal. */
2044 config1
->clients
= smartlist_new();
2045 config2
->clients
= smartlist_new();
2047 hs_service_authorized_client_t
*client1
, *client2
;
2048 client1
= helper_create_authorized_client();
2049 client2
= helper_create_authorized_client();
2051 smartlist_add(config1
->clients
, client1
);
2052 smartlist_add(config1
->clients
, client2
);
2054 smartlist_add(config2
->clients
, helper_clone_authorized_client(client1
));
2056 ret
= service_authorized_client_config_equal(config1
, config2
);
2057 tt_int_op(ret
, OP_EQ
, 0);
2059 service_clear_config(config1
);
2060 service_clear_config(config2
);
2063 /* The first config has two distinct clients while the second config
2064 * has two clients but they are duplicate. */
2066 config1
->clients
= smartlist_new();
2067 config2
->clients
= smartlist_new();
2069 hs_service_authorized_client_t
*client1
, *client2
;
2070 client1
= helper_create_authorized_client();
2071 client2
= helper_create_authorized_client();
2073 smartlist_add(config1
->clients
, client1
);
2074 smartlist_add(config1
->clients
, client2
);
2076 smartlist_add(config2
->clients
, helper_clone_authorized_client(client1
));
2077 smartlist_add(config2
->clients
, helper_clone_authorized_client(client1
));
2079 ret
= service_authorized_client_config_equal(config1
, config2
);
2080 tt_int_op(ret
, OP_EQ
, 0);
2082 service_clear_config(config1
);
2083 service_clear_config(config2
);
2086 /* Both configs have totally distinct clients. */
2088 config1
->clients
= smartlist_new();
2089 config2
->clients
= smartlist_new();
2091 hs_service_authorized_client_t
*client1
, *client2
, *client3
, *client4
;
2092 client1
= helper_create_authorized_client();
2093 client2
= helper_create_authorized_client();
2094 client3
= helper_create_authorized_client();
2095 client4
= helper_create_authorized_client();
2097 smartlist_add(config1
->clients
, client1
);
2098 smartlist_add(config1
->clients
, client2
);
2100 smartlist_add(config2
->clients
, client3
);
2101 smartlist_add(config2
->clients
, client4
);
2103 ret
= service_authorized_client_config_equal(config1
, config2
);
2104 tt_int_op(ret
, OP_EQ
, 0);
2106 service_clear_config(config1
);
2107 service_clear_config(config2
);
2115 /** Test that client circuit ID gets correctly exported */
2117 test_export_client_circuit_id(void *arg
)
2119 origin_circuit_t
*or_circ
= NULL
;
2121 char *cp1
=NULL
, *cp2
=NULL
;
2122 connection_t
*conn
= NULL
;
2126 MOCK(connection_write_to_buf_impl_
, connection_write_to_buf_mock
);
2130 /* Create service */
2131 hs_service_t
*service
= helper_create_service();
2132 /* Check that export circuit ID detection works */
2133 service
->config
.circuit_id_protocol
= HS_CIRCUIT_ID_PROTOCOL_NONE
;
2135 hs_service_exports_circuit_id(&service
->keys
.identity_pk
));
2136 service
->config
.circuit_id_protocol
= HS_CIRCUIT_ID_PROTOCOL_HAPROXY
;
2138 hs_service_exports_circuit_id(&service
->keys
.identity_pk
));
2140 /* Create client connection */
2141 conn
= test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT
, CONN_TYPE_AP
, 0);
2143 /* Create client edge conn hs_ident */
2144 edge_connection_t
*edge_conn
= TO_EDGE_CONN(conn
);
2145 edge_conn
->hs_ident
= hs_ident_edge_conn_new(&service
->keys
.identity_pk
);
2146 edge_conn
->hs_ident
->orig_virtual_port
= 42;
2148 /* Create rend circuit */
2149 or_circ
= origin_circuit_new();
2150 or_circ
->base_
.purpose
= CIRCUIT_PURPOSE_C_REND_JOINED
;
2151 edge_conn
->on_circuit
= TO_CIRCUIT(or_circ
);
2152 or_circ
->global_identifier
= 666;
2154 /* Export circuit ID */
2155 export_hs_client_circuit_id(edge_conn
, service
->config
.circuit_id_protocol
);
2157 /* Check contents */
2158 cp1
= buf_get_contents(conn
->outbuf
, &sz
);
2159 tt_str_op(cp1
, OP_EQ
,
2160 "PROXY TCP6 fc00:dead:beef:4dad::0:29a ::1 666 42\r\n");
2162 /* Change circ GID and see that the reported circuit ID also changes */
2163 or_circ
->global_identifier
= 22;
2166 export_hs_client_circuit_id(edge_conn
, service
->config
.circuit_id_protocol
);
2167 cp2
= buf_get_contents(conn
->outbuf
, &sz
);
2168 tt_str_op(cp1
, OP_NE
, cp2
);
2171 /* Check that GID with UINT32_MAX works. */
2172 or_circ
->global_identifier
= UINT32_MAX
;
2174 export_hs_client_circuit_id(edge_conn
, service
->config
.circuit_id_protocol
);
2175 cp1
= buf_get_contents(conn
->outbuf
, &sz
);
2176 tt_str_op(cp1
, OP_EQ
,
2177 "PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
2180 /* Check that GID with UINT16_MAX works. */
2181 or_circ
->global_identifier
= UINT16_MAX
;
2183 export_hs_client_circuit_id(edge_conn
, service
->config
.circuit_id_protocol
);
2184 cp1
= buf_get_contents(conn
->outbuf
, &sz
);
2185 tt_str_op(cp1
, OP_EQ
,
2186 "PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
2189 /* Check that GID with UINT16_MAX + 7 works. */
2190 or_circ
->global_identifier
= UINT16_MAX
+ 7;
2192 export_hs_client_circuit_id(edge_conn
, service
->config
.circuit_id_protocol
);
2193 cp1
= buf_get_contents(conn
->outbuf
, &sz
);
2194 tt_str_op(cp1
, OP_EQ
, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");
2197 UNMOCK(connection_write_to_buf_impl_
);
2198 circuit_free_(TO_CIRCUIT(or_circ
));
2199 connection_free_minimal(conn
);
2200 hs_service_free(service
);
2205 static smartlist_t
*
2206 mock_node_get_link_specifier_smartlist(const node_t
*node
, bool direct_conn
)
2211 smartlist_t
*lspecs
= smartlist_new();
2212 link_specifier_t
*ls_legacy
= link_specifier_new();
2213 smartlist_add(lspecs
, ls_legacy
);
2218 static node_t
*fake_node
= NULL
;
2220 static const node_t
*
2221 mock_build_state_get_exit_node(cpath_build_state_t
*state
)
2226 curve25519_secret_key_t seckey
;
2227 curve25519_secret_key_generate(&seckey
, 0);
2229 fake_node
= tor_malloc_zero(sizeof(node_t
));
2230 fake_node
->ri
= tor_malloc_zero(sizeof(routerinfo_t
));
2231 fake_node
->ri
->onion_curve25519_pkey
=
2232 tor_malloc_zero(sizeof(curve25519_public_key_t
));
2233 curve25519_public_key_generate(fake_node
->ri
->onion_curve25519_pkey
,
2241 mock_launch_rendezvous_point_circuit(const hs_service_t
*service
,
2242 const hs_service_intro_point_t
*ip
,
2243 const hs_cell_introduce2_data_t
*data
)
2252 * Test that INTRO2 cells are handled well by onion services in the normal
2253 * case and also when onionbalance is enabled.
2256 test_intro2_handling(void *arg
)
2260 MOCK(build_state_get_exit_node
, mock_build_state_get_exit_node
);
2261 MOCK(relay_send_command_from_edge_
, mock_relay_send_command_from_edge
);
2262 MOCK(node_get_link_specifier_smartlist
,
2263 mock_node_get_link_specifier_smartlist
);
2264 MOCK(launch_rendezvous_point_circuit
, mock_launch_rendezvous_point_circuit
);
2266 memset(relay_payload
, 0, sizeof(relay_payload
));
2269 time_t now
= 0101010101;
2270 update_approx_time(now
);
2272 /** OK this is the play:
2274 * In Act I, we have a standalone onion service X (without onionbalance
2275 * enabled). We test that X can properly handle INTRO2 cells sent by a
2278 * In Act II, we create an onionbalance setup with frontend being Z which
2279 * includes instances X and Y. We then setup onionbalance on X and test that
2280 * Alice who addresses Z can communicate with X through INTRO2 cells.
2282 * In Act III, we test that Alice can also communicate with X
2283 * directly even tho onionbalance is enabled.
2285 * And finally in Act IV, we check various cases where the INTRO2 cell
2286 * should not go through because the subcredentials don't line up
2287 * (e.g. Alice sends INTRO2 to X using Y's subcredential).
2290 /** Let's start with some setup! Create the instances and the frontend
2291 service, create Alice, etc: */
2293 /* Create instance X */
2294 hs_service_t x_service
;
2295 memset(&x_service
, 0, sizeof(hs_service_t
));
2296 /* Disable onionbalance */
2297 x_service
.config
.ob_master_pubkeys
= NULL
;
2298 x_service
.state
.replay_cache_rend_cookie
= replaycache_new(0,0);
2300 /* Create subcredential for x: */
2301 ed25519_keypair_t x_identity_keypair
;
2302 hs_subcredential_t x_subcred
;
2303 ed25519_keypair_generate(&x_identity_keypair
, 0);
2304 hs_helper_get_subcred_from_identity_keypair(&x_identity_keypair
,
2307 /* Create the x instance's intro point */
2308 hs_service_intro_point_t
*x_ip
= NULL
;
2310 curve25519_secret_key_t seckey
;
2311 curve25519_public_key_t pkey
;
2312 curve25519_secret_key_generate(&seckey
, 0);
2313 curve25519_public_key_generate(&pkey
, &seckey
);
2316 memset(&intro_node
, 0, sizeof(intro_node
));
2318 memset(&ri
, 0, sizeof(routerinfo_t
));
2319 ri
.onion_curve25519_pkey
= &pkey
;
2320 intro_node
.ri
= &ri
;
2322 x_ip
= service_intro_point_new(&intro_node
);
2325 /* Create z frontend's subcredential */
2326 ed25519_keypair_t z_identity_keypair
;
2327 hs_subcredential_t z_subcred
;
2328 ed25519_keypair_generate(&z_identity_keypair
, 0);
2329 hs_helper_get_subcred_from_identity_keypair(&z_identity_keypair
,
2332 /* Create y instance's subcredential */
2333 ed25519_keypair_t y_identity_keypair
;
2334 hs_subcredential_t y_subcred
;
2335 ed25519_keypair_generate(&y_identity_keypair
, 0);
2336 hs_helper_get_subcred_from_identity_keypair(&y_identity_keypair
,
2339 /* Create Alice's intro point */
2340 hs_desc_intro_point_t
*alice_ip
;
2341 ed25519_keypair_t signing_kp
;
2342 ed25519_keypair_generate(&signing_kp
, 0);
2343 alice_ip
= hs_helper_build_intro_point(&signing_kp
, now
, "1.2.3.4", 0,
2347 /* Create Alice's intro and rend circuits */
2348 origin_circuit_t
*intro_circ
= origin_circuit_new();
2349 intro_circ
->cpath
= tor_malloc_zero(sizeof(crypt_path_t
));
2350 intro_circ
->cpath
->prev
= intro_circ
->cpath
;
2351 intro_circ
->hs_ident
= tor_malloc_zero(sizeof(*intro_circ
->hs_ident
));
2352 origin_circuit_t rend_circ
;
2353 rend_circ
.hs_ident
= tor_malloc_zero(sizeof(*rend_circ
.hs_ident
));
2354 curve25519_keypair_generate(&rend_circ
.hs_ident
->rendezvous_client_kp
, 0);
2355 memset(rend_circ
.hs_ident
->rendezvous_cookie
, 'r', HS_REND_COOKIE_LEN
);
2357 /* ************************************************************ */
2361 * Where Alice connects to X without onionbalance in the picture */
2363 /* Create INTRODUCE1 */
2364 tt_assert(fast_mem_is_zero(relay_payload
, sizeof(relay_payload
)));
2365 retval
= hs_circ_send_introduce1(intro_circ
, &rend_circ
,
2366 alice_ip
, &x_subcred
);
2368 /* Check that the payload was written successfully */
2369 tt_int_op(retval
, OP_EQ
, 0);
2370 tt_assert(!fast_mem_is_zero(relay_payload
, sizeof(relay_payload
)));
2371 tt_int_op(relay_payload_len
, OP_NE
, 0);
2373 /* Handle the cell */
2374 retval
= hs_circ_handle_introduce2(&x_service
,
2377 (uint8_t*)relay_payload
,relay_payload_len
);
2378 tt_int_op(retval
, OP_EQ
, 0);
2380 /* ************************************************************ */
2384 * We now create an onionbalance setup with Z being the frontend and X and Y
2385 * being the backend instances. Make sure that Alice can talk with the
2386 * backend instance X even tho she thinks she is talking to the frontend Z.
2389 /* Now configure the X instance to do onionbalance with Z as the frontend */
2390 x_service
.config
.ob_master_pubkeys
= smartlist_new();
2391 smartlist_add(x_service
.config
.ob_master_pubkeys
,
2392 &z_identity_keypair
.pubkey
);
2394 /* Create descriptors for x and load next descriptor with the x's
2395 * subcredential so that it can accept connections for itself. */
2396 x_service
.desc_current
= service_descriptor_new();
2397 memset(x_service
.desc_current
->desc
->subcredential
.subcred
, 'C',SUBCRED_LEN
);
2398 x_service
.desc_next
= service_descriptor_new();
2399 memcpy(&x_service
.desc_next
->desc
->subcredential
, &x_subcred
, SUBCRED_LEN
);
2401 /* Refresh OB keys */
2402 hs_ob_refresh_keys(&x_service
);
2404 /* Create INTRODUCE1 from Alice to X through Z */
2405 memset(relay_payload
, 0, sizeof(relay_payload
));
2406 retval
= hs_circ_send_introduce1(intro_circ
, &rend_circ
,
2407 alice_ip
, &z_subcred
);
2409 /* Check that the payload was written successfully */
2410 tt_int_op(retval
, OP_EQ
, 0);
2411 tt_assert(!fast_mem_is_zero(relay_payload
, sizeof(relay_payload
)));
2412 tt_int_op(relay_payload_len
, OP_NE
, 0);
2414 /* Deliver INTRODUCE1 to X even tho it carries Z's subcredential */
2415 replaycache_free(x_service
.state
.replay_cache_rend_cookie
);
2416 x_service
.state
.replay_cache_rend_cookie
= replaycache_new(0, 0);
2418 retval
= hs_circ_handle_introduce2(&x_service
,
2421 (uint8_t*)relay_payload
, relay_payload_len
);
2422 tt_int_op(retval
, OP_EQ
, 0);
2424 replaycache_free(x_ip
->replay_cache
);
2425 x_ip
->replay_cache
= replaycache_new(0, 0);
2427 replaycache_free(x_service
.state
.replay_cache_rend_cookie
);
2428 x_service
.state
.replay_cache_rend_cookie
= replaycache_new(0, 0);
2430 /* ************************************************************ */
2434 * Now send a direct INTRODUCE cell from Alice to X using X's subcredential
2435 * and check that it succeeds even with onionbalance enabled.
2438 /* Refresh OB keys (just to check for memleaks) */
2439 hs_ob_refresh_keys(&x_service
);
2441 /* Create INTRODUCE1 from Alice to X using X's subcred. */
2442 memset(relay_payload
, 0, sizeof(relay_payload
));
2443 retval
= hs_circ_send_introduce1(intro_circ
, &rend_circ
,
2444 alice_ip
, &x_subcred
);
2446 /* Check that the payload was written successfully */
2447 tt_int_op(retval
, OP_EQ
, 0);
2448 tt_assert(!fast_mem_is_zero(relay_payload
, sizeof(relay_payload
)));
2449 tt_int_op(relay_payload_len
, OP_NE
, 0);
2451 /* Send INTRODUCE1 to X with X's subcredential (should succeed) */
2452 replaycache_free(x_service
.state
.replay_cache_rend_cookie
);
2453 x_service
.state
.replay_cache_rend_cookie
= replaycache_new(0, 0);
2455 retval
= hs_circ_handle_introduce2(&x_service
,
2458 (uint8_t*)relay_payload
, relay_payload_len
);
2459 tt_int_op(retval
, OP_EQ
, 0);
2461 /* ************************************************************ */
2465 * Test cases where the INTRO2 cell should not be able to decode.
2468 /* Try sending the exact same INTRODUCE2 cell again and see that the intro
2469 * point replay cache triggers: */
2470 setup_full_capture_of_logs(LOG_WARN
);
2471 retval
= hs_circ_handle_introduce2(&x_service
,
2474 (uint8_t*)relay_payload
, relay_payload_len
);
2475 tt_int_op(retval
, OP_EQ
, -1);
2476 expect_log_msg_containing("with the same ENCRYPTED section");
2477 teardown_capture_of_logs();
2479 /* Now cleanup the intro point replay cache but not the service replay cache
2480 and see that this one triggers this time. */
2481 replaycache_free(x_ip
->replay_cache
);
2482 x_ip
->replay_cache
= replaycache_new(0, 0);
2483 setup_full_capture_of_logs(LOG_INFO
);
2484 retval
= hs_circ_handle_introduce2(&x_service
,
2487 (uint8_t*)relay_payload
, relay_payload_len
);
2488 tt_int_op(retval
, OP_EQ
, -1);
2489 expect_log_msg_containing("with same REND_COOKIE");
2490 teardown_capture_of_logs();
2492 /* Now just to make sure cleanup both replay caches and make sure that the
2493 cell gets through */
2494 replaycache_free(x_ip
->replay_cache
);
2495 x_ip
->replay_cache
= replaycache_new(0, 0);
2496 replaycache_free(x_service
.state
.replay_cache_rend_cookie
);
2497 x_service
.state
.replay_cache_rend_cookie
= replaycache_new(0, 0);
2498 retval
= hs_circ_handle_introduce2(&x_service
,
2501 (uint8_t*)relay_payload
, relay_payload_len
);
2502 tt_int_op(retval
, OP_EQ
, 0);
2504 /* As a final thing, create an INTRODUCE1 cell from Alice to X using Y's
2505 * subcred (should fail since Y is just another instance and not the frontend
2507 memset(relay_payload
, 0, sizeof(relay_payload
));
2508 retval
= hs_circ_send_introduce1(intro_circ
, &rend_circ
,
2509 alice_ip
, &y_subcred
);
2510 tt_int_op(retval
, OP_EQ
, 0);
2512 /* Check that the payload was written successfully */
2513 tt_assert(!fast_mem_is_zero(relay_payload
, sizeof(relay_payload
)));
2514 tt_int_op(relay_payload_len
, OP_NE
, 0);
2516 retval
= hs_circ_handle_introduce2(&x_service
,
2519 (uint8_t*)relay_payload
, relay_payload_len
);
2520 tt_int_op(retval
, OP_EQ
, -1);
2523 /* Start cleaning up X */
2524 replaycache_free(x_service
.state
.replay_cache_rend_cookie
);
2525 smartlist_free(x_service
.config
.ob_master_pubkeys
);
2526 tor_free(x_service
.state
.ob_subcreds
);
2527 service_descriptor_free(x_service
.desc_current
);
2528 service_descriptor_free(x_service
.desc_next
);
2529 service_intro_point_free(x_ip
);
2531 /* Clean up Alice */
2532 hs_desc_intro_point_free(alice_ip
);
2533 tor_free(rend_circ
.hs_ident
);
2536 tor_free(fake_node
->ri
->onion_curve25519_pkey
);
2537 tor_free(fake_node
->ri
);
2538 tor_free(fake_node
);
2541 UNMOCK(build_state_get_exit_node
);
2542 UNMOCK(relay_send_command_from_edge_
);
2543 UNMOCK(node_get_link_specifier_smartlist
);
2544 UNMOCK(launch_rendezvous_point_circuit
);
2548 test_cannot_upload_descriptors(void *arg
)
2552 hs_service_t
*service
;
2558 get_or_state_replacement
);
2559 MOCK(networkstatus_get_reasonably_live_consensus
,
2560 mock_networkstatus_get_reasonably_live_consensus
);
2562 dummy_state
= or_state_new();
2564 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
2565 &mock_ns
.valid_after
);
2566 tt_int_op(ret
, OP_EQ
, 0);
2567 ret
= parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
2568 &mock_ns
.fresh_until
);
2569 tt_int_op(ret
, OP_EQ
, 0);
2570 dirauth_sched_recalculate_timing(get_options(), mock_ns
.valid_after
);
2572 update_approx_time(mock_ns
.valid_after
+ 1);
2573 now
= mock_ns
.valid_after
+ 1;
2575 /* Create a service with no descriptor. It's added to the global map. */
2576 service
= hs_service_new(get_options());
2578 service
->config
.version
= HS_VERSION_THREE
;
2579 ed25519_secret_key_generate(&service
->keys
.identity_sk
, 0);
2580 ed25519_public_key_generate(&service
->keys
.identity_pk
,
2581 &service
->keys
.identity_sk
);
2582 /* Register service to global map. */
2583 ret
= register_service(get_hs_service_map(), service
);
2584 tt_int_op(ret
, OP_EQ
, 0);
2585 /* But first, build our descriptor. */
2586 build_all_descriptors(now
);
2588 /* 1. Testing missing intro points reason. */
2590 digest256map_t
*cur
= service
->desc_current
->intro_points
.map
;
2591 digest256map_t
*tmp
= digest256map_new();
2592 service
->desc_current
->intro_points
.map
= tmp
;
2593 service
->desc_current
->missing_intro_points
= 1;
2594 setup_full_capture_of_logs(LOG_INFO
);
2595 run_upload_descriptor_event(now
);
2596 digest256map_free(tmp
, tor_free_
);
2597 service
->desc_current
->intro_points
.map
= cur
;
2598 expect_log_msg_containing(
2599 "Service [scrubbed] can't upload its current descriptor: "
2600 "Missing intro points");
2601 teardown_capture_of_logs();
2603 service
->desc_current
->missing_intro_points
= 0;
2606 /* 2. Testing non established intro points. */
2608 setup_full_capture_of_logs(LOG_INFO
);
2609 run_upload_descriptor_event(now
);
2610 expect_log_msg_containing(
2611 "Service [scrubbed] can't upload its current descriptor: "
2612 "Intro circuits aren't yet all established (0/3).");
2613 teardown_capture_of_logs();
2616 /* We need to pass the established circuit tests and thus from now on, we
2617 * MOCK this to return 3 intro points. */
2618 MOCK(count_desc_circuit_established
, mock_count_desc_circuit_established
);
2619 num_intro_points
= 3;
2621 /* 3. Testing non established intro points. */
2623 service
->desc_current
->next_upload_time
= now
+ 1000;
2624 setup_full_capture_of_logs(LOG_INFO
);
2625 run_upload_descriptor_event(now
);
2626 expect_log_msg_containing(
2627 "Service [scrubbed] can't upload its current descriptor: "
2628 "Next upload time is");
2629 teardown_capture_of_logs();
2631 service
->desc_current
->next_upload_time
= 0;
2634 /* 4. Testing missing live consensus. */
2636 MOCK(networkstatus_get_reasonably_live_consensus
,
2637 mock_networkstatus_get_reasonably_live_consensus_null
);
2638 setup_full_capture_of_logs(LOG_INFO
);
2639 run_upload_descriptor_event(now
);
2640 expect_log_msg_containing(
2641 "Service [scrubbed] can't upload its current descriptor: "
2642 "No reasonably live consensus");
2643 teardown_capture_of_logs();
2645 MOCK(networkstatus_get_reasonably_live_consensus
,
2646 mock_networkstatus_get_reasonably_live_consensus
);
2649 /* 5. Test missing minimum directory information. */
2651 MOCK(router_have_minimum_dir_info
,
2652 mock_router_have_minimum_dir_info_false
);
2653 setup_full_capture_of_logs(LOG_INFO
);
2654 run_upload_descriptor_event(now
);
2655 expect_log_msg_containing(
2656 "Service [scrubbed] can't upload its current descriptor: "
2657 "Not enough directory information");
2658 teardown_capture_of_logs();
2660 /* Running it again shouldn't trigger anything due to rate limitation. */
2661 setup_full_capture_of_logs(LOG_INFO
);
2662 run_upload_descriptor_event(now
);
2663 expect_no_log_entry();
2664 teardown_capture_of_logs();
2665 UNMOCK(router_have_minimum_dir_info
);
2668 /* Increase time and redo test (5) in order to test the rate limiting. */
2669 update_approx_time(mock_ns
.valid_after
+ 61);
2671 MOCK(router_have_minimum_dir_info
,
2672 mock_router_have_minimum_dir_info_false
);
2673 setup_full_capture_of_logs(LOG_INFO
);
2674 run_upload_descriptor_event(now
);
2675 expect_log_msg_containing(
2676 "Service [scrubbed] can't upload its current descriptor: "
2677 "Not enough directory information");
2678 teardown_capture_of_logs();
2679 UNMOCK(router_have_minimum_dir_info
);
2684 UNMOCK(count_desc_circuit_established
);
2685 UNMOCK(networkstatus_get_reasonably_live_consensus
);
2686 UNMOCK(get_or_state
);
2689 struct testcase_t hs_service_tests
[] = {
2690 { "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup
, TT_FORK
,
2692 { "load_keys", test_load_keys
, TT_FORK
,
2694 { "client_filename_is_valid", test_client_filename_is_valid
, TT_FORK
,
2696 { "parse_authorized_client", test_parse_authorized_client
, TT_FORK
,
2698 { "load_keys_with_client_auth", test_load_keys_with_client_auth
, TT_FORK
,
2700 { "access_service", test_access_service
, TT_FORK
,
2702 { "service_intro_point", test_service_intro_point
, TT_FORK
,
2704 { "helper_functions", test_helper_functions
, TT_FORK
,
2706 { "intro_circuit_opened", test_intro_circuit_opened
, TT_FORK
,
2708 { "intro_established", test_intro_established
, TT_FORK
,
2710 { "closing_intro_circs", test_closing_intro_circs
, TT_FORK
,
2712 { "rdv_circuit_opened", test_rdv_circuit_opened
, TT_FORK
,
2714 { "bad_introduce2", test_bad_introduce2
, TT_FORK
,
2716 { "service_event", test_service_event
, TT_FORK
,
2718 { "rotate_descriptors", test_rotate_descriptors
, TT_FORK
,
2720 { "build_update_descriptors", test_build_update_descriptors
, TT_FORK
,
2722 { "build_descriptors", test_build_descriptors
, TT_FORK
,
2724 { "upload_descriptors", test_upload_descriptors
, TT_FORK
,
2726 { "cannot_upload_descriptors", test_cannot_upload_descriptors
, TT_FORK
,
2728 { "rendezvous1_parsing", test_rendezvous1_parsing
, TT_FORK
,
2730 { "authorized_client_config_equal", test_authorized_client_config_equal
,
2731 TT_FORK
, NULL
, NULL
},
2732 { "export_client_circuit_id", test_export_client_circuit_id
, TT_FORK
,
2734 { "intro2_handling", test_intro2_handling
, TT_FORK
, NULL
, NULL
},