Forked from
briar / briar
3523 commits behind the upstream repository.
tor.patch 5.67 KiB
diff --git a/src/or/control.c b/src/or/control.c
index c8c5062..f38ba23 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -196,6 +196,8 @@ static int handle_control_hsfetch(control_connection_t *conn, uint32_t len,
const char *body);
static int handle_control_hspost(control_connection_t *conn, uint32_t len,
const char *body);
+static int handle_control_hsforget(control_connection_t *conn, uint32_t len,
+ const char *body);
static int handle_control_add_onion(control_connection_t *conn, uint32_t len,
const char *body);
static int handle_control_del_onion(control_connection_t *conn, uint32_t len,
@@ -4246,6 +4248,33 @@ handle_control_hspost(control_connection_t *conn,
return 0;
}
+/** Called when we get an HSFORGET command: parse the hidden service's onion
+ * address and purge any cached state related to the service. */
+static int
+handle_control_hsforget(control_connection_t *conn, uint32_t len,
+ const char *body)
+{
+ smartlist_t *args;
+ char *onion_address;
+
+ args = getargs_helper("HSFORGET", conn, body, 1, 1);
+ if (!args)
+ return -1;
+ onion_address = smartlist_get(args, 0);
+ smartlist_free(args);
+
+ if (!rend_valid_service_id(onion_address)) {
+ connection_write_str_to_buf("513 Invalid hidden service address\r\n", conn);
+ tor_free(onion_address);
+ return -1;
+ }
+
+ rend_client_purge_hidden_service(onion_address);
+ tor_free(onion_address);
+ send_control_done(conn);
+ return 0;
+}
+
/** Called when we get a ADD_ONION command; parse the body, and set up
* the new ephemeral Onion Service. */
static int
@@ -5065,6 +5094,9 @@ connection_control_process_inbuf(control_connection_t *conn)
} else if (!strcasecmp(conn->incoming_cmd, "+HSPOST")) {
if (handle_control_hspost(conn, cmd_data_len, args))
return -1;
+ } else if (!strcasecmp(conn->incoming_cmd, "HSFORGET")) {
+ if (handle_control_hsforget(conn, cmd_data_len, args))
+ return -1;
} else if (!strcasecmp(conn->incoming_cmd, "ADD_ONION")) {
int ret = handle_control_add_onion(conn, cmd_data_len, args);
memwipe(args, 0, cmd_data_len); /* Scrub the private key. */
diff --git a/src/or/rendcache.c b/src/or/rendcache.c
index aa69d73..473a6a4 100644
--- a/src/or/rendcache.c
+++ b/src/or/rendcache.c
@@ -587,6 +587,34 @@ rend_cache_lookup_v2_desc_as_service(const char *query, rend_cache_entry_t **e)
return ret;
}
+/** Remove any cached descriptors for <b>service_id</b>. */
+void
+rend_cache_remove_entry(const char *service_id)
+{
+ char key[REND_SERVICE_ID_LEN_BASE32 + 2]; /* <version><service_id>\0 */
+ rend_cache_entry_t *removed;
+
+ tor_assert(rend_valid_service_id(service_id));
+ if (!rend_cache)
+ return;
+
+ tor_snprintf(key, sizeof(key), "2%s", service_id);
+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key);
+ if (removed) {
+ log_info(LD_REND, "Removed cached v2 descriptor for service %s.",
+ safe_str_client(service_id));
+ rend_cache_entry_free(removed);
+ }
+
+ tor_snprintf(key, sizeof(key), "0%s", service_id);
+ removed = (rend_cache_entry_t *)strmap_remove_lc(rend_cache, key);
+ if (removed) {
+ log_info(LD_REND, "Removed cached v0 descriptor for service %s.",
+ safe_str_client(service_id));
+ rend_cache_entry_free(removed);
+ }
+}
+
/** Lookup the v2 service descriptor with base32-encoded <b>desc_id</b> and
* copy the pointer to it to *<b>desc</b>. Return 1 on success, 0 on
* well-formed-but-not-found, and -1 on failure.
diff --git a/src/or/rendcache.h b/src/or/rendcache.h
index 270b614..69d1b1b 100644
--- a/src/or/rendcache.h
+++ b/src/or/rendcache.h
@@ -61,6 +61,7 @@ void rend_cache_purge(void);
void rend_cache_free_all(void);
int rend_cache_lookup_entry(const char *query, int version,
rend_cache_entry_t **entry_out);
+void rend_cache_remove_entry(const char *service_id);
int rend_cache_lookup_v2_desc_as_service(const char *query,
rend_cache_entry_t **entry_out);
int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc);
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index a93bc94..f311e1f 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -32,6 +32,9 @@ static extend_info_t *rend_client_get_random_intro_impl(
const rend_cache_entry_t *rend_query,
const int strict, const int warnings);
+static void purge_hid_serv_from_last_hid_serv_requests(
+ const char *onion_address);
+
/** Purge all potentially remotely-detectable state held in the hidden
* service client code. Called on SIGNAL NEWNYM. */
void
@@ -43,6 +46,15 @@ rend_client_purge_state(void)
rend_client_purge_last_hid_serv_requests();
}
+/** Purge all cached state relating to the given hidden service. */
+void
+rend_client_purge_hidden_service(const char *onion_address)
+{
+ tor_assert(rend_valid_service_id(onion_address));
+ rend_cache_remove_entry(onion_address);
+ purge_hid_serv_from_last_hid_serv_requests(onion_address);
+}
+
/** Called when we've established a circuit to an introduction point:
* send the introduction request. */
void
diff --git a/src/or/rendclient.h b/src/or/rendclient.h
index b8f8c2f..b1da48c 100644
--- a/src/or/rendclient.h
+++ b/src/or/rendclient.h
@@ -15,6 +15,7 @@
#include "rendcache.h"
void rend_client_purge_state(void);
+void rend_client_purge_hidden_service(const char *onion_address);
void rend_client_introcirc_has_opened(origin_circuit_t *circ);
void rend_client_rendcirc_has_opened(origin_circuit_t *circ);
--
2.9.3