diff --git a/doc/tor-spec.txt b/doc/tor-spec.txt index 58c4fdf2a4bb1789d2d44b5d3be57f9b90e664b7..b846ebee6a17a67c117a256e39972044acfe417b 100644 --- a/doc/tor-spec.txt +++ b/doc/tor-spec.txt @@ -228,8 +228,8 @@ which reveals the downstream node. ACI (anonymous circuit identifier) [2 bytes] Command [1 byte] - Length [1 byte] Sequence number (unused, set to 0) [4 bytes] + Length [1 byte] Payload (padded with 0 bytes) [248 bytes] [Total size: 256 bytes] diff --git a/src/common/crypto.h b/src/common/crypto.h index 0629b8f1c0f78421f77c7346408a03310ccfb15e..5f2d3e29b85d136f81710fb2eb8c113cf575fda7 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -85,6 +85,8 @@ int crypto_SHA_digest(unsigned char *m, int len, unsigned char *digest); int crypto_rand(unsigned int n, unsigned char *to); int crypto_pseudo_rand(unsigned int n, unsigned char *to); +#define CRYPTO_PSEUDO_RAND_INT(v) crypto_pseudo_rand(sizeof(v),(char*)&(v)) + /* errors */ char *crypto_perror(); #endif diff --git a/src/or/circuit.c b/src/or/circuit.c index 54fb8bc6206556af1d3afeb822283b838d98345b..9b11d55803b724632fcf03313eb5dcc34732e5ad 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -118,7 +118,8 @@ aci_t get_unique_aci_by_addr_port(uint32_t addr, uint16_t port, int aci_type) { try_again: log(LOG_DEBUG,"get_unique_aci_by_addr_port() trying to get a unique aci"); - crypto_pseudo_rand(2, (unsigned char *)&test_aci); + if (CRYPTO_PSEUDO_RAND_INT(test_aci)) + return -1; if(aci_type == ACI_TYPE_LOWER && test_aci >= (1<<15)) test_aci -= (1<<15); diff --git a/src/or/connection.c b/src/or/connection.c index 4ef246d83827897500338db178e2ab9aea74b147..7dd00cff5489c4b6054ffabc478d46be1abb6307 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -698,8 +698,8 @@ repeat_connection_package_raw_inbuf: cell.command = CELL_DATA; - cell.topic_command = TOPIC_COMMAND_DATA; - cell.topic_id = conn->topic_id; + SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_DATA); + SET_CELL_TOPIC_ID(cell, conn->topic_id); cell.length += TOPIC_HEADER_SIZE; if(conn->type == CONN_TYPE_EXIT) { @@ -752,8 +752,8 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) { memset(&cell, 0, sizeof(cell_t)); cell.command = CELL_DATA; - cell.topic_command = TOPIC_COMMAND_SENDME; - cell.topic_id = conn->topic_id; + SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_SENDME); + SET_CELL_TOPIC_ID(cell, conn->topic_id); cell.length += TOPIC_HEADER_SIZE; if(edge_type == EDGE_EXIT) { /* we're at an exit */ @@ -860,14 +860,7 @@ cell_pack(char *dest, const cell_t *src) *(uint8_t*)(dest+2) = src->command; *(uint8_t*)(dest+3) = src->length; *(uint32_t*)(dest+4) = 0; /* Reserved */ - if (src->command != CELL_DATA) { - memcpy(dest+8, src->payload, CELL_PAYLOAD_SIZE); - } else { - *(uint8_t*)(dest+8) = src->topic_command; - *(uint8_t*)(dest+9) = 0; - *(uint16_t*)(dest+10) = htons(src->topic_id); - memcpy(dest+12, src->payload, CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE); - } + memcpy(dest+8, src->payload, CELL_PAYLOAD_SIZE); } void @@ -877,14 +870,7 @@ cell_unpack(cell_t *dest, const char *src) dest->command = *(uint8_t*)(src+2); dest->length = *(uint8_t*)(src+3); dest->seq = ntohl(*(uint32_t*)(src+4)); - if (dest->command != CELL_DATA) { - memcpy(dest->payload, src+8, CELL_PAYLOAD_SIZE); - } else { - dest->topic_command = *(uint8_t*)(src+8); - /* zero = *(uint8_t*)(src+9); */ - dest->topic_id = ntohs(*(uint16_t*)(src+10)); - memcpy(dest->payload, src+12, CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE); - } + memcpy(dest->payload, src+8, CELL_PAYLOAD_SIZE); } /* diff --git a/src/or/connection_ap.c b/src/or/connection_ap.c index 444dfc00af783ecf7df9408c90bbe506eeb648c3..7dfa1ccc51f7ce0686064076a6465e7a8fd4e381 100644 --- a/src/or/connection_ap.c +++ b/src/or/connection_ap.c @@ -119,15 +119,18 @@ int ap_handshake_process_socks(connection_t *conn) { int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) { cell_t cell; + uint16_t topic_id; memset(&cell, 0, sizeof(cell_t)); /* deliver the dest_addr in a data cell */ cell.command = CELL_DATA; cell.aci = circ->n_aci; - cell.topic_command = TOPIC_COMMAND_BEGIN; - crypto_pseudo_rand(2, (char*)&cell.topic_id); + SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_BEGIN); + if (CRYPTO_PSEUDO_RAND_INT(topic_id)) + return -1; + SET_CELL_TOPIC_ID(cell, topic_id); /* FIXME check for collisions */ - ap_conn->topic_id = cell.topic_id; + ap_conn->topic_id = topic_id; snprintf(cell.payload+4, CELL_PAYLOAD_SIZE-4, "%s:%d", ap_conn->dest_addr, ap_conn->dest_port); cell.length = strlen(cell.payload+TOPIC_HEADER_SIZE)+1+TOPIC_HEADER_SIZE; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4a82d65a904a812007ad727ed33b241a1dfb373a..bc3828439c58febebbd3f4348d846a907b96b0ba 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -27,8 +27,8 @@ int connection_edge_process_inbuf(connection_t *conn) { memset(&cell, 0, sizeof(cell_t)); cell.command = CELL_DATA; cell.length = TOPIC_HEADER_SIZE; - cell.topic_command = TOPIC_COMMAND_END; - cell.topic_id = conn->topic_id; + SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_END); + SET_CELL_TOPIC_ID(cell, conn->topic_id); cell.aci = circ->n_aci; if (circuit_deliver_data_cell_from_edge(&cell, circ, conn->type) < 0) { @@ -76,8 +76,8 @@ int connection_edge_send_command(connection_t *conn, circuit_t *circ, int topic_ else cell.aci = circ->p_aci; cell.command = CELL_DATA; - cell.topic_command = topic_command; - cell.topic_id = conn->topic_id; + SET_CELL_TOPIC_COMMAND(cell, topic_command); + SET_CELL_TOPIC_ID(cell, conn->topic_id); cell.length = TOPIC_HEADER_SIZE; log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", topic_command, conn->type == CONN_TYPE_AP ? "forward" : "backward"); @@ -100,8 +100,8 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty assert(cell && circ); - topic_command = cell->topic_command; - topic_id = cell->topic_id; + topic_command = CELL_TOPIC_COMMAND(*cell); + topic_id = CELL_TOPIC_ID(*cell); log(LOG_DEBUG,"connection_edge_process_data_cell(): command %d topic %d", topic_command, topic_id); num_seen++; log(LOG_DEBUG,"connection_edge_process_data_cell(): Now seen %d data cells here.", num_seen); diff --git a/src/or/onion.c b/src/or/onion.c index 61ad1e2a5a887bb70da0e2cd2a3e371d48082efd..7b288f975d88ad6ab9351aa2c277ebc51c3aca58 100644 --- a/src/or/onion.c +++ b/src/or/onion.c @@ -311,15 +311,14 @@ int chooselen(double cw) { int len = 2; int retval = 0; - unsigned char coin; + uint8_t coin; if ((cw < 0) || (cw >= 1)) /* invalid parameter */ return -1; while(1) { - retval = crypto_pseudo_rand(1, &coin); - if (retval) + if (CRYPTO_PSEUDO_RAND_INT(coin)) return -1; if (coin > cw*255) /* don't extend */ @@ -378,7 +377,7 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r oldchoice = rarray_len; for(i=0;i<*routelen;i++) { log(LOG_DEBUG,"new_route(): Choosing hop %u.",i); - if(crypto_pseudo_rand(sizeof(unsigned int),(unsigned char *)&choice)) { + if (CRYPTO_PSEUDO_RAND_INT(choice)) { free((void *)route); return NULL; } diff --git a/src/or/or.h b/src/or/or.h index 1687cae38df70c06f0ad3f73df8907946ffe45b2..f2a6da55668e911a3d5ab018295b3feb173b9643 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -198,12 +198,12 @@ typedef struct { unsigned char length; /* of payload if data cell, else value of sendme */ uint32_t seq; /* sequence number */ - /* The following 2 fields are only set when command is CELL_DATA */ - unsigned char topic_command; - uint16_t topic_id; - unsigned char payload[CELL_PAYLOAD_SIZE]; } cell_t; +#define CELL_TOPIC_COMMAND(c) (*(uint8_t*)((c).payload)) +#define SET_CELL_TOPIC_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd)) +#define CELL_TOPIC_ID(c) ntohs(*(uint16_t*)((c).payload+2)) +#define SET_CELL_TOPIC_ID(c,id) (*(uint16_t*)((c).payload+2) = htons(id)) #define SOCKS4_REQUEST_GRANTED 90 #define SOCKS4_REQUEST_REJECT 91