|
@@ -292,7 +292,9 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
|
routerinfo_t *router;
|
|
routerinfo_t *router;
|
|
int r;
|
|
int r;
|
|
int circ_id_type;
|
|
int circ_id_type;
|
|
- char payload[2+4+ONIONSKIN_CHALLENGE_LEN];
|
|
|
|
|
|
+ char payload[2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN];
|
|
|
|
+ char *onionskin;
|
|
|
|
+ int payload_len;
|
|
|
|
|
|
tor_assert(circ && CIRCUIT_IS_ORIGIN(circ));
|
|
tor_assert(circ && CIRCUIT_IS_ORIGIN(circ));
|
|
|
|
|
|
@@ -352,7 +354,17 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
|
|
|
|
|
*(uint32_t*)payload = htonl(hop->addr);
|
|
*(uint32_t*)payload = htonl(hop->addr);
|
|
*(uint16_t*)(payload+4) = htons(hop->port);
|
|
*(uint16_t*)(payload+4) = htons(hop->port);
|
|
- if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), payload+6) < 0) {
|
|
|
|
|
|
+ if (strncmp(router->platform, "Tor 0.0.7", 9)) {
|
|
|
|
+ /* Before 0.0.8, we didn't support the long payload format. */
|
|
|
|
+ memcpy(payload+2+4, hop->identity_digest, DIGEST_LEN);
|
|
|
|
+ onionskin = payload+2+4+DIGEST_LEN;
|
|
|
|
+ payload_len = 2+4+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN;
|
|
|
|
+ } else {
|
|
|
|
+ onionskin = payload+2+4;
|
|
|
|
+ payload_len = 2+4+ONIONSKIN_CHALLENGE_LEN;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), onionskin) < 0) {
|
|
log_fn(LOG_WARN,"onion_skin_create failed.");
|
|
log_fn(LOG_WARN,"onion_skin_create failed.");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
@@ -361,7 +373,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
|
/* send it to hop->prev, because it will transfer
|
|
/* send it to hop->prev, because it will transfer
|
|
* it to a create cell and then send to hop */
|
|
* it to a create cell and then send to hop */
|
|
if(connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTEND,
|
|
if(connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTEND,
|
|
- payload, sizeof(payload), hop->prev) < 0)
|
|
|
|
|
|
+ payload, payload_len, hop->prev) < 0)
|
|
return 0; /* circuit is closed */
|
|
return 0; /* circuit is closed */
|
|
|
|
|
|
hop->state = CPATH_STATE_AWAITING_KEYS;
|
|
hop->state = CPATH_STATE_AWAITING_KEYS;
|
|
@@ -377,16 +389,42 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
|
|
connection_t *n_conn;
|
|
connection_t *n_conn;
|
|
int circ_id_type;
|
|
int circ_id_type;
|
|
cell_t newcell;
|
|
cell_t newcell;
|
|
|
|
+ relay_header_t rh;
|
|
|
|
+ int old_format;
|
|
|
|
+ char *onionskin;
|
|
|
|
|
|
if(circ->n_conn) {
|
|
if(circ->n_conn) {
|
|
log_fn(LOG_WARN,"n_conn already set. Bug/attack. Closing.");
|
|
log_fn(LOG_WARN,"n_conn already set. Bug/attack. Closing.");
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ relay_header_unpack(&rh, cell->payload);
|
|
|
|
+
|
|
|
|
+ if (rh.length == 4+2+ONIONSKIN_CHALLENGE_LEN) {
|
|
|
|
+ old_format = 1;
|
|
|
|
+ } else if (rh.length == 4+2+DIGEST_LEN+ONIONSKIN_CHALLENGE_LEN) {
|
|
|
|
+ old_format = 0;
|
|
|
|
+ } else {
|
|
|
|
+ log_fn(LOG_WARN, "Wrong length on extend cell. Closing circuit.");
|
|
|
|
+ circuit_mark_for_close(circ);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
circ->n_addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
|
|
circ->n_addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE));
|
|
circ->n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4));
|
|
circ->n_port = ntohs(get_uint16(cell->payload+RELAY_HEADER_SIZE+4));
|
|
|
|
|
|
- n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
|
|
|
|
|
|
+ if (old_format) {
|
|
|
|
+ n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
|
|
|
|
+ onionskin = cell->payload+RELAY_HEADER_SIZE+4+2;
|
|
|
|
+ } else {
|
|
|
|
+ /* XXXX Roger: in this case, we should create the connnection if
|
|
|
|
+ * n_conn is null. */
|
|
|
|
+ n_conn = connection_get_by_identity_digest(
|
|
|
|
+ cell->payload+RELAY_HEADER_SIZE+4+2,
|
|
|
|
+ CONN_TYPE_OR);
|
|
|
|
+ onionskin = cell->payload+RELAY_HEADER_SIZE+4+2+DIGEST_LEN;
|
|
|
|
+ }
|
|
|
|
+
|
|
if(!n_conn || n_conn->type != CONN_TYPE_OR) {
|
|
if(!n_conn || n_conn->type != CONN_TYPE_OR) {
|
|
/* I've disabled making connections through OPs, but it's definitely
|
|
/* I've disabled making connections through OPs, but it's definitely
|
|
* possible here. I'm not sure if it would be a bug or a feature.
|
|
* possible here. I'm not sure if it would be a bug or a feature.
|
|
@@ -426,8 +464,7 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
|
|
newcell.command = CELL_CREATE;
|
|
newcell.command = CELL_CREATE;
|
|
newcell.circ_id = circ->n_circ_id;
|
|
newcell.circ_id = circ->n_circ_id;
|
|
|
|
|
|
- memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+2+4,
|
|
|
|
- ONIONSKIN_CHALLENGE_LEN);
|
|
|
|
|
|
+ memcpy(newcell.payload, onionskin, ONIONSKIN_CHALLENGE_LEN);
|
|
|
|
|
|
connection_or_write_cell_to_buf(&newcell, circ->n_conn);
|
|
connection_or_write_cell_to_buf(&newcell, circ->n_conn);
|
|
return 0;
|
|
return 0;
|
|
@@ -1079,6 +1116,7 @@ onion_extend_cpath(crypt_path_t **head_ptr, cpath_build_state_t
|
|
|
|
|
|
hop->port = choice->or_port;
|
|
hop->port = choice->or_port;
|
|
hop->addr = choice->addr;
|
|
hop->addr = choice->addr;
|
|
|
|
+ memcpy(hop->identity_digest, choice->identity_digest, DIGEST_LEN);
|
|
|
|
|
|
hop->package_window = CIRCWINDOW_START;
|
|
hop->package_window = CIRCWINDOW_START;
|
|
hop->deliver_window = CIRCWINDOW_START;
|
|
hop->deliver_window = CIRCWINDOW_START;
|