commit 12305b6bb6a68640e011dc5e2f2557bdccc2ae22
Author: George Kadianakis <desnac...@riseup.net>
Date:   Mon Nov 25 18:31:29 2019 +0200

    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 cb902290f..823a0a45a 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 <b>filename</b> 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 <b>cred</b> 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 <b>hs_address</b>. */
 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 572b7f3ab..d064f203a 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);



_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to