Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : #define CIRCUITBUILD_PRIVATE
7 : #define CIRCUITLIST_PRIVATE
8 : #define ENTRYNODES_PRIVATE
9 :
10 : #include "core/or/or.h"
11 :
12 : #include "test/test.h"
13 : #include "test/test_helpers.h"
14 : #include "test/log_test_helpers.h"
15 :
16 : #define CONFIG_PRIVATE
17 : #include "app/config/config.h"
18 :
19 : #include "core/or/channel.h"
20 : #include "core/or/circuitbuild.h"
21 : #include "core/or/circuitlist.h"
22 : #include "core/or/circuituse.h"
23 : #include "core/or/onion.h"
24 :
25 : #include "core/or/cell_st.h"
26 : #include "core/or/cpath_build_state_st.h"
27 : #include "core/or/extend_info_st.h"
28 : #include "core/or/origin_circuit_st.h"
29 : #include "core/or/or_circuit_st.h"
30 :
31 : #include "feature/client/entrynodes.h"
32 : #include "feature/nodelist/nodelist.h"
33 : #include "feature/nodelist/node_select.h"
34 : #include "feature/relay/circuitbuild_relay.h"
35 : #include "feature/relay/router.h"
36 : #include "feature/relay/routermode.h"
37 :
38 : #include "feature/nodelist/node_st.h"
39 : #include "feature/nodelist/routerinfo_st.h"
40 :
41 : /* Dummy nodes smartlist for testing */
42 : static smartlist_t dummy_nodes;
43 : /* Dummy exit extend_info for testing */
44 : static extend_info_t dummy_ei;
45 :
46 : static int
47 18 : mock_count_acceptable_nodes(const smartlist_t *nodes, int direct)
48 : {
49 18 : (void)nodes;
50 :
51 18 : return direct ? 1 : DEFAULT_ROUTE_LEN + 1;
52 : }
53 :
54 : /* Test route lengths when the caller of new_route_len() doesn't
55 : * specify exit_ei. */
56 : static void
57 1 : test_new_route_len_noexit(void *arg)
58 : {
59 1 : int r;
60 :
61 1 : (void)arg;
62 1 : MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
63 :
64 1 : r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, NULL, &dummy_nodes);
65 1 : tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
66 :
67 1 : r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, NULL, &dummy_nodes);
68 1 : tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
69 :
70 1 : r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, NULL, &dummy_nodes);
71 1 : tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
72 :
73 1 : done:
74 1 : UNMOCK(count_acceptable_nodes);
75 1 : }
76 :
77 : /* Test route lengths where someone else chose the "exit" node, which
78 : * require an extra hop for safety. */
79 : static void
80 1 : test_new_route_len_unsafe_exit(void *arg)
81 : {
82 1 : int r;
83 :
84 1 : (void)arg;
85 1 : MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
86 :
87 : /* connecting to hidden service directory */
88 1 : r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, &dummy_ei, &dummy_nodes);
89 1 : tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
90 :
91 : /* client connecting to introduction point */
92 1 : r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCING, &dummy_ei, &dummy_nodes);
93 1 : tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
94 :
95 : /* hidden service connecting to rendezvous point */
96 1 : r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, &dummy_ei, &dummy_nodes);
97 1 : tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
98 :
99 1 : done:
100 1 : UNMOCK(count_acceptable_nodes);
101 1 : }
102 :
103 : /* Test route lengths where we chose the "exit" node, which don't
104 : * require an extra hop for safety. */
105 : static void
106 1 : test_new_route_len_safe_exit(void *arg)
107 : {
108 1 : int r;
109 :
110 1 : (void)arg;
111 1 : MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
112 :
113 : /* hidden service connecting to introduction point */
114 1 : r = new_route_len(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, &dummy_ei,
115 : &dummy_nodes);
116 1 : tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
117 :
118 : /* router testing its own reachability */
119 1 : r = new_route_len(CIRCUIT_PURPOSE_TESTING, &dummy_ei, &dummy_nodes);
120 1 : tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
121 :
122 1 : done:
123 1 : UNMOCK(count_acceptable_nodes);
124 1 : }
125 :
126 : /* Make sure a non-fatal assertion fails when new_route_len() gets an
127 : * unexpected circuit purpose. */
128 : static void
129 1 : test_new_route_len_unhandled_exit(void *arg)
130 : {
131 1 : int r;
132 :
133 1 : (void)arg;
134 : #ifdef ALL_BUGS_ARE_FATAL
135 : /* Coverity (and maybe clang analyser) complain that the code following
136 : * tt_skip() is unconditionally unreachable. */
137 : #if !defined(__COVERITY__) && !defined(__clang_analyzer__)
138 : tt_skip();
139 : #endif
140 : #endif /* defined(ALL_BUGS_ARE_FATAL) */
141 :
142 1 : MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
143 :
144 1 : tor_capture_bugs_(1);
145 1 : setup_full_capture_of_logs(LOG_WARN);
146 1 : r = new_route_len(CIRCUIT_PURPOSE_CONTROLLER, &dummy_ei, &dummy_nodes);
147 1 : tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
148 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
149 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
150 : "!(exit_ei && !known_purpose)");
151 1 : expect_single_log_msg_containing("Unhandled purpose");
152 1 : expect_single_log_msg_containing("with a chosen exit; assuming routelen");
153 :
154 1 : done:
155 1 : teardown_capture_of_logs();
156 1 : tor_end_capture_bugs_();
157 1 : UNMOCK(count_acceptable_nodes);
158 1 : }
159 :
160 : static void
161 1 : test_upgrade_from_guard_wait(void *arg)
162 : {
163 1 : circuit_t *circ = NULL;
164 1 : origin_circuit_t *orig_circ = NULL;
165 1 : entry_guard_t *guard = NULL;
166 1 : smartlist_t *list = NULL;
167 :
168 1 : (void) arg;
169 :
170 1 : circ = dummy_origin_circuit_new(0);
171 1 : orig_circ = TO_ORIGIN_CIRCUIT(circ);
172 1 : tt_assert(orig_circ);
173 :
174 1 : orig_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
175 :
176 1 : circuit_set_state(circ, CIRCUIT_STATE_GUARD_WAIT);
177 :
178 : /* Put it in guard wait state. */
179 1 : guard = tor_malloc_zero(sizeof(*guard));
180 1 : guard->in_selection = get_guard_selection_info();
181 :
182 2 : orig_circ->guard_state =
183 1 : circuit_guard_state_new(guard, GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD,
184 : NULL);
185 :
186 : /* Mark the circuit for close. */
187 1 : circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
188 1 : tt_int_op(circ->marked_for_close, OP_NE, 0);
189 :
190 : /* We shouldn't pick the mark for close circuit. */
191 1 : list = circuit_find_circuits_to_upgrade_from_guard_wait();
192 1 : tt_assert(!list);
193 :
194 1 : done:
195 1 : smartlist_free(list);
196 1 : circuit_free(circ);
197 1 : entry_guard_free_(guard);
198 1 : }
199 :
200 : static int server = 0;
201 : static int
202 21 : mock_server_mode(const or_options_t *options)
203 : {
204 21 : (void)options;
205 21 : return server;
206 : }
207 :
208 : /* Test the different cases in circuit_extend_state_valid_helper(). */
209 : static void
210 1 : test_circuit_extend_state_valid(void *arg)
211 : {
212 1 : (void)arg;
213 1 : circuit_t *circ = tor_malloc_zero(sizeof(circuit_t));
214 :
215 1 : server = 0;
216 1 : MOCK(server_mode, mock_server_mode);
217 :
218 1 : setup_full_capture_of_logs(LOG_INFO);
219 :
220 : /* Clients can't extend */
221 1 : server = 0;
222 1 : tt_int_op(circuit_extend_state_valid_helper(NULL), OP_EQ, -1);
223 1 : expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
224 1 : mock_clean_saved_logs();
225 :
226 : #ifndef ALL_BUGS_ARE_FATAL
227 : /* Circuit must be non-NULL */
228 1 : tor_capture_bugs_(1);
229 1 : server = 1;
230 1 : tt_int_op(circuit_extend_state_valid_helper(NULL), OP_EQ, -1);
231 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
232 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
233 : "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
234 1 : tor_end_capture_bugs_();
235 1 : mock_clean_saved_logs();
236 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
237 :
238 : /* n_chan and n_hop are NULL, this should succeed */
239 1 : server = 1;
240 1 : tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, 0);
241 1 : mock_clean_saved_logs();
242 :
243 : /* But clients still can't extend */
244 1 : server = 0;
245 1 : tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
246 1 : expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
247 1 : mock_clean_saved_logs();
248 :
249 : /* n_chan must be NULL */
250 1 : circ->n_chan = tor_malloc_zero(sizeof(channel_t));
251 1 : server = 1;
252 1 : tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
253 1 : expect_log_msg("n_chan already set. Bug/attack. Closing.\n");
254 1 : mock_clean_saved_logs();
255 1 : tor_free(circ->n_chan);
256 :
257 : /* n_hop must be NULL */
258 1 : circ->n_hop = tor_malloc_zero(sizeof(extend_info_t));
259 1 : server = 1;
260 1 : tt_int_op(circuit_extend_state_valid_helper(circ), OP_EQ, -1);
261 1 : expect_log_msg("conn to next hop already launched. Bug/attack. Closing.\n");
262 1 : mock_clean_saved_logs();
263 1 : tor_free(circ->n_hop);
264 :
265 1 : done:
266 1 : tor_end_capture_bugs_();
267 1 : teardown_capture_of_logs();
268 :
269 1 : UNMOCK(server_mode);
270 1 : server = 0;
271 :
272 1 : tor_free(circ->n_chan);
273 1 : tor_free(circ->n_hop);
274 1 : tor_free(circ);
275 1 : }
276 :
277 : static node_t *mocked_node = NULL;
278 : static const node_t *
279 8 : mock_node_get_by_id(const char *identity_digest)
280 : {
281 8 : (void)identity_digest;
282 8 : return mocked_node;
283 : }
284 :
285 : static bool mocked_supports_ed25519_link_authentication = 0;
286 : static bool
287 4 : mock_node_supports_ed25519_link_authentication(const node_t *node,
288 : bool compatible_with_us)
289 : {
290 4 : (void)node;
291 4 : (void)compatible_with_us;
292 4 : return mocked_supports_ed25519_link_authentication;
293 : }
294 :
295 : static ed25519_public_key_t * mocked_ed25519_id = NULL;
296 : static const ed25519_public_key_t *
297 3 : mock_node_get_ed25519_id(const node_t *node)
298 : {
299 3 : (void)node;
300 3 : return mocked_ed25519_id;
301 : }
302 :
303 : /* Test the different cases in circuit_extend_add_ed25519_helper(). */
304 : static void
305 1 : test_circuit_extend_add_ed25519(void *arg)
306 : {
307 1 : (void)arg;
308 1 : extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
309 1 : extend_cell_t *old_ec = tor_malloc_zero(sizeof(extend_cell_t));
310 1 : extend_cell_t *zero_ec = tor_malloc_zero(sizeof(extend_cell_t));
311 :
312 1 : node_t *fake_node = tor_malloc_zero(sizeof(node_t));
313 1 : ed25519_public_key_t *fake_ed25519_id = NULL;
314 1 : fake_ed25519_id = tor_malloc_zero(sizeof(ed25519_public_key_t));
315 :
316 1 : MOCK(node_get_by_id, mock_node_get_by_id);
317 1 : MOCK(node_supports_ed25519_link_authentication,
318 : mock_node_supports_ed25519_link_authentication);
319 1 : MOCK(node_get_ed25519_id, mock_node_get_ed25519_id);
320 :
321 1 : setup_full_capture_of_logs(LOG_INFO);
322 :
323 : #ifndef ALL_BUGS_ARE_FATAL
324 : /* The extend cell must be non-NULL */
325 1 : tor_capture_bugs_(1);
326 1 : tt_int_op(circuit_extend_add_ed25519_helper(NULL), OP_EQ, -1);
327 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
328 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
329 : "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
330 1 : tor_end_capture_bugs_();
331 1 : mock_clean_saved_logs();
332 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
333 :
334 : /* The node id must be non-zero */
335 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
336 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, -1);
337 1 : expect_log_msg(
338 1 : "Client asked me to extend without specifying an id_digest.\n");
339 : /* And nothing should have changed */
340 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
341 1 : mock_clean_saved_logs();
342 :
343 : /* Fill in fake node_id, and try again */
344 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
345 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
346 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
347 : /* There's no node with that id, so the ed pubkey should still be zeroed */
348 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
349 : /* In fact, nothing should have changed */
350 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
351 1 : mock_clean_saved_logs();
352 :
353 : /* Provide 2 out of 3 of node, supports link auth, and ed_id.
354 : * The ed_id should remain zeroed. */
355 :
356 : /* Provide node and supports link auth */
357 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
358 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
359 : /* Set up the fake variables */
360 1 : mocked_node = fake_node;
361 1 : mocked_supports_ed25519_link_authentication = 1;
362 : /* Do the test */
363 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
364 : /* The ed pubkey should still be zeroed */
365 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
366 : /* In fact, nothing should have changed */
367 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
368 : /* Cleanup */
369 1 : mock_clean_saved_logs();
370 1 : mocked_node = NULL;
371 1 : mocked_supports_ed25519_link_authentication = 0;
372 1 : mocked_ed25519_id = NULL;
373 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
374 :
375 : /* Provide supports link auth and ed id */
376 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
377 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
378 : /* Set up the fake variables */
379 1 : mocked_supports_ed25519_link_authentication = 1;
380 1 : memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
381 1 : mocked_ed25519_id = fake_ed25519_id;
382 : /* Do the test */
383 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
384 : /* The ed pubkey should still be zeroed */
385 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
386 : /* In fact, nothing should have changed */
387 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
388 : /* Cleanup */
389 1 : mock_clean_saved_logs();
390 1 : mocked_node = NULL;
391 1 : mocked_supports_ed25519_link_authentication = 0;
392 1 : mocked_ed25519_id = NULL;
393 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
394 :
395 : /* Provide node and ed id */
396 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
397 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
398 : /* Set up the fake variables */
399 1 : mocked_node = fake_node;
400 1 : memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
401 1 : mocked_ed25519_id = fake_ed25519_id;
402 : /* Do the test */
403 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
404 : /* The ed pubkey should still be zeroed */
405 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, &zero_ec->ed_pubkey, sizeof(ec->ed_pubkey));
406 : /* In fact, nothing should have changed */
407 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
408 : /* Cleanup */
409 1 : mock_clean_saved_logs();
410 1 : mocked_node = NULL;
411 1 : mocked_supports_ed25519_link_authentication = 0;
412 1 : mocked_ed25519_id = NULL;
413 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
414 :
415 : /* Now do the real lookup */
416 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
417 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
418 : /* Set up the fake variables */
419 1 : mocked_node = fake_node;
420 1 : mocked_supports_ed25519_link_authentication = 1;
421 1 : memset(fake_ed25519_id, 0xEE, sizeof(ed25519_public_key_t));
422 1 : mocked_ed25519_id = fake_ed25519_id;
423 : /* Do the test */
424 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
425 : /* The ed pubkey should match */
426 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, fake_ed25519_id, sizeof(ec->ed_pubkey));
427 : /* Nothing else should have changed */
428 1 : memcpy(&ec->ed_pubkey, &old_ec->ed_pubkey, sizeof(ec->ed_pubkey));
429 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
430 : /* Cleanup */
431 1 : mock_clean_saved_logs();
432 1 : mocked_node = NULL;
433 1 : mocked_supports_ed25519_link_authentication = 0;
434 1 : mocked_ed25519_id = NULL;
435 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
436 :
437 : /* Now do the real lookup, but with a zeroed ed id */
438 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
439 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
440 : /* Set up the fake variables */
441 1 : mocked_node = fake_node;
442 1 : mocked_supports_ed25519_link_authentication = 1;
443 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
444 1 : mocked_ed25519_id = fake_ed25519_id;
445 : /* Do the test */
446 1 : tt_int_op(circuit_extend_add_ed25519_helper(ec), OP_EQ, 0);
447 : /* The ed pubkey should match */
448 1 : tt_mem_op(&ec->ed_pubkey, OP_EQ, fake_ed25519_id, sizeof(ec->ed_pubkey));
449 : /* Nothing else should have changed */
450 1 : memcpy(&ec->ed_pubkey, &old_ec->ed_pubkey, sizeof(ec->ed_pubkey));
451 1 : tt_mem_op(ec, OP_EQ, old_ec, sizeof(extend_cell_t));
452 : /* Cleanup */
453 1 : mock_clean_saved_logs();
454 1 : mocked_node = NULL;
455 1 : mocked_supports_ed25519_link_authentication = 0;
456 1 : mocked_ed25519_id = NULL;
457 1 : memset(fake_ed25519_id, 0x00, sizeof(ed25519_public_key_t));
458 :
459 1 : done:
460 1 : UNMOCK(node_get_by_id);
461 1 : UNMOCK(node_supports_ed25519_link_authentication);
462 1 : UNMOCK(node_get_ed25519_id);
463 :
464 1 : tor_end_capture_bugs_();
465 1 : teardown_capture_of_logs();
466 :
467 1 : tor_free(ec);
468 1 : tor_free(old_ec);
469 1 : tor_free(zero_ec);
470 :
471 1 : tor_free(fake_ed25519_id);
472 1 : tor_free(fake_node);
473 1 : }
474 :
475 : static or_options_t *mocked_options = NULL;
476 : static const or_options_t *
477 51 : mock_get_options(void)
478 : {
479 51 : return mocked_options;
480 : }
481 :
482 : #define PUBLIC_IPV4 "1.2.3.4"
483 : #define INTERNAL_IPV4 "0.0.0.1"
484 :
485 : #define PUBLIC_IPV6 "1234::cdef"
486 : #define INTERNAL_IPV6 "::1"
487 :
488 : #define VALID_PORT 0x1234
489 :
490 : /* Test the different cases in circuit_extend_lspec_valid_helper(). */
491 : static void
492 1 : test_circuit_extend_lspec_valid(void *arg)
493 : {
494 1 : (void)arg;
495 1 : extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
496 1 : channel_t *p_chan = tor_malloc_zero(sizeof(channel_t));
497 1 : or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
498 1 : circuit_t *circ = TO_CIRCUIT(or_circ);
499 :
500 1 : or_options_t *fake_options = options_new();
501 1 : MOCK(get_options, mock_get_options);
502 1 : mocked_options = fake_options;
503 :
504 1 : setup_full_capture_of_logs(LOG_INFO);
505 :
506 : #ifndef ALL_BUGS_ARE_FATAL
507 : /* Extend cell must be non-NULL */
508 1 : tor_capture_bugs_(1);
509 1 : tt_int_op(circuit_extend_lspec_valid_helper(NULL, circ), OP_EQ, -1);
510 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
511 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
512 : "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
513 1 : tor_end_capture_bugs_();
514 1 : mock_clean_saved_logs();
515 :
516 : /* Circuit must be non-NULL */
517 1 : tor_capture_bugs_(1);
518 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, NULL), OP_EQ, -1);
519 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
520 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
521 : "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
522 1 : tor_end_capture_bugs_();
523 1 : mock_clean_saved_logs();
524 :
525 : /* Extend cell and circuit must be non-NULL */
526 1 : tor_capture_bugs_(1);
527 1 : tt_int_op(circuit_extend_lspec_valid_helper(NULL, NULL), OP_EQ, -1);
528 : /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
529 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
530 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
531 1 : tor_end_capture_bugs_();
532 1 : mock_clean_saved_logs();
533 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
534 :
535 : /* IPv4 and IPv6 addr and port are all zero, this should fail */
536 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
537 1 : expect_log_msg("Client asked me to extend to a zero destination port "
538 1 : "or unspecified address '[scrubbed]'.\n");
539 1 : mock_clean_saved_logs();
540 :
541 : /* Now ask for the actual address in the logs */
542 1 : fake_options->SafeLogging_ = SAFELOG_SCRUB_NONE;
543 :
544 : /* IPv4 port is 0, IPv6 addr and port are both zero, this should fail */
545 1 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
546 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
547 1 : expect_log_msg("Client asked me to extend to a zero destination port "
548 1 : "or IPv4 address '1.2.3.4:0'.\n");
549 1 : mock_clean_saved_logs();
550 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
551 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
552 :
553 : /* IPv4 addr is 0, IPv6 addr and port are both zero, this should fail */
554 1 : ec->orport_ipv4.port = VALID_PORT;
555 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
556 1 : expect_log_msg("Client asked me to extend to a zero destination port "
557 1 : "or IPv4 address '0.0.0.0:4660'.\n");
558 1 : mock_clean_saved_logs();
559 1 : ec->orport_ipv4.port = 0;
560 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
561 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
562 :
563 : /* IPv4 addr is internal, and port is valid.
564 : * (IPv6 addr and port are both zero.)
565 : * Result depends on ExtendAllowPrivateAddresses. */
566 1 : tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
567 1 : ec->orport_ipv4.port = VALID_PORT;
568 :
569 1 : fake_options->ExtendAllowPrivateAddresses = 0;
570 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
571 1 : expect_log_msg("Client asked me to extend "
572 1 : "to a private IPv4 address '0.0.0.1'.\n");
573 1 : mock_clean_saved_logs();
574 1 : fake_options->ExtendAllowPrivateAddresses = 0;
575 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
576 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
577 :
578 : /* Now do the same tests, but for IPv6 */
579 :
580 : /* IPv6 port is 0, IPv4 addr and port are both zero, this should fail */
581 1 : tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
582 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
583 1 : expect_log_msg("Client asked me to extend to a zero destination port "
584 1 : "or IPv6 address '[1234::cdef]:0'.\n");
585 1 : mock_clean_saved_logs();
586 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
587 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
588 :
589 : /* IPv6 addr is 0, IPv4 addr and port are both zero, this should fail */
590 1 : ec->orport_ipv6.port = VALID_PORT;
591 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
592 1 : expect_log_msg("Client asked me to extend to a zero destination port "
593 1 : "or IPv6 address '[::]:4660'.\n");
594 1 : mock_clean_saved_logs();
595 1 : ec->orport_ipv4.port = 0;
596 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
597 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
598 :
599 : /* IPv6 addr is internal, and port is valid.
600 : * (IPv4 addr and port are both zero.)
601 : * Result depends on ExtendAllowPrivateAddresses. */
602 1 : tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
603 1 : ec->orport_ipv6.port = VALID_PORT;
604 :
605 1 : fake_options->ExtendAllowPrivateAddresses = 0;
606 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
607 1 : expect_log_msg("Client asked me to extend "
608 1 : "to a private IPv6 address '[::1]'.\n");
609 1 : mock_clean_saved_logs();
610 1 : fake_options->ExtendAllowPrivateAddresses = 0;
611 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
612 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
613 :
614 : /* Both addresses are internal.
615 : * Result depends on ExtendAllowPrivateAddresses. */
616 1 : tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
617 1 : ec->orport_ipv4.port = VALID_PORT;
618 1 : tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
619 1 : ec->orport_ipv6.port = VALID_PORT;
620 :
621 1 : fake_options->ExtendAllowPrivateAddresses = 0;
622 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
623 1 : expect_log_msg("Client asked me to extend "
624 1 : "to a private IPv4 address '0.0.0.1'.\n");
625 1 : expect_log_msg("Client asked me to extend "
626 1 : "to a private IPv6 address '[::1]'.\n");
627 1 : mock_clean_saved_logs();
628 1 : fake_options->ExtendAllowPrivateAddresses = 0;
629 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
630 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
631 :
632 : #ifndef ALL_BUGS_ARE_FATAL
633 : /* If we pass the private address check, but don't have the right
634 : * OR circuit magic number, we trigger another bug */
635 1 : tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
636 1 : ec->orport_ipv4.port = VALID_PORT;
637 1 : tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
638 1 : ec->orport_ipv6.port = VALID_PORT;
639 1 : fake_options->ExtendAllowPrivateAddresses = 1;
640 :
641 1 : tor_capture_bugs_(1);
642 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
643 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
644 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
645 : "!(ASSERT_PREDICT_UNLIKELY_(circ->magic != 0x98ABC04Fu))");
646 1 : tor_end_capture_bugs_();
647 1 : mock_clean_saved_logs();
648 1 : fake_options->ExtendAllowPrivateAddresses = 0;
649 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
650 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
651 :
652 : /* Fail again, but this time only set an IPv4 address. */
653 1 : tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
654 1 : ec->orport_ipv4.port = VALID_PORT;
655 1 : fake_options->ExtendAllowPrivateAddresses = 1;
656 1 : tor_capture_bugs_(1);
657 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
658 : /* Since we're using IF_BUG_ONCE(), expect 0-1 bug logs */
659 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
660 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 1);
661 1 : tor_end_capture_bugs_();
662 1 : mock_clean_saved_logs();
663 1 : fake_options->ExtendAllowPrivateAddresses = 0;
664 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
665 :
666 : /* Now set the right magic */
667 1 : or_circ->base_.magic = OR_CIRCUIT_MAGIC;
668 :
669 : #ifndef ALL_BUGS_ARE_FATAL
670 : /* If we pass the OR circuit magic check, but don't have p_chan,
671 : * we trigger another bug */
672 1 : fake_options->ExtendAllowPrivateAddresses = 1;
673 1 : tor_capture_bugs_(1);
674 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
675 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
676 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
677 : "!(ASSERT_PREDICT_UNLIKELY_(!p_chan))");
678 1 : tor_end_capture_bugs_();
679 1 : mock_clean_saved_logs();
680 1 : fake_options->ExtendAllowPrivateAddresses = 0;
681 :
682 : /* We can also pass the OR circuit magic check with a public address */
683 1 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
684 1 : fake_options->ExtendAllowPrivateAddresses = 0;
685 1 : tor_capture_bugs_(1);
686 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
687 : /* Since we're using IF_BUG_ONCE(), expect 0-1 bug logs */
688 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
689 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 1);
690 1 : tor_end_capture_bugs_();
691 1 : mock_clean_saved_logs();
692 1 : fake_options->ExtendAllowPrivateAddresses = 0;
693 :
694 1 : tor_addr_make_null(&ec->orport_ipv4.addr, AF_INET);
695 1 : ec->orport_ipv4.port = 0x0000;
696 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
697 :
698 : /* Now let's fake a p_chan and the addresses */
699 1 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
700 1 : ec->orport_ipv4.port = VALID_PORT;
701 1 : or_circ->p_chan = p_chan;
702 :
703 : /* This is a trivial failure: node_id and p_chan->identity_digest are both
704 : * zeroed */
705 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
706 1 : expect_log_msg("Client asked me to extend back to the previous hop.\n");
707 1 : mock_clean_saved_logs();
708 :
709 : /* Let's check with non-zero identities as well */
710 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
711 1 : memset(p_chan->identity_digest, 0xAA, sizeof(p_chan->identity_digest));
712 :
713 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
714 1 : expect_log_msg("Client asked me to extend back to the previous hop.\n");
715 1 : mock_clean_saved_logs();
716 :
717 1 : memset(ec->node_id, 0, sizeof(ec->node_id));
718 1 : memset(p_chan->identity_digest, 0, sizeof(p_chan->identity_digest));
719 :
720 : /* Let's pass the node_id test */
721 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
722 1 : memset(p_chan->identity_digest, 0xBB, sizeof(p_chan->identity_digest));
723 :
724 : /* ed_pubkey is zero, and that's allowed, so we should succeed */
725 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
726 1 : mock_clean_saved_logs();
727 :
728 : /* Now let's check that we warn, but succeed, when only one address is
729 : * private */
730 1 : tor_addr_parse(&ec->orport_ipv4.addr, INTERNAL_IPV4);
731 1 : ec->orport_ipv4.port = VALID_PORT;
732 1 : tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
733 1 : ec->orport_ipv6.port = VALID_PORT;
734 1 : fake_options->ExtendAllowPrivateAddresses = 0;
735 :
736 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
737 1 : expect_log_msg("Client asked me to extend "
738 1 : "to a private IPv4 address '0.0.0.1'.\n");
739 1 : mock_clean_saved_logs();
740 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
741 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
742 :
743 : /* Now with private IPv6 */
744 1 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
745 1 : ec->orport_ipv4.port = VALID_PORT;
746 1 : tor_addr_parse(&ec->orport_ipv6.addr, INTERNAL_IPV6);
747 1 : ec->orport_ipv6.port = VALID_PORT;
748 1 : fake_options->ExtendAllowPrivateAddresses = 0;
749 :
750 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
751 1 : expect_log_msg("Client asked me to extend "
752 1 : "to a private IPv6 address '[::1]'.\n");
753 1 : mock_clean_saved_logs();
754 1 : tor_addr_port_make_null_ap(&ec->orport_ipv4, AF_INET);
755 1 : tor_addr_port_make_null_ap(&ec->orport_ipv6, AF_INET6);
756 :
757 : /* Now reset to public IPv4 and IPv6 */
758 1 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
759 1 : ec->orport_ipv4.port = VALID_PORT;
760 1 : tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
761 1 : ec->orport_ipv6.port = VALID_PORT;
762 :
763 : /* Fail on matching non-zero identities */
764 1 : memset(&ec->ed_pubkey, 0xEE, sizeof(ec->ed_pubkey));
765 1 : memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
766 :
767 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, -1);
768 1 : expect_log_msg("Client asked me to extend back to the previous hop "
769 1 : "(by Ed25519 ID).\n");
770 1 : mock_clean_saved_logs();
771 :
772 1 : memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
773 1 : memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
774 :
775 : /* Succeed on different, non-zero identities */
776 1 : memset(&ec->ed_pubkey, 0xDD, sizeof(ec->ed_pubkey));
777 1 : memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
778 :
779 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
780 1 : mock_clean_saved_logs();
781 :
782 1 : memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
783 1 : memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
784 :
785 : /* Succeed if the client knows the identity, but we don't */
786 1 : memset(&ec->ed_pubkey, 0xDD, sizeof(ec->ed_pubkey));
787 1 : memset(&p_chan->ed25519_identity, 0x00, sizeof(p_chan->ed25519_identity));
788 :
789 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
790 1 : mock_clean_saved_logs();
791 :
792 1 : memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
793 1 : memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
794 :
795 : /* Succeed if we know the identity, but the client doesn't */
796 1 : memset(&ec->ed_pubkey, 0x00, sizeof(ec->ed_pubkey));
797 1 : memset(&p_chan->ed25519_identity, 0xEE, sizeof(p_chan->ed25519_identity));
798 :
799 1 : tt_int_op(circuit_extend_lspec_valid_helper(ec, circ), OP_EQ, 0);
800 1 : mock_clean_saved_logs();
801 :
802 1 : memset(&ec->ed_pubkey, 0, sizeof(ec->ed_pubkey));
803 1 : memset(&p_chan->ed25519_identity, 0, sizeof(p_chan->ed25519_identity));
804 :
805 : /* Cleanup the node ids */
806 1 : memset(ec->node_id, 0, sizeof(ec->node_id));
807 1 : memset(p_chan->identity_digest, 0, sizeof(p_chan->identity_digest));
808 :
809 : /* Cleanup the p_chan and the addresses */
810 1 : tor_addr_make_null(&ec->orport_ipv4.addr, AF_UNSPEC);
811 1 : ec->orport_ipv4.port = 0;
812 1 : or_circ->p_chan = NULL;
813 :
814 1 : done:
815 1 : tor_end_capture_bugs_();
816 1 : teardown_capture_of_logs();
817 :
818 1 : UNMOCK(get_options);
819 1 : or_options_free(fake_options);
820 1 : mocked_options = NULL;
821 :
822 1 : tor_free(ec);
823 1 : tor_free(or_circ);
824 1 : tor_free(p_chan);
825 1 : }
826 :
827 : #define NODE_SET_IPV4(node, ipv4_addr_str, ipv4_port) { \
828 : tor_addr_parse(&node->ri->ipv4_addr, ipv4_addr_str); \
829 : node->ri->ipv4_orport = ipv4_port; \
830 : }
831 :
832 : #define NODE_CLEAR_IPV4(node) { \
833 : tor_addr_make_unspec(&node->ri->ipv4_addr); \
834 : node->ri->ipv4_orport = 0; \
835 : }
836 :
837 : #define NODE_SET_IPV6(node, ipv6_addr_str, ipv6_port) { \
838 : tor_addr_parse(&node->ri->ipv6_addr, ipv6_addr_str); \
839 : node->ri->ipv6_orport = ipv6_port; \
840 : }
841 :
842 : /* Test the different cases in circuit_extend_add_ed25519_helper(). */
843 : static void
844 1 : test_circuit_extend_add_ip(void *arg)
845 : {
846 1 : (void) arg;
847 1 : tor_addr_t ipv4_tmp;
848 1 : extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
849 1 : extend_cell_t *old_ec = tor_malloc_zero(sizeof(extend_cell_t));
850 :
851 1 : node_t *fake_node = tor_malloc_zero(sizeof(node_t));
852 1 : routerinfo_t *ri = tor_malloc_zero(sizeof(routerinfo_t));
853 :
854 1 : MOCK(node_get_by_id, mock_node_get_by_id);
855 :
856 : /* Set up the fake variables for the IPv4 test */
857 1 : fake_node->ri = ri;
858 1 : mocked_node = fake_node;
859 1 : memset(ec->node_id, 0xAA, sizeof(ec->node_id));
860 1 : memcpy(old_ec, ec, sizeof(extend_cell_t));
861 1 : NODE_SET_IPV4(fake_node, PUBLIC_IPV4, VALID_PORT);
862 :
863 : /* Do the IPv4 test */
864 1 : tt_int_op(circuit_extend_add_ipv4_helper(ec), OP_EQ, 0);
865 1 : tor_addr_copy(&ipv4_tmp, &fake_node->ri->ipv4_addr);
866 : /* The IPv4 should match */
867 1 : tt_int_op(tor_addr_compare(&ec->orport_ipv4.addr, &ipv4_tmp, CMP_SEMANTIC),
868 : OP_EQ, 0);
869 1 : tt_int_op(ec->orport_ipv4.port, OP_EQ, VALID_PORT);
870 :
871 : /* Set up the fake variables for the IPv6 test */
872 1 : memcpy(ec, old_ec, sizeof(extend_cell_t));
873 1 : NODE_CLEAR_IPV4(fake_node);
874 1 : NODE_SET_IPV6(fake_node, PUBLIC_IPV6, VALID_PORT);
875 :
876 : /* Do the IPv6 test */
877 1 : tt_int_op(circuit_extend_add_ipv6_helper(ec), OP_EQ, 0);
878 : /* The IPv6 should match */
879 1 : tt_int_op(tor_addr_compare(&ec->orport_ipv6.addr, &fake_node->ri->ipv6_addr,
880 : CMP_SEMANTIC), OP_EQ, 0);
881 1 : tt_int_op(ec->orport_ipv6.port, OP_EQ, VALID_PORT);
882 :
883 : /* Cleanup */
884 1 : mocked_node = NULL;
885 :
886 1 : done:
887 1 : UNMOCK(node_get_by_id);
888 :
889 1 : tor_free(ec);
890 1 : tor_free(old_ec);
891 :
892 1 : tor_free(ri);
893 1 : tor_free(fake_node);
894 1 : }
895 :
896 : static bool can_extend_over_ipv6_result = false;
897 : static int mock_router_can_extend_over_ipv6_calls = 0;
898 : static bool
899 17 : mock_router_can_extend_over_ipv6(const or_options_t *options)
900 : {
901 17 : (void)options;
902 17 : mock_router_can_extend_over_ipv6_calls++;
903 17 : return can_extend_over_ipv6_result;
904 : }
905 :
906 : /* Test the different cases in circuit_choose_ip_ap_for_extend(). */
907 : static void
908 1 : test_circuit_choose_ip_ap_for_extend(void *arg)
909 : {
910 1 : (void)arg;
911 1 : tor_addr_port_t ipv4_ap;
912 1 : tor_addr_port_t ipv6_ap;
913 :
914 : /* Set up valid addresses */
915 1 : tor_addr_parse(&ipv4_ap.addr, PUBLIC_IPV4);
916 1 : ipv4_ap.port = VALID_PORT;
917 1 : tor_addr_parse(&ipv6_ap.addr, PUBLIC_IPV6);
918 1 : ipv6_ap.port = VALID_PORT;
919 :
920 1 : or_options_t *fake_options = options_new();
921 1 : MOCK(get_options, mock_get_options);
922 1 : mocked_options = fake_options;
923 :
924 1 : MOCK(router_can_extend_over_ipv6,
925 : mock_router_can_extend_over_ipv6);
926 1 : can_extend_over_ipv6_result = true;
927 1 : mock_router_can_extend_over_ipv6_calls = 0;
928 :
929 : /* No valid addresses */
930 1 : can_extend_over_ipv6_result = true;
931 1 : mock_router_can_extend_over_ipv6_calls = 0;
932 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
933 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
934 :
935 1 : can_extend_over_ipv6_result = false;
936 1 : mock_router_can_extend_over_ipv6_calls = 0;
937 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, NULL), OP_EQ, NULL);
938 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
939 :
940 : /* One valid address: IPv4 */
941 1 : can_extend_over_ipv6_result = true;
942 1 : mock_router_can_extend_over_ipv6_calls = 0;
943 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
944 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
945 :
946 1 : can_extend_over_ipv6_result = false;
947 1 : mock_router_can_extend_over_ipv6_calls = 0;
948 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, NULL), OP_EQ, &ipv4_ap);
949 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
950 :
951 : /* One valid address: IPv6 */
952 1 : can_extend_over_ipv6_result = true;
953 1 : mock_router_can_extend_over_ipv6_calls = 0;
954 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, &ipv6_ap);
955 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
956 :
957 1 : can_extend_over_ipv6_result = false;
958 1 : mock_router_can_extend_over_ipv6_calls = 0;
959 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(NULL, &ipv6_ap), OP_EQ, NULL);
960 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
961 :
962 : /* Two valid addresses */
963 1 : const tor_addr_port_t *chosen_addr = NULL;
964 :
965 1 : can_extend_over_ipv6_result = true;
966 1 : mock_router_can_extend_over_ipv6_calls = 0;
967 1 : chosen_addr = circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap);
968 1 : tt_assert(chosen_addr == &ipv4_ap || chosen_addr == &ipv6_ap);
969 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
970 :
971 1 : can_extend_over_ipv6_result = false;
972 1 : mock_router_can_extend_over_ipv6_calls = 0;
973 1 : tt_ptr_op(circuit_choose_ip_ap_for_extend(&ipv4_ap, &ipv6_ap),
974 : OP_EQ, &ipv4_ap);
975 1 : tt_int_op(mock_router_can_extend_over_ipv6_calls, OP_EQ, 1);
976 :
977 1 : done:
978 1 : UNMOCK(get_options);
979 1 : or_options_free(fake_options);
980 1 : mocked_options = NULL;
981 :
982 1 : UNMOCK(router_can_extend_over_ipv6);
983 :
984 1 : tor_free(fake_options);
985 1 : }
986 :
987 : static int mock_circuit_close_calls = 0;
988 : static void
989 9 : mock_circuit_mark_for_close_(circuit_t *circ, int reason,
990 : int line, const char *cfile)
991 : {
992 9 : (void)circ;
993 9 : (void)reason;
994 9 : (void)line;
995 9 : (void)cfile;
996 9 : mock_circuit_close_calls++;
997 9 : }
998 :
999 : static int mock_channel_connect_calls = 0;
1000 : static channel_t *mock_channel_connect_nchan = NULL;
1001 : static channel_t *
1002 7 : mock_channel_connect_for_circuit(const extend_info_t *ei)
1003 : {
1004 7 : (void)ei;
1005 7 : mock_channel_connect_calls++;
1006 7 : return mock_channel_connect_nchan;
1007 : }
1008 :
1009 : /* Test the different cases in circuit_open_connection_for_extend().
1010 : * Chooses different IP addresses depending on the first character in arg:
1011 : * - 4: IPv4
1012 : * - 6: IPv6
1013 : * - d: IPv4 and IPv6 (dual-stack)
1014 : */
1015 : static void
1016 3 : test_circuit_open_connection_for_extend(void *arg)
1017 : {
1018 3 : const char ip_version = ((const char *)arg)[0];
1019 3 : const bool use_ipv4 = (ip_version == '4' || ip_version == 'd');
1020 3 : const bool use_ipv6 = (ip_version == '6' || ip_version == 'd');
1021 3 : tor_assert(use_ipv4 || use_ipv6);
1022 :
1023 3 : extend_cell_t *ec = tor_malloc_zero(sizeof(extend_cell_t));
1024 3 : circuit_t *circ = tor_malloc_zero(sizeof(circuit_t));
1025 3 : channel_t *fake_n_chan = tor_malloc_zero(sizeof(channel_t));
1026 :
1027 3 : or_options_t *fake_options = options_new();
1028 3 : MOCK(get_options, mock_get_options);
1029 3 : mocked_options = fake_options;
1030 :
1031 3 : MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close_);
1032 3 : mock_circuit_close_calls = 0;
1033 3 : MOCK(channel_connect_for_circuit, mock_channel_connect_for_circuit);
1034 3 : mock_channel_connect_calls = 0;
1035 3 : mock_channel_connect_nchan = NULL;
1036 :
1037 3 : MOCK(router_can_extend_over_ipv6,
1038 : mock_router_can_extend_over_ipv6);
1039 3 : can_extend_over_ipv6_result = true;
1040 :
1041 3 : setup_full_capture_of_logs(LOG_INFO);
1042 :
1043 : #ifndef ALL_BUGS_ARE_FATAL
1044 : /* Circuit must be non-NULL */
1045 3 : mock_circuit_close_calls = 0;
1046 3 : mock_channel_connect_calls = 0;
1047 3 : tor_capture_bugs_(1);
1048 3 : circuit_open_connection_for_extend(ec, NULL, 0);
1049 : /* We can't close a NULL circuit */
1050 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
1051 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1052 3 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1053 3 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1054 : "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
1055 3 : tor_end_capture_bugs_();
1056 3 : mock_clean_saved_logs();
1057 :
1058 : /* Extend cell must be non-NULL */
1059 3 : mock_circuit_close_calls = 0;
1060 3 : mock_channel_connect_calls = 0;
1061 3 : tor_capture_bugs_(1);
1062 3 : circuit_open_connection_for_extend(NULL, circ, 0);
1063 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
1064 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1065 3 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1066 3 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1067 : "!(ASSERT_PREDICT_UNLIKELY_(!ec))");
1068 3 : tor_end_capture_bugs_();
1069 3 : mock_clean_saved_logs();
1070 :
1071 : /* Extend cell and circuit must be non-NULL */
1072 3 : mock_circuit_close_calls = 0;
1073 3 : mock_channel_connect_calls = 0;
1074 3 : tor_capture_bugs_(1);
1075 3 : circuit_open_connection_for_extend(NULL, NULL, 0);
1076 : /* We can't close a NULL circuit */
1077 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
1078 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1079 : /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
1080 3 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
1081 3 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
1082 3 : tor_end_capture_bugs_();
1083 3 : mock_clean_saved_logs();
1084 :
1085 : /* Fail, because neither address is valid */
1086 3 : mock_circuit_close_calls = 0;
1087 3 : mock_channel_connect_calls = 0;
1088 3 : tor_capture_bugs_(1);
1089 3 : circuit_open_connection_for_extend(ec, circ, 0);
1090 : /* Close the circuit, don't connect */
1091 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
1092 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1093 : /* Check state */
1094 3 : tt_ptr_op(circ->n_hop, OP_EQ, NULL);
1095 3 : tt_ptr_op(circ->n_chan_create_cell, OP_EQ, NULL);
1096 3 : tt_int_op(circ->state, OP_EQ, 0);
1097 : /* Cleanup */
1098 3 : tor_end_capture_bugs_();
1099 3 : mock_clean_saved_logs();
1100 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
1101 :
1102 : /* Set up valid addresses */
1103 3 : if (use_ipv4) {
1104 2 : tor_addr_parse(&ec->orport_ipv4.addr, PUBLIC_IPV4);
1105 2 : ec->orport_ipv4.port = VALID_PORT;
1106 : }
1107 3 : if (use_ipv6) {
1108 2 : tor_addr_parse(&ec->orport_ipv6.addr, PUBLIC_IPV6);
1109 2 : ec->orport_ipv6.port = VALID_PORT;
1110 : }
1111 :
1112 : /* Succeed, but don't try to open a connection */
1113 3 : mock_circuit_close_calls = 0;
1114 3 : mock_channel_connect_calls = 0;
1115 3 : circuit_open_connection_for_extend(ec, circ, 0);
1116 : /* If we haven't closed the circuit, that's success */
1117 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
1118 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1119 : /* Check state */
1120 3 : tt_ptr_op(circ->n_hop, OP_NE, NULL);
1121 3 : tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
1122 3 : tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
1123 : /* Cleanup */
1124 3 : mock_clean_saved_logs();
1125 3 : tor_free(circ->n_hop);
1126 3 : tor_free(circ->n_chan_create_cell);
1127 3 : circ->state = 0;
1128 :
1129 : /* Try to open a connection, but fail with a NULL n_chan */
1130 3 : mock_circuit_close_calls = 0;
1131 3 : mock_channel_connect_calls = 0;
1132 3 : circuit_open_connection_for_extend(ec, circ, 1);
1133 : /* Try to connect, but fail, and close the circuit */
1134 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 1);
1135 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
1136 3 : expect_log_msg("Launching n_chan failed. Closing circuit.\n");
1137 : /* Check state */
1138 3 : tt_ptr_op(circ->n_hop, OP_NE, NULL);
1139 3 : tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
1140 3 : tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
1141 : /* Cleanup */
1142 3 : mock_clean_saved_logs();
1143 3 : tor_free(circ->n_hop);
1144 3 : tor_free(circ->n_chan_create_cell);
1145 3 : circ->state = 0;
1146 :
1147 : /* Try to open a connection, and succeed, because n_chan is not NULL */
1148 3 : mock_channel_connect_nchan = fake_n_chan;
1149 3 : mock_circuit_close_calls = 0;
1150 3 : mock_channel_connect_calls = 0;
1151 3 : circuit_open_connection_for_extend(ec, circ, 1);
1152 : /* Connection attempt succeeded, leaving the circuit open */
1153 3 : tt_int_op(mock_circuit_close_calls, OP_EQ, 0);
1154 3 : tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
1155 : /* Check state */
1156 3 : tt_ptr_op(circ->n_hop, OP_NE, NULL);
1157 3 : tt_ptr_op(circ->n_chan_create_cell, OP_NE, NULL);
1158 3 : tt_int_op(circ->state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
1159 : /* Cleanup */
1160 3 : mock_clean_saved_logs();
1161 3 : tor_free(circ->n_hop);
1162 3 : tor_free(circ->n_chan_create_cell);
1163 3 : circ->state = 0;
1164 3 : mock_channel_connect_nchan = NULL;
1165 :
1166 3 : done:
1167 3 : tor_end_capture_bugs_();
1168 3 : teardown_capture_of_logs();
1169 :
1170 3 : UNMOCK(circuit_mark_for_close_);
1171 3 : mock_circuit_close_calls = 0;
1172 3 : UNMOCK(channel_connect_for_circuit);
1173 3 : mock_channel_connect_calls = 0;
1174 :
1175 3 : UNMOCK(get_options);
1176 3 : or_options_free(fake_options);
1177 3 : mocked_options = NULL;
1178 :
1179 3 : UNMOCK(router_can_extend_over_ipv6);
1180 :
1181 3 : tor_free(ec);
1182 3 : tor_free(circ->n_hop);
1183 3 : tor_free(circ->n_chan_create_cell);
1184 3 : tor_free(circ);
1185 3 : tor_free(fake_n_chan);
1186 3 : }
1187 :
1188 : /* Guaranteed to be initialised to zero. */
1189 : static extend_cell_t mock_extend_cell_parse_cell_out;
1190 : static int mock_extend_cell_parse_result = 0;
1191 : static int mock_extend_cell_parse_calls = 0;
1192 :
1193 : static int
1194 7 : mock_extend_cell_parse(extend_cell_t *cell_out,
1195 : const uint8_t command,
1196 : const uint8_t *payload_in,
1197 : size_t payload_len)
1198 : {
1199 7 : (void)command;
1200 7 : (void)payload_in;
1201 7 : (void)payload_len;
1202 :
1203 7 : mock_extend_cell_parse_calls++;
1204 7 : memcpy(cell_out, &mock_extend_cell_parse_cell_out,
1205 : sizeof(extend_cell_t));
1206 7 : return mock_extend_cell_parse_result;
1207 : }
1208 :
1209 : static int mock_channel_get_for_extend_calls = 0;
1210 : static int mock_channel_get_for_extend_launch_out = 0;
1211 : static channel_t *mock_channel_get_for_extend_nchan = NULL;
1212 : static channel_t *
1213 4 : mock_channel_get_for_extend(const char *rsa_id_digest,
1214 : const ed25519_public_key_t *ed_id,
1215 : const tor_addr_t *target_ipv4_addr,
1216 : const tor_addr_t *target_ipv6_addr,
1217 : bool for_origin_circ,
1218 : const char **msg_out,
1219 : int *launch_out)
1220 : {
1221 4 : (void)rsa_id_digest;
1222 4 : (void)ed_id;
1223 4 : (void)target_ipv4_addr;
1224 4 : (void)target_ipv6_addr;
1225 4 : (void)for_origin_circ;
1226 :
1227 : /* channel_get_for_extend() requires non-NULL arguments */
1228 4 : tt_ptr_op(msg_out, OP_NE, NULL);
1229 4 : tt_ptr_op(launch_out, OP_NE, NULL);
1230 :
1231 4 : mock_channel_get_for_extend_calls++;
1232 4 : *msg_out = NULL;
1233 4 : *launch_out = mock_channel_get_for_extend_launch_out;
1234 4 : return mock_channel_get_for_extend_nchan;
1235 :
1236 : done:
1237 : return NULL;
1238 : }
1239 :
1240 : static const char *
1241 2 : mock_channel_get_canonical_remote_descr(channel_t *chan)
1242 : {
1243 2 : (void)chan;
1244 2 : return "mock_channel_get_canonical_remote_descr()";
1245 : }
1246 :
1247 : /* Should mock_circuit_deliver_create_cell() expect a direct connection? */
1248 : static bool mock_circuit_deliver_create_cell_expect_direct = false;
1249 : static int mock_circuit_deliver_create_cell_calls = 0;
1250 : static int mock_circuit_deliver_create_cell_result = 0;
1251 : static int
1252 4 : mock_circuit_deliver_create_cell(circuit_t *circ,
1253 : const struct create_cell_t *create_cell,
1254 : int relayed)
1255 : {
1256 4 : (void)create_cell;
1257 :
1258 : /* circuit_deliver_create_cell() requires non-NULL arguments,
1259 : * but we only check circ and circ->n_chan here. */
1260 4 : tt_ptr_op(circ, OP_NE, NULL);
1261 : /* We expect n_chan for relayed cells. But should we also expect it for
1262 : * direct connections? */
1263 4 : if (!mock_circuit_deliver_create_cell_expect_direct)
1264 2 : tt_ptr_op(circ->n_chan, OP_NE, NULL);
1265 :
1266 : /* We should only ever get relayed cells from extends */
1267 4 : tt_int_op(relayed, OP_EQ, !mock_circuit_deliver_create_cell_expect_direct);
1268 :
1269 4 : mock_circuit_deliver_create_cell_calls++;
1270 4 : return mock_circuit_deliver_create_cell_result;
1271 :
1272 : done:
1273 : return -1;
1274 : }
1275 :
1276 : /* Test the different cases in circuit_extend(). */
1277 : static void
1278 1 : test_circuit_extend(void *arg)
1279 : {
1280 1 : (void)arg;
1281 1 : cell_t *cell = tor_malloc_zero(sizeof(cell_t));
1282 1 : channel_t *p_chan = tor_malloc_zero(sizeof(channel_t));
1283 1 : or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
1284 1 : circuit_t *circ = TO_CIRCUIT(or_circ);
1285 1 : channel_t *fake_n_chan = tor_malloc_zero(sizeof(channel_t));
1286 :
1287 1 : server = 0;
1288 1 : MOCK(server_mode, mock_server_mode);
1289 :
1290 : /* Mock a debug function, but otherwise ignore it */
1291 1 : MOCK(channel_describe_peer,
1292 : mock_channel_get_canonical_remote_descr);
1293 :
1294 1 : setup_full_capture_of_logs(LOG_INFO);
1295 :
1296 : #ifndef ALL_BUGS_ARE_FATAL
1297 : /* Circuit must be non-NULL */
1298 1 : tor_capture_bugs_(1);
1299 1 : tt_int_op(circuit_extend(cell, NULL), OP_EQ, -1);
1300 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1301 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1302 : "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
1303 1 : tor_end_capture_bugs_();
1304 1 : mock_clean_saved_logs();
1305 :
1306 : /* Cell must be non-NULL */
1307 1 : tor_capture_bugs_(1);
1308 1 : tt_int_op(circuit_extend(NULL, circ), OP_EQ, -1);
1309 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1310 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1311 : "!(ASSERT_PREDICT_UNLIKELY_(!cell))");
1312 1 : tor_end_capture_bugs_();
1313 1 : mock_clean_saved_logs();
1314 :
1315 : /* Extend cell and circuit must be non-NULL */
1316 1 : tor_capture_bugs_(1);
1317 1 : tt_int_op(circuit_extend(NULL, NULL), OP_EQ, -1);
1318 : /* Since we're using IF_BUG_ONCE(), we might not log any bugs */
1319 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_GE, 0);
1320 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_LE, 2);
1321 1 : tor_end_capture_bugs_();
1322 1 : mock_clean_saved_logs();
1323 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
1324 :
1325 : /* Clients can't extend */
1326 1 : server = 0;
1327 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1328 1 : expect_log_msg("Got an extend cell, but running as a client. Closing.\n");
1329 1 : mock_clean_saved_logs();
1330 :
1331 : /* But servers can. Unpack the cell, but fail parsing. */
1332 1 : server = 1;
1333 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1334 1 : expect_log_msg("Can't parse extend cell. Closing circuit.\n");
1335 1 : mock_clean_saved_logs();
1336 :
1337 : /* Now mock parsing */
1338 1 : MOCK(extend_cell_parse, mock_extend_cell_parse);
1339 :
1340 : /* And make parsing succeed, but fail on adding ed25519 */
1341 1 : memset(&mock_extend_cell_parse_cell_out, 0,
1342 : sizeof(mock_extend_cell_parse_cell_out));
1343 1 : mock_extend_cell_parse_result = 0;
1344 1 : mock_extend_cell_parse_calls = 0;
1345 :
1346 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1347 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1348 1 : expect_log_msg(
1349 1 : "Client asked me to extend without specifying an id_digest.\n");
1350 1 : mock_clean_saved_logs();
1351 1 : mock_extend_cell_parse_calls = 0;
1352 :
1353 : /* Now add a node_id. Fail the lspec check because IPv4 and port are zero. */
1354 1 : memset(&mock_extend_cell_parse_cell_out.node_id, 0xAA,
1355 : sizeof(mock_extend_cell_parse_cell_out.node_id));
1356 :
1357 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1358 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1359 1 : expect_log_msg("Client asked me to extend to a zero destination port "
1360 1 : "or unspecified address '[scrubbed]'.\n");
1361 1 : mock_clean_saved_logs();
1362 1 : mock_extend_cell_parse_calls = 0;
1363 :
1364 : /* Now add a valid IPv4 and port. Fail the OR circuit magic check. */
1365 1 : tor_addr_parse(&mock_extend_cell_parse_cell_out.orport_ipv4.addr,
1366 : PUBLIC_IPV4);
1367 1 : mock_extend_cell_parse_cell_out.orport_ipv4.port = VALID_PORT;
1368 :
1369 : #ifndef ALL_BUGS_ARE_FATAL
1370 1 : tor_capture_bugs_(1);
1371 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1372 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1373 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1374 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1375 : "!(ASSERT_PREDICT_UNLIKELY_(circ->magic != 0x98ABC04Fu))");
1376 1 : tor_end_capture_bugs_();
1377 1 : mock_clean_saved_logs();
1378 1 : mock_extend_cell_parse_calls = 0;
1379 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
1380 :
1381 : /* Now add the right magic and a p_chan. */
1382 1 : or_circ->base_.magic = OR_CIRCUIT_MAGIC;
1383 1 : or_circ->p_chan = p_chan;
1384 :
1385 : /* Mock channel_get_for_extend(), so it doesn't crash. */
1386 1 : mock_channel_get_for_extend_calls = 0;
1387 1 : MOCK(channel_get_for_extend, mock_channel_get_for_extend);
1388 :
1389 : /* Test circuit not established, but don't launch another one */
1390 1 : mock_channel_get_for_extend_launch_out = 0;
1391 1 : mock_channel_get_for_extend_nchan = NULL;
1392 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
1393 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1394 1 : tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
1395 :
1396 : /* cleanup */
1397 1 : mock_clean_saved_logs();
1398 1 : mock_extend_cell_parse_calls = 0;
1399 1 : mock_channel_get_for_extend_calls = 0;
1400 : /* circ and or_circ are the same object */
1401 1 : tor_free(circ->n_hop);
1402 1 : tor_free(circ->n_chan_create_cell);
1403 :
1404 : /* Mock channel_connect_for_circuit(), so we don't crash */
1405 1 : mock_channel_connect_calls = 0;
1406 1 : MOCK(channel_connect_for_circuit, mock_channel_connect_for_circuit);
1407 :
1408 : /* Test circuit not established, and successful launch of a channel */
1409 1 : mock_channel_get_for_extend_launch_out = 1;
1410 1 : mock_channel_get_for_extend_nchan = NULL;
1411 1 : mock_channel_connect_nchan = fake_n_chan;
1412 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
1413 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1414 1 : tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
1415 1 : tt_int_op(mock_channel_connect_calls, OP_EQ, 1);
1416 :
1417 : /* cleanup */
1418 1 : mock_clean_saved_logs();
1419 1 : mock_extend_cell_parse_calls = 0;
1420 1 : mock_channel_get_for_extend_calls = 0;
1421 1 : mock_channel_connect_calls = 0;
1422 : /* circ and or_circ are the same object */
1423 1 : tor_free(circ->n_hop);
1424 1 : tor_free(circ->n_chan_create_cell);
1425 :
1426 : /* Mock circuit_deliver_create_cell(), so it doesn't crash */
1427 1 : mock_circuit_deliver_create_cell_calls = 0;
1428 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1429 1 : MOCK(circuit_deliver_create_cell, mock_circuit_deliver_create_cell);
1430 :
1431 : /* Test circuit established, re-using channel, successful delivery */
1432 1 : mock_channel_get_for_extend_launch_out = 0;
1433 1 : mock_channel_get_for_extend_nchan = fake_n_chan;
1434 1 : mock_channel_connect_nchan = NULL;
1435 1 : mock_circuit_deliver_create_cell_result = 0;
1436 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, 0);
1437 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1438 1 : tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
1439 1 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1440 1 : tt_int_op(mock_circuit_deliver_create_cell_calls, OP_EQ, 1);
1441 1 : tt_ptr_op(circ->n_chan, OP_EQ, fake_n_chan);
1442 :
1443 : /* cleanup */
1444 1 : circ->n_chan = NULL;
1445 1 : mock_clean_saved_logs();
1446 1 : mock_extend_cell_parse_calls = 0;
1447 1 : mock_channel_get_for_extend_calls = 0;
1448 1 : mock_channel_connect_calls = 0;
1449 1 : mock_circuit_deliver_create_cell_calls = 0;
1450 : /* circ and or_circ are the same object */
1451 1 : tor_free(circ->n_hop);
1452 1 : tor_free(circ->n_chan_create_cell);
1453 :
1454 : /* Test circuit established, re-using channel, failed delivery */
1455 1 : mock_channel_get_for_extend_launch_out = 0;
1456 1 : mock_channel_get_for_extend_nchan = fake_n_chan;
1457 1 : mock_channel_connect_nchan = NULL;
1458 1 : mock_circuit_deliver_create_cell_result = -1;
1459 1 : tt_int_op(circuit_extend(cell, circ), OP_EQ, -1);
1460 1 : tt_int_op(mock_extend_cell_parse_calls, OP_EQ, 1);
1461 1 : tt_int_op(mock_channel_get_for_extend_calls, OP_EQ, 1);
1462 1 : tt_int_op(mock_channel_connect_calls, OP_EQ, 0);
1463 1 : tt_int_op(mock_circuit_deliver_create_cell_calls, OP_EQ, 1);
1464 1 : tt_ptr_op(circ->n_chan, OP_EQ, fake_n_chan);
1465 :
1466 : /* cleanup */
1467 1 : circ->n_chan = NULL;
1468 1 : mock_clean_saved_logs();
1469 1 : mock_extend_cell_parse_calls = 0;
1470 1 : mock_channel_get_for_extend_calls = 0;
1471 1 : mock_channel_connect_calls = 0;
1472 1 : mock_circuit_deliver_create_cell_calls = 0;
1473 : /* circ and or_circ are the same object */
1474 1 : tor_free(circ->n_hop);
1475 1 : tor_free(circ->n_chan_create_cell);
1476 :
1477 1 : done:
1478 1 : tor_end_capture_bugs_();
1479 1 : teardown_capture_of_logs();
1480 :
1481 1 : UNMOCK(server_mode);
1482 1 : server = 0;
1483 :
1484 1 : UNMOCK(channel_describe_peer);
1485 :
1486 1 : UNMOCK(extend_cell_parse);
1487 1 : memset(&mock_extend_cell_parse_cell_out, 0,
1488 : sizeof(mock_extend_cell_parse_cell_out));
1489 1 : mock_extend_cell_parse_result = 0;
1490 1 : mock_extend_cell_parse_calls = 0;
1491 :
1492 1 : UNMOCK(channel_get_for_extend);
1493 1 : mock_channel_get_for_extend_calls = 0;
1494 1 : mock_channel_get_for_extend_launch_out = 0;
1495 1 : mock_channel_get_for_extend_nchan = NULL;
1496 :
1497 1 : UNMOCK(channel_connect_for_circuit);
1498 1 : mock_channel_connect_calls = 0;
1499 1 : mock_channel_connect_nchan = NULL;
1500 :
1501 1 : UNMOCK(circuit_deliver_create_cell);
1502 1 : mock_circuit_deliver_create_cell_calls = 0;
1503 1 : mock_circuit_deliver_create_cell_result = 0;
1504 :
1505 1 : tor_free(cell);
1506 : /* circ and or_circ are the same object */
1507 1 : tor_free(circ->n_hop);
1508 1 : tor_free(circ->n_chan_create_cell);
1509 1 : tor_free(or_circ);
1510 1 : tor_free(p_chan);
1511 1 : tor_free(fake_n_chan);
1512 1 : }
1513 :
1514 : /* Test the different cases in onionskin_answer(). */
1515 : static void
1516 1 : test_onionskin_answer(void *arg)
1517 : {
1518 1 : (void)arg;
1519 1 : created_cell_t *created_cell = tor_malloc_zero(sizeof(created_cell_t));
1520 1 : or_circuit_t *or_circ = tor_malloc_zero(sizeof(or_circuit_t));
1521 1 : char keys[CPATH_KEY_MATERIAL_LEN] = {0};
1522 1 : uint8_t rend_circ_nonce[DIGEST_LEN] = {0};
1523 :
1524 1 : setup_full_capture_of_logs(LOG_INFO);
1525 :
1526 : #ifndef ALL_BUGS_ARE_FATAL
1527 : /* Circuit must be non-NULL */
1528 1 : tor_capture_bugs_(1);
1529 1 : tt_int_op(onionskin_answer(NULL, created_cell,
1530 : keys, CPATH_KEY_MATERIAL_LEN,
1531 : rend_circ_nonce), OP_EQ, -1);
1532 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1533 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1534 : "!(ASSERT_PREDICT_UNLIKELY_(!circ))");
1535 1 : tor_end_capture_bugs_();
1536 1 : mock_clean_saved_logs();
1537 :
1538 : /* Created cell must be non-NULL */
1539 1 : tor_capture_bugs_(1);
1540 1 : tt_int_op(onionskin_answer(or_circ, NULL,
1541 : keys, CPATH_KEY_MATERIAL_LEN,
1542 : rend_circ_nonce), OP_EQ, -1);
1543 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1544 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1545 : "!(ASSERT_PREDICT_UNLIKELY_(!created_cell))");
1546 1 : tor_end_capture_bugs_();
1547 1 : mock_clean_saved_logs();
1548 :
1549 : /* Keys must be non-NULL */
1550 1 : tor_capture_bugs_(1);
1551 1 : tt_int_op(onionskin_answer(or_circ, created_cell,
1552 : NULL, CPATH_KEY_MATERIAL_LEN,
1553 : rend_circ_nonce), OP_EQ, -1);
1554 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1555 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1556 : "!(ASSERT_PREDICT_UNLIKELY_(!keys))");
1557 1 : tor_end_capture_bugs_();
1558 1 : mock_clean_saved_logs();
1559 :
1560 : /* The rend circuit nonce must be non-NULL */
1561 1 : tor_capture_bugs_(1);
1562 1 : tt_int_op(onionskin_answer(or_circ, created_cell,
1563 : keys, CPATH_KEY_MATERIAL_LEN,
1564 : NULL), OP_EQ, -1);
1565 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1566 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1567 : "!(ASSERT_PREDICT_UNLIKELY_(!rend_circ_nonce))");
1568 1 : tor_end_capture_bugs_();
1569 1 : mock_clean_saved_logs();
1570 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
1571 :
1572 : /* Also, the keys length must be CPATH_KEY_MATERIAL_LEN, but we can't catch
1573 : * asserts in unit tests. */
1574 :
1575 : /* Fail when formatting the created cell */
1576 1 : tt_int_op(onionskin_answer(or_circ, created_cell,
1577 : keys, CPATH_KEY_MATERIAL_LEN,
1578 : rend_circ_nonce), OP_EQ, -1);
1579 1 : expect_log_msg("couldn't format created cell (type=0, len=0).\n");
1580 1 : mock_clean_saved_logs();
1581 :
1582 : /* TODO: test the rest of onionskin_answer(), see #33860 */
1583 : /* TODO: mock created_cell_format for the next test */
1584 :
1585 1 : done:
1586 1 : tor_end_capture_bugs_();
1587 1 : teardown_capture_of_logs();
1588 :
1589 1 : tor_free(created_cell);
1590 1 : tor_free(or_circ);
1591 1 : }
1592 :
1593 : /* Test the different cases in origin_circuit_init(). */
1594 : static void
1595 1 : test_origin_circuit_init(void *arg)
1596 : {
1597 1 : (void)arg;
1598 1 : origin_circuit_t *origin_circ = NULL;
1599 :
1600 : /* Init with 0 purpose and 0 flags */
1601 1 : origin_circ = origin_circuit_init(0, 0);
1602 1 : tt_int_op(origin_circ->base_.purpose, OP_EQ, 0);
1603 1 : tt_int_op(origin_circ->base_.state, OP_EQ, CIRCUIT_STATE_CHAN_WAIT);
1604 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1605 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
1606 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
1607 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
1608 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
1609 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
1610 : /* The circuits are automatically freed by the circuitlist. */
1611 :
1612 : /* Init with a purpose */
1613 1 : origin_circ = origin_circuit_init(CIRCUIT_PURPOSE_C_GENERAL, 0);
1614 1 : tt_int_op(origin_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_C_GENERAL);
1615 :
1616 : /* Init with each flag */
1617 1 : origin_circ = origin_circuit_init(0, CIRCLAUNCH_IS_INTERNAL);
1618 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1619 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 1);
1620 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
1621 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
1622 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
1623 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
1624 :
1625 1 : origin_circ = origin_circuit_init(0, CIRCLAUNCH_IS_IPV6_SELFTEST);
1626 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1627 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
1628 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 1);
1629 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
1630 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
1631 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
1632 :
1633 1 : origin_circ = origin_circuit_init(0, CIRCLAUNCH_NEED_CAPACITY);
1634 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1635 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
1636 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
1637 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 1);
1638 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
1639 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
1640 :
1641 1 : origin_circ = origin_circuit_init(0, CIRCLAUNCH_NEED_UPTIME);
1642 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1643 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
1644 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
1645 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
1646 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 1);
1647 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 0);
1648 :
1649 1 : origin_circ = origin_circuit_init(0, CIRCLAUNCH_ONEHOP_TUNNEL);
1650 1 : tt_ptr_op(origin_circ->build_state, OP_NE, NULL);
1651 1 : tt_int_op(origin_circ->build_state->is_internal, OP_EQ, 0);
1652 1 : tt_int_op(origin_circ->build_state->is_ipv6_selftest, OP_EQ, 0);
1653 1 : tt_int_op(origin_circ->build_state->need_capacity, OP_EQ, 0);
1654 1 : tt_int_op(origin_circ->build_state->need_uptime, OP_EQ, 0);
1655 1 : tt_int_op(origin_circ->build_state->onehop_tunnel, OP_EQ, 1);
1656 :
1657 1 : done:
1658 : /* The circuits are automatically freed by the circuitlist. */
1659 1 : ;
1660 1 : }
1661 :
1662 : /* Test the different cases in circuit_send_next_onion_skin(). */
1663 : static void
1664 1 : test_circuit_send_next_onion_skin(void *arg)
1665 : {
1666 1 : (void)arg;
1667 1 : origin_circuit_t *origin_circ = NULL;
1668 1 : struct timeval circ_start_time;
1669 1 : memset(&circ_start_time, 0, sizeof(circ_start_time));
1670 :
1671 1 : extend_info_t fakehop;
1672 1 : memset(&fakehop, 0, sizeof(fakehop));
1673 1 : extend_info_t *single_fakehop = &fakehop;
1674 1 : extend_info_t *multi_fakehop[DEFAULT_ROUTE_LEN] = {&fakehop,
1675 : &fakehop,
1676 : &fakehop};
1677 :
1678 1 : extend_info_t ipv6_hop;
1679 1 : memset(&ipv6_hop, 0, sizeof(ipv6_hop));
1680 1 : tor_addr_parse(&ipv6_hop.orports[0].addr, "1::2");
1681 1 : extend_info_t *multi_ipv6_hop[DEFAULT_ROUTE_LEN] = {&ipv6_hop,
1682 : &ipv6_hop,
1683 : &ipv6_hop};
1684 :
1685 1 : extend_info_t ipv4_hop;
1686 1 : memset(&ipv4_hop, 0, sizeof(ipv4_hop));
1687 1 : tor_addr_from_ipv4h(&ipv4_hop.orports[0].addr, 0x20304050);
1688 1 : extend_info_t *multi_ipv4_hop[DEFAULT_ROUTE_LEN] = {&ipv4_hop,
1689 : &ipv4_hop,
1690 : &ipv4_hop};
1691 :
1692 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1693 1 : MOCK(circuit_deliver_create_cell, mock_circuit_deliver_create_cell);
1694 1 : server = 0;
1695 1 : MOCK(server_mode, mock_server_mode);
1696 :
1697 : /* Try a direct connection, and succeed on a client */
1698 1 : server = 0;
1699 1 : origin_circ = new_test_origin_circuit(false,
1700 : circ_start_time,
1701 : 1,
1702 : &single_fakehop);
1703 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1704 : /* Skip some of the multi-hop checks */
1705 1 : origin_circ->build_state->onehop_tunnel = 1;
1706 : /* This is a direct connection */
1707 1 : mock_circuit_deliver_create_cell_expect_direct = true;
1708 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, 0);
1709 : /* The circuits are automatically freed by the circuitlist. */
1710 :
1711 : /* Try a direct connection, and succeed on a server */
1712 1 : server = 1;
1713 1 : origin_circ = new_test_origin_circuit(false,
1714 : circ_start_time,
1715 : 1,
1716 : &single_fakehop);
1717 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1718 1 : origin_circ->build_state->onehop_tunnel = 1;
1719 1 : mock_circuit_deliver_create_cell_expect_direct = true;
1720 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ, 0);
1721 :
1722 : /* Start capturing bugs */
1723 1 : setup_full_capture_of_logs(LOG_WARN);
1724 1 : tor_capture_bugs_(1);
1725 :
1726 : /* Try an extend, but fail the client valid address family check */
1727 1 : server = 0;
1728 1 : origin_circ = new_test_origin_circuit(true,
1729 : circ_start_time,
1730 : ARRAY_LENGTH(multi_fakehop),
1731 : multi_fakehop);
1732 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1733 : /* Fix the state */
1734 1 : origin_circ->base_.state = 0;
1735 : /* This is an indirect connection */
1736 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1737 : /* Fail because the address family is invalid */
1738 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1739 : -END_CIRC_REASON_INTERNAL);
1740 1 : expect_log_msg("No supported address family found in extend_info.\n");
1741 1 : mock_clean_saved_logs();
1742 :
1743 : /* Try an extend, but fail the server valid address check */
1744 1 : server = 1;
1745 1 : origin_circ = new_test_origin_circuit(true,
1746 : circ_start_time,
1747 : ARRAY_LENGTH(multi_fakehop),
1748 : multi_fakehop);
1749 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1750 1 : origin_circ->base_.state = 0;
1751 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1752 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1753 : -END_CIRC_REASON_INTERNAL);
1754 1 : expect_log_msg("No supported address family found in extend_info.\n");
1755 1 : mock_clean_saved_logs();
1756 :
1757 : /* Try an extend, but fail in the client code, with an IPv6 address */
1758 1 : server = 0;
1759 1 : origin_circ = new_test_origin_circuit(true,
1760 : circ_start_time,
1761 : ARRAY_LENGTH(multi_ipv6_hop),
1762 : multi_ipv6_hop);
1763 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1764 1 : origin_circ->base_.state = 0;
1765 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1766 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1767 : -END_CIRC_REASON_INTERNAL);
1768 1 : expect_log_msg("No supported address family found in extend_info.\n");
1769 1 : mock_clean_saved_logs();
1770 :
1771 : /* Stop capturing bugs, but keep capturing logs */
1772 1 : tor_end_capture_bugs_();
1773 :
1774 : /* Try an extend, pass the client IPv4 check, but fail later */
1775 1 : server = 0;
1776 1 : origin_circ = new_test_origin_circuit(true,
1777 : circ_start_time,
1778 : ARRAY_LENGTH(multi_ipv4_hop),
1779 : multi_ipv4_hop);
1780 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1781 1 : origin_circ->base_.state = 0;
1782 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1783 : /* Fail because the circuit data is invalid */
1784 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1785 : -END_CIRC_REASON_INTERNAL);
1786 1 : expect_log_msg("onion_skin_create failed.\n");
1787 1 : mock_clean_saved_logs();
1788 :
1789 : /* Try an extend, pass the server IPv4 check, but fail later */
1790 1 : server = 1;
1791 1 : origin_circ = new_test_origin_circuit(true,
1792 : circ_start_time,
1793 : ARRAY_LENGTH(multi_ipv4_hop),
1794 : multi_ipv4_hop);
1795 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1796 1 : origin_circ->base_.state = 0;
1797 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1798 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1799 : -END_CIRC_REASON_INTERNAL);
1800 1 : expect_log_msg("onion_skin_create failed.\n");
1801 1 : mock_clean_saved_logs();
1802 :
1803 : /* Try an extend, pass the server IPv6 check, but fail later */
1804 1 : server = 1;
1805 1 : origin_circ = new_test_origin_circuit(true,
1806 : circ_start_time,
1807 : ARRAY_LENGTH(multi_ipv6_hop),
1808 : multi_ipv6_hop);
1809 1 : tt_ptr_op(origin_circ, OP_NE, NULL);
1810 1 : origin_circ->base_.state = 0;
1811 1 : mock_circuit_deliver_create_cell_expect_direct = false;
1812 1 : tt_int_op(circuit_send_next_onion_skin(origin_circ), OP_EQ,
1813 : -END_CIRC_REASON_INTERNAL);
1814 1 : expect_log_msg("onion_skin_create failed.\n");
1815 1 : mock_clean_saved_logs();
1816 :
1817 : /* Things we're not testing right now:
1818 : * - the addresses in the extend cell inside
1819 : * circuit_send_intermediate_onion_skin() matches the address in the
1820 : * supplied extend_info.
1821 : * - valid circuit data.
1822 : * - actually extending the circuit to each hop. */
1823 :
1824 1 : done:
1825 1 : tor_end_capture_bugs_();
1826 1 : mock_clean_saved_logs();
1827 1 : teardown_capture_of_logs();
1828 :
1829 1 : UNMOCK(circuit_deliver_create_cell);
1830 1 : UNMOCK(server_mode);
1831 1 : server = 0;
1832 :
1833 : /* The circuits are automatically freed by the circuitlist. */
1834 1 : }
1835 :
1836 : /* Test the different cases in cpath_build_state_to_crn_flags(). */
1837 : static void
1838 1 : test_cpath_build_state_to_crn_flags(void *arg)
1839 : {
1840 1 : (void)arg;
1841 :
1842 1 : cpath_build_state_t state;
1843 1 : memset(&state, 0, sizeof(state));
1844 :
1845 1 : tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
1846 : 0);
1847 :
1848 1 : memset(&state, 0, sizeof(state));
1849 1 : state.need_uptime = 1;
1850 1 : tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
1851 : CRN_NEED_UPTIME);
1852 :
1853 1 : memset(&state, 0, sizeof(state));
1854 1 : state.need_capacity = 1;
1855 1 : tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
1856 : CRN_NEED_CAPACITY);
1857 :
1858 1 : memset(&state, 0, sizeof(state));
1859 1 : state.need_capacity = 1;
1860 1 : state.need_uptime = 1;
1861 1 : tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
1862 : CRN_NEED_CAPACITY | CRN_NEED_UPTIME);
1863 :
1864 : /* Check that no other flags are handled */
1865 1 : memset(&state, 0xff, sizeof(state));
1866 1 : tt_int_op(cpath_build_state_to_crn_flags(&state), OP_EQ,
1867 : CRN_NEED_CAPACITY | CRN_NEED_UPTIME);
1868 :
1869 1 : done:
1870 1 : ;
1871 1 : }
1872 :
1873 : /* Test the different cases in cpath_build_state_to_crn_ipv6_extend_flag(). */
1874 : static void
1875 1 : test_cpath_build_state_to_crn_ipv6_extend_flag(void *arg)
1876 : {
1877 1 : (void)arg;
1878 :
1879 1 : cpath_build_state_t state;
1880 :
1881 1 : memset(&state, 0, sizeof(state));
1882 1 : state.desired_path_len = DEFAULT_ROUTE_LEN;
1883 1 : tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, 0), OP_EQ,
1884 : 0);
1885 :
1886 : /* Pass the state flag check, but not the length check */
1887 1 : memset(&state, 0, sizeof(state));
1888 1 : state.desired_path_len = DEFAULT_ROUTE_LEN;
1889 1 : state.is_ipv6_selftest = 1;
1890 1 : tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, 0), OP_EQ,
1891 : 0);
1892 :
1893 : /* Pass the length check, but not the state flag check */
1894 1 : memset(&state, 0, sizeof(state));
1895 1 : state.desired_path_len = DEFAULT_ROUTE_LEN;
1896 1 : tt_int_op(
1897 : cpath_build_state_to_crn_ipv6_extend_flag(&state,
1898 : DEFAULT_ROUTE_LEN - 2),
1899 : OP_EQ, 0);
1900 :
1901 : /* Pass both checks */
1902 1 : memset(&state, 0, sizeof(state));
1903 1 : state.desired_path_len = DEFAULT_ROUTE_LEN;
1904 1 : state.is_ipv6_selftest = 1;
1905 1 : tt_int_op(
1906 : cpath_build_state_to_crn_ipv6_extend_flag(&state,
1907 : DEFAULT_ROUTE_LEN - 2),
1908 : OP_EQ, CRN_INITIATE_IPV6_EXTEND);
1909 :
1910 : /* Check that no other flags are handled */
1911 1 : memset(&state, 0xff, sizeof(state));
1912 1 : state.desired_path_len = INT_MAX;
1913 1 : tt_int_op(cpath_build_state_to_crn_ipv6_extend_flag(&state, INT_MAX), OP_EQ,
1914 : 0);
1915 :
1916 : #ifndef ALL_BUGS_ARE_FATAL
1917 : /* Start capturing bugs */
1918 1 : setup_full_capture_of_logs(LOG_INFO);
1919 1 : tor_capture_bugs_(1);
1920 :
1921 : /* Now test the single hop circuit case */
1922 : #define SINGLE_HOP_ROUTE_LEN 1
1923 1 : memset(&state, 0, sizeof(state));
1924 1 : state.desired_path_len = SINGLE_HOP_ROUTE_LEN;
1925 1 : state.is_ipv6_selftest = 1;
1926 1 : tt_int_op(
1927 : cpath_build_state_to_crn_ipv6_extend_flag(&state,
1928 : SINGLE_HOP_ROUTE_LEN - 2),
1929 : OP_EQ, 0);
1930 1 : tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
1931 1 : tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
1932 : "!(ASSERT_PREDICT_UNLIKELY_(state->desired_path_len < 2))");
1933 1 : mock_clean_saved_logs();
1934 : #endif /* !defined(ALL_BUGS_ARE_FATAL) */
1935 :
1936 1 : done:
1937 1 : tor_end_capture_bugs_();
1938 1 : mock_clean_saved_logs();
1939 1 : teardown_capture_of_logs();
1940 1 : }
1941 :
1942 : #define TEST(name, flags, setup, cleanup) \
1943 : { #name, test_ ## name, flags, setup, cleanup }
1944 :
1945 : #define TEST_NEW_ROUTE_LEN(name, flags) \
1946 : { #name, test_new_route_len_ ## name, flags, NULL, NULL }
1947 :
1948 : #define TEST_CIRCUIT(name, flags) \
1949 : { #name, test_circuit_ ## name, flags, NULL, NULL }
1950 :
1951 : #define TEST_CPATH(name, flags) \
1952 : { #name, test_cpath_ ## name, flags, NULL, NULL }
1953 :
1954 : #ifndef COCCI
1955 : #define TEST_CIRCUIT_PASSTHROUGH(name, flags, arg) \
1956 : { #name "/" arg, test_circuit_ ## name, flags, \
1957 : &passthrough_setup, (void *)(arg) }
1958 : #endif
1959 :
1960 : struct testcase_t circuitbuild_tests[] = {
1961 : TEST_NEW_ROUTE_LEN(noexit, 0),
1962 : TEST_NEW_ROUTE_LEN(safe_exit, 0),
1963 : TEST_NEW_ROUTE_LEN(unsafe_exit, 0),
1964 : TEST_NEW_ROUTE_LEN(unhandled_exit, 0),
1965 :
1966 : TEST(upgrade_from_guard_wait, TT_FORK, &helper_pubsub_setup, NULL),
1967 :
1968 : TEST_CIRCUIT(extend_state_valid, TT_FORK),
1969 : TEST_CIRCUIT(extend_add_ed25519, TT_FORK),
1970 : TEST_CIRCUIT(extend_lspec_valid, TT_FORK),
1971 : TEST_CIRCUIT(extend_add_ip, TT_FORK),
1972 : TEST_CIRCUIT(choose_ip_ap_for_extend, 0),
1973 :
1974 : TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "4"),
1975 : TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "6"),
1976 : TEST_CIRCUIT_PASSTHROUGH(open_connection_for_extend, TT_FORK, "dual-stack"),
1977 :
1978 : TEST_CIRCUIT(extend, TT_FORK),
1979 :
1980 : TEST(onionskin_answer, TT_FORK, NULL, NULL),
1981 :
1982 : TEST(origin_circuit_init, TT_FORK, NULL, NULL),
1983 : TEST_CIRCUIT(send_next_onion_skin, TT_FORK),
1984 : TEST_CPATH(build_state_to_crn_flags, 0),
1985 : TEST_CPATH(build_state_to_crn_ipv6_extend_flag, TT_FORK),
1986 :
1987 : END_OF_TESTCASES
1988 : };
|