diff --git a/ChangeLog b/ChangeLog index a7eaafdbf..0f9321cf9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Changes in version 0.2.0.33 - 200?-??-?? +Changes in version 0.2.0.33 - 2009-??-?? o Major bugfixes: - When a stream at an exit relay is in state "resolving" or "connecting" and it receives an "end" relay cell, the exit relay @@ -52,6 +52,10 @@ Changes in version 0.2.0.33 - 200?-??-?? - Send a valid END cell back when a client tries to connect to a nonexistent hidden service port. Bugfix on 0.1.2.15. Fixes bug 840. Patch from rovv. + - Check which hops rendezvous stream cells are associated with to + prevent possible guess-the-streamid injection attacks from + intermediate hops. Fixes another case of bug 446. Based on patch + from rovv. o Minor features: - Report the case where all signatures in a detached set are rejected diff --git a/doc/TODO.020 b/doc/TODO.020 index 1cb129c75..16c6cb5cb 100644 --- a/doc/TODO.020 +++ b/doc/TODO.020 @@ -19,7 +19,7 @@ Backport for 0.2.0 once better tested: o r17137: send END cell in response to connect to nonexistent hidserv port. - r17138: reject *:* servers should never do DNS lookups. o r17139: Fix another case of overriding .exit choices. - - r17162 and r17164: fix another case of not checking cpath_layer. + o r17162 and r17164: fix another case of not checking cpath_layer. - r17208,r17209,r7211,r17212,r17214: Avoid gotterdammerung when an authority has an expired certificate. - r17562: Fix bug 874, wherein a sighup would make us kill all our intro diff --git a/src/or/or.h b/src/or/or.h index a0a6a5e37..0e7ce9a30 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3688,8 +3688,8 @@ typedef struct rend_service_descriptor_t { int rend_cmp_service_ids(const char *one, const char *two); -void rend_process_relay_cell(circuit_t *circ, int command, size_t length, - const char *payload); +void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint, + int command, size_t length, const char *payload); void rend_service_descriptor_free(rend_service_descriptor_t *desc); int rend_encode_service_descriptor(rend_service_descriptor_t *desc, diff --git a/src/or/relay.c b/src/or/relay.c index 92d5db794..5ada6d319 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1253,7 +1253,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, case RELAY_COMMAND_RENDEZVOUS2: case RELAY_COMMAND_INTRO_ESTABLISHED: case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED: - rend_process_relay_cell(circ, rh.command, rh.length, + rend_process_relay_cell(circ, layer_hint, + rh.command, rh.length, cell->payload+RELAY_HEADER_SIZE); return 0; } diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 559d67e94..dfa718c0a 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1180,16 +1180,24 @@ rend_cache_store_v2_desc_as_client(const char *desc, /** Called when we get a rendezvous-related relay cell on circuit * circ. Dispatch on rendezvous relay command. */ void -rend_process_relay_cell(circuit_t *circ, int command, size_t length, +rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint, + int command, size_t length, const char *payload) { or_circuit_t *or_circ = NULL; origin_circuit_t *origin_circ = NULL; int r = -2; - if (CIRCUIT_IS_ORIGIN(circ)) + if (CIRCUIT_IS_ORIGIN(circ)) { origin_circ = TO_ORIGIN_CIRCUIT(circ); - else + if (!layer_hint || layer_hint != origin_circ->cpath->prev) { + log_fn(LOG_PROTOCOL_WARN, LD_APP, + "Relay cell (rend purpose %d) from wrong hop on origin circ", + command); + origin_circ = NULL; + } + } else { or_circ = TO_OR_CIRCUIT(circ); + } switch (command) { case RELAY_COMMAND_ESTABLISH_INTRO: