diff --git a/docs/Prevent_Tracking.txt b/docs/Prevent_Tracking.txt index 08c3f673..e4d19edc 100644 --- a/docs/Prevent_Tracking.txt +++ b/docs/Prevent_Tracking.txt @@ -110,8 +110,8 @@ data to route request packet: Data sent to us: announce response packet: [uint8_t packet id (132)][nonce] -encrypted with the DHT private key of Node D, our long term public key and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]] -(if the ping id is zero, it means the client id we are searching for is stored on ) +encrypted with the DHT private key of Node D, the public key in the request and the nonce:[[(32 bytes) ping_id][Node_Format * (maximum of 8)]] +(if the ping id is zero, it means the information to reach the client id we are searching for is stored on this node) data to route response packet: [uint8_t packet id (134)][nonce]encrypted with that temporary private key and the nonce:[data] diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 935f0246..07500032 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -36,9 +36,6 @@ #include "misc_tools.h" #include "util.h" -/* The max number of nodes to send with send nodes. */ -#define MAX_SENT_NODES 8 - /* The timeout after which a node is discarded completely. */ #define KILL_NODE_TIMEOUT 300 @@ -366,8 +363,8 @@ static int get_somewhat_close_nodes(DHT *dht, uint8_t *client_id, Node_format *n return num_nodes; } -static int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, - uint8_t want_good) +int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, + uint8_t want_good) { if (!dht->assoc) return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 25a257e3..c42bceb8 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -35,6 +35,9 @@ /* A list of the clients mathematically closest to ours. */ #define LCLIENT_LIST 32 +/* The max number of nodes to send with send nodes. */ +#define MAX_SENT_NODES 8 + /* Maximum newly announced nodes to ping per TIME_TOPING seconds. */ #define MAX_TOPING 16 @@ -204,6 +207,19 @@ int DHT_getfriendip(DHT *dht, uint8_t *client_id, IP_Port *ip_port); */ int id_closest(uint8_t *id, uint8_t *id1, uint8_t *id2); +/* Get the (maximum MAX_SENT_NODES) closest nodes to client_id we know + * and put them in nodes_list (must be MAX_SENT_NODES big). + * + * sa_family = family (IPv4 or IPv6)? + * is_LAN = return some LAN ips (true or false) + * want_good = do we want tested nodes or not? (TODO) + * + * return the number of nodes returned. + * + */ +int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_family_t sa_family, uint8_t is_LAN, + uint8_t want_good); + /* Run this function at least a couple times per second (It's the main loop). */ void do_DHT(DHT *dht); diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c new file mode 100644 index 00000000..b6f78430 --- /dev/null +++ b/toxcore/onion_announce.c @@ -0,0 +1,146 @@ +/* +* onion_announce.c -- Implementation of the announce part of docs/Prevent_Tracking.txt +* +* Copyright (C) 2013 Tox project All Rights Reserved. +* +* This file is part of Tox. +* +* Tox is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Tox is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Tox. If not, see . +* +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "onion_announce.h" +#include "LAN_discovery.h" +#include "util.h" + +#define PING_ID_SIZE crypto_hash_sha256_BYTES +#define PING_ID_TIMEOUT 10 + +#define ANNOUNCE_REQUEST_SIZE (1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES + PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES + ONION_RETURN_3) + +uint8_t ping_id_zero[PING_ID_SIZE]; + +/* Generate a ping_id and put it in ping_id */ +static void generate_ping_id(Onion_Announce *onion_a, uint64_t time, uint8_t *public_key, uint8_t *ret, + uint8_t *ping_id) +{ + time /= PING_ID_TIMEOUT; + uint8_t data[crypto_secretbox_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES + ONION_RETURN_3]; + memcpy(data, onion_a->secret_bytes, crypto_secretbox_KEYBYTES); + memcpy(data + crypto_secretbox_KEYBYTES, &time, sizeof(time)); + memcpy(data + crypto_secretbox_KEYBYTES + sizeof(time), public_key, crypto_box_PUBLICKEYBYTES); + memcpy(data + crypto_secretbox_KEYBYTES + sizeof(time) + crypto_box_PUBLICKEYBYTES, ret, ONION_RETURN_3); + crypto_hash_sha256(ping_id, data, sizeof(data)); +} + +/* add entry to entries list + * + * return 0 if failure + * return 1 if added + */ +static int add_to_entries(Onion_Announce *onion_a, uint8_t *public_key, uint8_t *ret) +{ + + return 0; +} + +/* check if public key is in entries list + * + * return 0 if no + * return 1 if yes + */ +static int in_entries(Onion_Announce *onion_a, uint8_t *public_key) +{ + + return 0; +} + +static int handle_announce_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) +{ + Onion_Announce *onion_a = object; + + if (length != ANNOUNCE_REQUEST_SIZE) + return 1; + + uint8_t plain[PING_ID_SIZE + crypto_box_PUBLICKEYBYTES]; + int len = decrypt_data(packet + 1 + crypto_box_NONCEBYTES, onion_a->dht->self_secret_key, packet + 1, + packet + 1 + crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES, + PING_ID_SIZE + crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES, plain); + + if ((uint32_t)len != sizeof(plain)) + return 1; + + uint8_t ping_id1[PING_ID_SIZE]; + generate_ping_id(onion_a, unix_time(), packet + 1 + crypto_box_NONCEBYTES, + packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3), ping_id1); + + uint8_t ping_id2[PING_ID_SIZE]; + generate_ping_id(onion_a, unix_time() + PING_ID_TIMEOUT, packet + 1 + crypto_box_NONCEBYTES, + packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3), ping_id2); + + int stored = 0; + + if (memcmp(ping_id1, plain, PING_ID_SIZE) == 0 || memcmp(ping_id2, plain, PING_ID_SIZE) == 0) { + stored = add_to_entries(onion_a, packet + 1 + crypto_box_NONCEBYTES, + packet + (ANNOUNCE_REQUEST_SIZE - ONION_RETURN_3)); + } else { + stored = in_entries(onion_a, plain + PING_ID_SIZE); + } + + Node_format nodes_list[MAX_SENT_NODES]; + uint32_t num_nodes = get_close_nodes(onion_a->dht, plain + PING_ID_SIZE, nodes_list, source.ip.family, + LAN_ip(source.ip) == 0, 1); + + uint8_t nonce[crypto_box_NONCEBYTES]; + new_nonce(nonce); + + return 0; +} + +static int handle_data_request(void *object, IP_Port source, uint8_t *packet, uint32_t length) +{ + Onion_Announce *onion_a = object; + + return 0; +} + +Onion_Announce *new_onion_announce(DHT *dht) +{ + if (dht == NULL) + return NULL; + + Onion_Announce *onion_a = calloc(1, sizeof(Onion_Announce)); + + if (onion_a == NULL) + return NULL; + + onion_a->dht = dht; + onion_a->net = dht->c->lossless_udp->net; + new_symmetric_key(onion_a->secret_bytes); + + networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_announce_request, onion_a); + networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, &handle_data_request, onion_a); + + return onion_a; +} + +void kill_onion_announce(Onion_Announce *onion_a) +{ + networking_registerhandler(onion_a->net, NET_PACKET_ANNOUNCE_REQUEST, NULL, NULL); + networking_registerhandler(onion_a->net, NET_PACKET_ONION_DATA_REQUEST, NULL, NULL); + free(onion_a); +} diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h new file mode 100644 index 00000000..2b36d35c --- /dev/null +++ b/toxcore/onion_announce.h @@ -0,0 +1,41 @@ +/* +* onion_announce.h -- Implementation of the announce part of docs/Prevent_Tracking.txt +* +* Copyright (C) 2013 Tox project All Rights Reserved. +* +* This file is part of Tox. +* +* Tox is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* Tox is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Tox. If not, see . +* +*/ + +#include "onion.h" + +#define ONION_ANNOUNCE_MAX_ENTRIES 32 +typedef struct { + DHT *dht; + Networking_Core *net; + struct { + uint8_t public_key[crypto_box_PUBLICKEYBYTES]; + uint8_t ret[ONION_RETURN_3]; + } entries[ONION_ANNOUNCE_MAX_ENTRIES]; + /* This is crypto_secretbox_KEYBYTES long just so we can use new_symmetric_key() to fill it */ + uint8_t secret_bytes[crypto_secretbox_KEYBYTES]; +} Onion_Announce; + + + +Onion_Announce *new_onion_announce(DHT *dht); + +void kill_onion_announce(Onion_Announce *onion_a);