diff options
author | David Goulet <dgoulet@torproject.org> | 2021-10-19 10:29:20 -0400 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-10-19 10:29:20 -0400 |
commit | d4c697b2f7342eea8b750428c28a222be5bcd411 (patch) | |
tree | 61cb7eec75b61c816f0052914f492d03f55b814e | |
parent | 816c45606b686428fc004d382547fa42b6c73596 (diff) | |
parent | d949a2f924bfabd4aacf48e884d99cd6a8db61ef (diff) | |
download | tor-d4c697b2f7342eea8b750428c28a222be5bcd411.tar.gz tor-d4c697b2f7342eea8b750428c28a222be5bcd411.zip |
Merge branch 'maint-0.4.5' into release-0.4.5
-rw-r--r-- | changes/ticket40476 | 8 | ||||
-rw-r--r-- | src/core/or/connection_edge.c | 17 | ||||
-rw-r--r-- | src/feature/control/control_cmd.c | 32 | ||||
-rw-r--r-- | src/feature/dircache/dircache.c | 61 | ||||
-rw-r--r-- | src/feature/hs/hs_common.h | 2 | ||||
-rw-r--r-- | src/feature/hs/hs_config.c | 8 | ||||
-rw-r--r-- | src/feature/hs/hs_intropoint.c | 3 | ||||
-rw-r--r-- | src/test/include.am | 13 | ||||
-rw-r--r-- | src/test/test_dir_handle_get.c | 75 | ||||
-rw-r--r-- | src/test/test_entryconn.c | 41 | ||||
-rw-r--r-- | src/test/test_hs_common.c | 15 | ||||
-rw-r--r-- | src/test/test_hs_config.c | 201 | ||||
-rw-r--r-- | src/test/test_hs_intropoint.c | 64 | ||||
-rw-r--r-- | src/test/test_hs_service.c | 5 |
14 files changed, 75 insertions, 470 deletions
diff --git a/changes/ticket40476 b/changes/ticket40476 new file mode 100644 index 0000000000..062e36f9bc --- /dev/null +++ b/changes/ticket40476 @@ -0,0 +1,8 @@ + o Major feature (onion service v2): + - Tor does NOT allow anymore to create v2 services, to connect as a client + to a v2 service and for a relay to be a v2 HSDir or introduction point. + This effectively disable onion service version 2 tor wide. Closes 40476. + - The control port command HSFETCH and HSPOST don't allow version 2 as well. + It is also not possible to create a v2 service with ADD_ONION. + - See https://blog.torproject.org/v2-deprecation-timeline for details on + how to transition from v2 to v3. diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 82e8ead5e0..d9067d5c29 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -1636,12 +1636,12 @@ consider_plaintext_ports(entry_connection_t *conn, uint16_t port) * The possible recognized forms are (where true is returned): * * If address is of the form "y.onion" with a well-formed handle y: - * Put a NUL after y, lower-case it, and return ONION_V2_HOSTNAME or - * ONION_V3_HOSTNAME depending on the HS version. + * Put a NUL after y, lower-case it, and return ONION_V3_HOSTNAME + * depending on the HS version. * * If address is of the form "x.y.onion" with a well-formed handle x: * Drop "x.", put a NUL after y, lower-case it, and return - * ONION_V2_HOSTNAME or ONION_V3_HOSTNAME depending on the HS version. + * ONION_V3_HOSTNAME depending on the HS version. * * If address is of the form "y.onion" with a badly-formed handle y: * Return BAD_HOSTNAME and log a message. @@ -1691,14 +1691,6 @@ parse_extended_hostname(char *address, hostname_type_t *type_out) if (q != address) { memmove(address, q, strlen(q) + 1 /* also get \0 */); } - /* v2 onion address check. */ - if (strlen(query) == REND_SERVICE_ID_LEN_BASE32) { - *type_out = ONION_V2_HOSTNAME; - if (rend_valid_v2_service_id(query)) { - goto success; - } - goto failed; - } /* v3 onion address check. */ if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) { @@ -1718,8 +1710,7 @@ parse_extended_hostname(char *address, hostname_type_t *type_out) failed: /* otherwise, return to previous state and return 0 */ *s = '.'; - const bool is_onion = (*type_out == ONION_V2_HOSTNAME) || - (*type_out == ONION_V3_HOSTNAME); + const bool is_onion = (*type_out == ONION_V3_HOSTNAME); log_warn(LD_APP, "Invalid %shostname %s; rejecting", is_onion ? "onion " : "", safe_str_client(address)); diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index 0456d709f5..b4d7228b51 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -1443,10 +1443,8 @@ handle_control_hsfetch(control_connection_t *conn, const control_cmd_args_t *args) { - char digest[DIGEST_LEN], *desc_id = NULL; + char *desc_id = NULL; smartlist_t *hsdirs = NULL; - static const char *v2_str = "v2-"; - const size_t v2_str_len = strlen(v2_str); rend_data_t *rend_query = NULL; ed25519_public_key_t v3_pk; uint32_t version; @@ -1454,20 +1452,7 @@ handle_control_hsfetch(control_connection_t *conn, /* Extract the first argument (either HSAddress or DescID). */ const char *arg1 = smartlist_get(args->args, 0); - /* Test if it's an HS address without the .onion part. */ - if (rend_valid_v2_service_id(arg1)) { - hsaddress = arg1; - version = HS_VERSION_TWO; - } else if (strcmpstart(arg1, v2_str) == 0 && - rend_valid_descriptor_id(arg1 + v2_str_len) && - base32_decode(digest, sizeof(digest), arg1 + v2_str_len, - REND_DESC_ID_V2_LEN_BASE32) == - sizeof(digest)) { - /* We have a well formed version 2 descriptor ID. Keep the decoded value - * of the id. */ - desc_id = digest; - version = HS_VERSION_TWO; - } else if (hs_address_is_valid(arg1)) { + if (hs_address_is_valid(arg1)) { hsaddress = arg1; version = HS_VERSION_THREE; hs_parse_address(hsaddress, &v3_pk, NULL, NULL); @@ -1590,6 +1575,11 @@ handle_control_hspost(control_connection_t *conn, goto done; } + /* As for HSFETCH, we no longer support v2 on the network and so we stop + * right now. Code is not removed in order to minimize the merge forward + * conflicts. */ + goto done; + /* From this point on, it is only v2. */ /* parse it. */ @@ -1662,11 +1652,13 @@ add_onion_helper_add_service(int hs_version, tor_assert(port_cfgs); tor_assert(address_out); + /* Version 2 is disabled. */ + (void) auth_type; + (void) auth_clients; + switch (hs_version) { case HS_VERSION_TWO: - ret = rend_service_add_ephemeral(pk->v2, port_cfgs, max_streams, - max_streams_close_circuit, auth_type, - auth_clients, address_out); + ret = RSAE_INTERNAL; break; case HS_VERSION_THREE: ret = hs_service_add_ephemeral(pk->v3, port_cfgs, max_streams, diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index 84bb7c220c..2af550a760 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -356,8 +356,6 @@ static int handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args); static int handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args); -static int handle_get_hs_descriptor_v2(dir_connection_t *conn, - const get_handler_args_t *args); static int handle_get_robots(dir_connection_t *conn, const get_handler_args_t *args); static int handle_get_networkstatus_bridges(dir_connection_t *conn, @@ -376,7 +374,6 @@ static const url_table_ent_t url_table[] = { { "/tor/server/", 1, handle_get_descriptor }, { "/tor/extra/", 1, handle_get_descriptor }, { "/tor/keys/", 1, handle_get_keys }, - { "/tor/rendezvous2/", 1, handle_get_hs_descriptor_v2 }, { "/tor/hs/3/", 1, handle_get_hs_descriptor_v3 }, { "/tor/robots.txt", 0, handle_get_robots }, { "/tor/networkstatus-bridges", 0, handle_get_networkstatus_bridges }, @@ -1350,45 +1347,7 @@ handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args) return 0; } -/** Helper function for GET /tor/rendezvous2/ - */ -static int -handle_get_hs_descriptor_v2(dir_connection_t *conn, - const get_handler_args_t *args) -{ - const char *url = args->url; - if (connection_dir_is_encrypted(conn)) { - /* Handle v2 rendezvous descriptor fetch request. */ - const char *descp; - const char *query = url + strlen("/tor/rendezvous2/"); - if (rend_valid_descriptor_id(query)) { - log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'", - safe_str(escaped(query))); - switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) { - case 1: /* valid */ - write_http_response_header(conn, strlen(descp), NO_METHOD, 0); - connection_buf_add(descp, strlen(descp), TO_CONN(conn)); - break; - case 0: /* well-formed but not present */ - write_short_http_response(conn, 404, "Not found"); - break; - case -1: /* not well-formed */ - write_short_http_response(conn, 400, "Bad request"); - break; - } - } else { /* not well-formed */ - write_short_http_response(conn, 400, "Bad request"); - } - goto done; - } else { - /* Not encrypted! */ - write_short_http_response(conn, 404, "Not found"); - } - done: - return 0; -} - -/** Helper function for GET `/tor/hs/3/...`. Only for version 3. +/** Helper function for GET /tor/hs/3/... Only for version 3. */ STATIC int handle_get_hs_descriptor_v3(dir_connection_t *conn, @@ -1611,6 +1570,8 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, char *url = NULL; const or_options_t *options = get_options(); + (void) body_len; + log_debug(LD_DIRSERV,"Received POST command."); conn->base_.state = DIR_CONN_STATE_SERVER_WRITING; @@ -1629,22 +1590,6 @@ directory_handle_command_post,(dir_connection_t *conn, const char *headers, } log_debug(LD_DIRSERV,"rewritten url as '%s'.", escaped(url)); - /* Handle v2 rendezvous service publish request. */ - if (connection_dir_is_encrypted(conn) && - !strcmpstart(url,"/tor/rendezvous2/publish")) { - if (rend_cache_store_v2_desc_as_dir(body) < 0) { - log_warn(LD_REND, "Rejected v2 rend descriptor (body size %d) from %s.", - (int)body_len, - connection_describe_peer(TO_CONN(conn))); - write_short_http_response(conn, 400, - "Invalid v2 service descriptor rejected"); - } else { - write_short_http_response(conn, 200, "Service descriptor (v2) stored"); - log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted"); - } - goto done; - } - /* Handle HS descriptor publish request. We force an anonymous connection * (which also tests for encrypted). We do not allow single-hop client to * post a descriptor onto an HSDir. */ diff --git a/src/feature/hs/hs_common.h b/src/feature/hs/hs_common.h index 4a9c7a9918..274017180a 100644 --- a/src/feature/hs/hs_common.h +++ b/src/feature/hs/hs_common.h @@ -25,7 +25,7 @@ struct ed25519_keypair_t; /** Version 3 of the protocol (prop224). */ #define HS_VERSION_THREE 3 /** Earliest version we support. */ -#define HS_VERSION_MIN HS_VERSION_TWO +#define HS_VERSION_MIN HS_VERSION_THREE /** Latest version we support. */ #define HS_VERSION_MAX HS_VERSION_THREE diff --git a/src/feature/hs/hs_config.c b/src/feature/hs/hs_config.c index 7ffc7ecb96..f8d71674de 100644 --- a/src/feature/hs/hs_config.c +++ b/src/feature/hs/hs_config.c @@ -179,8 +179,12 @@ static bool check_value_oob(int i, const char *name, int low, int high) { if (i < low || i > high) { - log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.", - name, low, high, i); + if (low == high) { + log_warn(LD_CONFIG, "%s must be %d, not %d.", name, low, i); + } else { + log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.", + name, low, high, i); + } return true; } return false; diff --git a/src/feature/hs/hs_intropoint.c b/src/feature/hs/hs_intropoint.c index 69d60f21c3..fa6b54b18a 100644 --- a/src/feature/hs/hs_intropoint.c +++ b/src/feature/hs/hs_intropoint.c @@ -514,7 +514,8 @@ hs_intro_received_establish_intro(or_circuit_t *circ, const uint8_t *request, switch (first_byte) { case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY0: case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_LEGACY1: - return rend_mid_establish_intro_legacy(circ, request, request_len); + /* Don't accept version 2 introduction anymore. */ + goto err; case TRUNNEL_HS_INTRO_AUTH_KEY_TYPE_ED25519: return handle_establish_intro(circ, request, request_len); default: diff --git a/src/test/include.am b/src/test/include.am index cdf3b20c48..ba802e7b04 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -74,22 +74,21 @@ TESTS += src/test/test-slow src/test/test-memwipe \ # run a quick test or two # this test only uses IPv4 -TEST_CHUTNEY_FLAVOR_QUICK = bridges+hs-v23 +TEST_CHUTNEY_FLAVOR_QUICK = bridges+hs-v3 # only run if we can ping6 ::1 (localhost) -TEST_CHUTNEY_FLAVOR_QUICK_IPV6 = single-onion-v23-ipv6-md +TEST_CHUTNEY_FLAVOR_QUICK_IPV6 = single-onion-v3-ipv6-md # run a basic set of tests, which only use IPv4 -TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v23-min single-onion-v23 +TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v3-min single-onion-v3 # only run if we can ping ::1 (localhost) -TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v23-ipv6-md \ - single-onion-v23-ipv6-md +TEST_CHUTNEY_FLAVORS_IPV6 = bridges+ipv6-min ipv6-exit-min hs-v3-ipv6 single-onion-v3-ipv6-md # only run if we can find a stable (or simply another) version of tor -TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v23 +TEST_CHUTNEY_FLAVORS_MIXED = mixed+hs-v3 # only run if IPv6 and mixed networks are run -TEST_CHUTNEY_FLAVORS_IPV6_MIXED = mixed+hs-v23-ipv6 +TEST_CHUTNEY_FLAVORS_IPV6_MIXED = mixed+hs-v3-ipv6 ### This is a lovely feature, but it requires automake >= 1.12, and Tor ### doesn't require that yet. diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c index 28f07efbe8..95339160c3 100644 --- a/src/test/test_dir_handle_get.c +++ b/src/test/test_dir_handle_get.c @@ -309,7 +309,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_with_invalid_desc_id( fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, NULL, NULL, 1, 0); - tt_str_op(header, OP_EQ, BAD_REQUEST); + tt_str_op(header, OP_EQ, NOT_FOUND); done: UNMOCK(connection_write_to_buf_impl_); @@ -342,7 +342,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_not_well_formed(void *data) fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, NULL, NULL, 1, 0); - tt_str_op(header, OP_EQ, BAD_REQUEST); + tt_str_op(header, OP_EQ, NOT_FOUND); done: UNMOCK(connection_write_to_buf_impl_); @@ -395,76 +395,6 @@ dhg_tests_router_get_my_routerinfo(void) return mock_routerinfo; } -static void -test_dir_handle_get_rendezvous2_on_encrypted_conn_success(void *data) -{ - dir_connection_t *conn = NULL; - char *header = NULL; - char *body = NULL; - size_t body_used = 0; - char buff[30]; - char req[70]; - rend_encoded_v2_service_descriptor_t *desc_holder = NULL; - char *service_id = NULL; - char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1]; - size_t body_len = 0; - (void) data; - - MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock); - MOCK(router_get_my_routerinfo, - dhg_tests_router_get_my_routerinfo); - - rend_cache_init(); - - /* create a valid rend service descriptor */ - #define RECENT_TIME -10 - generate_desc(RECENT_TIME, &desc_holder, &service_id, 3); - - tt_int_op(rend_cache_store_v2_desc_as_dir(desc_holder->desc_str), - OP_EQ, 0); - - base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_holder->desc_id, - DIGEST_LEN); - - conn = new_dir_conn(); - - // connection is encrypted - TO_CONN(conn)->linked = 1; - tt_assert(connection_dir_is_encrypted(conn)); - - tor_snprintf(req, sizeof(req), RENDEZVOUS2_GET("%s"), desc_id_base32); - - tt_int_op(directory_handle_command_get(conn, req, NULL, 0), OP_EQ, 0); - - body_len = strlen(desc_holder->desc_str); - fetch_from_buf_http(TO_CONN(conn)->outbuf, &header, MAX_HEADERS_SIZE, - &body, &body_used, body_len+1, 0); - - tt_assert(header); - tt_assert(body); - - tt_ptr_op(strstr(header, "HTTP/1.0 200 OK\r\n"), OP_EQ, header); - tt_assert(strstr(header, "Content-Type: text/plain\r\n")); - tt_assert(strstr(header, "Content-Encoding: identity\r\n")); - tt_assert(strstr(header, "Pragma: no-cache\r\n")); - tor_snprintf(buff, sizeof(buff), "Content-Length: %ld\r\n", (long) body_len); - tt_assert(strstr(header, buff)); - - tt_int_op(body_used, OP_EQ, strlen(body)); - tt_str_op(body, OP_EQ, desc_holder->desc_str); - - done: - UNMOCK(connection_write_to_buf_impl_); - UNMOCK(router_get_my_routerinfo); - - connection_free_minimal(TO_CONN(conn)); - tor_free(header); - tor_free(body); - rend_encoded_v2_service_descriptor_free(desc_holder); - tor_free(service_id); - rend_cache_free_all(); -} - #define MICRODESC_GET(digest) GET("/tor/micro/d/" digest) static void test_dir_handle_get_micro_d_not_found(void *data) @@ -2938,7 +2868,6 @@ struct testcase_t dir_handle_get_tests[] = { DIR_HANDLE_CMD(rendezvous2_not_found, 0), DIR_HANDLE_CMD(rendezvous2_on_encrypted_conn_with_invalid_desc_id, 0), DIR_HANDLE_CMD(rendezvous2_on_encrypted_conn_not_well_formed, 0), - DIR_HANDLE_CMD(rendezvous2_on_encrypted_conn_success, 0), DIR_HANDLE_CMD(micro_d_not_found, 0), DIR_HANDLE_CMD(micro_d_server_busy, 0), DIR_HANDLE_CMD(micro_d, 0), diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index 9cdd7f6d0e..75018260f7 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -728,46 +728,6 @@ test_entryconn_rewrite_mapaddress_automap_onion4(void *arg) test_entryconn_rewrite_mapaddress_automap_onion_common(arg, 0, 1); } -/** Test that rewrite functions can handle v2 addresses */ -static void -test_entryconn_rewrite_onion_v2(void *arg) -{ - int retval; - entry_connection_t *conn = arg; - - (void) arg; - - rend_cache_init(); - - /* Make a SOCKS request */ - conn->socks_request->command = SOCKS_COMMAND_CONNECT; - strlcpy(conn->socks_request->address, - "pqeed46efnwmfuid.onion", - sizeof(conn->socks_request->address)); - - /* Make an onion connection using the SOCKS request */ - conn->entry_cfg.onion_traffic = 1; - ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_SOCKS_WAIT; - tt_assert(!ENTRY_TO_EDGE_CONN(conn)->rend_data); - - /* Handle SOCKS and rewrite! */ - retval = connection_ap_handshake_rewrite_and_attach(conn, NULL, NULL); - tt_int_op(retval, OP_EQ, 0); - - /* Check connection state after rewrite */ - tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT); - /* check that the address got rewritten */ - tt_str_op(conn->socks_request->address, OP_EQ, - "pqeed46efnwmfuid"); - /* check that HS information got attached to the connection */ - tt_assert(ENTRY_TO_EDGE_CONN(conn)->rend_data); - tt_assert(!ENTRY_TO_EDGE_CONN(conn)->hs_ident); - - done: - rend_cache_free_all(); - /* 'conn' is cleaned by handler */ -} - /** Test that rewrite functions can handle v3 onion addresses */ static void test_entryconn_rewrite_onion_v3(void *arg) @@ -830,7 +790,6 @@ struct testcase_t entryconn_tests[] = { REWRITE(rewrite_mapaddress_automap_onion2), REWRITE(rewrite_mapaddress_automap_onion3), REWRITE(rewrite_mapaddress_automap_onion4), - REWRITE(rewrite_onion_v2), REWRITE(rewrite_onion_v3), END_OF_TESTCASES diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c index 5032a82b9c..fccf638a07 100644 --- a/src/test/test_hs_common.c +++ b/src/test/test_hs_common.c @@ -803,9 +803,8 @@ test_parse_extended_hostname(void *arg) tt_assert(!parse_extended_hostname(address1, &type)); tt_int_op(type, OP_EQ, BAD_HOSTNAME); - tt_assert(parse_extended_hostname(address2, &type)); - tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME); - tt_str_op(address2, OP_EQ, "aaaaaaaaaaaaaaaa"); + tt_assert(!parse_extended_hostname(address2, &type)); + tt_int_op(type, OP_EQ, BAD_HOSTNAME); tt_assert(parse_extended_hostname(address3, &type)); tt_int_op(type, OP_EQ, EXIT_HOSTNAME); @@ -813,13 +812,11 @@ test_parse_extended_hostname(void *arg) tt_assert(parse_extended_hostname(address4, &type)); tt_int_op(type, OP_EQ, NORMAL_HOSTNAME); - tt_assert(parse_extended_hostname(address5, &type)); - tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME); - tt_str_op(address5, OP_EQ, "abcdefghijklmnop"); + tt_assert(!parse_extended_hostname(address5, &type)); + tt_int_op(type, OP_EQ, BAD_HOSTNAME); - tt_assert(parse_extended_hostname(address6, &type)); - tt_int_op(type, OP_EQ, ONION_V2_HOSTNAME); - tt_str_op(address6, OP_EQ, "abcdefghijklmnop"); + tt_assert(!parse_extended_hostname(address6, &type)); + tt_int_op(type, OP_EQ, BAD_HOSTNAME); tt_assert(!parse_extended_hostname(address7, &type)); tt_int_op(type, OP_EQ, BAD_HOSTNAME); diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c index dc3b598c34..20e6b014ee 100644 --- a/src/test/test_hs_config.c +++ b/src/test/test_hs_config.c @@ -49,7 +49,19 @@ test_invalid_service(void *arg) setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("HiddenServiceVersion must be between 2 and 3"); + expect_log_msg_containing("HiddenServiceVersion must be 3, not 1"); + teardown_capture_of_logs(); + } + + /* Version 2 not accepted anymore. */ + { + const char *conf = + "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" + "HiddenServiceVersion 2\n"; + setup_full_capture_of_logs(LOG_WARN); + ret = helper_config_service(conf, 1); + tt_int_op(ret, OP_EQ, -1); + expect_log_msg_containing("HiddenServiceVersion must be 3, not 2"); teardown_capture_of_logs(); } @@ -57,7 +69,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServiceAllowUnknownPorts 2\n"; /* Should be 0 or 1. */ setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -72,7 +84,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServiceDirGroupReadable 2\n"; /* Should be 0 or 1. */ setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -87,7 +99,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServiceMaxStreamsCloseCircuit 2\n"; /* Should be 0 or 1. */ setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -102,7 +114,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServicePort 80\n" "HiddenServiceMaxStreams 65536\n"; /* One too many. */ setup_full_capture_of_logs(LOG_WARN); @@ -117,10 +129,10 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServicePort 80\n" "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServicePort 81\n"; setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -134,7 +146,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServicePort 65536\n"; setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -147,7 +159,7 @@ test_invalid_service(void *arg) { const char *conf = "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServicePort 80 127.0.0.1 8000\n"; setup_full_capture_of_logs(LOG_WARN); ret = helper_config_service(conf, 1); @@ -160,7 +172,7 @@ test_invalid_service(void *arg) /* Out of order directives. */ { const char *conf = - "HiddenServiceVersion 2\n" + "HiddenServiceVersion 3\n" "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" "HiddenServicePort 80\n"; setup_full_capture_of_logs(LOG_WARN); @@ -182,18 +194,12 @@ test_valid_service(void *arg) (void) arg; - /* Mix of v2 and v3. Still valid. */ + /* v3. */ { const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n" "HiddenServiceVersion 3\n" - "HiddenServicePort 81\n" - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 82\n"; + "HiddenServicePort 81\n"; ret = helper_config_service(conf, 1); tt_int_op(ret, OP_EQ, 0); } @@ -203,127 +209,6 @@ test_valid_service(void *arg) } static void -test_invalid_service_v2(void *arg) -{ - int validate_only = 1, ret; - - (void) arg; - - /* Try with a missing port configuration. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n"; - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, validate_only); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("with no ports configured."); - teardown_capture_of_logs(); - } - - /* Too many introduction points. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" - "HiddenServiceNumIntroductionPoints 11\n"; /* One too many. */ - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, validate_only); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("HiddenServiceNumIntroductionPoints must " - "be between 0 and 10, not 11."); - teardown_capture_of_logs(); - } - - /* Too little introduction points. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" - "HiddenServiceNumIntroductionPoints -1\n"; - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, validate_only); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("Could not parse " - "HiddenServiceNumIntroductionPoints: " - "Integer -1 is malformed or out of bounds."); - teardown_capture_of_logs(); - } - - /* Bad authorized client type. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" - "HiddenServiceAuthorizeClient blah alice,bob\n"; /* blah is no good. */ - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, validate_only); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("HiddenServiceAuthorizeClient contains " - "unrecognized auth-type"); - teardown_capture_of_logs(); - } - - done: - ; -} - -static void -test_valid_service_v2(void *arg) -{ - int ret; - - (void) arg; - mock_hostname_resolver(); - - /* Valid complex configuration. Basic client authorization. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" - "HiddenServicePort 22 localhost:22\n" -#ifdef HAVE_SYS_UN_H - "HiddenServicePort 42 unix:/path/to/socket\n" -#endif - "HiddenServiceAuthorizeClient basic alice,bob,eve\n" - "HiddenServiceAllowUnknownPorts 1\n" - "HiddenServiceMaxStreams 42\n" - "HiddenServiceMaxStreamsCloseCircuit 0\n" - "HiddenServiceDirGroupReadable 1\n" - "HiddenServiceNumIntroductionPoints 7\n"; - ret = helper_config_service(conf, 1); - tt_int_op(ret, OP_EQ, 0); - } - - /* Valid complex configuration. Stealth client authorization. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 65535\n" - "HiddenServicePort 22 1.1.1.1:22\n" -#ifdef HAVE_SYS_UN_H - "HiddenServicePort 9000 unix:/path/to/socket\n" -#endif - "HiddenServiceAuthorizeClient stealth charlie,romeo\n" - "HiddenServiceAllowUnknownPorts 0\n" - "HiddenServiceMaxStreams 42\n" - "HiddenServiceMaxStreamsCloseCircuit 0\n" - "HiddenServiceDirGroupReadable 1\n" - "HiddenServiceNumIntroductionPoints 8\n"; - ret = helper_config_service(conf, 1); - tt_int_op(ret, OP_EQ, 0); - } - - done: - unmock_hostname_resolver(); -} - -static void test_invalid_service_v3(void *arg) { int validate_only = 1, ret; @@ -372,22 +257,6 @@ test_invalid_service_v3(void *arg) teardown_capture_of_logs(); } - /* v2-specific HiddenServiceAuthorizeClient set. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 3\n" - "HiddenServiceAuthorizeClient stealth client1\n"; - setup_full_capture_of_logs(LOG_WARN); - ret = helper_config_service(conf, validate_only); - tt_int_op(ret, OP_EQ, -1); - expect_log_msg_containing("Hidden service option " - "HiddenServiceAuthorizeClient is incompatible " - "with version 3 of service in " - "/tmp/tor-test-hs-RANDOM/hs1"); - teardown_capture_of_logs(); - } - done: ; } @@ -438,22 +307,6 @@ test_valid_service_v3(void *arg) tt_int_op(ret, OP_EQ, 0); } - /* Mix of v2 and v3. Still valid. */ - { - const char *conf = - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 80\n" - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs2\n" - "HiddenServiceVersion 3\n" - "HiddenServicePort 81\n" - "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs3\n" - "HiddenServiceVersion 2\n" - "HiddenServicePort 82\n"; - ret = helper_config_service(conf, 1); - tt_int_op(ret, OP_EQ, 0); - } - done: unmock_hostname_resolver(); } @@ -611,12 +464,6 @@ struct testcase_t hs_config_tests[] = { { "valid_service", test_valid_service, TT_FORK, NULL, NULL }, - /* Test case only for version 2. */ - { "invalid_service_v2", test_invalid_service_v2, TT_FORK, - NULL, NULL }, - { "valid_service_v2", test_valid_service_v2, TT_FORK, - NULL, NULL }, - /* Test case only for version 3. */ { "invalid_service_v3", test_invalid_service_v3, TT_FORK, NULL, NULL }, diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c index e6b27d7a50..5f7dfc4f84 100644 --- a/src/test/test_hs_intropoint.c +++ b/src/test/test_hs_intropoint.c @@ -517,42 +517,6 @@ helper_establish_intro_v3(or_circuit_t *intro_circ) return cell; } -/* Helper function: Send a well-formed v2 ESTABLISH_INTRO cell to - * <b>intro_circ</b>. Return the public key advertised in the cell. */ -static crypto_pk_t * -helper_establish_intro_v2(or_circuit_t *intro_circ) -{ - crypto_pk_t *key1 = NULL; - int retval; - uint8_t cell_body[RELAY_PAYLOAD_SIZE]; - ssize_t cell_len = 0; - char circ_nonce[DIGEST_LEN] = {0}; - - tt_assert(intro_circ); - - /* Prepare the circuit for the incoming ESTABLISH_INTRO */ - crypto_rand(circ_nonce, sizeof(circ_nonce)); - helper_prepare_circ_for_intro(intro_circ, circ_nonce); - - /* Send legacy establish_intro */ - key1 = pk_generate(0); - - /* Use old circ_nonce why not */ - cell_len = rend_service_encode_establish_intro_cell( - (char*)cell_body, - sizeof(cell_body), key1, - circ_nonce); - tt_int_op(cell_len, OP_GT, 0); - - /* Receive legacy establish_intro */ - retval = hs_intro_received_establish_intro(intro_circ, - cell_body, (size_t) cell_len); - tt_int_op(retval, OP_EQ, 0); - - done: - return key1; -} - /* Helper function: test circuitmap free_all function outside of * test_intro_point_registration to prevent Coverity from seeing a * double free if the assertion hypothetically fails. @@ -576,16 +540,12 @@ test_circuitmap_free_all(void) static void test_intro_point_registration(void *arg) { - int retval; hs_circuitmap_ht *the_hs_circuitmap = NULL; or_circuit_t *intro_circ = NULL; trn_cell_establish_intro_t *establish_intro_cell = NULL; ed25519_public_key_t auth_key; - crypto_pk_t *legacy_auth_key = NULL; - or_circuit_t *legacy_intro_circ = NULL; - or_circuit_t *returned_intro_circ = NULL; (void) arg; @@ -621,35 +581,11 @@ test_intro_point_registration(void *arg) tt_ptr_op(intro_circ, OP_EQ, returned_intro_circ); } - /* Create a v2 intro point */ - { - char key_digest[DIGEST_LEN]; - - legacy_intro_circ = or_circuit_new(1, NULL); - tt_assert(legacy_intro_circ); - legacy_auth_key = helper_establish_intro_v2(legacy_intro_circ); - tt_assert(legacy_auth_key); - - /* Check that the circuitmap now has two elements */ - the_hs_circuitmap = get_hs_circuitmap(); - tt_assert(the_hs_circuitmap); - tt_int_op(2, OP_EQ, HT_SIZE(the_hs_circuitmap)); - - /* Check that the new element is our legacy intro circuit. */ - retval = crypto_pk_get_digest(legacy_auth_key, key_digest); - tt_int_op(retval, OP_EQ, 0); - returned_intro_circ = - hs_circuitmap_get_intro_circ_v2_relay_side((uint8_t*)key_digest); - tt_ptr_op(legacy_intro_circ, OP_EQ, returned_intro_circ); - } - /* XXX Continue test and try to register a second v3 intro point with the * same auth key. Make sure that old intro circuit gets closed. */ done: - crypto_pk_free(legacy_auth_key); circuit_free_(TO_CIRCUIT(intro_circ)); - circuit_free_(TO_CIRCUIT(legacy_intro_circ)); trn_cell_establish_intro_free(establish_intro_cell); test_circuitmap_free_all(); diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c index 66e8e2f473..287d25f825 100644 --- a/src/test/test_hs_service.c +++ b/src/test/test_hs_service.c @@ -403,10 +403,7 @@ test_load_keys(void *arg) tor_asprintf(&conf, conf_fmt, hsdir_v2, HS_VERSION_TWO); ret = helper_config_service(conf); tor_free(conf); - tt_int_op(ret, OP_EQ, 0); - /* This one should now be registered into the v2 list. */ - tt_int_op(get_hs_service_staging_list_size(), OP_EQ, 0); - tt_int_op(rend_num_services(), OP_EQ, 1); + tt_int_op(ret, OP_EQ, -1); /* v3 service. */ tor_asprintf(&conf, conf_fmt, hsdir_v3, HS_VERSION_THREE); |