diff options
author | David Goulet <dgoulet@torproject.org> | 2021-02-05 12:51:41 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2021-02-19 13:20:48 -0500 |
commit | 2c865542b6d2e78d2c2942ecdc6acfe1d8fb24bf (patch) | |
tree | e6be7f15e83a498dc6209f1895366379e3af4273 /src/feature/control/control_cmd.c | |
parent | a34885bc8035eb29524749582c16ce4ec8fbc715 (diff) | |
download | tor-2c865542b6d2e78d2c2942ecdc6acfe1d8fb24bf.tar.gz tor-2c865542b6d2e78d2c2942ecdc6acfe1d8fb24bf.zip |
hs-v2: Removal of service and relay support
This is unfortunately massive but both functionalities were extremely
intertwined and it would have required us to actually change the HSv2 code in
order to be able to split this into multiple commits.
After this commit, there are still artefacts of v2 in the code but there is no
more support for service, intro point and HSDir.
The v2 support for rendezvous circuit is still available since that code is
the same for the v3 and we will leave it in so if a client is able to
rendezvous on v2 then it can still transfer traffic. Once the entire network
has moved away from v2, we can remove v2 rendezvous point support.
Related to #40266
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/feature/control/control_cmd.c')
-rw-r--r-- | src/feature/control/control_cmd.c | 306 |
1 files changed, 20 insertions, 286 deletions
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index e88f17de09..009105bb20 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -38,8 +38,6 @@ #include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/rend/rendcommon.h" -#include "feature/rend/rendparse.h" -#include "feature/rend/rendservice.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" #include "lib/encoding/confline.h" @@ -53,9 +51,6 @@ #include "feature/control/control_connection_st.h" #include "feature/nodelist/node_st.h" #include "feature/nodelist/routerinfo_st.h" -#include "feature/rend/rend_authorized_client_st.h" -#include "feature/rend/rend_encoded_v2_service_descriptor_st.h" -#include "feature/rend/rend_service_descriptor_st.h" #include "src/app/config/statefile.h" @@ -1442,31 +1437,15 @@ 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; const char *hsaddress = NULL; /* 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); @@ -1495,15 +1474,6 @@ handle_control_hsfetch(control_connection_t *conn, } } - if (version == HS_VERSION_TWO) { - rend_query = rend_data_client_create(hsaddress, desc_id, NULL, - REND_NO_AUTH); - if (rend_query == NULL) { - control_write_endreply(conn, 551, "Error creating the HS query"); - goto done; - } - } - /* Using a descriptor ID, we force the user to provide at least one * hsdir server using the SERVER= option. */ if (desc_id && (!hsdirs || !smartlist_len(hsdirs))) { @@ -1526,7 +1496,6 @@ handle_control_hsfetch(control_connection_t *conn, done: /* Contains data pointer that we don't own thus no cleanup. */ smartlist_free(hsdirs); - rend_data_free(rend_query); return 0; } @@ -1547,7 +1516,6 @@ handle_control_hspost(control_connection_t *conn, { smartlist_t *hs_dirs = NULL; const char *encoded_desc = args->cmddata; - size_t encoded_desc_len = args->cmddata_len; const char *onion_address = NULL; const config_line_t *line; @@ -1587,44 +1555,6 @@ handle_control_hspost(control_connection_t *conn, goto done; } - /* From this point on, it is only v2. */ - - /* parse it. */ - rend_encoded_v2_service_descriptor_t *desc = - tor_malloc_zero(sizeof(rend_encoded_v2_service_descriptor_t)); - desc->desc_str = tor_memdup_nulterm(encoded_desc, encoded_desc_len); - - rend_service_descriptor_t *parsed = NULL; - char *intro_content = NULL; - size_t intro_size; - size_t encoded_size; - const char *next_desc; - if (!rend_parse_v2_service_descriptor(&parsed, desc->desc_id, &intro_content, - &intro_size, &encoded_size, - &next_desc, desc->desc_str, 1)) { - /* Post the descriptor. */ - char serviceid[REND_SERVICE_ID_LEN_BASE32+1]; - if (!rend_get_service_id(parsed->pk, serviceid)) { - smartlist_t *descs = smartlist_new(); - smartlist_add(descs, desc); - - /* We are about to trigger HS descriptor upload so send the OK now - * because after that 650 event(s) are possible so better to have the - * 250 OK before them to avoid out of order replies. */ - send_control_done(conn); - - /* Trigger the descriptor upload */ - directory_post_to_hs_dir(parsed, descs, hs_dirs, serviceid, 0); - smartlist_free(descs); - } - - rend_service_descriptor_free(parsed); - } else { - control_write_endreply(conn, 554, "Invalid descriptor"); - } - - tor_free(intro_content); - rend_encoded_v2_service_descriptor_free(desc); done: smartlist_free(hs_dirs); /* Contents belong to the rend service code. */ return 0; @@ -1640,7 +1570,6 @@ handle_control_hspost(control_connection_t *conn, * The port_cfgs is a list of service port. Ownership transferred to service. * The max_streams refers to the MaxStreams= key. * The max_streams_close_circuit refers to the MaxStreamsCloseCircuit key. - * The auth_type is the authentication type of the clients in auth_clients. * The ownership of that list is transferred to the service. * * On success (RSAE_OKAY), the address_out points to a newly allocated string @@ -1650,8 +1579,7 @@ STATIC hs_service_add_ephemeral_status_t add_onion_helper_add_service(int hs_version, add_onion_secret_key_t *pk, smartlist_t *port_cfgs, int max_streams, - int max_streams_close_circuit, int auth_type, - smartlist_t *auth_clients, + int max_streams_close_circuit, smartlist_t *auth_clients_v3, char **address_out) { hs_service_add_ephemeral_status_t ret; @@ -1661,11 +1589,6 @@ add_onion_helper_add_service(int hs_version, tor_assert(address_out); 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); - break; case HS_VERSION_THREE: ret = hs_service_add_ephemeral(pk->v3, port_cfgs, max_streams, max_streams_close_circuit, @@ -1711,16 +1634,14 @@ handle_control_add_onion(control_connection_t *conn, * material first, since there's no reason to touch that at all if any of * the other arguments are malformed. */ + rend_auth_type_t auth_type = REND_NO_AUTH; smartlist_t *port_cfgs = smartlist_new(); - smartlist_t *auth_clients = NULL; - smartlist_t *auth_created_clients = NULL; smartlist_t *auth_clients_v3 = NULL; smartlist_t *auth_clients_v3_str = NULL; int discard_pk = 0; int detach = 0; int max_streams = 0; int max_streams_close_circuit = 0; - rend_auth_type_t auth_type = REND_NO_AUTH; int non_anonymous = 0; const config_line_t *arg; @@ -1758,7 +1679,6 @@ handle_control_add_onion(control_connection_t *conn, static const char *discard_flag = "DiscardPK"; static const char *detach_flag = "Detach"; static const char *max_s_close_flag = "MaxStreamsCloseCircuit"; - static const char *basicauth_flag = "BasicAuth"; static const char *v3auth_flag = "V3Auth"; static const char *non_anonymous_flag = "NonAnonymous"; @@ -1778,8 +1698,6 @@ handle_control_add_onion(control_connection_t *conn, detach = 1; } else if (!strcasecmp(flag, max_s_close_flag)) { max_streams_close_circuit = 1; - } else if (!strcasecmp(flag, basicauth_flag)) { - auth_type = REND_BASIC_AUTH; } else if (!strcasecmp(flag, v3auth_flag)) { auth_type = REND_V3_AUTH; } else if (!strcasecmp(flag, non_anonymous_flag)) { @@ -1795,36 +1713,6 @@ handle_control_add_onion(control_connection_t *conn, smartlist_free(flags); if (bad) goto out; - - } else if (!strcasecmp(arg->key, "ClientAuth")) { - int created = 0; - rend_authorized_client_t *client = - add_onion_helper_clientauth(arg->value, &created, conn); - if (!client) { - goto out; - } - - if (auth_clients != NULL) { - int bad = 0; - SMARTLIST_FOREACH_BEGIN(auth_clients, rend_authorized_client_t *, ac) { - if (strcmp(ac->client_name, client->client_name) == 0) { - bad = 1; - break; - } - } SMARTLIST_FOREACH_END(ac); - if (bad) { - control_write_endreply(conn, 512, "Duplicate name in ClientAuth"); - rend_authorized_client_free(client); - goto out; - } - } else { - auth_clients = smartlist_new(); - auth_created_clients = smartlist_new(); - } - smartlist_add(auth_clients, client); - if (created) { - smartlist_add(auth_created_clients, client); - } } else if (!strcasecmp(arg->key, "ClientAuthV3")) { hs_service_authorized_client_t *client_v3 = parse_authorized_client_key(arg->value, LOG_INFO); @@ -1848,31 +1736,14 @@ handle_control_add_onion(control_connection_t *conn, if (smartlist_len(port_cfgs) == 0) { control_write_endreply(conn, 512, "Missing 'Port' argument"); goto out; - } else if (auth_type == REND_NO_AUTH && - (auth_clients != NULL && auth_clients_v3 != NULL)) { + } else if (auth_type == REND_NO_AUTH && auth_clients_v3 != NULL) { control_write_endreply(conn, 512, "No auth type specified"); goto out; - } else if (auth_type != REND_NO_AUTH && - (auth_clients == NULL && auth_clients_v3 == NULL)) { + } else if (auth_type != REND_NO_AUTH && auth_clients_v3 == NULL) { control_write_endreply(conn, 512, "No auth clients specified"); goto out; - } else if ((auth_type == REND_BASIC_AUTH && - smartlist_len(auth_clients) > 512) || - (auth_type == REND_STEALTH_AUTH && - smartlist_len(auth_clients) > 16)) { - control_write_endreply(conn, 512, "Too many auth clients"); - goto out; - } else if ((auth_type == REND_BASIC_AUTH || - auth_type == REND_STEALTH_AUTH) && auth_clients_v3) { - control_write_endreply(conn, 512, - "ClientAuthV3 does not support basic or stealth auth"); - goto out; - } else if (auth_type == REND_V3_AUTH && auth_clients) { - control_write_endreply(conn, 512, "ClientAuth does not support v3 auth"); - goto out; - - } else if (non_anonymous != rend_service_non_anonymous_mode_enabled( - get_options())) { + } else if (non_anonymous != hs_service_non_anonymous_mode_enabled( + get_options())) { /* If we failed, and the non-anonymous flag is set, Tor must be in * anonymous hidden service mode. * The error message changes based on the current Tor config: @@ -1899,29 +1770,15 @@ handle_control_add_onion(control_connection_t *conn, goto out; } - /* We can't mix ClientAuth and Version 3 Onion Services, or ClientAuthV3 and - * Version 2. If that's the case, send back an error. */ - if (hs_version == HS_VERSION_THREE && auth_clients) { - control_write_endreply(conn, 513, "ClientAuth not supported"); - goto out; - } - if (hs_version == HS_VERSION_TWO && auth_clients_v3) { - control_write_endreply(conn, 513, "ClientAuthV3 not supported"); - goto out; - } - - /* Create the HS, using private key pk, client authentication auth_type, - * the list of auth_clients, and port config port_cfg. - * rend_service_add_ephemeral() will take ownership of pk and port_cfg, - * regardless of success/failure. - */ + /* Create the HS, using private key pk and port config port_cfg. + * hs_service_add_ephemeral() will take ownership of pk and port_cfg, + * regardless of success/failure. */ char *service_id = NULL; - int ret = - add_onion_helper_add_service(hs_version, &pk, port_cfgs, max_streams, - max_streams_close_circuit, auth_type, - auth_clients, auth_clients_v3, &service_id); - port_cfgs = NULL; /* port_cfgs is now owned by the rendservice code. */ - auth_clients = NULL; /* so is auth_clients */ + int ret = add_onion_helper_add_service(hs_version, &pk, port_cfgs, + max_streams, + max_streams_close_circuit, + auth_clients_v3, &service_id); + port_cfgs = NULL; /* port_cfgs is now owned by the hs_service code. */ auth_clients_v3 = NULL; /* so is auth_clients_v3 */ switch (ret) { case RSAE_OKAY: @@ -1943,17 +1800,6 @@ handle_control_add_onion(control_connection_t *conn, control_printf_midreply(conn, 250, "PrivateKey=%s:%s", key_new_alg, key_new_blob); } - if (auth_created_clients) { - SMARTLIST_FOREACH(auth_created_clients, rend_authorized_client_t *, ac, { - char *encoded = rend_auth_encode_cookie(ac->descriptor_cookie, - auth_type); - tor_assert(encoded); - control_printf_midreply(conn, 250, "ClientAuth=%s:%s", - ac->client_name, encoded); - memwipe(encoded, 0, strlen(encoded)); - tor_free(encoded); - }); - } if (auth_clients_v3_str) { SMARTLIST_FOREACH(auth_clients_v3_str, char *, client_str, { control_printf_midreply(conn, 250, "ClientAuthV3=%s", client_str); @@ -1990,12 +1836,6 @@ handle_control_add_onion(control_connection_t *conn, hs_port_config_free(p)); smartlist_free(port_cfgs); } - - if (auth_clients) { - SMARTLIST_FOREACH(auth_clients, rend_authorized_client_t *, ac, - rend_authorized_client_free(ac)); - smartlist_free(auth_clients); - } if (auth_clients_v3) { SMARTLIST_FOREACH(auth_clients_v3, hs_service_authorized_client_t *, ac, service_authorized_client_free(ac)); @@ -2007,10 +1847,6 @@ handle_control_add_onion(control_connection_t *conn, smartlist_free(auth_clients_v3_str); } - if (auth_created_clients) { - // Do not free entries; they are the same as auth_clients - smartlist_free(auth_created_clients); - } return 0; } @@ -2034,7 +1870,6 @@ add_onion_helper_keyarg(const char *arg, int discard_pk, control_connection_t *conn) { smartlist_t *key_args = smartlist_new(); - crypto_pk_t *pk = NULL; const char *key_new_alg = NULL; char *key_new_blob = NULL; int ret = -1; @@ -2048,27 +1883,12 @@ add_onion_helper_keyarg(const char *arg, int discard_pk, /* The format is "KeyType:KeyBlob". */ static const char *key_type_new = "NEW"; static const char *key_type_best = "BEST"; - static const char *key_type_rsa1024 = "RSA1024"; static const char *key_type_ed25519_v3 = "ED25519-V3"; const char *key_type = smartlist_get(key_args, 0); const char *key_blob = smartlist_get(key_args, 1); - if (!strcasecmp(key_type_rsa1024, key_type)) { - /* "RSA:<Base64 Blob>" - Loading a pre-existing RSA1024 key. */ - pk = crypto_pk_base64_decode_private(key_blob, strlen(key_blob)); - if (!pk) { - control_write_endreply(conn, 512, "Failed to decode RSA key"); - goto err; - } - if (crypto_pk_num_bits(pk) != PK_BYTES*8) { - crypto_pk_free(pk); - control_write_endreply(conn, 512, "Invalid RSA key size"); - goto err; - } - decoded_key->v2 = pk; - *hs_version = HS_VERSION_TWO; - } else if (!strcasecmp(key_type_ed25519_v3, key_type)) { + if (!strcasecmp(key_type_ed25519_v3, key_type)) { /* parsing of private ed25519 key */ /* "ED25519-V3:<Base64 Blob>" - Loading a pre-existing ed25519 key. */ ed25519_secret_key_t *sk = tor_malloc_zero(sizeof(*sk)); @@ -2082,27 +1902,8 @@ add_onion_helper_keyarg(const char *arg, int discard_pk, *hs_version = HS_VERSION_THREE; } else if (!strcasecmp(key_type_new, key_type)) { /* "NEW:<Algorithm>" - Generating a new key, blob as algorithm. */ - if (!strcasecmp(key_type_rsa1024, key_blob)) { - /* "RSA1024", RSA 1024 bit, also currently "BEST" by default. */ - pk = crypto_pk_new(); - if (crypto_pk_generate_key(pk)) { - control_printf_endreply(conn, 551, "Failed to generate %s key", - key_type_rsa1024); - goto err; - } - if (!discard_pk) { - if (crypto_pk_base64_encode_private(pk, &key_new_blob)) { - crypto_pk_free(pk); - control_printf_endreply(conn, 551, "Failed to encode %s key", - key_type_rsa1024); - goto err; - } - key_new_alg = key_type_rsa1024; - } - decoded_key->v2 = pk; - *hs_version = HS_VERSION_TWO; - } else if (!strcasecmp(key_type_ed25519_v3, key_blob) || - !strcasecmp(key_type_best, key_blob)) { + if (!strcasecmp(key_type_ed25519_v3, key_blob) || + !strcasecmp(key_type_best, key_blob)) { /* "ED25519-V3", ed25519 key, also currently "BEST" by default. */ ed25519_secret_key_t *sk = tor_malloc_zero(sizeof(*sk)); if (ed25519_secret_key_generate(sk, 1) < 0) { @@ -2151,68 +1952,6 @@ add_onion_helper_keyarg(const char *arg, int discard_pk, return ret; } -/** Helper function to handle parsing a ClientAuth argument to the - * ADD_ONION command. Return a new rend_authorized_client_t, or NULL - * and an optional control protocol error message on failure. The - * caller is responsible for freeing the returned auth_client. - * - * If 'created' is specified, it will be set to 1 when a new cookie has - * been generated. - * - * Note: conn is only used for writing control replies. For testing - * purposes, it can be NULL if control_write_reply() is appropriately - * mocked. - */ -STATIC rend_authorized_client_t * -add_onion_helper_clientauth(const char *arg, int *created, - control_connection_t *conn) -{ - int ok = 0; - - tor_assert(arg); - tor_assert(created); - - smartlist_t *auth_args = smartlist_new(); - rend_authorized_client_t *client = - tor_malloc_zero(sizeof(rend_authorized_client_t)); - smartlist_split_string(auth_args, arg, ":", 0, 0); - if (smartlist_len(auth_args) < 1 || smartlist_len(auth_args) > 2) { - control_write_endreply(conn, 512, "Invalid ClientAuth syntax"); - goto err; - } - client->client_name = tor_strdup(smartlist_get(auth_args, 0)); - if (smartlist_len(auth_args) == 2) { - char *decode_err_msg = NULL; - if (rend_auth_decode_cookie(smartlist_get(auth_args, 1), - client->descriptor_cookie, - NULL, &decode_err_msg) < 0) { - tor_assert(decode_err_msg); - control_write_endreply(conn, 512, decode_err_msg); - tor_free(decode_err_msg); - goto err; - } - *created = 0; - } else { - crypto_rand((char *) client->descriptor_cookie, REND_DESC_COOKIE_LEN); - *created = 1; - } - - if (!rend_valid_client_name(client->client_name)) { - control_write_endreply(conn, 512, "Invalid name in ClientAuth"); - goto err; - } - - ok = 1; - err: - SMARTLIST_FOREACH(auth_args, char *, item, tor_free(item)); - smartlist_free(auth_args); - if (!ok) { - rend_authorized_client_free(client); - client = NULL; - } - return client; -} - static const control_cmd_syntax_t del_onion_syntax = { .min_args = 1, .max_args = 1, }; @@ -2228,9 +1967,7 @@ handle_control_del_onion(control_connection_t *conn, tor_assert(smartlist_len(args) == 1); const char *service_id = smartlist_get(args, 0); - if (rend_valid_v2_service_id(service_id)) { - hs_version = HS_VERSION_TWO; - } else if (hs_address_is_valid(service_id)) { + if (hs_address_is_valid(service_id)) { hs_version = HS_VERSION_THREE; } else { control_write_endreply(conn, 512, "Malformed Onion Service id"); @@ -2261,9 +1998,6 @@ handle_control_del_onion(control_connection_t *conn, } else { int ret = -1; switch (hs_version) { - case HS_VERSION_TWO: - ret = rend_service_del_ephemeral(service_id); - break; case HS_VERSION_THREE: ret = hs_service_del_ephemeral(service_id); break; |