From 12305b6bb6a68640e011dc5e2f2557bdccc2ae22 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Mon, 25 Nov 2019 18:31:29 +0200 Subject: [PATCH] hsv3: ONION_CLIENT_AUTH_REMOVE now also removes the credential file. --- src/feature/hs/hs_client.c | 84 ++++++++++++++++++++++++++++++++++++++ src/test/test_hs_control.c | 23 ++++++++++- 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index cb902290f9..823a0a45a7 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -1613,6 +1613,84 @@ get_creds_from_client_auth_filename(const char *filename, return auth; } +/* + * Remove the file in filename under the global client auth credential + * storage. + */ +static void +remove_client_auth_creds_file(const char *filename) +{ + char *creds_file_path = NULL; + const or_options_t *options = get_options(); + + creds_file_path = hs_path_from_filename(options->ClientOnionAuthDir, + filename); + if (tor_unlink(creds_file_path) != 0) { + log_warn(LD_REND, "Failed to remove client auth file (%s).", + creds_file_path); + goto end; + } + + log_warn(LD_REND, "Successfuly removed client auth file (%s).", + creds_file_path); + + end: + tor_free(creds_file_path); +} + +/** + * Find the filesystem file corresponding to the permanent client auth + * credentials in cred and remove it. + */ +static void +find_and_remove_client_auth_creds_file( + const hs_client_service_authorization_t *cred) +{ + smartlist_t *file_list = NULL; + const or_options_t *options = get_options(); + + tor_assert(cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT); + + if (!options->ClientOnionAuthDir) { + log_warn(LD_REND, "Found permanent credential but no ClientOnionAuthDir " + "configured. There is no file to be removed."); + goto end; + } + + file_list = tor_listdir(options->ClientOnionAuthDir); + if (file_list == NULL) { + log_warn(LD_REND, "Client authorization key directory %s can't be listed.", + options->ClientOnionAuthDir); + goto end; + } + + SMARTLIST_FOREACH_BEGIN(file_list, const char *, filename) { + hs_client_service_authorization_t *tmp_cred = NULL; + + tmp_cred = get_creds_from_client_auth_filename(filename, options); + if (!tmp_cred) { + continue; + } + + /* Find the right file for this credential */ + if (!strcmp(tmp_cred->onion_address, cred->onion_address)) { + /* Found it! Remove the file! */ + remove_client_auth_creds_file(filename); + /* cleanup and get out of here */ + client_service_authorization_free(tmp_cred); + break; + } + + client_service_authorization_free(tmp_cred); + } SMARTLIST_FOREACH_END(filename); + + end: + if (file_list) { + SMARTLIST_FOREACH(file_list, char *, s, tor_free(s)); + smartlist_free(file_list); + } +} + /** Remove client auth credentials for the service hs_address. */ hs_client_removal_auth_status_t hs_client_remove_auth_credentials(const char *hsaddress) @@ -1629,8 +1707,14 @@ hs_client_remove_auth_credentials(const char *hsaddress) 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) { + if (cred->flags & CLIENT_AUTH_FLAG_IS_PERMANENT) { + /* These creds are stored on disk: remove the corresponding file. */ + find_and_remove_client_auth_creds_file(cred); + } + client_service_authorization_free(cred); return REMOVAL_SUCCESS; } diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c index 572b7f3ab1..d064f203a6 100644 --- a/src/test/test_hs_control.c +++ b/src/test/test_hs_control.c @@ -585,7 +585,7 @@ test_hs_control_store_permanent_creds(void *arg) /* This is the base32 represenation of the base64 UDRv... key above */ "x25519:ka2g6zf33qti2ecexpbx4stan3nsu3sijbiqm4t2rwctigxajnpq"); - /* Now for our final act!!! Actually get the HS client subsystem to parse the + /* Now for our next act!!! Actually get the HS client subsystem to parse the * whole directory and make sure that it extracted the right credential! */ hs_config_client_authorization(get_options(), 0); @@ -600,6 +600,27 @@ test_hs_control_store_permanent_creds(void *arg) tt_str_op(hex_str((char*)client_2fv->enc_seckey.secret_key, 32), OP_EQ, "50346F64BBDC268D1044BBC37E4A606EDB2A6E48485106727A8D85341AE04B5F"); + /* And now for the final act! Use the REMOVE control port command to remove + the credential, and ensure that the file has also been removed! */ + tor_free(conn.current_cmd); + tor_free(cp1); + tor_free(args); + + /* Ensure that the creds file exists */ + tt_int_op(file_status(creds_fname), OP_EQ, FN_FILE); + + /* Do the REMOVE */ + conn.current_cmd = tor_strdup("ONION_CLIENT_AUTH_REMOVE"); + args =tor_strdup("2fvhjskjet3n5syd6yfg5lhvwcs62bojmthr35ko5bllr3iqdb4ctdyd"); + retval = handle_control_command(&conn, (uint32_t) strlen(args), args); + tt_int_op(retval, OP_EQ, 0); + cp1 = buf_get_contents(TO_CONN(&conn)->outbuf, &sz); + tt_str_op(cp1, OP_EQ, "250 OK\r\n"); + + /* Ensure that the file has been removed and the map is empty */ + tt_int_op(file_status(creds_fname), OP_EQ, FN_NOENT); + tt_uint_op(digest256map_size(client_auths), OP_EQ, 0); + done: tor_free(args); tor_free(cp1);