summaryrefslogtreecommitdiff
path: root/toxcore
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore')
-rw-r--r--toxcore/DHT.c109
1 files changed, 105 insertions, 4 deletions
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index 661ac98a..60e8b88f 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -765,7 +765,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
765{ 765{
766 DHT *dht = object; 766 DHT *dht = object;
767 767
768 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH + crypto_box_MACBYTES )) 768 if (length != ( 1 + CLIENT_ID_SIZE + crypto_box_NONCEBYTES + CLIENT_ID_SIZE + NODES_ENCRYPTED_MESSAGE_LENGTH +
769 crypto_box_MACBYTES ))
769 return 1; 770 return 1;
770 771
771 /* Check if packet is from ourself. */ 772 /* Check if packet is from ourself. */
@@ -785,7 +786,8 @@ static int handle_getnodes(void *object, IP_Port source, uint8_t *packet, uint32
785 return 1; 786 return 1;
786 787
787 sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE); 788 sendnodes(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE);
788 sendnodes_ipv6(dht, source, packet + 1, plain, plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */ 789 sendnodes_ipv6(dht, source, packet + 1, plain,
790 plain + CLIENT_ID_SIZE); /* TODO: prevent possible amplification attacks */
789 791
790 add_toping(dht->ping, packet + 1, source); 792 add_toping(dht->ping, packet + 1, source);
791 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */ 793 //send_ping_request(dht, source, packet + 1); /* TODO: make this smarter? */
@@ -804,13 +806,17 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i
804 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES, 806 NODES_ENCRYPTED_MESSAGE_LENGTH - crypto_secretbox_NONCEBYTES,
805 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2) 807 plain_message) != sizeof(uint64_t) + sizeof(Node_format) * 2)
806 return 0; 808 return 0;
809
807 uint64_t comp_time; 810 uint64_t comp_time;
808 memcpy(&comp_time, plain_message, sizeof(uint64_t)); 811 memcpy(&comp_time, plain_message, sizeof(uint64_t));
809 uint64_t temp_time = unix_time(); 812 uint64_t temp_time = unix_time();
813
810 if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time) 814 if (comp_time + PING_TIMEOUT < temp_time || temp_time < comp_time)
811 return 0; 815 return 0;
816
812 Node_format test; 817 Node_format test;
813 memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format)); 818 memcpy(&test, plain_message + sizeof(uint64_t), sizeof(Node_format));
819
814 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0) 820 if (!ipport_equal(&test.ip_port, &node_ip_port) || memcmp(test.client_id, client_id, CLIENT_ID_SIZE) != 0)
815 return 0; 821 return 0;
816 822
@@ -818,6 +824,9 @@ static uint8_t sent_getnode_to_node(DHT *dht, uint8_t *client_id, IP_Port node_i
818 return 1; 824 return 1;
819} 825}
820 826
827/* Function is needed in following functions. */
828static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes);
829
821static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length) 830static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint32_t length)
822{ 831{
823 DHT *dht = object; 832 DHT *dht = object;
@@ -845,6 +854,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
845 return 1; 854 return 1;
846 855
847 Node_format sendback_node; 856 Node_format sendback_node;
857
848 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node)) 858 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node4_format_size, &sendback_node))
849 return 1; 859 return 1;
850 860
@@ -868,6 +878,7 @@ static int handle_sendnodes(void *object, IP_Port source, uint8_t *packet, uint3
868 num_nodes = num_nodes_ok; 878 num_nodes = num_nodes_ok;
869 } 879 }
870 880
881 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
871 addto_lists(dht, source, packet + 1); 882 addto_lists(dht, source, packet + 1);
872 883
873 for (i = 0; i < num_nodes; ++i) { 884 for (i = 0; i < num_nodes; ++i) {
@@ -905,6 +916,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
905 return 1; 916 return 1;
906 917
907 Node_format sendback_node; 918 Node_format sendback_node;
919
908 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node)) 920 if (!sent_getnode_to_node(dht, packet + 1, source, plain + num_nodes * Node_format_size, &sendback_node))
909 return 1; 921 return 1;
910 922
@@ -912,6 +924,7 @@ static int handle_sendnodes_ipv6(void *object, IP_Port source, uint8_t *packet,
912 Node_format nodes_list[MAX_SENT_NODES]; 924 Node_format nodes_list[MAX_SENT_NODES];
913 memcpy(nodes_list, plain, num_nodes * sizeof(Node_format)); 925 memcpy(nodes_list, plain, num_nodes * sizeof(Node_format));
914 926
927 send_hardening_getnode_res(dht, &sendback_node, nodes_list, num_nodes);
915 addto_lists(dht, source, packet + 1); 928 addto_lists(dht, source, packet + 1);
916 929
917 for (i = 0; i < num_nodes; ++i) { 930 for (i = 0; i < num_nodes; ++i) {
@@ -1552,12 +1565,100 @@ static void do_NAT(DHT *dht)
1552/*----------------------------------------------------------------------------------*/ 1565/*----------------------------------------------------------------------------------*/
1553/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/ 1566/*-----------------------END OF NAT PUNCHING FUNCTIONS------------------------------*/
1554 1567
1568#define HARDREQ_DATA_SIZE 768 /* Attempt to prevent amplification/other attacks*/
1555 1569
1556/* Handle a received ping request for. */ 1570#define CHECK_TYPE_GETNODE_REQ 0
1571#define CHECK_TYPE_GETNODE_RES 1
1572
1573static int send_hardening_req(DHT *dht, Node_format *sendto, uint8_t type, uint8_t *contents, uint16_t length)
1574{
1575 if (length > HARDREQ_DATA_SIZE - 1)
1576 return -1;
1577
1578 uint8_t packet[MAX_DATA_SIZE];
1579 uint8_t data[HARDREQ_DATA_SIZE] = {0};
1580 data[0] = type;
1581 memcpy(data + 1, contents, length);
1582 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1583 sizeof(data), CRYPTO_PACKET_HARDENING);
1584
1585 if (len == -1)
1586 return -1;
1587
1588 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1589}
1590
1591/* Send a get node hardening request */
1592static int send_hardening_getnode_req(DHT *dht, Node_format *dest, Node_format *node_totest, uint8_t *search_id)
1593{
1594 uint8_t data[sizeof(Node_format) + CLIENT_ID_SIZE];
1595 memcpy(data, node_totest, sizeof(Node_format));
1596 memcpy(data + sizeof(Node_format), search_id, CLIENT_ID_SIZE);
1597 return send_hardening_req(dht, dest, CHECK_TYPE_GETNODE_REQ, data, sizeof(Node_format) + CLIENT_ID_SIZE);
1598}
1599
1600/* Send a get node hardening response */
1601static int send_hardening_getnode_res(DHT *dht, Node_format *sendto, Node_format *list, uint16_t num_nodes)
1602{
1603 if (!ip_isset(&sendto->ip_port.ip))
1604 return -1;
1605
1606 uint8_t packet[MAX_DATA_SIZE];
1607 uint8_t data[1 + num_nodes * sizeof(Node_format)];
1608 data[0] = CHECK_TYPE_GETNODE_RES;
1609 memcpy(data + 1, list, num_nodes * sizeof(Node_format));
1610 int len = create_request(dht->c->self_public_key, dht->c->self_secret_key, packet, sendto->client_id, data,
1611 sizeof(data), CRYPTO_PACKET_HARDENING);
1612
1613 if (len == -1)
1614 return -1;
1615
1616 return sendpacket(dht->c->lossless_udp->net, sendto->ip_port, packet, len);
1617}
1618
1619/* Handle a received hardening packet */
1557static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length) 1620static int handle_hardening(void *object, IP_Port source, uint8_t *source_pubkey, uint8_t *packet, uint32_t length)
1558{ 1621{
1559 DHT *dht = object; 1622 DHT *dht = object;
1560 return 0;/* success*/ 1623
1624 if (length < 2) {
1625 return 1;
1626 }
1627
1628 switch (packet[0]) {
1629 case CHECK_TYPE_GETNODE_REQ: {
1630 if (length != HARDREQ_DATA_SIZE)
1631 return 1;
1632
1633 Node_format node, tocheck_node;
1634 node.ip_port = source;
1635 memcpy(node.client_id, source_pubkey, CLIENT_ID_SIZE);
1636 memcpy(&tocheck_node, packet + 1, sizeof(Node_format));
1637
1638 if (getnodes(dht, tocheck_node.ip_port, tocheck_node.client_id, packet + 1 + sizeof(Node_format), &node) == -1)
1639 return 1;
1640
1641 return 0;
1642 }
1643
1644 case CHECK_TYPE_GETNODE_RES: {
1645 if ((length - 1) % sizeof(Node_format) != 0)
1646 return 1;
1647
1648 uint16_t num = (length - 1) / sizeof(Node_format);
1649
1650 if (num > MAX_SENT_NODES || num == 0)
1651 return 1;
1652
1653 Node_format nodes[num];
1654 memcpy(nodes, packet + 1, sizeof(Node_format)*num);
1655 /* If Nodes look good and the request checks out */
1656 //TODO
1657 return 0;/* success*/
1658 }
1659 }
1660
1661 return 1;
1561} 1662}
1562 1663
1563/*----------------------------------------------------------------------------------*/ 1664/*----------------------------------------------------------------------------------*/