test_protover.c (29884B)
1 /* Copyright (c) 2016-2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 #define PROTOVER_PRIVATE 5 #define DIRVOTE_PRIVATE 6 7 #include "orconfig.h" 8 #include "test/test.h" 9 10 #include "lib/tls/tortls.h" 11 12 #include "core/or/or.h" 13 14 #include "core/or/connection_or.h" 15 #include "core/or/protover.h" 16 #include "core/or/versions.h" 17 18 #include "feature/dirauth/dirvote.h" 19 20 #include "feature/relay/relay_handshake.h" 21 22 static void 23 test_protover_parse(void *arg) 24 { 25 (void) arg; 26 char *re_encoded = NULL; 27 28 const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16"; 29 smartlist_t *elts = parse_protocol_list(orig); 30 31 tt_assert(elts); 32 tt_int_op(smartlist_len(elts), OP_EQ, 4); 33 34 const proto_entry_t *e; 35 e = smartlist_get(elts, 0); 36 tt_str_op(e->name, OP_EQ, "Foo"); 37 tt_int_op(e->bitmask, OP_EQ, 0x0a); 38 39 e = smartlist_get(elts, 1); 40 tt_str_op(e->name, OP_EQ, "Bar"); 41 tt_int_op(e->bitmask, OP_EQ, 0x08); 42 43 e = smartlist_get(elts, 2); 44 tt_str_op(e->name, OP_EQ, "Baz"); 45 tt_int_op(e->bitmask, OP_EQ, 0x00); 46 47 e = smartlist_get(elts, 3); 48 tt_str_op(e->name, OP_EQ, "Quux"); 49 tt_int_op(e->bitmask, OP_EQ, 0x1de00); 50 51 re_encoded = encode_protocol_list(elts); 52 tt_assert(re_encoded); 53 tt_str_op(re_encoded, OP_EQ, "Foo=1,3 Bar=3 Baz= Quux=9-12,14-16"); 54 55 done: 56 if (elts) 57 SMARTLIST_FOREACH(elts, proto_entry_t *, ent, proto_entry_free(ent)); 58 smartlist_free(elts); 59 tor_free(re_encoded); 60 } 61 62 static void 63 test_protover_parse_fail(void *arg) 64 { 65 (void)arg; 66 smartlist_t *elts; 67 68 /* random junk */ 69 elts = parse_protocol_list("!!3@*"); 70 tt_ptr_op(elts, OP_EQ, NULL); 71 72 /* Missing equals sign in an entry */ 73 elts = parse_protocol_list("Link=4 Haprauxymatyve Desc=9"); 74 tt_ptr_op(elts, OP_EQ, NULL); 75 76 /* Missing word. */ 77 elts = parse_protocol_list("Link=4 =3 Desc=9"); 78 tt_ptr_op(elts, OP_EQ, NULL); 79 80 /* Broken numbers */ 81 elts = parse_protocol_list("Link=fred"); 82 tt_ptr_op(elts, OP_EQ, NULL); 83 elts = parse_protocol_list("Link=1,fred"); 84 tt_ptr_op(elts, OP_EQ, NULL); 85 elts = parse_protocol_list("Link=1,fred,3"); 86 tt_ptr_op(elts, OP_EQ, NULL); 87 88 /* Broken range */ 89 elts = parse_protocol_list("Link=1,9-8,3"); 90 tt_ptr_op(elts, OP_EQ, NULL); 91 92 /* Protocol name too long */ 93 elts = parse_protocol_list("DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 94 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 95 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 96 tt_ptr_op(elts, OP_EQ, NULL); 97 98 done: 99 ; 100 } 101 102 static void 103 test_protover_vote(void *arg) 104 { 105 (void) arg; 106 107 smartlist_t *lst = smartlist_new(); 108 char *result = protover_compute_vote(lst, 1); 109 110 tt_str_op(result, OP_EQ, ""); 111 tor_free(result); 112 113 smartlist_add(lst, (void*) "Foo=1-10,63 Bar=1,3-7,8"); 114 result = protover_compute_vote(lst, 1); 115 tt_str_op(result, OP_EQ, "Bar=1,3-8 Foo=1-10,63"); 116 tor_free(result); 117 118 smartlist_add(lst, (void*) "Quux=12-45 Bar=2-6,8 Foo=9"); 119 result = protover_compute_vote(lst, 1); 120 tt_str_op(result, OP_EQ, "Bar=1-8 Foo=1-10,63 Quux=12-45"); 121 tor_free(result); 122 123 result = protover_compute_vote(lst, 2); 124 tt_str_op(result, OP_EQ, "Bar=3-6,8 Foo=9"); 125 tor_free(result); 126 127 /* High threshold */ 128 result = protover_compute_vote(lst, 3); 129 tt_str_op(result, OP_EQ, ""); 130 tor_free(result); 131 132 /* Don't count double-voting. */ 133 smartlist_clear(lst); 134 smartlist_add(lst, (void*) "Foo=1 Foo=1"); 135 smartlist_add(lst, (void*) "Bar=1-2,2-3"); 136 result = protover_compute_vote(lst, 2); 137 tt_str_op(result, OP_EQ, ""); 138 tor_free(result); 139 140 /* Bad votes: the result must be empty */ 141 smartlist_clear(lst); 142 smartlist_add(lst, (void*) "Faux=10-5"); 143 result = protover_compute_vote(lst, 1); 144 tt_str_op(result, OP_EQ, ""); 145 tor_free(result); 146 147 /* This fails, since "-0" is not valid. */ 148 smartlist_clear(lst); 149 smartlist_add(lst, (void*) "Faux=-0"); 150 result = protover_compute_vote(lst, 1); 151 tt_str_op(result, OP_EQ, ""); 152 tor_free(result); 153 154 /* Vote large protover lists that are just below the threshold */ 155 156 /* Just below the threshold: Rust */ 157 smartlist_clear(lst); 158 smartlist_add(lst, (void*) "Sleen=1-50"); 159 result = protover_compute_vote(lst, 1); 160 tt_str_op(result, OP_EQ, "Sleen=1-50"); 161 tor_free(result); 162 163 /* Just below the threshold: C */ 164 smartlist_clear(lst); 165 smartlist_add(lst, (void*) "Sleen=1-63"); 166 result = protover_compute_vote(lst, 1); 167 tt_str_op(result, OP_EQ, "Sleen=1-63"); 168 tor_free(result); 169 170 /* Protocol name too long */ 171 smartlist_clear(lst); 172 smartlist_add(lst, (void*) "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 173 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 175 result = protover_compute_vote(lst, 1); 176 tt_str_op(result, OP_EQ, ""); 177 tor_free(result); 178 179 done: 180 tor_free(result); 181 smartlist_free(lst); 182 } 183 184 static void 185 test_protover_all_supported(void *arg) 186 { 187 (void)arg; 188 char *msg = NULL; 189 190 tt_assert(protover_all_supported(NULL, &msg)); 191 tt_ptr_op(msg, OP_EQ, NULL); 192 193 tt_assert(protover_all_supported("", &msg)); 194 tt_ptr_op(msg, OP_EQ, NULL); 195 196 // Some things that we do support 197 tt_assert(protover_all_supported("Link=3-4", &msg)); 198 tt_ptr_op(msg, OP_EQ, NULL); 199 tt_assert(protover_all_supported("Link=3-4 Desc=2", &msg)); 200 tt_ptr_op(msg, OP_EQ, NULL); 201 202 // Some things we don't support 203 tt_assert(! protover_all_supported("Wombat=9", NULL)); 204 tt_assert(! protover_all_supported("Wombat=9", &msg)); 205 tt_str_op(msg, OP_EQ, "Wombat=9"); 206 tor_free(msg); 207 tt_assert(! protover_all_supported("Link=60", &msg)); 208 tt_str_op(msg, OP_EQ, "Link=60"); 209 tor_free(msg); 210 211 // Mix of things we support and things we don't 212 tt_assert(! protover_all_supported("Link=3-4 Wombat=9", &msg)); 213 tt_str_op(msg, OP_EQ, "Wombat=9"); 214 tor_free(msg); 215 216 /* Mix of things we support and don't support within a single protocol 217 * which we do support */ 218 tt_assert(! protover_all_supported("Link=3-60", &msg)); 219 tt_str_op(msg, OP_EQ, "Link=6-60"); 220 tor_free(msg); 221 tt_assert(! protover_all_supported("Link=1-3,50-63", &msg)); 222 tt_str_op(msg, OP_EQ, "Link=1-2,50-63"); 223 tor_free(msg); 224 tt_assert(! protover_all_supported("Link=1-3,5-12", &msg)); 225 tt_str_op(msg, OP_EQ, "Link=1-2,6-12"); 226 tor_free(msg); 227 228 /* Mix of protocols we do support and some we don't, where the protocols 229 * we do support have some versions we don't support. */ 230 tt_assert(! protover_all_supported("Link=3,5-12 Quokka=40-41", &msg)); 231 tt_str_op(msg, OP_EQ, "Link=6-12 Quokka=40-41"); 232 tor_free(msg); 233 234 /* If we get a (barely) valid (but unsupported list, we say "yes, that's 235 * supported." */ 236 tt_assert(protover_all_supported("Fribble=", &msg)); 237 tt_ptr_op(msg, OP_EQ, NULL); 238 239 #ifndef ALL_BUGS_ARE_FATAL 240 /* If we get a completely unparseable list, protover_all_supported should 241 * hit a fatal assertion for BUG(entries == NULL). */ 242 tor_capture_bugs_(1); 243 tt_assert(protover_all_supported("Fribble", &msg)); 244 tor_end_capture_bugs_(); 245 246 /* If we get a completely unparseable list, protover_all_supported should 247 * hit a fatal assertion for BUG(entries == NULL). */ 248 tor_capture_bugs_(1); 249 tt_assert(protover_all_supported("Sleen=1-4294967295", &msg)); 250 tor_end_capture_bugs_(); 251 #endif /* !defined(ALL_BUGS_ARE_FATAL) */ 252 253 /* Protocol name too long */ 254 #if !defined(ALL_BUGS_ARE_FATAL) 255 tor_capture_bugs_(1); 256 tt_assert(protover_all_supported( 257 "DoSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 258 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 259 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 260 "aaaaaaaaaaaa=1-65536", &msg)); 261 tor_end_capture_bugs_(); 262 #endif /* !defined(ALL_BUGS_ARE_FATAL) */ 263 264 done: 265 tor_end_capture_bugs_(); 266 tor_free(msg); 267 } 268 269 static void 270 test_protover_list_supports_protocol_returns_true(void *arg) 271 { 272 (void)arg; 273 274 const char *protocols = "Link=1"; 275 int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 1); 276 tt_int_op(is_supported, OP_EQ, 1); 277 278 done: 279 ; 280 } 281 282 static void 283 test_protover_list_supports_protocol_for_unsupported_returns_false(void *arg) 284 { 285 (void)arg; 286 287 const char *protocols = "Link=1"; 288 int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 10); 289 tt_int_op(is_supported, OP_EQ, 0); 290 291 done: 292 ; 293 } 294 295 static void 296 test_protover_supports_version(void *arg) 297 { 298 (void)arg; 299 300 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 3)); 301 tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 6)); 302 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINK, 7)); 303 tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINKAUTH, 3)); 304 305 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3", 306 PRT_LINKAUTH, 2)); 307 tt_assert(protocol_list_supports_protocol("Link=4-6 LinkAuth=3", 308 PRT_LINKAUTH, 3)); 309 tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3", 310 PRT_LINKAUTH, 4)); 311 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", 312 PRT_LINKAUTH, 4)); 313 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", 314 PRT_LINKAUTH, 3)); 315 tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", 316 PRT_LINKAUTH, 2)); 317 318 tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3", 319 PRT_DESC, 2)); 320 done: 321 ; 322 } 323 324 /* This could be MAX_PROTOCOLS_TO_EXPAND, but that's not exposed by protover */ 325 #define MAX_PROTOCOLS_TO_TEST 1024 326 327 /* LinkAuth and Relay protocol versions. 328 * Hard-coded here, because they are not in the code, or not exposed in the 329 * headers. */ 330 #define PROTOVER_LINKAUTH_V1 1 331 #define PROTOVER_LINKAUTH_V2 2 332 #define PROTOVER_RELAY_V2 2 333 334 /* Deprecated HSIntro versions */ 335 #define PROTOVER_HS_INTRO_DEPRECATED_1 1 336 #define PROTOVER_HS_INTRO_DEPRECATED_2 2 337 338 /* HSv2 Rend and HSDir protocol versions. */ 339 #define PROTOVER_HS_RENDEZVOUS_POINT_V2 1 340 #define PROTOVER_HSDIR_V2 2 341 342 /* DirCache, Desc, Microdesc, and Cons protocol versions. */ 343 #define PROTOVER_DIRCACHE_V1 1 344 #define PROTOVER_DIRCACHE_V2 2 345 346 #define PROTOVER_DESC_V1 1 347 #define PROTOVER_DESC_V2 2 348 349 #define PROTOVER_MICRODESC_V1 1 350 #define PROTOVER_MICRODESC_V2 2 351 352 #define PROTOVER_CONS_V1 1 353 #define PROTOVER_CONS_V2 2 354 355 #define PROTOVER_PADDING_V1 1 356 357 #define PROTOVER_FLOWCTRL_V1 1 358 359 #define PROTOVER_RELAY_NTOR_V3 4 360 361 /* Make sure we haven't forgotten any supported protocols */ 362 static void 363 test_protover_supported_protocols(void *arg) 364 { 365 (void)arg; 366 367 const char *supported_protocols = protover_get_supported_protocols(); 368 369 /* Test for new Link in the code, that hasn't been added to supported 370 * protocols */ 371 tt_assert(protocol_list_supports_protocol(supported_protocols, 372 PRT_LINK, 373 MAX_LINK_PROTO)); 374 for (uint16_t i = 0; i < MAX_PROTOCOLS_TO_TEST; i++) { 375 tt_int_op(protocol_list_supports_protocol(supported_protocols, 376 PRT_LINK, 377 i), 378 OP_EQ, 379 is_or_protocol_version_known(i)); 380 } 381 382 /* Legacy LinkAuth is only supported on OpenSSL and similar. */ 383 tt_int_op(protocol_list_supports_protocol(supported_protocols, 384 PRT_LINKAUTH, 385 PROTOVER_LINKAUTH_V1), 386 OP_EQ, 387 authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET)); 388 /* LinkAuth=2 is unused */ 389 tt_assert(!protocol_list_supports_protocol(supported_protocols, 390 PRT_LINKAUTH, 391 PROTOVER_LINKAUTH_V2)); 392 tt_assert( 393 protocol_list_supports_protocol(supported_protocols, 394 PRT_LINKAUTH, 395 PROTOVER_LINKAUTH_ED25519_HANDSHAKE)); 396 397 /* Relay protovers do not appear anywhere in the code. */ 398 tt_assert(protocol_list_supports_protocol(supported_protocols, 399 PRT_RELAY, 400 PROTOVER_RELAY_V2)); 401 tt_assert(protocol_list_supports_protocol(supported_protocols, 402 PRT_RELAY, 403 PROTOVER_RELAY_EXTEND2)); 404 tt_assert(protocol_list_supports_protocol(supported_protocols, 405 PRT_RELAY, 406 PROTOVER_RELAY_ACCEPT_IPV6)); 407 tt_assert(protocol_list_supports_protocol(supported_protocols, 408 PRT_RELAY, 409 PROTOVER_RELAY_EXTEND_IPV6)); 410 tt_assert(protocol_list_supports_protocol(supported_protocols, 411 PRT_RELAY, 412 PROTOVER_RELAY_CANONICAL_IPV6)); 413 414 /* These HSIntro versions are deprecated */ 415 tt_assert(!protocol_list_supports_protocol(supported_protocols, 416 PRT_HSINTRO, 417 PROTOVER_HS_INTRO_DEPRECATED_1)); 418 tt_assert(!protocol_list_supports_protocol(supported_protocols, 419 PRT_HSINTRO, 420 PROTOVER_HS_INTRO_DEPRECATED_2)); 421 /* Test for HSv3 HSIntro */ 422 tt_assert(protocol_list_supports_protocol(supported_protocols, 423 PRT_HSINTRO, 424 PROTOVER_HS_INTRO_V3)); 425 /* Test for HSIntro DoS */ 426 tt_assert(protocol_list_supports_protocol(supported_protocols, 427 PRT_HSINTRO, 428 PROTOVER_HS_INTRO_DOS)); 429 430 /* Legacy HSRend does not appear anywhere in the code. */ 431 tt_assert(protocol_list_supports_protocol(supported_protocols, 432 PRT_HSREND, 433 PROTOVER_HS_RENDEZVOUS_POINT_V2)); 434 /* Test for HSv3 HSRend */ 435 tt_assert(protocol_list_supports_protocol(supported_protocols, 436 PRT_HSREND, 437 PROTOVER_HS_RENDEZVOUS_POINT_V3)); 438 439 /* Legacy HSDir does not appear anywhere in the code. */ 440 tt_assert(protocol_list_supports_protocol(supported_protocols, 441 PRT_HSDIR, 442 PROTOVER_HSDIR_V2)); 443 /* Test for HSv3 HSDir */ 444 tt_assert(protocol_list_supports_protocol(supported_protocols, 445 PRT_HSDIR, 446 PROTOVER_HSDIR_V3)); 447 448 /* No DirCache versions appear anywhere in the code. */ 449 tt_assert(protocol_list_supports_protocol(supported_protocols, 450 PRT_DIRCACHE, 451 PROTOVER_DIRCACHE_V2)); 452 453 /* No Desc versions appear anywhere in the code. */ 454 tt_assert(protocol_list_supports_protocol(supported_protocols, 455 PRT_DESC, 456 PROTOVER_DESC_V1)); 457 tt_assert(protocol_list_supports_protocol(supported_protocols, 458 PRT_DESC, 459 PROTOVER_DESC_V2)); 460 /* Is there any way to test for new Desc? */ 461 462 /* No Microdesc versions appear anywhere in the code. */ 463 tt_assert(protocol_list_supports_protocol(supported_protocols, 464 PRT_MICRODESC, 465 PROTOVER_MICRODESC_V1)); 466 tt_assert(protocol_list_supports_protocol(supported_protocols, 467 PRT_MICRODESC, 468 PROTOVER_MICRODESC_V2)); 469 470 /* No Cons versions appear anywhere in the code. */ 471 tt_assert(protocol_list_supports_protocol(supported_protocols, 472 PRT_CONS, 473 PROTOVER_CONS_V1)); 474 tt_assert(protocol_list_supports_protocol(supported_protocols, 475 PRT_CONS, 476 PROTOVER_CONS_V2)); 477 478 /* Padding=1 is deprecated. */ 479 tt_assert(!protocol_list_supports_protocol(supported_protocols, 480 PRT_PADDING, 481 PROTOVER_PADDING_V1)); 482 tt_assert(protocol_list_supports_protocol(supported_protocols, 483 PRT_PADDING, 484 PROTOVER_HS_SETUP_PADDING)); 485 486 /* FlowCtrl */ 487 tt_assert(protocol_list_supports_protocol(supported_protocols, 488 PRT_FLOWCTRL, 489 PROTOVER_FLOWCTRL_V1)); 490 491 done: 492 ; 493 } 494 495 static void 496 test_protover_vote_roundtrip(void *args) 497 { 498 (void) args; 499 static const struct { 500 const char *input; 501 const char *expected_output; 502 } examples[] = { 503 { "Risqu\u00e9=1", NULL }, 504 { ",,,=1", NULL }, 505 { "\xc1=1", NULL }, 506 { "Foo_Bar=1", NULL }, 507 { "Fkrkljdsf", NULL }, 508 { "Zn=4294967295", NULL }, 509 { "Zn=4294967295-1", NULL }, 510 { "Zn=4294967293-4294967295", NULL }, 511 /* Will fail because of 4294967295. */ 512 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295", 513 NULL }, 514 { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,50 Zn=1,42", 515 "Bar=3 Foo=1,3 Quux=9-12,14-16,50 Zn=1,42" }, 516 { "Zu16=1,63", "Zu16=1,63" }, 517 { "N-1=1,2", "N-1=1-2" }, 518 { "-1=4294967295", NULL }, 519 { "-1=3", "-1=3" }, 520 { "Foo=,", NULL }, 521 { "Foo=,1", NULL }, 522 { "Foo=1,,3", NULL }, 523 { "Foo=1,3,", NULL }, 524 /* junk. */ 525 { "!!3@*", NULL }, 526 /* Missing equals sign */ 527 { "Link=4 Haprauxymatyve Desc=9", NULL }, 528 { "Link=4 Haprauxymatyve=7 Desc=9", 529 "Desc=9 Haprauxymatyve=7 Link=4" }, 530 { "=10-11", NULL }, 531 { "X=10-11", "X=10-11" }, 532 { "Link=4 =3 Desc=9", NULL }, 533 { "Link=4 Z=3 Desc=9", "Desc=9 Link=4 Z=3" }, 534 { "Link=fred", NULL }, 535 { "Link=1,fred", NULL }, 536 { "Link=1,fred,3", NULL }, 537 { "Link=1,9-8,3", NULL }, 538 { "Faux=-0", NULL }, 539 { "Faux=0--0", NULL }, 540 { "Faux=-1", NULL }, 541 { "Faux=-1-3", NULL }, 542 { "Faux=1--1", NULL }, 543 { "Link=1-2-", NULL }, 544 { "Link=1-2-3", NULL }, 545 { "Faux=1-2-", NULL }, 546 { "Faux=1-2-3", NULL }, 547 { "Link=\t1,3", NULL }, 548 { "Link=1\n,3", NULL }, 549 { "Faux=1,\r3", NULL }, 550 { "Faux=1,3\f", NULL }, 551 /* Large integers */ 552 { "Link=4294967296", NULL }, 553 /* Large range */ 554 { "Sleen=1-63", "Sleen=1-63" }, 555 { "Sleen=1-65537", NULL }, 556 }; 557 unsigned u; 558 smartlist_t *votes = smartlist_new(); 559 char *result = NULL; 560 561 for (u = 0; u < ARRAY_LENGTH(examples); ++u) { 562 const char *input = examples[u].input; 563 const char *expected_output = examples[u].expected_output; 564 565 smartlist_add(votes, (void*)input); 566 result = protover_compute_vote(votes, 1); 567 if (expected_output != NULL) { 568 tt_str_op(result, OP_EQ, expected_output); 569 } else { 570 tt_str_op(result, OP_EQ, ""); 571 } 572 573 smartlist_clear(votes); 574 tor_free(result); 575 } 576 577 done: 578 smartlist_free(votes); 579 tor_free(result); 580 } 581 582 static void 583 test_protover_vote_roundtrip_ours(void *args) 584 { 585 (void) args; 586 const char *examples[] = { 587 protover_get_supported_protocols(), 588 protover_get_recommended_client_protocols(), 589 protover_get_recommended_relay_protocols(), 590 protover_get_required_client_protocols(), 591 protover_get_required_relay_protocols(), 592 }; 593 unsigned u; 594 smartlist_t *votes = smartlist_new(); 595 char *result = NULL; 596 597 for (u = 0; u < ARRAY_LENGTH(examples); ++u) { 598 tt_assert(examples[u]); 599 const char *input = examples[u]; 600 const char *expected_output = examples[u]; 601 602 smartlist_add(votes, (void*)input); 603 result = protover_compute_vote(votes, 1); 604 if (expected_output != NULL) { 605 tt_str_op(result, OP_EQ, expected_output); 606 } else { 607 tt_str_op(result, OP_EQ, ""); 608 } 609 610 smartlist_clear(votes); 611 tor_free(result); 612 } 613 614 done: 615 smartlist_free(votes); 616 tor_free(result); 617 } 618 619 /* Stringifies its argument. 620 * 4 -> "4" */ 621 #define STR(x) #x 622 623 #ifdef COCCI 624 #define PROTOVER(proto_string, version_macro) 625 #else 626 /* Generate a protocol version string using proto_string and version_macro. 627 * PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS) -> "HSIntro" "=" "5" 628 * Uses two levels of macros to turn PROTOVER_HS_INTRO_DOS into "5". 629 */ 630 #define PROTOVER(proto_string, version_macro) \ 631 (proto_string "=" STR(version_macro)) 632 #endif /* defined(COCCI) */ 633 634 #define DEBUG_PROTOVER(flags) \ 635 STMT_BEGIN \ 636 log_debug(LD_GENERAL, \ 637 "protovers:\n" \ 638 "protocols_known: %d,\n" \ 639 "supports_extend2_cells: %d,\n" \ 640 "supports_accepting_ipv6_extends: %d,\n" \ 641 "supports_initiating_ipv6_extends: %d,\n" \ 642 "supports_canonical_ipv6_conns: %d,\n" \ 643 "supports_ed25519_link_handshake_compat: %d,\n" \ 644 "supports_ed25519_link_handshake_any: %d,\n" \ 645 "supports_ed25519_hs_intro: %d,\n" \ 646 "supports_establish_intro_dos_extension: %d,\n" \ 647 "supports_v3_hsdir: %d,\n" \ 648 "supports_v3_rendezvous_point: %d,\n" \ 649 "supports_hs_setup_padding: %d,\n" \ 650 "supports_congestion_control: %d.", \ 651 (flags).protocols_known, \ 652 (flags).supports_extend2_cells, \ 653 (flags).supports_accepting_ipv6_extends, \ 654 (flags).supports_initiating_ipv6_extends, \ 655 (flags).supports_canonical_ipv6_conns, \ 656 (flags).supports_ed25519_link_handshake_compat, \ 657 (flags).supports_ed25519_link_handshake_any, \ 658 (flags).supports_ed25519_hs_intro, \ 659 (flags).supports_establish_intro_dos_extension, \ 660 (flags).supports_v3_hsdir, \ 661 (flags).supports_v3_rendezvous_point, \ 662 (flags).supports_hs_setup_padding, \ 663 (flags).supports_congestion_control); \ 664 STMT_END 665 666 /* Test that the proto_string version version_macro sets summary_flag. */ 667 #define TEST_PROTOVER(proto_string, version_macro, summary_flag) \ 668 STMT_BEGIN \ 669 memset(&flags, 0, sizeof(flags)); \ 670 summarize_protover_flags(&flags, \ 671 PROTOVER(proto_string, version_macro), \ 672 NULL); \ 673 DEBUG_PROTOVER(flags); \ 674 tt_int_op(flags.protocols_known, OP_EQ, 1); \ 675 tt_int_op(flags.summary_flag, OP_EQ, 1); \ 676 flags.protocols_known = 0; \ 677 flags.summary_flag = 0; \ 678 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); \ 679 STMT_END 680 681 static void 682 test_protover_summarize_flags(void *args) 683 { 684 (void) args; 685 char pv[30]; 686 memset(&pv, 0, sizeof(pv)); 687 688 protover_summary_cache_free_all(); 689 690 protover_summary_flags_t zero_flags; 691 memset(&zero_flags, 0, sizeof(zero_flags)); 692 protover_summary_flags_t flags; 693 694 memset(&flags, 0, sizeof(flags)); 695 summarize_protover_flags(&flags, NULL, NULL); 696 DEBUG_PROTOVER(flags); 697 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 698 699 memset(&flags, 0, sizeof(flags)); 700 summarize_protover_flags(&flags, "", ""); 701 DEBUG_PROTOVER(flags); 702 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 703 704 /* Now check version exceptions */ 705 706 /* EXTEND2 cell support */ 707 memset(&flags, 0, sizeof(flags)); 708 summarize_protover_flags(&flags, NULL, "Tor 0.2.4.8-alpha"); 709 DEBUG_PROTOVER(flags); 710 tt_int_op(flags.protocols_known, OP_EQ, 1); 711 tt_int_op(flags.supports_extend2_cells, OP_EQ, 1); 712 /* Now clear those flags, and check the rest are zero */ 713 flags.protocols_known = 0; 714 flags.supports_extend2_cells = 0; 715 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 716 717 /* disabling HSDir v3 support for buggy versions */ 718 memset(&flags, 0, sizeof(flags)); 719 summarize_protover_flags(&flags, 720 PROTOVER("HSDir", PROTOVER_HSDIR_V3), 721 NULL); 722 DEBUG_PROTOVER(flags); 723 tt_int_op(flags.protocols_known, OP_EQ, 1); 724 tt_int_op(flags.supports_v3_hsdir, OP_EQ, 1); 725 /* Now clear those flags, and check the rest are zero */ 726 flags.protocols_known = 0; 727 flags.supports_v3_hsdir = 0; 728 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 729 730 memset(&flags, 0, sizeof(flags)); 731 summarize_protover_flags(&flags, 732 PROTOVER("HSDir", PROTOVER_HSDIR_V3), 733 "Tor 0.3.0.7"); 734 DEBUG_PROTOVER(flags); 735 tt_int_op(flags.protocols_known, OP_EQ, 1); 736 /* Now clear that flag, and check the rest are zero */ 737 flags.protocols_known = 0; 738 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 739 740 /* Now check standard summaries */ 741 742 /* LinkAuth */ 743 memset(&flags, 0, sizeof(flags)); 744 summarize_protover_flags(&flags, 745 PROTOVER("LinkAuth", 746 PROTOVER_LINKAUTH_ED25519_HANDSHAKE), 747 NULL); 748 DEBUG_PROTOVER(flags); 749 tt_int_op(flags.protocols_known, OP_EQ, 1); 750 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 1); 751 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1); 752 /* Now clear those flags, and check the rest are zero */ 753 flags.protocols_known = 0; 754 flags.supports_ed25519_link_handshake_compat = 0; 755 flags.supports_ed25519_link_handshake_any = 0; 756 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 757 758 /* Test one greater */ 759 memset(&flags, 0, sizeof(flags)); 760 snprintf(pv, sizeof(pv), 761 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE + 1); 762 summarize_protover_flags(&flags, pv, NULL); 763 DEBUG_PROTOVER(flags); 764 tt_int_op(flags.protocols_known, OP_EQ, 1); 765 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0); 766 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1); 767 /* Now clear those flags, and check the rest are zero */ 768 flags.protocols_known = 0; 769 flags.supports_ed25519_link_handshake_compat = 0; 770 flags.supports_ed25519_link_handshake_any = 0; 771 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 772 773 /* Test one less */ 774 memset(&flags, 0, sizeof(flags)); 775 snprintf(pv, sizeof(pv), 776 "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE - 1); 777 summarize_protover_flags(&flags, pv, NULL); 778 DEBUG_PROTOVER(flags); 779 tt_int_op(flags.protocols_known, OP_EQ, 1); 780 tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0); 781 tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 0); 782 /* Now clear those flags, and check the rest are zero */ 783 flags.protocols_known = 0; 784 flags.supports_ed25519_link_handshake_compat = 0; 785 flags.supports_ed25519_link_handshake_any = 0; 786 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 787 788 /* We don't test "one more" and "one less" for each protocol version. 789 * But that could be a useful thing to add. */ 790 791 /* Relay */ 792 memset(&flags, 0, sizeof(flags)); 793 /* This test relies on these versions being equal */ 794 tt_int_op(PROTOVER_RELAY_EXTEND2, OP_EQ, PROTOVER_RELAY_ACCEPT_IPV6); 795 summarize_protover_flags(&flags, 796 PROTOVER("Relay", PROTOVER_RELAY_EXTEND2), NULL); 797 DEBUG_PROTOVER(flags); 798 tt_int_op(flags.protocols_known, OP_EQ, 1); 799 tt_int_op(flags.supports_extend2_cells, OP_EQ, 1); 800 tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1); 801 /* Now clear those flags, and check the rest are zero */ 802 flags.protocols_known = 0; 803 flags.supports_extend2_cells = 0; 804 flags.supports_accepting_ipv6_extends = 0; 805 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 806 807 memset(&flags, 0, sizeof(flags)); 808 /* This test relies on these versions being equal */ 809 tt_int_op(PROTOVER_RELAY_EXTEND_IPV6, OP_EQ, PROTOVER_RELAY_CANONICAL_IPV6); 810 summarize_protover_flags(&flags, 811 PROTOVER("Relay", PROTOVER_RELAY_EXTEND_IPV6), 812 NULL); 813 DEBUG_PROTOVER(flags); 814 tt_int_op(flags.protocols_known, OP_EQ, 1); 815 tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1); 816 tt_int_op(flags.supports_initiating_ipv6_extends, OP_EQ, 1); 817 tt_int_op(flags.supports_canonical_ipv6_conns, OP_EQ, 1); 818 /* Now clear those flags, and check the rest are zero */ 819 flags.protocols_known = 0; 820 flags.supports_accepting_ipv6_extends = 0; 821 flags.supports_initiating_ipv6_extends = 0; 822 flags.supports_canonical_ipv6_conns = 0; 823 tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); 824 825 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_V3, 826 supports_ed25519_hs_intro); 827 TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS, 828 supports_establish_intro_dos_extension); 829 830 TEST_PROTOVER("HSRend", PROTOVER_HS_RENDEZVOUS_POINT_V3, 831 supports_v3_rendezvous_point); 832 833 TEST_PROTOVER("HSDir", PROTOVER_HSDIR_V3, 834 supports_v3_hsdir); 835 836 TEST_PROTOVER("Padding", PROTOVER_HS_SETUP_PADDING, 837 supports_hs_setup_padding); 838 839 done: 840 ; 841 } 842 843 #define PV_TEST(name, flags) \ 844 { #name, test_protover_ ##name, (flags), NULL, NULL } 845 846 struct testcase_t protover_tests[] = { 847 PV_TEST(parse, 0), 848 PV_TEST(parse_fail, 0), 849 PV_TEST(vote, 0), 850 PV_TEST(all_supported, 0), 851 PV_TEST(list_supports_protocol_for_unsupported_returns_false, 0), 852 PV_TEST(list_supports_protocol_returns_true, 0), 853 PV_TEST(supports_version, 0), 854 PV_TEST(supported_protocols, 0), 855 PV_TEST(vote_roundtrip, 0), 856 PV_TEST(vote_roundtrip_ours, 0), 857 /* fork, because we memoize flags internally */ 858 PV_TEST(summarize_flags, TT_FORK), 859 END_OF_TESTCASES 860 };