1 /* Copyright (c) 2016-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 #define PROTOVER_PRIVATE
5 #define DIRVOTE_PRIVATE
10 #include "lib/tls/tortls.h"
12 #include "core/or/or.h"
14 #include "core/or/connection_or.h"
15 #include "core/or/protover.h"
16 #include "core/or/versions.h"
18 #include "feature/dirauth/dirvote.h"
20 #include "feature/relay/relay_handshake.h"
23 test_protover_parse(void *arg
)
27 /** This test is disabled on rust builds, because it only exists to test
28 * internal C functions. */
32 #else /* !defined(HAVE_RUST) */
33 char *re_encoded
= NULL
;
35 const char *orig
= "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900";
36 smartlist_t
*elts
= parse_protocol_list(orig
);
39 tt_int_op(smartlist_len(elts
), OP_EQ
, 4);
41 const proto_entry_t
*e
;
42 const proto_range_t
*r
;
43 e
= smartlist_get(elts
, 0);
44 tt_str_op(e
->name
, OP_EQ
, "Foo");
45 tt_int_op(smartlist_len(e
->ranges
), OP_EQ
, 2);
47 r
= smartlist_get(e
->ranges
, 0);
48 tt_int_op(r
->low
, OP_EQ
, 1);
49 tt_int_op(r
->high
, OP_EQ
, 1);
51 r
= smartlist_get(e
->ranges
, 1);
52 tt_int_op(r
->low
, OP_EQ
, 3);
53 tt_int_op(r
->high
, OP_EQ
, 3);
56 e
= smartlist_get(elts
, 1);
57 tt_str_op(e
->name
, OP_EQ
, "Bar");
58 tt_int_op(smartlist_len(e
->ranges
), OP_EQ
, 1);
60 r
= smartlist_get(e
->ranges
, 0);
61 tt_int_op(r
->low
, OP_EQ
, 3);
62 tt_int_op(r
->high
, OP_EQ
, 3);
65 e
= smartlist_get(elts
, 2);
66 tt_str_op(e
->name
, OP_EQ
, "Baz");
67 tt_int_op(smartlist_len(e
->ranges
), OP_EQ
, 0);
69 e
= smartlist_get(elts
, 3);
70 tt_str_op(e
->name
, OP_EQ
, "Quux");
71 tt_int_op(smartlist_len(e
->ranges
), OP_EQ
, 4);
73 r
= smartlist_get(e
->ranges
, 0);
74 tt_int_op(r
->low
, OP_EQ
, 9);
75 tt_int_op(r
->high
, OP_EQ
, 12);
77 r
= smartlist_get(e
->ranges
, 1);
78 tt_int_op(r
->low
, OP_EQ
, 14);
79 tt_int_op(r
->high
, OP_EQ
, 14);
81 r
= smartlist_get(e
->ranges
, 2);
82 tt_int_op(r
->low
, OP_EQ
, 15);
83 tt_int_op(r
->high
, OP_EQ
, 16);
85 r
= smartlist_get(e
->ranges
, 3);
86 tt_int_op(r
->low
, OP_EQ
, 900);
87 tt_int_op(r
->high
, OP_EQ
, 900);
90 re_encoded
= encode_protocol_list(elts
);
91 tt_assert(re_encoded
);
92 tt_str_op(re_encoded
, OP_EQ
, orig
);
96 SMARTLIST_FOREACH(elts
, proto_entry_t
*, ent
, proto_entry_free(ent
));
99 #endif /* defined(HAVE_RUST) */
103 test_protover_parse_fail(void *arg
)
107 /** This test is disabled on rust builds, because it only exists to test
108 * internal C functions. */
114 elts
= parse_protocol_list("!!3@*");
115 tt_ptr_op(elts
, OP_EQ
, NULL
);
117 /* Missing equals sign in an entry */
118 elts
= parse_protocol_list("Link=4 Haprauxymatyve Desc=9");
119 tt_ptr_op(elts
, OP_EQ
, NULL
);
122 elts
= parse_protocol_list("Link=4 =3 Desc=9");
123 tt_ptr_op(elts
, OP_EQ
, NULL
);
126 elts
= parse_protocol_list("Link=fred");
127 tt_ptr_op(elts
, OP_EQ
, NULL
);
128 elts
= parse_protocol_list("Link=1,fred");
129 tt_ptr_op(elts
, OP_EQ
, NULL
);
130 elts
= parse_protocol_list("Link=1,fred,3");
131 tt_ptr_op(elts
, OP_EQ
, NULL
);
134 elts
= parse_protocol_list("Link=1,9-8,3");
135 tt_ptr_op(elts
, OP_EQ
, NULL
);
137 /* Protocol name too long */
138 elts
= parse_protocol_list("DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
139 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
140 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
141 tt_ptr_op(elts
, OP_EQ
, NULL
);
143 #endif /* defined(HAVE_RUST) */
149 test_protover_vote(void *arg
)
153 smartlist_t
*lst
= smartlist_new();
154 char *result
= protover_compute_vote(lst
, 1);
156 tt_str_op(result
, OP_EQ
, "");
159 smartlist_add(lst
, (void*) "Foo=1-10,500 Bar=1,3-7,8");
160 result
= protover_compute_vote(lst
, 1);
161 tt_str_op(result
, OP_EQ
, "Bar=1,3-8 Foo=1-10,500");
164 smartlist_add(lst
, (void*) "Quux=123-456,78 Bar=2-6,8 Foo=9");
165 result
= protover_compute_vote(lst
, 1);
166 tt_str_op(result
, OP_EQ
, "Bar=1-8 Foo=1-10,500 Quux=78,123-456");
169 result
= protover_compute_vote(lst
, 2);
170 tt_str_op(result
, OP_EQ
, "Bar=3-6,8 Foo=9");
174 result
= protover_compute_vote(lst
, 3);
175 tt_str_op(result
, OP_EQ
, "");
178 /* Don't count double-voting. */
179 smartlist_clear(lst
);
180 smartlist_add(lst
, (void*) "Foo=1 Foo=1");
181 smartlist_add(lst
, (void*) "Bar=1-2,2-3");
182 result
= protover_compute_vote(lst
, 2);
183 tt_str_op(result
, OP_EQ
, "");
186 /* Bad votes: the result must be empty */
187 smartlist_clear(lst
);
188 smartlist_add(lst
, (void*) "Faux=10-5");
189 result
= protover_compute_vote(lst
, 1);
190 tt_str_op(result
, OP_EQ
, "");
193 /* This fails, since "-0" is not valid. */
194 smartlist_clear(lst
);
195 smartlist_add(lst
, (void*) "Faux=-0");
196 result
= protover_compute_vote(lst
, 1);
197 tt_str_op(result
, OP_EQ
, "");
200 /* Vote large protover lists that are just below the threshold */
202 /* Just below the threshold: Rust */
203 smartlist_clear(lst
);
204 smartlist_add(lst
, (void*) "Sleen=1-500");
205 result
= protover_compute_vote(lst
, 1);
206 tt_str_op(result
, OP_EQ
, "Sleen=1-500");
209 /* Just below the threshold: C */
210 smartlist_clear(lst
);
211 smartlist_add(lst
, (void*) "Sleen=1-65536");
212 result
= protover_compute_vote(lst
, 1);
213 tt_str_op(result
, OP_EQ
, "Sleen=1-65536");
216 /* Large protover lists that exceed the threshold */
218 /* By adding two votes, C allows us to exceed the limit */
219 smartlist_add(lst
, (void*) "Sleen=1-65536");
220 smartlist_add(lst
, (void*) "Sleen=100000");
221 result
= protover_compute_vote(lst
, 1);
222 tt_str_op(result
, OP_EQ
, "Sleen=1-65536,100000");
226 smartlist_clear(lst
);
227 smartlist_add(lst
, (void*) "Sleen=4294967294");
228 result
= protover_compute_vote(lst
, 1);
229 tt_str_op(result
, OP_EQ
, "Sleen=4294967294");
232 /* This parses, but fails at the vote stage */
233 smartlist_clear(lst
);
234 smartlist_add(lst
, (void*) "Sleen=4294967295");
235 result
= protover_compute_vote(lst
, 1);
236 tt_str_op(result
, OP_EQ
, "");
239 smartlist_clear(lst
);
240 smartlist_add(lst
, (void*) "Sleen=4294967296");
241 result
= protover_compute_vote(lst
, 1);
242 tt_str_op(result
, OP_EQ
, "");
245 /* Protocol name too long */
246 smartlist_clear(lst
);
247 smartlist_add(lst
, (void*) "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
248 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
249 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
250 result
= protover_compute_vote(lst
, 1);
251 tt_str_op(result
, OP_EQ
, "");
260 test_protover_all_supported(void *arg
)
265 tt_assert(protover_all_supported(NULL
, &msg
));
266 tt_ptr_op(msg
, OP_EQ
, NULL
);
268 tt_assert(protover_all_supported("", &msg
));
269 tt_ptr_op(msg
, OP_EQ
, NULL
);
271 // Some things that we do support
272 tt_assert(protover_all_supported("Link=3-4", &msg
));
273 tt_ptr_op(msg
, OP_EQ
, NULL
);
274 tt_assert(protover_all_supported("Link=3-4 Desc=2", &msg
));
275 tt_ptr_op(msg
, OP_EQ
, NULL
);
277 // Some things we don't support
278 tt_assert(! protover_all_supported("Wombat=9", NULL
));
279 tt_assert(! protover_all_supported("Wombat=9", &msg
));
280 tt_str_op(msg
, OP_EQ
, "Wombat=9");
282 tt_assert(! protover_all_supported("Link=999", &msg
));
283 tt_str_op(msg
, OP_EQ
, "Link=999");
286 // Mix of things we support and things we don't
287 tt_assert(! protover_all_supported("Link=3-4 Wombat=9", &msg
));
288 tt_str_op(msg
, OP_EQ
, "Wombat=9");
291 /* Mix of things we support and don't support within a single protocol
292 * which we do support */
293 tt_assert(! protover_all_supported("Link=3-999", &msg
));
294 tt_str_op(msg
, OP_EQ
, "Link=6-999");
296 tt_assert(! protover_all_supported("Link=1-3,345-666", &msg
));
297 tt_str_op(msg
, OP_EQ
, "Link=345-666");
299 tt_assert(! protover_all_supported("Link=1-3,5-12", &msg
));
300 tt_str_op(msg
, OP_EQ
, "Link=6-12");
303 /* Mix of protocols we do support and some we don't, where the protocols
304 * we do support have some versions we don't support. */
305 tt_assert(! protover_all_supported("Link=1-3,5-12 Quokka=9000-9001", &msg
));
306 tt_str_op(msg
, OP_EQ
, "Link=6-12 Quokka=9000-9001");
309 /* We shouldn't be able to DoS ourselves parsing a large range. */
310 tt_assert(! protover_all_supported("Sleen=1-2147483648", &msg
));
311 tt_str_op(msg
, OP_EQ
, "Sleen=1-2147483648");
314 /* This case is allowed. */
315 tt_assert(! protover_all_supported("Sleen=1-4294967294", &msg
));
316 tt_str_op(msg
, OP_EQ
, "Sleen=1-4294967294");
319 /* If we get a (barely) valid (but unsupported list, we say "yes, that's
321 tt_assert(protover_all_supported("Fribble=", &msg
));
322 tt_ptr_op(msg
, OP_EQ
, NULL
);
324 #ifndef ALL_BUGS_ARE_FATAL
325 /* If we get a completely unparseable list, protover_all_supported should
326 * hit a fatal assertion for BUG(entries == NULL). */
327 tor_capture_bugs_(1);
328 tt_assert(protover_all_supported("Fribble", &msg
));
329 tor_end_capture_bugs_();
331 /* If we get a completely unparseable list, protover_all_supported should
332 * hit a fatal assertion for BUG(entries == NULL). */
333 tor_capture_bugs_(1);
334 tt_assert(protover_all_supported("Sleen=1-4294967295", &msg
));
335 tor_end_capture_bugs_();
336 #endif /* !defined(ALL_BUGS_ARE_FATAL) */
338 /* Protocol name too long */
339 #if !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL)
340 tor_capture_bugs_(1);
341 tt_assert(protover_all_supported(
342 "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
343 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
344 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
345 "aaaaaaaaaaaa=1-65536", &msg
));
346 tor_end_capture_bugs_();
347 #endif /* !defined(HAVE_RUST) && !defined(ALL_BUGS_ARE_FATAL) */
350 tor_end_capture_bugs_();
355 test_protover_list_supports_protocol_returns_true(void *arg
)
359 const char *protocols
= "Link=1";
360 int is_supported
= protocol_list_supports_protocol(protocols
, PRT_LINK
, 1);
361 tt_int_op(is_supported
, OP_EQ
, 1);
368 test_protover_list_supports_protocol_for_unsupported_returns_false(void *arg
)
372 const char *protocols
= "Link=1";
373 int is_supported
= protocol_list_supports_protocol(protocols
, PRT_LINK
, 10);
374 tt_int_op(is_supported
, OP_EQ
, 0);
381 test_protover_supports_version(void *arg
)
385 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK
, 3));
386 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK
, 6));
387 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINK
, 7));
388 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINKAUTH
, 3));
390 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
392 tt_assert(protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
394 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
396 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
398 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
400 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
403 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
409 /* This could be MAX_PROTOCOLS_TO_EXPAND, but that's not exposed by protover */
410 #define MAX_PROTOCOLS_TO_TEST 1024
412 /* LinkAuth and Relay protocol versions.
413 * Hard-coded here, because they are not in the code, or not exposed in the
415 #define PROTOVER_LINKAUTH_V1 1
416 #define PROTOVER_LINKAUTH_V2 2
417 #define PROTOVER_RELAY_V1 1
419 /* Deprecated HSIntro versions */
420 #define PROTOVER_HS_INTRO_DEPRECATED_1 1
421 #define PROTOVER_HS_INTRO_DEPRECATED_2 2
422 /* Highest supported HSv2 introduce protocol version.
423 * It's not clear if we actually support version 2, see #25068. */
424 #define PROTOVER_HS_INTRO_V2 3
426 /* HSv2 Rend and HSDir protocol versions. */
427 #define PROTOVER_HS_RENDEZVOUS_POINT_V2 1
428 #define PROTOVER_HSDIR_V2 1
430 /* DirCache, Desc, Microdesc, and Cons protocol versions. */
431 #define PROTOVER_DIRCACHE_V1 1
432 #define PROTOVER_DIRCACHE_V2 2
434 #define PROTOVER_DESC_V1 1
435 #define PROTOVER_DESC_V2 2
437 #define PROTOVER_MICRODESC_V1 1
438 #define PROTOVER_MICRODESC_V2 2
440 #define PROTOVER_CONS_V1 1
441 #define PROTOVER_CONS_V2 2
443 #define PROTOVER_PADDING_V1 1
445 #define PROTOVER_FLOWCTRL_V1 1
447 /* Make sure we haven't forgotten any supported protocols */
449 test_protover_supported_protocols(void *arg
)
453 const char *supported_protocols
= protover_get_supported_protocols();
455 /* Test for new Link in the code, that hasn't been added to supported
457 tt_assert(protocol_list_supports_protocol(supported_protocols
,
460 for (uint16_t i
= 0; i
< MAX_PROTOCOLS_TO_TEST
; i
++) {
461 tt_int_op(protocol_list_supports_protocol(supported_protocols
,
465 is_or_protocol_version_known(i
));
468 /* Legacy LinkAuth is only supported on OpenSSL and similar. */
469 tt_int_op(protocol_list_supports_protocol(supported_protocols
,
471 PROTOVER_LINKAUTH_V1
),
473 authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET
));
474 /* LinkAuth=2 is unused */
475 tt_assert(!protocol_list_supports_protocol(supported_protocols
,
477 PROTOVER_LINKAUTH_V2
));
479 protocol_list_supports_protocol(supported_protocols
,
481 PROTOVER_LINKAUTH_ED25519_HANDSHAKE
));
483 /* Relay protovers do not appear anywhere in the code. */
484 tt_assert(protocol_list_supports_protocol(supported_protocols
,
487 tt_assert(protocol_list_supports_protocol(supported_protocols
,
489 PROTOVER_RELAY_EXTEND2
));
490 tt_assert(protocol_list_supports_protocol(supported_protocols
,
492 PROTOVER_RELAY_ACCEPT_IPV6
));
493 tt_assert(protocol_list_supports_protocol(supported_protocols
,
495 PROTOVER_RELAY_EXTEND_IPV6
));
496 tt_assert(protocol_list_supports_protocol(supported_protocols
,
498 PROTOVER_RELAY_CANONICAL_IPV6
));
500 /* These HSIntro versions are deprecated */
501 tt_assert(!protocol_list_supports_protocol(supported_protocols
,
503 PROTOVER_HS_INTRO_DEPRECATED_1
));
504 tt_assert(!protocol_list_supports_protocol(supported_protocols
,
506 PROTOVER_HS_INTRO_DEPRECATED_2
));
507 /* We could test legacy HSIntro by calling rend_service_update_descriptor(),
508 * and checking the protocols field. But that's unlikely to change, so
509 * we just use a hard-coded value. */
510 tt_assert(protocol_list_supports_protocol(supported_protocols
,
512 PROTOVER_HS_INTRO_V2
));
513 /* Test for HSv3 HSIntro */
514 tt_assert(protocol_list_supports_protocol(supported_protocols
,
516 PROTOVER_HS_INTRO_V3
));
517 /* Test for HSIntro DoS */
518 tt_assert(protocol_list_supports_protocol(supported_protocols
,
520 PROTOVER_HS_INTRO_DOS
));
522 /* Legacy HSRend does not appear anywhere in the code. */
523 tt_assert(protocol_list_supports_protocol(supported_protocols
,
525 PROTOVER_HS_RENDEZVOUS_POINT_V2
));
526 /* Test for HSv3 HSRend */
527 tt_assert(protocol_list_supports_protocol(supported_protocols
,
529 PROTOVER_HS_RENDEZVOUS_POINT_V3
));
531 /* Legacy HSDir does not appear anywhere in the code. */
532 tt_assert(protocol_list_supports_protocol(supported_protocols
,
535 /* Test for HSv3 HSDir */
536 tt_assert(protocol_list_supports_protocol(supported_protocols
,
540 /* No DirCache versions appear anywhere in the code. */
541 tt_assert(protocol_list_supports_protocol(supported_protocols
,
543 PROTOVER_DIRCACHE_V1
));
544 tt_assert(protocol_list_supports_protocol(supported_protocols
,
546 PROTOVER_DIRCACHE_V2
));
548 /* No Desc versions appear anywhere in the code. */
549 tt_assert(protocol_list_supports_protocol(supported_protocols
,
552 tt_assert(protocol_list_supports_protocol(supported_protocols
,
555 /* Is there any way to test for new Desc? */
557 /* No Microdesc versions appear anywhere in the code. */
558 tt_assert(protocol_list_supports_protocol(supported_protocols
,
560 PROTOVER_MICRODESC_V1
));
561 tt_assert(protocol_list_supports_protocol(supported_protocols
,
563 PROTOVER_MICRODESC_V2
));
565 /* No Cons versions appear anywhere in the code. */
566 tt_assert(protocol_list_supports_protocol(supported_protocols
,
569 tt_assert(protocol_list_supports_protocol(supported_protocols
,
573 /* Padding=1 is deprecated. */
574 tt_assert(!protocol_list_supports_protocol(supported_protocols
,
576 PROTOVER_PADDING_V1
));
577 tt_assert(protocol_list_supports_protocol(supported_protocols
,
579 PROTOVER_HS_SETUP_PADDING
));
582 tt_assert(protocol_list_supports_protocol(supported_protocols
,
584 PROTOVER_FLOWCTRL_V1
));
591 test_protover_vote_roundtrip(void *args
)
594 static const struct {
596 const char *expected_output
;
598 { "Risqu\u00e9=1", NULL
},
601 { "Foo_Bar=1", NULL
},
602 { "Fkrkljdsf", NULL
},
603 { "Zn=4294967295", NULL
},
604 { "Zn=4294967295-1", NULL
},
605 { "Zn=4294967293-4294967295", NULL
},
606 /* Will fail because of 4294967295. */
607 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295",
609 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967294",
610 "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=1,4294967294" },
611 { "Zu16=1,65536", "Zu16=1,65536" },
612 { "N-1=1,2", "N-1=1-2" },
613 { "-1=4294967295", NULL
},
617 /* Missing equals sign */
618 { "Link=4 Haprauxymatyve Desc=9", NULL
},
619 { "Link=4 Haprauxymatyve=7 Desc=9",
620 "Desc=9 Haprauxymatyve=7 Link=4" },
622 { "X=10-11", "X=10-11" },
623 { "Link=4 =3 Desc=9", NULL
},
624 { "Link=4 Z=3 Desc=9", "Desc=9 Link=4 Z=3" },
625 { "Link=fred", NULL
},
626 { "Link=1,fred", NULL
},
627 { "Link=1,fred,3", NULL
},
628 { "Link=1,9-8,3", NULL
},
630 { "Faux=0--0", NULL
},
632 { "Faux=-1-3", NULL
},
633 { "Faux=1--1", NULL
},
634 { "Link=1-2-", NULL
},
635 { "Link=1-2-3", NULL
},
636 { "Faux=1-2-", NULL
},
637 { "Faux=1-2-3", NULL
},
638 { "Link=\t1,3", NULL
},
639 { "Link=1\n,3", NULL
},
640 { "Faux=1,\r3", NULL
},
641 { "Faux=1,3\f", NULL
},
643 { "Link=4294967296", NULL
},
645 { "Sleen=1-501", "Sleen=1-501" },
646 { "Sleen=1-65537", NULL
},
647 /* Both C/Rust implementations should be able to handle this mild DoS. */
648 { "Sleen=1-2147483648", NULL
},
649 /* Rust tests are built in debug mode, so ints are bounds-checked. */
650 { "Sleen=1-4294967295", NULL
},
653 smartlist_t
*votes
= smartlist_new();
656 for (u
= 0; u
< ARRAY_LENGTH(examples
); ++u
) {
657 const char *input
= examples
[u
].input
;
658 const char *expected_output
= examples
[u
].expected_output
;
660 smartlist_add(votes
, (void*)input
);
661 result
= protover_compute_vote(votes
, 1);
662 if (expected_output
!= NULL
) {
663 tt_str_op(result
, OP_EQ
, expected_output
);
665 tt_str_op(result
, OP_EQ
, "");
668 smartlist_clear(votes
);
673 smartlist_free(votes
);
678 test_protover_vote_roundtrip_ours(void *args
)
681 const char *examples
[] = {
682 protover_get_supported_protocols(),
683 DIRVOTE_RECOMMEND_RELAY_PROTO
,
684 DIRVOTE_RECOMMEND_CLIENT_PROTO
,
685 DIRVOTE_REQUIRE_RELAY_PROTO
,
686 DIRVOTE_REQUIRE_CLIENT_PROTO
,
689 smartlist_t
*votes
= smartlist_new();
692 for (u
= 0; u
< ARRAY_LENGTH(examples
); ++u
) {
693 tt_assert(examples
[u
]);
694 const char *input
= examples
[u
];
695 const char *expected_output
= examples
[u
];
697 smartlist_add(votes
, (void*)input
);
698 result
= protover_compute_vote(votes
, 1);
699 if (expected_output
!= NULL
) {
700 tt_str_op(result
, OP_EQ
, expected_output
);
702 tt_str_op(result
, OP_EQ
, "");
705 smartlist_clear(votes
);
710 smartlist_free(votes
);
714 /* Stringifies its argument.
719 #define PROTOVER(proto_string, version_macro)
721 /* Generate a protocol version string using proto_string and version_macro.
722 * PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS) -> "HSIntro" "=" "5"
723 * Uses two levels of macros to turn PROTOVER_HS_INTRO_DOS into "5".
725 #define PROTOVER(proto_string, version_macro) \
726 (proto_string "=" STR(version_macro))
729 #define DEBUG_PROTOVER(flags) \
731 log_debug(LD_GENERAL, \
733 "protocols_known: %d,\n" \
734 "supports_extend2_cells: %d,\n" \
735 "supports_accepting_ipv6_extends: %d,\n" \
736 "supports_initiating_ipv6_extends: %d,\n" \
737 "supports_canonical_ipv6_conns: %d,\n" \
738 "supports_ed25519_link_handshake_compat: %d,\n" \
739 "supports_ed25519_link_handshake_any: %d,\n" \
740 "supports_ed25519_hs_intro: %d,\n" \
741 "supports_establish_intro_dos_extension: %d,\n" \
742 "supports_v3_hsdir: %d,\n" \
743 "supports_v3_rendezvous_point: %d,\n" \
744 "supports_hs_setup_padding: %d.", \
745 (flags).protocols_known, \
746 (flags).supports_extend2_cells, \
747 (flags).supports_accepting_ipv6_extends, \
748 (flags).supports_initiating_ipv6_extends, \
749 (flags).supports_canonical_ipv6_conns, \
750 (flags).supports_ed25519_link_handshake_compat, \
751 (flags).supports_ed25519_link_handshake_any, \
752 (flags).supports_ed25519_hs_intro, \
753 (flags).supports_establish_intro_dos_extension, \
754 (flags).supports_v3_hsdir, \
755 (flags).supports_v3_rendezvous_point, \
756 (flags).supports_hs_setup_padding); \
759 /* Test that the proto_string version version_macro sets summary_flag. */
760 #define TEST_PROTOVER(proto_string, version_macro, summary_flag) \
762 memset(&flags, 0, sizeof(flags)); \
763 summarize_protover_flags(&flags, \
764 PROTOVER(proto_string, version_macro), \
766 DEBUG_PROTOVER(flags); \
767 tt_int_op(flags.protocols_known, OP_EQ, 1); \
768 tt_int_op(flags.summary_flag, OP_EQ, 1); \
769 flags.protocols_known = 0; \
770 flags.summary_flag = 0; \
771 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); \
775 test_protover_summarize_flags(void *args
)
779 memset(&pv
, 0, sizeof(pv
));
781 protover_summary_cache_free_all();
783 protover_summary_flags_t zero_flags
;
784 memset(&zero_flags
, 0, sizeof(zero_flags
));
785 protover_summary_flags_t flags
;
787 memset(&flags
, 0, sizeof(flags
));
788 summarize_protover_flags(&flags
, NULL
, NULL
);
789 DEBUG_PROTOVER(flags
);
790 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
792 memset(&flags
, 0, sizeof(flags
));
793 summarize_protover_flags(&flags
, "", "");
794 DEBUG_PROTOVER(flags
);
795 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
797 /* Now check version exceptions */
799 /* EXTEND2 cell support */
800 memset(&flags
, 0, sizeof(flags
));
801 summarize_protover_flags(&flags
, NULL
, "Tor 0.2.4.8-alpha");
802 DEBUG_PROTOVER(flags
);
803 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
804 tt_int_op(flags
.supports_extend2_cells
, OP_EQ
, 1);
805 /* Now clear those flags, and check the rest are zero */
806 flags
.protocols_known
= 0;
807 flags
.supports_extend2_cells
= 0;
808 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
810 /* disabling HSDir v3 support for buggy versions */
811 memset(&flags
, 0, sizeof(flags
));
812 summarize_protover_flags(&flags
,
813 PROTOVER("HSDir", PROTOVER_HSDIR_V3
),
815 DEBUG_PROTOVER(flags
);
816 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
817 tt_int_op(flags
.supports_v3_hsdir
, OP_EQ
, 1);
818 /* Now clear those flags, and check the rest are zero */
819 flags
.protocols_known
= 0;
820 flags
.supports_v3_hsdir
= 0;
821 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
823 memset(&flags
, 0, sizeof(flags
));
824 summarize_protover_flags(&flags
,
825 PROTOVER("HSDir", PROTOVER_HSDIR_V3
),
827 DEBUG_PROTOVER(flags
);
828 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
829 /* Now clear that flag, and check the rest are zero */
830 flags
.protocols_known
= 0;
831 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
833 /* Now check standard summaries */
836 memset(&flags
, 0, sizeof(flags
));
837 summarize_protover_flags(&flags
,
839 PROTOVER_LINKAUTH_ED25519_HANDSHAKE
),
841 DEBUG_PROTOVER(flags
);
842 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
843 tt_int_op(flags
.supports_ed25519_link_handshake_compat
, OP_EQ
, 1);
844 tt_int_op(flags
.supports_ed25519_link_handshake_any
, OP_EQ
, 1);
845 /* Now clear those flags, and check the rest are zero */
846 flags
.protocols_known
= 0;
847 flags
.supports_ed25519_link_handshake_compat
= 0;
848 flags
.supports_ed25519_link_handshake_any
= 0;
849 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
851 /* Test one greater */
852 memset(&flags
, 0, sizeof(flags
));
853 snprintf(pv
, sizeof(pv
),
854 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE
+ 1);
855 summarize_protover_flags(&flags
, pv
, NULL
);
856 DEBUG_PROTOVER(flags
);
857 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
858 tt_int_op(flags
.supports_ed25519_link_handshake_compat
, OP_EQ
, 0);
859 tt_int_op(flags
.supports_ed25519_link_handshake_any
, OP_EQ
, 1);
860 /* Now clear those flags, and check the rest are zero */
861 flags
.protocols_known
= 0;
862 flags
.supports_ed25519_link_handshake_compat
= 0;
863 flags
.supports_ed25519_link_handshake_any
= 0;
864 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
867 memset(&flags
, 0, sizeof(flags
));
868 snprintf(pv
, sizeof(pv
),
869 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE
- 1);
870 summarize_protover_flags(&flags
, pv
, NULL
);
871 DEBUG_PROTOVER(flags
);
872 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
873 tt_int_op(flags
.supports_ed25519_link_handshake_compat
, OP_EQ
, 0);
874 tt_int_op(flags
.supports_ed25519_link_handshake_any
, OP_EQ
, 0);
875 /* Now clear those flags, and check the rest are zero */
876 flags
.protocols_known
= 0;
877 flags
.supports_ed25519_link_handshake_compat
= 0;
878 flags
.supports_ed25519_link_handshake_any
= 0;
879 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
881 /* We don't test "one more" and "one less" for each protocol version.
882 * But that could be a useful thing to add. */
885 memset(&flags
, 0, sizeof(flags
));
886 /* This test relies on these versions being equal */
887 tt_int_op(PROTOVER_RELAY_EXTEND2
, OP_EQ
, PROTOVER_RELAY_ACCEPT_IPV6
);
888 summarize_protover_flags(&flags
,
889 PROTOVER("Relay", PROTOVER_RELAY_EXTEND2
), NULL
);
890 DEBUG_PROTOVER(flags
);
891 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
892 tt_int_op(flags
.supports_extend2_cells
, OP_EQ
, 1);
893 tt_int_op(flags
.supports_accepting_ipv6_extends
, OP_EQ
, 1);
894 /* Now clear those flags, and check the rest are zero */
895 flags
.protocols_known
= 0;
896 flags
.supports_extend2_cells
= 0;
897 flags
.supports_accepting_ipv6_extends
= 0;
898 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
900 memset(&flags
, 0, sizeof(flags
));
901 /* This test relies on these versions being equal */
902 tt_int_op(PROTOVER_RELAY_EXTEND_IPV6
, OP_EQ
, PROTOVER_RELAY_CANONICAL_IPV6
);
903 summarize_protover_flags(&flags
,
904 PROTOVER("Relay", PROTOVER_RELAY_EXTEND_IPV6
),
906 DEBUG_PROTOVER(flags
);
907 tt_int_op(flags
.protocols_known
, OP_EQ
, 1);
908 tt_int_op(flags
.supports_accepting_ipv6_extends
, OP_EQ
, 1);
909 tt_int_op(flags
.supports_initiating_ipv6_extends
, OP_EQ
, 1);
910 tt_int_op(flags
.supports_canonical_ipv6_conns
, OP_EQ
, 1);
911 /* Now clear those flags, and check the rest are zero */
912 flags
.protocols_known
= 0;
913 flags
.supports_accepting_ipv6_extends
= 0;
914 flags
.supports_initiating_ipv6_extends
= 0;
915 flags
.supports_canonical_ipv6_conns
= 0;
916 tt_mem_op(&flags
, OP_EQ
, &zero_flags
, sizeof(flags
));
918 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_V3
,
919 supports_ed25519_hs_intro
);
920 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS
,
921 supports_establish_intro_dos_extension
);
923 TEST_PROTOVER("HSRend", PROTOVER_HS_RENDEZVOUS_POINT_V3
,
924 supports_v3_rendezvous_point
);
926 TEST_PROTOVER("HSDir", PROTOVER_HSDIR_V3
,
929 TEST_PROTOVER("Padding", PROTOVER_HS_SETUP_PADDING
,
930 supports_hs_setup_padding
);
936 #define PV_TEST(name, flags) \
937 { #name, test_protover_ ##name, (flags), NULL, NULL }
939 struct testcase_t protover_tests
[] = {
941 PV_TEST(parse_fail
, 0),
943 PV_TEST(all_supported
, 0),
944 PV_TEST(list_supports_protocol_for_unsupported_returns_false
, 0),
945 PV_TEST(list_supports_protocol_returns_true
, 0),
946 PV_TEST(supports_version
, 0),
947 PV_TEST(supported_protocols
, 0),
948 PV_TEST(vote_roundtrip
, 0),
949 PV_TEST(vote_roundtrip_ours
, 0),
950 /* fork, because we memoize flags internally */
951 PV_TEST(summarize_flags
, TT_FORK
),