diff options
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; |