diff options
author | George Kadianakis <desnacked@riseup.net> | 2019-06-03 15:43:54 +0300 |
---|---|---|
committer | George Kadianakis <desnacked@riseup.net> | 2019-11-18 19:18:49 +0200 |
commit | 8330b4dc2a18befa0eda8e48abb7f6e151596562 (patch) | |
tree | c9310b17d5755ccd34a5120f3d3d26df430fd982 /src | |
parent | 46f441502227665c25aa0ad8710bdf8487193904 (diff) | |
download | tor-8330b4dc2a18befa0eda8e48abb7f6e151596562.tar.gz tor-8330b4dc2a18befa0eda8e48abb7f6e151596562.zip |
control-port: Implement ONION_CLIENT_AUTH_REMOVE.
Diffstat (limited to 'src')
-rw-r--r-- | src/feature/control/control_cmd.c | 1 | ||||
-rw-r--r-- | src/feature/control/control_hs.c | 50 | ||||
-rw-r--r-- | src/feature/control/control_hs.h | 6 | ||||
-rw-r--r-- | src/feature/hs/hs_client.c | 25 | ||||
-rw-r--r-- | src/feature/hs/hs_client.h | 13 |
5 files changed, 94 insertions, 1 deletions
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index 3c16722e15..fcd0d8b292 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -2320,6 +2320,7 @@ static const control_cmd_def_t CONTROL_COMMANDS[] = ONE_LINE(add_onion, CMD_FL_WIPE), ONE_LINE(del_onion, CMD_FL_WIPE), ONE_LINE(onion_client_auth_add, CMD_FL_WIPE), + ONE_LINE(onion_client_auth_remove, 0), }; /** diff --git a/src/feature/control/control_hs.c b/src/feature/control/control_hs.c index 5db8a0f007..93e66261e0 100644 --- a/src/feature/control/control_hs.c +++ b/src/feature/control/control_hs.c @@ -159,3 +159,53 @@ handle_control_onion_client_auth_add(control_connection_t *conn, smartlist_free(flags); return retval; } + +/** Syntax details for ONION_CLIENT_AUTH_REMOVE */ +const control_cmd_syntax_t onion_client_auth_remove_syntax = { + .max_args = 1, + .accept_keywords = true, +}; + +/** Called when we get an ONION_CLIENT_AUTH_REMOVE command; parse the body, and + * register the new client-side client auth credentials. + * "ONION_CLIENT_AUTH_REMOVE" SP HSAddress + */ +int +handle_control_onion_client_auth_remove(control_connection_t *conn, + const control_cmd_args_t *args) +{ + int retval = -1; + + tor_assert(args); + + int argc = smartlist_len(args->args); + if (argc < 1) { + control_printf_endreply(conn, 512, + "Incomplete ONION_CLIENT_AUTH_REMOVE command"); + goto err; + } + + const char *hsaddress = smartlist_get(args->args, 0); + if (!hs_address_is_valid(hsaddress)) { + control_printf_endreply(conn, 512, "Invalid v3 address \"%s\"",hsaddress); + goto err; + } + + hs_client_removal_auth_status_t removal_status; + removal_status = hs_client_remove_auth_credentials(hsaddress); + if (BUG(removal_status == REMOVAL_BAD_ADDRESS)) { + /* It's a bug because the service addr has already been validated above */ + control_printf_endreply(conn, 512, "Invalid v3 address \"%s\"",hsaddress); + } else if (removal_status == REMOVAL_SUCCESS_NOT_FOUND) { + control_printf_endreply(conn, 251, "No credentials for \"%s\"",hsaddress); + } else if (removal_status == REMOVAL_SUCCESS) { + control_printf_endreply(conn, 250, "OK"); + } else { + tor_assert_nonfatal_unreached(); + } + + retval = 0; + + err: + return retval; +} diff --git a/src/feature/control/control_hs.h b/src/feature/control/control_hs.h index 1fcd7de36c..067c7dc47f 100644 --- a/src/feature/control/control_hs.h +++ b/src/feature/control/control_hs.h @@ -13,12 +13,16 @@ struct control_cmd_syntax_t; -extern const char *onion_client_auth_add_keywords[]; extern const struct control_cmd_syntax_t onion_client_auth_add_syntax; +extern const struct control_cmd_syntax_t onion_client_auth_remove_syntax; int handle_control_onion_client_auth_add(control_connection_t *conn, const control_cmd_args_t *args); +int +handle_control_onion_client_auth_remove(control_connection_t *conn, + const control_cmd_args_t *args); + #endif diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index c854737bef..bbe7b87a60 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -1475,6 +1475,31 @@ hs_client_register_auth_credentials(hs_client_service_authorization_t *creds) return REGISTER_SUCCESS; } +/** Remove client auth credentials for the service <b>hs_address</b>. */ +hs_client_removal_auth_status_t +hs_client_remove_auth_credentials(const char *hsaddress) +{ + ed25519_public_key_t service_identity_pk; + + if (!client_auths) { + return REMOVAL_SUCCESS_NOT_FOUND; + } + + if (hs_parse_address(hsaddress, &service_identity_pk, NULL, NULL) < 0) { + return REMOVAL_BAD_ADDRESS; + } + + hs_client_service_authorization_t *cred = NULL; + cred = digest256map_remove(client_auths, service_identity_pk.pubkey); + /* digestmap_remove() returns the previously stored data if there were any */ + if (cred) { + client_service_authorization_free(cred); + return REMOVAL_SUCCESS; + } + + return REMOVAL_SUCCESS_NOT_FOUND; +} + /* ========== */ /* Public API */ /* ========== */ diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h index ea726e2370..459c19db58 100644 --- a/src/feature/hs/hs_client.h +++ b/src/feature/hs/hs_client.h @@ -41,6 +41,16 @@ typedef enum { REGISTER_FAIL_BAD_ADDRESS, } hs_client_register_auth_status_t; +/* Status code of client auth credential removal */ +typedef enum { + /* We successfuly removed these credentials */ + REMOVAL_SUCCESS, + /* No need to remove those credentials, because they were not there. */ + REMOVAL_SUCCESS_NOT_FOUND, + /* We failed to register these credentials, because of a bad HS address. */ + REMOVAL_BAD_ADDRESS, +} hs_client_removal_auth_status_t; + /** Flag to set when a client auth is permanent (saved on disk). */ #define CLIENT_AUTH_FLAG_IS_PERMANENT (1<<0) @@ -63,6 +73,9 @@ typedef struct hs_client_service_authorization_t { hs_client_register_auth_status_t hs_client_register_auth_credentials(hs_client_service_authorization_t *creds); +hs_client_removal_auth_status_t +hs_client_remove_auth_credentials(const char *hsaddress); + #define client_service_authorization_free(auth) \ FREE_AND_NULL(hs_client_service_authorization_t, \ client_service_authorization_free_, (auth)) |