diff options
Diffstat (limited to 'src/test/test_protover.c')
-rw-r--r-- | src/test/test_protover.c | 327 |
1 files changed, 293 insertions, 34 deletions
diff --git a/src/test/test_protover.c b/src/test/test_protover.c index 8fccae1a45..5e74265550 100644 --- a/src/test/test_protover.c +++ b/src/test/test_protover.c @@ -7,14 +7,18 @@ #include "orconfig.h" #include "test/test.h" -#include "core/or/protover.h" +#include "lib/tls/tortls.h" #include "core/or/or.h" + #include "core/or/connection_or.h" -#include "lib/tls/tortls.h" +#include "core/or/protover.h" +#include "core/or/versions.h" #include "feature/dirauth/dirvote.h" +#include "feature/relay/relay_handshake.h" + static void test_protover_parse(void *arg) { @@ -409,23 +413,21 @@ test_protover_supports_version(void *arg) * Hard-coded here, because they are not in the code, or not exposed in the * headers. */ #define PROTOVER_LINKAUTH_V1 1 -#define PROTOVER_LINKAUTH_V3 3 - +#define PROTOVER_LINKAUTH_V2 2 #define PROTOVER_RELAY_V1 1 -#define PROTOVER_RELAY_V2 2 +/* Deprecated HSIntro versions */ +#define PROTOVER_HS_INTRO_DEPRECATED_1 1 +#define PROTOVER_HS_INTRO_DEPRECATED_2 2 /* Highest supported HSv2 introduce protocol version. - * Hard-coded here, because it does not appear anywhere in the code. * It's not clear if we actually support version 2, see #25068. */ -#define PROTOVER_HSINTRO_V2 3 +#define PROTOVER_HS_INTRO_V2 3 -/* HSv2 Rend and HSDir protocol versions. - * Hard-coded here, because they do not appear anywhere in the code. */ +/* HSv2 Rend and HSDir protocol versions. */ #define PROTOVER_HS_RENDEZVOUS_POINT_V2 1 #define PROTOVER_HSDIR_V2 1 -/* DirCache, Desc, Microdesc, and Cons protocol versions. - * Hard-coded here, because they do not appear anywhere in the code. */ +/* DirCache, Desc, Microdesc, and Cons protocol versions. */ #define PROTOVER_DIRCACHE_V1 1 #define PROTOVER_DIRCACHE_V2 2 @@ -438,6 +440,10 @@ test_protover_supports_version(void *arg) #define PROTOVER_CONS_V1 1 #define PROTOVER_CONS_V2 2 +#define PROTOVER_PADDING_V1 1 + +#define PROTOVER_FLOWCTRL_V1 1 + /* Make sure we haven't forgotten any supported protocols */ static void test_protover_supported_protocols(void *arg) @@ -452,24 +458,27 @@ test_protover_supported_protocols(void *arg) PRT_LINK, MAX_LINK_PROTO)); for (uint16_t i = 0; i < MAX_PROTOCOLS_TO_TEST; i++) { - if (is_or_protocol_version_known(i)) { - tt_assert(protocol_list_supports_protocol(supported_protocols, + tt_int_op(protocol_list_supports_protocol(supported_protocols, PRT_LINK, - i)); - } + i), + OP_EQ, + is_or_protocol_version_known(i)); } -#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS - /* Legacy LinkAuth does not appear anywhere in the code. */ - tt_assert(protocol_list_supports_protocol(supported_protocols, - PRT_LINKAUTH, - PROTOVER_LINKAUTH_V1)); -#endif /* defined(HAVE_WORKING_TOR_TLS_GET_TLSSECRETS) */ - /* Latest LinkAuth is not exposed in the headers. */ - tt_assert(protocol_list_supports_protocol(supported_protocols, + /* Legacy LinkAuth is only supported on OpenSSL and similar. */ + tt_int_op(protocol_list_supports_protocol(supported_protocols, PRT_LINKAUTH, - PROTOVER_LINKAUTH_V3)); - /* Is there any way to test for new LinkAuth? */ + PROTOVER_LINKAUTH_V1), + OP_EQ, + authchallenge_type_is_supported(AUTHTYPE_RSA_SHA256_TLSSECRET)); + /* LinkAuth=2 is unused */ + tt_assert(!protocol_list_supports_protocol(supported_protocols, + PRT_LINKAUTH, + PROTOVER_LINKAUTH_V2)); + tt_assert( + protocol_list_supports_protocol(supported_protocols, + PRT_LINKAUTH, + PROTOVER_LINKAUTH_ED25519_HANDSHAKE)); /* Relay protovers do not appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -477,20 +486,38 @@ test_protover_supported_protocols(void *arg) PROTOVER_RELAY_V1)); tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_RELAY, - PROTOVER_RELAY_V2)); - /* Is there any way to test for new Relay? */ + PROTOVER_RELAY_EXTEND2)); + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_RELAY, + PROTOVER_RELAY_ACCEPT_IPV6)); + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_RELAY, + PROTOVER_RELAY_EXTEND_IPV6)); + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_RELAY, + PROTOVER_RELAY_CANONICAL_IPV6)); + /* These HSIntro versions are deprecated */ + tt_assert(!protocol_list_supports_protocol(supported_protocols, + PRT_HSINTRO, + PROTOVER_HS_INTRO_DEPRECATED_1)); + tt_assert(!protocol_list_supports_protocol(supported_protocols, + PRT_HSINTRO, + PROTOVER_HS_INTRO_DEPRECATED_2)); /* We could test legacy HSIntro by calling rend_service_update_descriptor(), * and checking the protocols field. But that's unlikely to change, so * we just use a hard-coded value. */ tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_HSINTRO, - PROTOVER_HSINTRO_V2)); + PROTOVER_HS_INTRO_V2)); /* Test for HSv3 HSIntro */ tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_HSINTRO, PROTOVER_HS_INTRO_V3)); - /* Is there any way to test for new HSIntro? */ + /* Test for HSIntro DoS */ + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_HSINTRO, + PROTOVER_HS_INTRO_DOS)); /* Legacy HSRend does not appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -500,7 +527,6 @@ test_protover_supported_protocols(void *arg) tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_HSREND, PROTOVER_HS_RENDEZVOUS_POINT_V3)); - /* Is there any way to test for new HSRend? */ /* Legacy HSDir does not appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -510,7 +536,6 @@ test_protover_supported_protocols(void *arg) tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_HSDIR, PROTOVER_HSDIR_V3)); - /* Is there any way to test for new HSDir? */ /* No DirCache versions appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -519,7 +544,6 @@ test_protover_supported_protocols(void *arg) tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_DIRCACHE, PROTOVER_DIRCACHE_V2)); - /* Is there any way to test for new DirCache? */ /* No Desc versions appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -537,7 +561,6 @@ test_protover_supported_protocols(void *arg) tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_MICRODESC, PROTOVER_MICRODESC_V2)); - /* Is there any way to test for new Microdesc? */ /* No Cons versions appear anywhere in the code. */ tt_assert(protocol_list_supports_protocol(supported_protocols, @@ -546,7 +569,19 @@ test_protover_supported_protocols(void *arg) tt_assert(protocol_list_supports_protocol(supported_protocols, PRT_CONS, PROTOVER_CONS_V2)); - /* Is there any way to test for new Cons? */ + + /* Padding=1 is deprecated. */ + tt_assert(!protocol_list_supports_protocol(supported_protocols, + PRT_PADDING, + PROTOVER_PADDING_V1)); + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_PADDING, + PROTOVER_HS_SETUP_PADDING)); + + /* FlowCtrl */ + tt_assert(protocol_list_supports_protocol(supported_protocols, + PRT_FLOWCTRL, + PROTOVER_FLOWCTRL_V1)); done: ; @@ -676,6 +711,228 @@ test_protover_vote_roundtrip_ours(void *args) tor_free(result); } +/* Stringifies its argument. + * 4 -> "4" */ +#define STR(x) #x + +#ifdef COCCI +#define PROTOVER(proto_string, version_macro) +#else +/* Generate a protocol version string using proto_string and version_macro. + * PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS) -> "HSIntro" "=" "5" + * Uses two levels of macros to turn PROTOVER_HS_INTRO_DOS into "5". + */ +#define PROTOVER(proto_string, version_macro) \ + (proto_string "=" STR(version_macro)) +#endif + +#define DEBUG_PROTOVER(flags) \ + STMT_BEGIN \ + log_debug(LD_GENERAL, \ + "protovers:\n" \ + "protocols_known: %d,\n" \ + "supports_extend2_cells: %d,\n" \ + "supports_accepting_ipv6_extends: %d,\n" \ + "supports_initiating_ipv6_extends: %d,\n" \ + "supports_canonical_ipv6_conns: %d,\n" \ + "supports_ed25519_link_handshake_compat: %d,\n" \ + "supports_ed25519_link_handshake_any: %d,\n" \ + "supports_ed25519_hs_intro: %d,\n" \ + "supports_establish_intro_dos_extension: %d,\n" \ + "supports_v3_hsdir: %d,\n" \ + "supports_v3_rendezvous_point: %d,\n" \ + "supports_hs_setup_padding: %d.", \ + (flags).protocols_known, \ + (flags).supports_extend2_cells, \ + (flags).supports_accepting_ipv6_extends, \ + (flags).supports_initiating_ipv6_extends, \ + (flags).supports_canonical_ipv6_conns, \ + (flags).supports_ed25519_link_handshake_compat, \ + (flags).supports_ed25519_link_handshake_any, \ + (flags).supports_ed25519_hs_intro, \ + (flags).supports_establish_intro_dos_extension, \ + (flags).supports_v3_hsdir, \ + (flags).supports_v3_rendezvous_point, \ + (flags).supports_hs_setup_padding); \ + STMT_END + +/* Test that the proto_string version version_macro sets summary_flag. */ +#define TEST_PROTOVER(proto_string, version_macro, summary_flag) \ + STMT_BEGIN \ + memset(&flags, 0, sizeof(flags)); \ + summarize_protover_flags(&flags, \ + PROTOVER(proto_string, version_macro), \ + NULL); \ + DEBUG_PROTOVER(flags); \ + tt_int_op(flags.protocols_known, OP_EQ, 1); \ + tt_int_op(flags.summary_flag, OP_EQ, 1); \ + flags.protocols_known = 0; \ + flags.summary_flag = 0; \ + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); \ + STMT_END + +static void +test_protover_summarize_flags(void *args) +{ + (void) args; + char pv[30]; + memset(&pv, 0, sizeof(pv)); + + protover_summary_cache_free_all(); + + protover_summary_flags_t zero_flags; + memset(&zero_flags, 0, sizeof(zero_flags)); + protover_summary_flags_t flags; + + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, NULL, NULL); + DEBUG_PROTOVER(flags); + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, "", ""); + DEBUG_PROTOVER(flags); + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* Now check version exceptions */ + + /* EXTEND2 cell support */ + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, NULL, "Tor 0.2.4.8-alpha"); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_extend2_cells, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_extend2_cells = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* disabling HSDir v3 support for buggy versions */ + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, + PROTOVER("HSDir", PROTOVER_HSDIR_V3), + NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_v3_hsdir, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_v3_hsdir = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, + PROTOVER("HSDir", PROTOVER_HSDIR_V3), + "Tor 0.3.0.7"); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + /* Now clear that flag, and check the rest are zero */ + flags.protocols_known = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* Now check standard summaries */ + + /* LinkAuth */ + memset(&flags, 0, sizeof(flags)); + summarize_protover_flags(&flags, + PROTOVER("LinkAuth", + PROTOVER_LINKAUTH_ED25519_HANDSHAKE), + NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 1); + tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_ed25519_link_handshake_compat = 0; + flags.supports_ed25519_link_handshake_any = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* Test one greater */ + memset(&flags, 0, sizeof(flags)); + snprintf(pv, sizeof(pv), + "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE + 1); + summarize_protover_flags(&flags, pv, NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0); + tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_ed25519_link_handshake_compat = 0; + flags.supports_ed25519_link_handshake_any = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* Test one less */ + memset(&flags, 0, sizeof(flags)); + snprintf(pv, sizeof(pv), + "%s=%d", "LinkAuth", PROTOVER_LINKAUTH_ED25519_HANDSHAKE - 1); + summarize_protover_flags(&flags, pv, NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_ed25519_link_handshake_compat, OP_EQ, 0); + tt_int_op(flags.supports_ed25519_link_handshake_any, OP_EQ, 0); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_ed25519_link_handshake_compat = 0; + flags.supports_ed25519_link_handshake_any = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + /* We don't test "one more" and "one less" for each protocol version. + * But that could be a useful thing to add. */ + + /* Relay */ + memset(&flags, 0, sizeof(flags)); + /* This test relies on these versions being equal */ + tt_int_op(PROTOVER_RELAY_EXTEND2, OP_EQ, PROTOVER_RELAY_ACCEPT_IPV6); + summarize_protover_flags(&flags, + PROTOVER("Relay", PROTOVER_RELAY_EXTEND2), NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_extend2_cells, OP_EQ, 1); + tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_extend2_cells = 0; + flags.supports_accepting_ipv6_extends = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + memset(&flags, 0, sizeof(flags)); + /* This test relies on these versions being equal */ + tt_int_op(PROTOVER_RELAY_EXTEND_IPV6, OP_EQ, PROTOVER_RELAY_CANONICAL_IPV6); + summarize_protover_flags(&flags, + PROTOVER("Relay", PROTOVER_RELAY_EXTEND_IPV6), + NULL); + DEBUG_PROTOVER(flags); + tt_int_op(flags.protocols_known, OP_EQ, 1); + tt_int_op(flags.supports_accepting_ipv6_extends, OP_EQ, 1); + tt_int_op(flags.supports_initiating_ipv6_extends, OP_EQ, 1); + tt_int_op(flags.supports_canonical_ipv6_conns, OP_EQ, 1); + /* Now clear those flags, and check the rest are zero */ + flags.protocols_known = 0; + flags.supports_accepting_ipv6_extends = 0; + flags.supports_initiating_ipv6_extends = 0; + flags.supports_canonical_ipv6_conns = 0; + tt_mem_op(&flags, OP_EQ, &zero_flags, sizeof(flags)); + + TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_V3, + supports_ed25519_hs_intro); + TEST_PROTOVER("HSIntro", PROTOVER_HS_INTRO_DOS, + supports_establish_intro_dos_extension); + + TEST_PROTOVER("HSRend", PROTOVER_HS_RENDEZVOUS_POINT_V3, + supports_v3_rendezvous_point); + + TEST_PROTOVER("HSDir", PROTOVER_HSDIR_V3, + supports_v3_hsdir); + + TEST_PROTOVER("Padding", PROTOVER_HS_SETUP_PADDING, + supports_hs_setup_padding); + + done: + ; +} + #define PV_TEST(name, flags) \ { #name, test_protover_ ##name, (flags), NULL, NULL } @@ -690,5 +947,7 @@ struct testcase_t protover_tests[] = { PV_TEST(supported_protocols, 0), PV_TEST(vote_roundtrip, 0), PV_TEST(vote_roundtrip_ours, 0), + /* fork, because we memoize flags internally */ + PV_TEST(summarize_flags, TT_FORK), END_OF_TESTCASES }; |