Forget all rendezvous client state on SIGNAL NEWNYM

This commit is contained in:
Robert Ransom 2011-04-20 02:27:58 -07:00 committed by Sebastian Hahn
parent 43ffd023e9
commit 440e48ddf2
5 changed files with 56 additions and 0 deletions

View File

@ -0,0 +1,5 @@
o Security fixes:
- Forget all hidden service descriptors cached as a client when
processing a SIGNAL NEWNYM command. Fixes bug 3000. Bugfix on
0.0.6.

View File

@ -785,6 +785,8 @@ signewnym_impl(time_t now)
{ {
circuit_expire_all_dirty_circs(); circuit_expire_all_dirty_circs();
addressmap_clear_transient(); addressmap_clear_transient();
rend_cache_purge();
rend_client_cancel_descriptor_fetches();
time_of_last_signewnym = now; time_of_last_signewnym = now;
signewnym_is_pending = 0; signewnym_is_pending = 0;
} }

View File

@ -4039,6 +4039,7 @@ int rend_client_introduction_acked(origin_circuit_t *circ,
size_t request_len); size_t request_len);
void rend_client_refetch_renddesc(const char *query); void rend_client_refetch_renddesc(const char *query);
void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query); void rend_client_refetch_v2_renddesc(const rend_data_t *rend_query);
void rend_client_cancel_descriptor_fetches(void);
int rend_client_remove_intro_point(extend_info_t *failed_intro, int rend_client_remove_intro_point(extend_info_t *failed_intro,
const rend_data_t *rend_query); const rend_data_t *rend_query);
int rend_client_rendezvous_acked(origin_circuit_t *circ, int rend_client_rendezvous_acked(origin_circuit_t *circ,
@ -4137,6 +4138,7 @@ typedef struct rend_cache_entry_t {
void rend_cache_init(void); void rend_cache_init(void);
void rend_cache_clean(void); void rend_cache_clean(void);
void rend_cache_clean_v2_descs_as_dir(void); void rend_cache_clean_v2_descs_as_dir(void);
void rend_cache_purge(void);
void rend_cache_free_all(void); void rend_cache_free_all(void);
int rend_valid_service_id(const char *query); int rend_valid_service_id(const char *query);
int rend_cache_lookup_desc(const char *query, int version, const char **desc, int rend_cache_lookup_desc(const char *query, int version, const char **desc,

View File

@ -557,8 +557,45 @@ rend_client_refetch_v2_renddesc(const rend_data_t *rend_query)
return; return;
} }
/** Cancel all rendezvous descriptor fetches currently in progress.
*/
void
rend_client_cancel_descriptor_fetches(void)
{
smartlist_t *connection_array = get_connection_array();
SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
if (conn->type == CONN_TYPE_DIR &&
(conn->purpose == DIR_PURPOSE_FETCH_RENDDESC ||
conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2)) {
/* It's a rendezvous descriptor fetch in progress -- cancel it
* by marking the connection for close.
*
* Even if this connection has already reached EOF, this is
* enough to make sure that if the descriptor hasn't been
* processed yet, it won't be. See the end of
* connection_handle_read; connection_reached_eof (indirectly)
* processes whatever response the connection received. */
const rend_data_t *rd = (TO_DIR_CONN(conn))->rend_data;
if (!rd) {
log_warn(LD_BUG | LD_REND,
"Marking for close dir conn fetching rendezvous "
"descriptor for unknown service!");
} else {
log_debug(LD_REND, "Marking for close dir conn fetching v%d "
"rendezvous descriptor for service %s",
(int)(rd->rend_desc_version),
safe_str(rd->onion_address));
}
connection_mark_for_close(conn);
}
} SMARTLIST_FOREACH_END(conn);
}
/** Remove failed_intro from ent. If ent now has no intro points, or /** Remove failed_intro from ent. If ent now has no intro points, or
* service is unrecognized, then launch a new renddesc fetch. * service is unrecognized, then launch a new renddesc fetch.
* *
* Return -1 if error, 0 if no intro points remain or service * Return -1 if error, 0 if no intro points remain or service
* unrecognized, 1 if recognized and some intro points remain. * unrecognized, 1 if recognized and some intro points remain.

View File

@ -871,6 +871,16 @@ rend_cache_clean(void)
} }
} }
/** Remove ALL entries from the rendezvous service descriptor cache.
*/
void
rend_cache_purge(void)
{
if (rend_cache)
strmap_free(rend_cache, _rend_cache_entry_free);
rend_cache = strmap_new();
}
/** Remove all old v2 descriptors and those for which this hidden service /** Remove all old v2 descriptors and those for which this hidden service
* directory is not responsible for any more. */ * directory is not responsible for any more. */
void void