diff options
author | George Kadianakis <desnacked@riseup.net> | 2019-05-16 14:02:16 +0300 |
---|---|---|
committer | George Kadianakis <desnacked@riseup.net> | 2019-05-16 14:23:17 +0300 |
commit | ac895fa40552b78744eddfb648dadde23834e553 (patch) | |
tree | 09eb7b3ccea1ad3ae63ab82bdd9ba9e52e19dd9e /src/test/test_circuitpadding.c | |
parent | 9b582edddb3a56d0eb2049820c6e14bfead7b143 (diff) | |
download | tor-ac895fa40552b78744eddfb648dadde23834e553.tar.gz tor-ac895fa40552b78744eddfb648dadde23834e553.zip |
Add client-side onion service circuit hiding machines.
Diffstat (limited to 'src/test/test_circuitpadding.c')
-rw-r--r-- | src/test/test_circuitpadding.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/test/test_circuitpadding.c b/src/test/test_circuitpadding.c index c5aad0f5d9..7835b438f8 100644 --- a/src/test/test_circuitpadding.c +++ b/src/test/test_circuitpadding.c @@ -415,6 +415,8 @@ helper_create_basic_machine(void) /* Start, burst */ circpad_machine_states_init(&circ_client_machine, 2); + circ_client_machine.name = "basic"; + circ_client_machine.states[CIRCPAD_STATE_START]. next_state[CIRCPAD_EVENT_NONPADDING_RECV] = CIRCPAD_STATE_BURST; circ_client_machine.states[CIRCPAD_STATE_START].use_rtt_estimate = 1; @@ -2917,6 +2919,192 @@ test_circuitpadding_manage_circuit_lifetime(void *arg) UNMOCK(tor_gettimeofday); } +/** Helper for the test_circuitpadding_hs_machines test: + * + * - Create a client and relay circuit. + * - Setup right circuit purpose and attach a machine to the client circuit. + * - Verify that state transitions work as intended and state length gets + * enforced. + * + * This function is able to do this test both for intro and rend circuits + * depending on the value of <b>test_intro_circs</b>. + */ +static void +helper_test_hs_machines(bool test_intro_circs) +{ + /* Setup the circuits */ + origin_circuit_t *origin_client_side = origin_circuit_new(); + client_side = TO_CIRCUIT(origin_client_side); + client_side->purpose = CIRCUIT_PURPOSE_C_GENERAL; + + dummy_channel.cmux = circuitmux_alloc(); + relay_side = TO_CIRCUIT(new_fake_orcirc(&dummy_channel, &dummy_channel)); + relay_side->purpose = CIRCUIT_PURPOSE_OR; + + /* extend the client circ to two hops */ + simulate_single_hop_extend(client_side, relay_side, 1); + simulate_single_hop_extend(client_side, relay_side, 1); + + /* machines only apply on opened circuits */ + origin_client_side->has_opened = 1; + + /************************************/ + + /* Attaching the client machine now won't work here because of a wrong + * purpose */ + tt_assert(!client_side->padding_machine[0]); + circpad_add_matching_machines(origin_client_side, origin_padding_machines); + tt_assert(!client_side->padding_machine[0]); + + /* Change the purpose, see the machine getting attached */ + client_side->purpose = test_intro_circs ? + CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT : CIRCUIT_PURPOSE_C_REND_JOINED; + circpad_add_matching_machines(origin_client_side, origin_padding_machines); + tt_ptr_op(client_side->padding_info[0], OP_NE, NULL); + tt_ptr_op(client_side->padding_machine[0], OP_NE, NULL); + + tt_ptr_op(relay_side->padding_info[0], OP_NE, NULL); + tt_ptr_op(relay_side->padding_machine[0], OP_NE, NULL); + + /* Verify that the right machine is attached */ + tt_str_op(client_side->padding_machine[0]->name, OP_EQ, + test_intro_circs ? "client_ip_circ" : "client_rp_circ"); + tt_str_op(relay_side->padding_machine[0]->name, OP_EQ, + test_intro_circs ? "relay_ip_circ": "relay_rp_circ"); + + /***********************************/ + + /* Intro machines are at START state, but rend machines have already skipped + * to OBFUSCATE_CIRC_SETUP because of the sent PADDING_NEGOTIATE. */ + tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, + CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); + tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, + CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); + + /*Send non-padding to move the machines from START to OBFUSCATE_CIRC_SETUP */ + circpad_cell_event_nonpadding_received(client_side); + circpad_cell_event_nonpadding_received(relay_side); + tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, + CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); + tt_int_op(relay_side->padding_info[0]->current_state, OP_EQ, + CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP); + + /* For rendezvous circuit machines we can stop early since are simpler than + * the intro circuit machines. */ + if (!test_intro_circs) { + tt_int_op(client_side->padding_info[0]->histogram[0], OP_EQ, 1); + goto done; + } + + /* Check that the state lengths have been sampled and are within range */ + circpad_machine_runtime_t *client_machine_runtime = + client_side->padding_info[0]; + circpad_machine_runtime_t *relay_machine_runtime = + relay_side->padding_info[0]; + if (test_intro_circs) { + tt_int_op(client_machine_runtime->state_length, OP_GE, + INTRO_MACHINE_MINIMUM_PADDING); + tt_int_op(client_machine_runtime->state_length, OP_LT, + INTRO_MACHINE_MAXIMUM_PADDING); + tt_int_op(relay_machine_runtime->state_length, OP_GE, + INTRO_MACHINE_MINIMUM_PADDING); + tt_int_op(relay_machine_runtime->state_length, OP_LT, + INTRO_MACHINE_MAXIMUM_PADDING); + } else { + tt_int_op(client_machine_runtime->state_length, OP_EQ, 1); + tt_int_op(relay_machine_runtime->state_length, OP_EQ, 1); + } + + /* Send state_length worth of padding and see that the state goes to END */ + int i; + for (i = (int) client_machine_runtime->state_length ; i > 0 ; i--) { + circpad_send_padding_cell_for_callback(client_machine_runtime); + } + /* See that the machine has been teared down after all the length has been + * exhausted. */ + tt_int_op(client_side->padding_info[0]->current_state, OP_EQ, + CIRCPAD_STATE_END); + + done: + free_fake_orcirc(relay_side); + circuitmux_detach_all_circuits(dummy_channel.cmux, NULL); + circuitmux_free(dummy_channel.cmux); + free_fake_origin_circuit(TO_ORIGIN_CIRCUIT(client_side)); +} + +/** Test that the HS circuit padding machines work as intended. */ +static void +test_circuitpadding_hs_machines(void *arg) +{ + (void)arg; + + /* Test logic: + * + * 1) Register the HS machines, which aim to hide the presense of + * onion service traffic on the client-side + * + * 2) Call helper_test_hs_machines() to perform tests for the intro circuit + * machines and for the rend circuit machines. + */ + + MOCK(circuitmux_attach_circuit, circuitmux_attach_circuit_mock); + MOCK(circuit_package_relay_cell, circuit_package_relay_cell_mock); + MOCK(circuit_get_nth_node, circuit_get_nth_node_mock); + MOCK(circpad_machine_schedule_padding,circpad_machine_schedule_padding_mock); + + origin_padding_machines = smartlist_new(); + relay_padding_machines = smartlist_new(); + + nodes_init(); + + monotime_init(); + monotime_enable_test_mocking(); + monotime_set_mock_time_nsec(1*TOR_NSEC_PER_USEC); + monotime_coarse_set_mock_time_nsec(1*TOR_NSEC_PER_USEC); + curr_mocked_time = 1*TOR_NSEC_PER_USEC; + + timers_initialize(); + + /* This is needed so that we are not considered to be dormant */ + note_user_activity(20); + + /************************************/ + + /* Register the HS machines */ + circpad_machine_client_hide_intro_circuits(origin_padding_machines); + circpad_machine_client_hide_rend_circuits(origin_padding_machines); + circpad_machine_relay_hide_intro_circuits(relay_padding_machines); + circpad_machine_relay_hide_rend_circuits(relay_padding_machines); + + /***********************************/ + + /* Do the tests for the intro circuit machines */ + helper_test_hs_machines(true); + /* Do the tests for the rend circuit machines */ + helper_test_hs_machines(false); + + timers_shutdown(); + monotime_disable_test_mocking(); + + SMARTLIST_FOREACH_BEGIN(origin_padding_machines, + circpad_machine_spec_t *, m) { + machine_spec_free(m); + } SMARTLIST_FOREACH_END(m); + + SMARTLIST_FOREACH_BEGIN(relay_padding_machines, + circpad_machine_spec_t *, m) { + machine_spec_free(m); + } SMARTLIST_FOREACH_END(m); + + smartlist_free(origin_padding_machines); + smartlist_free(relay_padding_machines); + + UNMOCK(circuitmux_attach_circuit); + UNMOCK(circuit_package_relay_cell); + UNMOCK(circuit_get_nth_node); + UNMOCK(circpad_machine_schedule_padding); +} + #define TEST_CIRCUITPADDING(name, flags) \ { #name, test_##name, (flags), NULL, NULL } |