summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-13 09:32:31 -0400
committerirungentoo <irungentoo@gmail.com>2013-08-13 09:32:31 -0400
commit97f449a2f1aa3e4fbe7f2d853efa0c7935ded967 (patch)
tree9896c268be528828617823d7b04da9f7a0d0386f
parent8fe1dec5d634a2bba214b9204bda8341e8b26ed5 (diff)
Fixed spam problem. (I broke the API so this will not build)
The friend address is what the byte string that you give away for people to add you will be called. 1. Every friend address now contains a number set by the friend. This is to prevent someone from randomly spamming people in the DHT with friend requests and makes it so you need the person to actually give you the address in some way to send the friend request. This number is expected to be encrypted with the friend request. All requests that do not contain this number will be rejected. This means the spammer can no longer use the DHT to collect lists of valid addresses to spam. It also enables users to quickly change the number in case a spammer gets hold of the address and starts spamming it. 2. A 2 byte checksum will be added (not implemented yet) to prevent people from accidentally adding random strings as friends. (NOTE that this has nothing to do with the spam problem I just decided to add a placeholder for it now.)
-rw-r--r--core/Messenger.c26
-rw-r--r--core/Messenger.h15
-rw-r--r--core/friend_requests.c32
-rw-r--r--core/friend_requests.h7
-rw-r--r--testing/toxic/chat.c8
-rw-r--r--testing/toxic/prompt.c14
6 files changed, 82 insertions, 20 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index af102406..ae7c5ff3 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -77,9 +77,23 @@ int getclient_id(Messenger *m, int friend_id, uint8_t *client_id)
77} 77}
78 78
79/* 79/*
80 * returns a FRIEND_ADDRESS_SIZE byte address to give to others.
81 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
82 *
83 * TODO: add checksum.
84 */
85void getaddress(Messenger *m, uint8_t *address)
86{
87 //memcpy(address, m->public_key, crypto_box_PUBLICKEYBYTES); //TODO
88 memcpy(address, self_public_key, crypto_box_PUBLICKEYBYTES);
89 uint32_t nospam = get_nospam();
90 memcpy(address + crypto_box_PUBLICKEYBYTES, &nospam, sizeof(nospam));
91}
92
93/*
80 * add a friend 94 * add a friend
81 * set the data that will be sent along with friend request 95 * set the data that will be sent along with friend request
82 * client_id is the client id of the friend 96 * address is the address of the friend (returned by getaddress) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum.
83 * data is the data and length is the length 97 * data is the data and length is the length
84 * returns the friend number if success 98 * returns the friend number if success
85 * return FA_TOOLONG if message length is too long 99 * return FA_TOOLONG if message length is too long
@@ -88,12 +102,14 @@ int getclient_id(Messenger *m, int friend_id, uint8_t *client_id)
88 * return FAERR_ALREADYSENT if friend request already sent or already a friend 102 * return FAERR_ALREADYSENT if friend request already sent or already a friend
89 * return FAERR_UNKNOWN for unknown error 103 * return FAERR_UNKNOWN for unknown error
90 */ 104 */
91int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length) 105int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
92{ 106{
93 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES 107 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
94 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES 108 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
95 + crypto_box_ZEROBYTES)) 109 + crypto_box_ZEROBYTES))
96 return FAERR_TOOLONG; 110 return FAERR_TOOLONG;
111 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
112 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
97 if (length < 1) 113 if (length < 1)
98 return FAERR_NOMESSAGE; 114 return FAERR_NOMESSAGE;
99 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 115 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
@@ -119,6 +135,7 @@ int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length
119 m->friendlist[i].info_size = length; 135 m->friendlist[i].info_size = length;
120 m->friendlist[i].message_id = 0; 136 m->friendlist[i].message_id = 0;
121 m->friendlist[i].receives_read_receipts = 1; /* default: YES */ 137 m->friendlist[i].receives_read_receipts = 1; /* default: YES */
138 memcpy(&(m->friendlist[i].friendrequest_nospam), address + crypto_box_PUBLICKEYBYTES, sizeof(uint32_t));
122 139
123 ++ m->numfriends; 140 ++ m->numfriends;
124 return i; 141 return i;
@@ -524,6 +541,7 @@ Messenger * initMessenger(void)
524 LosslessUDP_init(); 541 LosslessUDP_init();
525 friendreq_init(); 542 friendreq_init();
526 LANdiscovery_init(); 543 LANdiscovery_init();
544 set_nospam(random_int());
527 545
528 timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL); 546 timer_single(&LANdiscovery, 0, LAN_DISCOVERY_INTERVAL);
529 547
@@ -545,7 +563,7 @@ void doFriends(Messenger *m)
545 uint8_t temp[MAX_DATA_SIZE]; 563 uint8_t temp[MAX_DATA_SIZE];
546 for (i = 0; i < m->numfriends; ++i) { 564 for (i = 0; i < m->numfriends; ++i) {
547 if (m->friendlist[i].status == FRIEND_ADDED) { 565 if (m->friendlist[i].status == FRIEND_ADDED) {
548 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size); 566 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size);
549 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */ 567 if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
550 set_friend_status(m, i, FRIEND_REQUESTED); 568 set_friend_status(m, i, FRIEND_REQUESTED);
551 else if (fr > 0) 569 else if (fr > 0)
@@ -554,7 +572,7 @@ void doFriends(Messenger *m)
554 if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ 572 if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
555 if (m->friendlist[i].status == FRIEND_REQUESTED) { 573 if (m->friendlist[i].status == FRIEND_REQUESTED) {
556 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ 574 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
557 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size); 575 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size);
558 m->friendlist[i].friend_request_id = unix_time(); 576 m->friendlist[i].friend_request_id = unix_time();
559 } 577 }
560 } 578 }
diff --git a/core/Messenger.h b/core/Messenger.h
index aa9611a4..48e14cf7 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -38,6 +38,8 @@ extern "C" {
38#define MAX_NAME_LENGTH 128 38#define MAX_NAME_LENGTH 128
39#define MAX_STATUSMESSAGE_LENGTH 128 39#define MAX_STATUSMESSAGE_LENGTH 128
40 40
41#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
42
41#define PACKET_ID_NICKNAME 48 43#define PACKET_ID_NICKNAME 48
42#define PACKET_ID_STATUSMESSAGE 49 44#define PACKET_ID_STATUSMESSAGE 49
43#define PACKET_ID_USERSTATUS 50 45#define PACKET_ID_USERSTATUS 50
@@ -89,6 +91,7 @@ typedef struct {
89 uint16_t info_size; /* length of the info */ 91 uint16_t info_size; /* length of the info */
90 uint32_t message_id; /* a semi-unique id used in read receipts */ 92 uint32_t message_id; /* a semi-unique id used in read receipts */
91 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */ 93 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
94 uint32_t friendrequest_nospam; /*The nospam number used in the friend request*/
92} Friend; 95} Friend;
93 96
94typedef struct Messenger { 97typedef struct Messenger {
@@ -134,9 +137,17 @@ typedef struct Messenger {
134} Messenger; 137} Messenger;
135 138
136/* 139/*
140 * returns a FRIEND_ADDRESS_SIZE byte address to give to others.
141 * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]
142 *
143 * TODO: add checksum.
144 */
145void getaddress(Messenger *m, uint8_t *address);
146
147/*
137 * add a friend 148 * add a friend
138 * set the data that will be sent along with friend request 149 * set the data that will be sent along with friend request
139 * client_id is the client id of the friend 150 * address is the address of the friend (returned by getaddress) it must be FRIEND_ADDRESS_SIZE bytes. TODO: add checksum.
140 * data is the data and length is the length 151 * data is the data and length is the length
141 * returns the friend number if success 152 * returns the friend number if success
142 * return -1 if message length is too long 153 * return -1 if message length is too long
@@ -145,7 +156,7 @@ typedef struct Messenger {
145 * return -4 if friend request already sent or already a friend 156 * return -4 if friend request already sent or already a friend
146 * return -5 for unknown error 157 * return -5 for unknown error
147 */ 158 */
148int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length); 159int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length);
149 160
150 161
151/* add a friend without sending a friendrequest. 162/* add a friend without sending a friendrequest.
diff --git a/core/friend_requests.c b/core/friend_requests.c
index 5e9b447c..8276db29 100644
--- a/core/friend_requests.c
+++ b/core/friend_requests.c
@@ -25,15 +25,22 @@
25 25
26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; 26uint8_t self_public_key[crypto_box_PUBLICKEYBYTES];
27 27
28
28/* Try to send a friendrequest to peer with public_key 29/* Try to send a friendrequest to peer with public_key
29 data is the data in the request and length is the length. 30 data is the data in the request and length is the length.
30 return -1 if failure. 31 return -1 if failure.
31 return 0 if it sent the friend request directly to the friend. 32 return 0 if it sent the friend request directly to the friend.
32 return the number of peers it was routed through if it did not send it directly.*/ 33 return the number of peers it was routed through if it did not send it directly.*/
33int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length) 34int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length)
34{ 35{
36 if(length - sizeof(nospam_num) > MAX_DATA_SIZE)
37 return -1;
38
39 uint8_t temp[MAX_DATA_SIZE];
40 memcpy(temp, &nospam_num, sizeof(nospam_num));
41 memcpy(temp + sizeof(nospam_num), data, length);
35 uint8_t packet[MAX_DATA_SIZE]; 42 uint8_t packet[MAX_DATA_SIZE];
36 int len = create_request(packet, public_key, data, length, 32); /* 32 is friend request packet id */ 43 int len = create_request(packet, public_key, temp, length + sizeof(nospam_num), 32); /* 32 is friend request packet id */
37 44
38 if (len == -1) 45 if (len == -1)
39 return -1; 46 return -1;
@@ -57,6 +64,20 @@ int send_friendrequest(uint8_t * public_key, uint8_t * data, uint32_t length)
57 return num; 64 return num;
58} 65}
59 66
67static uint32_t nospam;
68/*
69 * Set and get the nospam variable used to prevent one type of friend request spam
70 */
71void set_nospam(uint32_t num)
72{
73 nospam = num;
74}
75
76uint32_t get_nospam()
77{
78 return nospam;
79}
80
60static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void*); 81static void (*handle_friendrequest)(uint8_t *, uint8_t *, uint16_t, void*);
61static uint8_t handle_friendrequest_isset = 0; 82static uint8_t handle_friendrequest_isset = 0;
62static void* handle_friendrequest_userdata; 83static void* handle_friendrequest_userdata;
@@ -115,14 +136,17 @@ static int friendreq_handlepacket(IP_Port source, uint8_t * packet, uint32_t len
115 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 136 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
116 uint8_t data[MAX_DATA_SIZE]; 137 uint8_t data[MAX_DATA_SIZE];
117 int len = handle_request(public_key, data, packet, length); 138 int len = handle_request(public_key, data, packet, length);
118
119 if (len == -1) 139 if (len == -1)
120 return 1; 140 return 1;
141 if (len <= sizeof(nospam))
142 return 1;
121 if (request_received(public_key)) 143 if (request_received(public_key))
122 return 1; 144 return 1;
145 if (memcmp(data, &nospam, sizeof(nospam)) != 0)
146 return 1;
123 147
124 addto_receivedlist(public_key); 148 addto_receivedlist(public_key);
125 (*handle_friendrequest)(public_key, data, len, handle_friendrequest_userdata); 149 (*handle_friendrequest)(public_key, data + 4, len - 4, handle_friendrequest_userdata);
126 } else { /* if request is not for us, try routing it. */ 150 } else { /* if request is not for us, try routing it. */
127 if(route_packet(packet + 1, packet, length) == length) 151 if(route_packet(packet + 1, packet, length) == length)
128 return 0; 152 return 0;
diff --git a/core/friend_requests.h b/core/friend_requests.h
index f18107ce..0b75fd60 100644
--- a/core/friend_requests.h
+++ b/core/friend_requests.h
@@ -33,7 +33,12 @@ extern "C" {
33 33
34/* Try to send a friendrequest to peer with public_key 34/* Try to send a friendrequest to peer with public_key
35 data is the data in the request and length is the length. */ 35 data is the data in the request and length is the length. */
36int send_friendrequest(uint8_t *public_key, uint8_t *data, uint32_t length); 36int send_friendrequest(uint8_t * public_key, uint32_t nospam_num, uint8_t * data, uint32_t length);
37/*
38 * Set and get the nospam variable used to prevent one type of friend request spam
39 */
40void set_nospam(uint32_t num);
41uint32_t get_nospam();
37 42
38/* set the function that will be executed when a friend request for us is received. 43/* set the function that will be executed when a friend request for us is received.
39 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */ 44 function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) */
diff --git a/testing/toxic/chat.c b/testing/toxic/chat.c
index 35be3bd3..1b5e743d 100644
--- a/testing/toxic/chat.c
+++ b/testing/toxic/chat.c
@@ -307,11 +307,13 @@ void execute(ToxWindow *self, ChatContext *ctx, Messenger *m, char *cmd)
307 } 307 }
308 308
309 else if (!strcmp(cmd, "/myid")) { 309 else if (!strcmp(cmd, "/myid")) {
310 char id[KEY_SIZE_BYTES*2+1] = {0}; 310 char id[FRIEND_ADDRESS_SIZE*2+1] = {0};
311 int i; 311 int i;
312 for (i = 0; i < KEY_SIZE_BYTES; i++) { 312 uint8_t address[FRIEND_ADDRESS_SIZE];
313 getaddress(m, address);
314 for (i = 0; i < FRIEND_ADDRESS_SIZE; i++) {
313 char xx[3]; 315 char xx[3];
314 snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); 316 snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
315 strcat(id, xx); 317 strcat(id, xx);
316 } 318 }
317 wprintw(ctx->history, "Your ID: %s\n", id); 319 wprintw(ctx->history, "Your ID: %s\n", id);
diff --git a/testing/toxic/prompt.c b/testing/toxic/prompt.c
index 67f80fef..e1a7d75c 100644
--- a/testing/toxic/prompt.c
+++ b/testing/toxic/prompt.c
@@ -93,7 +93,7 @@ void cmd_accept(ToxWindow *self, Messenger *m, char **args)
93 93
94void cmd_add(ToxWindow *self, Messenger *m, char **args) 94void cmd_add(ToxWindow *self, Messenger *m, char **args)
95{ 95{
96 uint8_t id_bin[KEY_SIZE_BYTES]; 96 uint8_t id_bin[FRIEND_ADDRESS_SIZE];
97 char xx[3]; 97 char xx[3];
98 uint32_t x; 98 uint32_t x;
99 char *id = args[1]; 99 char *id = args[1];
@@ -106,12 +106,12 @@ void cmd_add(ToxWindow *self, Messenger *m, char **args)
106 if (!msg) 106 if (!msg)
107 msg = ""; 107 msg = "";
108 108
109 if (strlen(id) != 2*KEY_SIZE_BYTES) { 109 if (strlen(id) != 2*FRIEND_ADDRESS_SIZE) {
110 wprintw(self->window, "Invalid ID length.\n"); 110 wprintw(self->window, "Invalid ID length.\n");
111 return; 111 return;
112 } 112 }
113 int i; 113 int i;
114 for (i = 0; i < KEY_SIZE_BYTES; ++i) { 114 for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
115 xx[0] = id[2*i]; 115 xx[0] = id[2*i];
116 xx[1] = id[2*i+1]; 116 xx[1] = id[2*i+1];
117 xx[2] = '\0'; 117 xx[2] = '\0';
@@ -217,11 +217,13 @@ void cmd_msg(ToxWindow *self, Messenger *m, char **args)
217 217
218void cmd_myid(ToxWindow *self, Messenger *m, char **args) 218void cmd_myid(ToxWindow *self, Messenger *m, char **args)
219{ 219{
220 char id[KEY_SIZE_BYTES*2 + 1] = {0}; 220 char id[FRIEND_ADDRESS_SIZE*2 + 1] = {0};
221 size_t i; 221 size_t i;
222 for (i = 0; i < KEY_SIZE_BYTES; ++i) { 222 uint8_t address[FRIEND_ADDRESS_SIZE];
223 getaddress(m, address);
224 for (i = 0; i < FRIEND_ADDRESS_SIZE; ++i) {
223 char xx[3]; 225 char xx[3];
224 snprintf(xx, sizeof(xx), "%02x", self_public_key[i] & 0xff); 226 snprintf(xx, sizeof(xx), "%02X", address[i] & 0xff);
225 strcat(id, xx); 227 strcat(id, xx);
226 } 228 }
227 wprintw(self->window, "Your ID: %s\n", id); 229 wprintw(self->window, "Your ID: %s\n", id);