1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include "or.h"
/********* START VARIABLES **********/
tracked_onion_t *tracked_onions = NULL; /* linked list of tracked onions */
tracked_onion_t *last_tracked_onion = NULL;
/********* END VARIABLES ************/
int decide_aci_type(uint32_t local_addr, uint16_t local_port,
uint32_t remote_addr, uint16_t remote_port) {
if(local_addr > remote_addr)
return ACI_TYPE_HIGHER;
if(local_addr < remote_addr)
return ACI_TYPE_LOWER;
if(local_port > remote_port)
return ACI_TYPE_HIGHER;
/* else */
return ACI_TYPE_LOWER;
}
int process_onion(circuit_t *circ, connection_t *conn) {
aci_t aci_type;
if(!decrypt_onion((onion_layer_t *)circ->onion,circ->onionlen,conn->prkey)) {
log(LOG_DEBUG,"command_process_create_cell(): decrypt_onion() failed, closing circuit.");
return -1;
}
log(LOG_DEBUG,"command_process_create_cell(): Onion decrypted.");
/* check freshness */
if (((onion_layer_t *)circ->onion)->expire < time(NULL)) /* expired onion */
{
log(LOG_NOTICE,"I have just received an expired onion. This could be a replay attack.");
return -1;
}
aci_type = decide_aci_type(conn->local.sin_addr.s_addr, conn->local.sin_port,
((onion_layer_t *)circ->onion)->addr,((onion_layer_t *)circ->onion)->port);
if(circuit_init(circ, aci_type) < 0) {
log(LOG_ERR,"process_onion(): init_circuit() failed.");
return -1;
}
/* check for replay */
if(id_tracked_onion(circ->onion, circ->onionlen, tracked_onions)) {
log(LOG_NOTICE,"process_onion(): I have just received a replayed onion. This could be a replay attack.");
return -1;
}
/* track the new onion */
if(!new_tracked_onion(circ->onion,circ->onionlen, &tracked_onions, &last_tracked_onion)) {
log(LOG_DEBUG,"process_onion(): Onion tracking failed. Will ignore.");
}
return 0;
}
|