summaryrefslogtreecommitdiff
path: root/core/Messenger.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/Messenger.c')
-rw-r--r--core/Messenger.c320
1 files changed, 211 insertions, 109 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index 4ed8bc41..09032067 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -35,11 +35,14 @@ static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_i
35 35
36/* set the size of the friend list to numfriends 36/* set the size of the friend list to numfriends
37 return -1 if realloc fails */ 37 return -1 if realloc fails */
38int realloc_friendlist(Messenger *m, uint32_t num) { 38int realloc_friendlist(Messenger *m, uint32_t num)
39 Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend)); 39{
40 Friend *newfriendlist = realloc(m->friendlist, num * sizeof(Friend));
41
40 if (newfriendlist == NULL) 42 if (newfriendlist == NULL)
41 return -1; 43 return -1;
42 memset(&newfriendlist[num-1], 0, sizeof(Friend)); 44
45 memset(&newfriendlist[num - 1], 0, sizeof(Friend));
43 m->friendlist = newfriendlist; 46 m->friendlist = newfriendlist;
44 return 0; 47 return 0;
45} 48}
@@ -85,8 +88,10 @@ static uint16_t address_checksum(uint8_t *address, uint32_t len)
85 uint8_t checksum[2] = {0}; 88 uint8_t checksum[2] = {0};
86 uint16_t check; 89 uint16_t check;
87 uint32_t i; 90 uint32_t i;
88 for(i = 0; i < len; ++i) 91
92 for (i = 0; i < len; ++i)
89 checksum[i % 2] ^= address[i]; 93 checksum[i % 2] ^= address[i];
94
90 memcpy(&check, checksum, sizeof(check)); 95 memcpy(&check, checksum, sizeof(check));
91 return check; 96 return check;
92} 97}
@@ -125,25 +130,33 @@ void getaddress(Messenger *m, uint8_t *address)
125int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length) 130int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
126{ 131{
127 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES 132 if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
128 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES 133 - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
129 + crypto_box_ZEROBYTES)) 134 + crypto_box_ZEROBYTES))
130 return FAERR_TOOLONG; 135 return FAERR_TOOLONG;
136
131 uint8_t client_id[crypto_box_PUBLICKEYBYTES]; 137 uint8_t client_id[crypto_box_PUBLICKEYBYTES];
132 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES); 138 memcpy(client_id, address, crypto_box_PUBLICKEYBYTES);
133 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum)); 139 uint16_t check, checksum = address_checksum(address, FRIEND_ADDRESS_SIZE - sizeof(checksum));
134 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check)); 140 memcpy(&check, address + crypto_box_PUBLICKEYBYTES + sizeof(uint32_t), sizeof(check));
141
135 if (check != checksum) 142 if (check != checksum)
136 return FAERR_BADCHECKSUM; 143 return FAERR_BADCHECKSUM;
144
137 if (length < 1) 145 if (length < 1)
138 return FAERR_NOMESSAGE; 146 return FAERR_NOMESSAGE;
147
139 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) 148 if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
140 return FAERR_OWNKEY; 149 return FAERR_OWNKEY;
150
141 int friend_id = getfriend_id(m, client_id); 151 int friend_id = getfriend_id(m, client_id);
152
142 if (friend_id != -1) { 153 if (friend_id != -1) {
143 uint32_t nospam; 154 uint32_t nospam;
144 memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam)); 155 memcpy(&nospam, address + crypto_box_PUBLICKEYBYTES, sizeof(nospam));
145 if(m->friendlist[friend_id].friendrequest_nospam == nospam) 156
157 if (m->friendlist[friend_id].friendrequest_nospam == nospam)
146 return FAERR_ALREADYSENT; 158 return FAERR_ALREADYSENT;
159
147 m->friendlist[friend_id].friendrequest_nospam = nospam; 160 m->friendlist[friend_id].friendrequest_nospam = nospam;
148 return FAERR_SETNEWNOSPAM; 161 return FAERR_SETNEWNOSPAM;
149 } 162 }
@@ -153,6 +166,7 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
153 return FAERR_NOMEM; 166 return FAERR_NOMEM;
154 167
155 uint32_t i; 168 uint32_t i;
169
156 for (i = 0; i <= m->numfriends; ++i) { 170 for (i = 0; i <= m->numfriends; ++i) {
157 if (m->friendlist[i].status == NOFRIEND) { 171 if (m->friendlist[i].status == NOFRIEND) {
158 DHT_addfriend(client_id); 172 DHT_addfriend(client_id);
@@ -173,10 +187,11 @@ int m_addfriend(Messenger *m, uint8_t *address, uint8_t *data, uint16_t length)
173 return i; 187 return i;
174 } 188 }
175 } 189 }
190
176 return FAERR_UNKNOWN; 191 return FAERR_UNKNOWN;
177} 192}
178 193
179int m_addfriend_norequest(Messenger *m, uint8_t * client_id) 194int m_addfriend_norequest(Messenger *m, uint8_t *client_id)
180{ 195{
181 if (getfriend_id(m, client_id) != -1) 196 if (getfriend_id(m, client_id) != -1)
182 return -1; 197 return -1;
@@ -186,8 +201,9 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
186 return FAERR_NOMEM; 201 return FAERR_NOMEM;
187 202
188 uint32_t i; 203 uint32_t i;
204
189 for (i = 0; i <= m->numfriends; ++i) { 205 for (i = 0; i <= m->numfriends; ++i) {
190 if(m->friendlist[i].status == NOFRIEND) { 206 if (m->friendlist[i].status == NOFRIEND) {
191 DHT_addfriend(client_id); 207 DHT_addfriend(client_id);
192 m->friendlist[i].status = FRIEND_REQUESTED; 208 m->friendlist[i].status = FRIEND_REQUESTED;
193 m->friendlist[i].crypt_connection_id = -1; 209 m->friendlist[i].crypt_connection_id = -1;
@@ -202,6 +218,7 @@ int m_addfriend_norequest(Messenger *m, uint8_t * client_id)
202 return i; 218 return i;
203 } 219 }
204 } 220 }
221
205 return -1; 222 return -1;
206} 223}
207 224
@@ -220,9 +237,10 @@ int m_delfriend(Messenger *m, int friendnumber)
220 uint32_t i; 237 uint32_t i;
221 238
222 for (i = m->numfriends; i != 0; --i) { 239 for (i = m->numfriends; i != 0; --i) {
223 if (m->friendlist[i-1].status != NOFRIEND) 240 if (m->friendlist[i - 1].status != NOFRIEND)
224 break; 241 break;
225 } 242 }
243
226 m->numfriends = i; 244 m->numfriends = i;
227 245
228 if (realloc_friendlist(m, m->numfriends + 1) != 0) 246 if (realloc_friendlist(m, m->numfriends + 1) != 0)
@@ -240,6 +258,7 @@ int m_friendstatus(Messenger *m, int friendnumber)
240{ 258{
241 if (friendnumber < 0 || friendnumber >= m->numfriends) 259 if (friendnumber < 0 || friendnumber >= m->numfriends)
242 return NOFRIEND; 260 return NOFRIEND;
261
243 return m->friendlist[friendnumber].status; 262 return m->friendlist[friendnumber].status;
244} 263}
245 264
@@ -250,10 +269,13 @@ uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_
250{ 269{
251 if (friendnumber < 0 || friendnumber >= m->numfriends) 270 if (friendnumber < 0 || friendnumber >= m->numfriends)
252 return 0; 271 return 0;
272
253 uint32_t msgid = ++m->friendlist[friendnumber].message_id; 273 uint32_t msgid = ++m->friendlist[friendnumber].message_id;
274
254 if (msgid == 0) 275 if (msgid == 0)
255 msgid = 1; /* otherwise, false error */ 276 msgid = 1; /* otherwise, false error */
256 if(m_sendmessage_withid(m, friendnumber, msgid, message, length)) { 277
278 if (m_sendmessage_withid(m, friendnumber, msgid, message, length)) {
257 return msgid; 279 return msgid;
258 } 280 }
259 281
@@ -264,6 +286,7 @@ uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, ui
264{ 286{
265 if (length >= (MAX_DATA_SIZE - sizeof(theid))) 287 if (length >= (MAX_DATA_SIZE - sizeof(theid)))
266 return 0; 288 return 0;
289
267 uint8_t temp[MAX_DATA_SIZE]; 290 uint8_t temp[MAX_DATA_SIZE];
268 theid = htonl(theid); 291 theid = htonl(theid);
269 memcpy(temp, &theid, sizeof(theid)); 292 memcpy(temp, &theid, sizeof(theid));
@@ -281,20 +304,22 @@ int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t lengt
281 304
282/* send a name packet to friendnumber 305/* send a name packet to friendnumber
283 length is the length with the NULL terminator*/ 306 length is the length with the NULL terminator*/
284static int m_sendname(Messenger *m, int friendnumber, uint8_t * name, uint16_t length) 307static int m_sendname(Messenger *m, int friendnumber, uint8_t *name, uint16_t length)
285{ 308{
286 if(length > MAX_NAME_LENGTH || length == 0) 309 if (length > MAX_NAME_LENGTH || length == 0)
287 return 0; 310 return 0;
311
288 return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length); 312 return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length);
289} 313}
290 314
291/* set the name of a friend 315/* set the name of a friend
292 return 0 if success 316 return 0 if success
293 return -1 if failure */ 317 return -1 if failure */
294static int setfriendname(Messenger *m, int friendnumber, uint8_t * name) 318static int setfriendname(Messenger *m, int friendnumber, uint8_t *name)
295{ 319{
296 if (friendnumber >= m->numfriends || friendnumber < 0) 320 if (friendnumber >= m->numfriends || friendnumber < 0)
297 return -1; 321 return -1;
322
298 memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH); 323 memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH);
299 return 0; 324 return 0;
300} 325}
@@ -305,15 +330,18 @@ static int setfriendname(Messenger *m, int friendnumber, uint8_t * name)
305 length is the length of name with the NULL terminator 330 length is the length of name with the NULL terminator
306 return 0 if success 331 return 0 if success
307 return -1 if failure */ 332 return -1 if failure */
308int setname(Messenger *m, uint8_t * name, uint16_t length) 333int setname(Messenger *m, uint8_t *name, uint16_t length)
309{ 334{
310 if (length > MAX_NAME_LENGTH || length == 0) 335 if (length > MAX_NAME_LENGTH || length == 0)
311 return -1; 336 return -1;
337
312 memcpy(m->name, name, length); 338 memcpy(m->name, name, length);
313 m->name_length = length; 339 m->name_length = length;
314 uint32_t i; 340 uint32_t i;
341
315 for (i = 0; i < m->numfriends; ++i) 342 for (i = 0; i < m->numfriends; ++i)
316 m->friendlist[i].name_sent = 0; 343 m->friendlist[i].name_sent = 0;
344
317 return 0; 345 return 0;
318} 346}
319 347
@@ -340,10 +368,11 @@ uint16_t getself_name(Messenger *m, uint8_t *name, uint16_t nlen)
340 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. 368 name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes.
341 return 0 if success 369 return 0 if success
342 return -1 if failure */ 370 return -1 if failure */
343int getname(Messenger *m, int friendnumber, uint8_t * name) 371int getname(Messenger *m, int friendnumber, uint8_t *name)
344{ 372{
345 if (friendnumber >= m->numfriends || friendnumber < 0) 373 if (friendnumber >= m->numfriends || friendnumber < 0)
346 return -1; 374 return -1;
375
347 memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH); 376 memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH);
348 return 0; 377 return 0;
349} 378}
@@ -352,12 +381,15 @@ int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length)
352{ 381{
353 if (length > MAX_STATUSMESSAGE_LENGTH) 382 if (length > MAX_STATUSMESSAGE_LENGTH)
354 return -1; 383 return -1;
384
355 memcpy(m->statusmessage, status, length); 385 memcpy(m->statusmessage, status, length);
356 m->statusmessage_length = length; 386 m->statusmessage_length = length;
357 387
358 uint32_t i; 388 uint32_t i;
389
359 for (i = 0; i < m->numfriends; ++i) 390 for (i = 0; i < m->numfriends; ++i)
360 m->friendlist[i].statusmessage_sent = 0; 391 m->friendlist[i].statusmessage_sent = 0;
392
361 return 0; 393 return 0;
362} 394}
363 395
@@ -366,10 +398,13 @@ int m_set_userstatus(Messenger *m, USERSTATUS status)
366 if (status >= USERSTATUS_INVALID) { 398 if (status >= USERSTATUS_INVALID) {
367 return -1; 399 return -1;
368 } 400 }
401
369 m->userstatus = status; 402 m->userstatus = status;
370 uint32_t i; 403 uint32_t i;
404
371 for (i = 0; i < m->numfriends; ++i) 405 for (i = 0; i < m->numfriends; ++i)
372 m->friendlist[i].userstatus_sent = 0; 406 m->friendlist[i].userstatus_sent = 0;
407
373 return 0; 408 return 0;
374} 409}
375 410
@@ -379,21 +414,23 @@ int m_get_statusmessage_size(Messenger *m, int friendnumber)
379{ 414{
380 if (friendnumber >= m->numfriends || friendnumber < 0) 415 if (friendnumber >= m->numfriends || friendnumber < 0)
381 return -1; 416 return -1;
417
382 return m->friendlist[friendnumber].statusmessage_length; 418 return m->friendlist[friendnumber].statusmessage_length;
383} 419}
384 420
385/* copy the user status of friendnumber into buf, truncating if needed to maxlen 421/* copy the user status of friendnumber into buf, truncating if needed to maxlen
386 bytes, use m_get_statusmessage_size to find out how much you need to allocate */ 422 bytes, use m_get_statusmessage_size to find out how much you need to allocate */
387int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t * buf, uint32_t maxlen) 423int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t *buf, uint32_t maxlen)
388{ 424{
389 if (friendnumber >= m->numfriends || friendnumber < 0) 425 if (friendnumber >= m->numfriends || friendnumber < 0)
390 return -1; 426 return -1;
427
391 memset(buf, 0, maxlen); 428 memset(buf, 0, maxlen);
392 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 429 memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
393 return 0; 430 return 0;
394} 431}
395 432
396int m_copy_self_statusmessage(Messenger *m, uint8_t * buf, uint32_t maxlen) 433int m_copy_self_statusmessage(Messenger *m, uint8_t *buf, uint32_t maxlen)
397{ 434{
398 memset(buf, 0, maxlen); 435 memset(buf, 0, maxlen);
399 memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); 436 memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1);
@@ -404,10 +441,13 @@ USERSTATUS m_get_userstatus(Messenger *m, int friendnumber)
404{ 441{
405 if (friendnumber >= m->numfriends || friendnumber < 0) 442 if (friendnumber >= m->numfriends || friendnumber < 0)
406 return USERSTATUS_INVALID; 443 return USERSTATUS_INVALID;
444
407 USERSTATUS status = m->friendlist[friendnumber].userstatus; 445 USERSTATUS status = m->friendlist[friendnumber].userstatus;
446
408 if (status >= USERSTATUS_INVALID) { 447 if (status >= USERSTATUS_INVALID) {
409 status = USERSTATUS_NONE; 448 status = USERSTATUS_NONE;
410 } 449 }
450
411 return status; 451 return status;
412} 452}
413 453
@@ -416,7 +456,7 @@ USERSTATUS m_get_self_userstatus(Messenger *m)
416 return m->userstatus; 456 return m->userstatus;
417} 457}
418 458
419static int send_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) 459static int send_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
420{ 460{
421 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); 461 return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length);
422} 462}
@@ -427,10 +467,11 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
427 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); 467 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
428} 468}
429 469
430static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) 470static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
431{ 471{
432 if (friendnumber >= m->numfriends || friendnumber < 0) 472 if (friendnumber >= m->numfriends || friendnumber < 0)
433 return -1; 473 return -1;
474
434 uint8_t *newstatus = calloc(length, 1); 475 uint8_t *newstatus = calloc(length, 1);
435 memcpy(newstatus, status, length); 476 memcpy(newstatus, status, length);
436 free(m->friendlist[friendnumber].statusmessage); 477 free(m->friendlist[friendnumber].statusmessage);
@@ -449,56 +490,61 @@ void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno)
449{ 490{
450 if (yesno != 0 || yesno != 1) 491 if (yesno != 0 || yesno != 1)
451 return; 492 return;
493
452 if (friendnumber >= m->numfriends || friendnumber < 0) 494 if (friendnumber >= m->numfriends || friendnumber < 0)
453 return; 495 return;
496
454 m->friendlist[friendnumber].receives_read_receipts = yesno; 497 m->friendlist[friendnumber].receives_read_receipts = yesno;
455} 498}
456 499
457/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */ 500/* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); */
458/* set the function that will be executed when a friend request is received. */ 501/* set the function that will be executed when a friend request is received. */
459void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void*), void* userdata) 502void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t, void *), void *userdata)
460{ 503{
461 callback_friendrequest(function, userdata); 504 callback_friendrequest(function, userdata);
462} 505}
463 506
464/* set the function that will be executed when a message from a friend is received. */ 507/* set the function that will be executed when a message from a friend is received. */
465void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 508void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
509 void *userdata)
466{ 510{
467 m->friend_message = function; 511 m->friend_message = function;
468 m->friend_message_userdata = userdata; 512 m->friend_message_userdata = userdata;
469} 513}
470 514
471void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 515void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *), void *userdata)
472{ 516{
473 m->friend_action = function; 517 m->friend_action = function;
474 m->friend_action_userdata = userdata; 518 m->friend_action_userdata = userdata;
475} 519}
476 520
477void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 521void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
522 void *userdata)
478{ 523{
479 m->friend_namechange = function; 524 m->friend_namechange = function;
480 m->friend_namechange_userdata = userdata; 525 m->friend_namechange_userdata = userdata;
481} 526}
482 527
483void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void*), void* userdata) 528void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
529 void *userdata)
484{ 530{
485 m->friend_statusmessagechange = function; 531 m->friend_statusmessagechange = function;
486 m->friend_statuschange_userdata = userdata; 532 m->friend_statuschange_userdata = userdata;
487} 533}
488 534
489void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void*), void* userdata) 535void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS, void *), void *userdata)
490{ 536{
491 m->friend_userstatuschange = function; 537 m->friend_userstatuschange = function;
492 m->friend_userstatuschange_userdata = userdata; 538 m->friend_userstatuschange_userdata = userdata;
493} 539}
494 540
495void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void*), void* userdata) 541void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t, void *), void *userdata)
496{ 542{
497 m->read_receipt = function; 543 m->read_receipt = function;
498 m->read_receipt_userdata = userdata; 544 m->read_receipt_userdata = userdata;
499} 545}
500 546
501void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void*), void* userdata) 547void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata)
502{ 548{
503 m->friend_connectionstatuschange = function; 549 m->friend_connectionstatuschange = function;
504 m->friend_connectionstatuschange_userdata = userdata; 550 m->friend_connectionstatuschange_userdata = userdata;
@@ -508,10 +554,13 @@ static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_
508{ 554{
509 if (!m->friend_connectionstatuschange) 555 if (!m->friend_connectionstatuschange)
510 return; 556 return;
557
511 if (status == NOFRIEND) 558 if (status == NOFRIEND)
512 return; 559 return;
560
513 const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE; 561 const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE;
514 const uint8_t is_connected = status == FRIEND_ONLINE; 562 const uint8_t is_connected = status == FRIEND_ONLINE;
563
515 if (is_connected != was_connected) 564 if (is_connected != was_connected)
516 m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata); 565 m->friend_connectionstatuschange(m, friendnumber, is_connected, m->friend_connectionstatuschange_userdata);
517} 566}
@@ -526,8 +575,10 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
526{ 575{
527 if (friendnumber < 0 || friendnumber >= m->numfriends) 576 if (friendnumber < 0 || friendnumber >= m->numfriends)
528 return 0; 577 return 0;
578
529 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE) 579 if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE)
530 return 0; 580 return 0;
581
531 uint8_t packet[length + 1]; 582 uint8_t packet[length + 1];
532 packet[0] = packet_id; 583 packet[0] = packet_id;
533 memcpy(packet + 1, data, length); 584 memcpy(packet + 1, data, length);
@@ -541,7 +592,7 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
541#define PORT 33445 592#define PORT 33445
542 593
543/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ 594/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
544int LANdiscovery(timer* t, void* arg) 595int LANdiscovery(timer *t, void *arg)
545{ 596{
546 send_LANdiscovery(htons(PORT)); 597 send_LANdiscovery(htons(PORT));
547 timer_start(t, LAN_DISCOVERY_INTERVAL); 598 timer_start(t, LAN_DISCOVERY_INTERVAL);
@@ -549,19 +600,20 @@ int LANdiscovery(timer* t, void* arg)
549} 600}
550 601
551/* run this at startup */ 602/* run this at startup */
552Messenger * initMessenger(void) 603Messenger *initMessenger(void)
553{ 604{
554 Messenger *m = calloc(1, sizeof(Messenger)); 605 Messenger *m = calloc(1, sizeof(Messenger));
555 if( ! m ) 606
607 if ( ! m )
556 return 0; 608 return 0;
557 609
558 new_keys(); 610 new_keys();
559 m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online")); 611 m_set_statusmessage(m, (uint8_t *)"Online", sizeof("Online"));
560 initNetCrypto(); 612 initNetCrypto();
561 IP ip; 613 IP ip;
562 ip.i = 0; 614 ip.i = 0;
563 615
564 if(init_networking(ip,PORT) == -1) 616 if (init_networking(ip, PORT) == -1)
565 return 0; 617 return 0;
566 618
567 DHT_init(); 619 DHT_init();
@@ -576,7 +628,8 @@ Messenger * initMessenger(void)
576} 628}
577 629
578/* run this before closing shop */ 630/* run this before closing shop */
579void cleanupMessenger(Messenger *m){ 631void cleanupMessenger(Messenger *m)
632{
580 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger 633 /* FIXME TODO ideally cleanupMessenger will mirror initMessenger
581 * this requires the other modules to expose cleanup functions 634 * this requires the other modules to expose cleanup functions
582 */ 635 */
@@ -591,117 +644,155 @@ void doFriends(Messenger *m)
591 uint32_t i; 644 uint32_t i;
592 int len; 645 int len;
593 uint8_t temp[MAX_DATA_SIZE]; 646 uint8_t temp[MAX_DATA_SIZE];
647
594 for (i = 0; i < m->numfriends; ++i) { 648 for (i = 0; i < m->numfriends; ++i) {
595 if (m->friendlist[i].status == FRIEND_ADDED) { 649 if (m->friendlist[i].status == FRIEND_ADDED) {
596 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); 650 int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
651 m->friendlist[i].info_size);
652
597 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 */ 653 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 */
598 set_friend_status(m, i, FRIEND_REQUESTED); 654 set_friend_status(m, i, FRIEND_REQUESTED);
599 else if (fr > 0) 655 else if (fr > 0)
600 set_friend_status(m, i, FRIEND_REQUESTED); 656 set_friend_status(m, i, FRIEND_REQUESTED);
601 } 657 }
602 if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ 658
659 if (m->friendlist[i].status == FRIEND_REQUESTED
660 || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
603 if (m->friendlist[i].status == FRIEND_REQUESTED) { 661 if (m->friendlist[i].status == FRIEND_REQUESTED) {
604 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ 662 if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
605 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info, m->friendlist[i].info_size); 663 send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].friendrequest_nospam, m->friendlist[i].info,
664 m->friendlist[i].info_size);
606 m->friendlist[i].friend_request_id = unix_time(); 665 m->friendlist[i].friend_request_id = unix_time();
607 } 666 }
608 } 667 }
668
609 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); 669 IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id);
670
610 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { 671 switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) {
611 case 0: 672 case 0:
612 if (friendip.ip.i > 1) 673 if (friendip.ip.i > 1)
613 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); 674 m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip);
614 break; 675
615 case 3: /* Connection is established */ 676 break;
616 set_friend_status(m, i, FRIEND_ONLINE); 677
617 m->friendlist[i].name_sent = 0; 678 case 3: /* Connection is established */
618 m->friendlist[i].userstatus_sent = 0; 679 set_friend_status(m, i, FRIEND_ONLINE);
619 m->friendlist[i].statusmessage_sent = 0; 680 m->friendlist[i].name_sent = 0;
620 break; 681 m->friendlist[i].userstatus_sent = 0;
621 case 4: 682 m->friendlist[i].statusmessage_sent = 0;
622 crypto_kill(m->friendlist[i].crypt_connection_id); 683 break;
623 m->friendlist[i].crypt_connection_id = -1; 684
624 break; 685 case 4:
625 default: 686 crypto_kill(m->friendlist[i].crypt_connection_id);
626 break; 687 m->friendlist[i].crypt_connection_id = -1;
688 break;
689
690 default:
691 break;
627 } 692 }
628 } 693 }
694
629 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ 695 while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
630 if (m->friendlist[i].name_sent == 0) { 696 if (m->friendlist[i].name_sent == 0) {
631 if (m_sendname(m, i, m->name, m->name_length)) 697 if (m_sendname(m, i, m->name, m->name_length))
632 m->friendlist[i].name_sent = 1; 698 m->friendlist[i].name_sent = 1;
633 } 699 }
700
634 if (m->friendlist[i].statusmessage_sent == 0) { 701 if (m->friendlist[i].statusmessage_sent == 0) {
635 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) 702 if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length))
636 m->friendlist[i].statusmessage_sent = 1; 703 m->friendlist[i].statusmessage_sent = 1;
637 } 704 }
705
638 if (m->friendlist[i].userstatus_sent == 0) { 706 if (m->friendlist[i].userstatus_sent == 0) {
639 if (send_userstatus(m, i, m->userstatus)) 707 if (send_userstatus(m, i, m->userstatus))
640 m->friendlist[i].userstatus_sent = 1; 708 m->friendlist[i].userstatus_sent = 1;
641 } 709 }
710
642 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); 711 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
643 uint8_t packet_id = temp[0]; 712 uint8_t packet_id = temp[0];
644 uint8_t* data = temp + 1; 713 uint8_t *data = temp + 1;
645 int data_length = len - 1; 714 int data_length = len - 1;
715
646 if (len > 0) { 716 if (len > 0) {
647 switch (packet_id) { 717 switch (packet_id) {
648 case PACKET_ID_NICKNAME: { 718 case PACKET_ID_NICKNAME: {
649 if (data_length >= MAX_NAME_LENGTH || data_length == 0) 719 if (data_length >= MAX_NAME_LENGTH || data_length == 0)
720 break;
721
722 if (m->friend_namechange)
723 m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata);
724
725 memcpy(m->friendlist[i].name, data, data_length);
726 m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
650 break; 727 break;
651 if(m->friend_namechange) 728 }
652 m->friend_namechange(m, i, data, data_length, m->friend_namechange_userdata); 729
653 memcpy(m->friendlist[i].name, data, data_length); 730 case PACKET_ID_STATUSMESSAGE: {
654 m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ 731 if (data_length == 0)
655 break; 732 break;
656 } 733
657 case PACKET_ID_STATUSMESSAGE: { 734 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
658 if (data_length == 0) 735 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
736
737 if (m->friend_statusmessagechange)
738 m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH),
739 m->friend_statuschange_userdata);
740
741 set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
742 free(status);
659 break; 743 break;
660 uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); 744 }
661 memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 745
662 if (m->friend_statusmessagechange) 746 case PACKET_ID_USERSTATUS: {
663 m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 747 if (data_length != 1)
664 m->friend_statuschange_userdata); 748 break;
665 set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); 749
666 free(status); 750 USERSTATUS status = data[0];
667 break; 751
668 } 752 if (m->friend_userstatuschange)
669 case PACKET_ID_USERSTATUS: { 753 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
670 if (data_length != 1) 754
755 set_friend_userstatus(m, i, status);
671 break; 756 break;
672 USERSTATUS status = data[0];
673 if (m->friend_userstatuschange)
674 m->friend_userstatuschange(m, i, status, m->friend_userstatuschange_userdata);
675 set_friend_userstatus(m, i, status);
676 break;
677 }
678 case PACKET_ID_MESSAGE: {
679 uint8_t *message_id = data;
680 uint8_t message_id_length = 4;
681 uint8_t *message = data + message_id_length;
682 uint16_t message_length = data_length - message_id_length;
683 if (m->friendlist[i].receives_read_receipts) {
684 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
685 } 757 }
686 if (m->friend_message) 758
687 (*m->friend_message)(m, i, message, message_length, m->friend_message_userdata); 759 case PACKET_ID_MESSAGE: {
688 break; 760 uint8_t *message_id = data;
689 } 761 uint8_t message_id_length = 4;
690 case PACKET_ID_ACTION: { 762 uint8_t *message = data + message_id_length;
691 if (m->friend_action) 763 uint16_t message_length = data_length - message_id_length;
692 (*m->friend_action)(m, i, data, data_length, m->friend_action_userdata); 764
693 break; 765 if (m->friendlist[i].receives_read_receipts) {
694 } 766 write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length);
695 case PACKET_ID_RECEIPT: { 767 }
696 uint32_t msgid; 768
697 if (data_length < sizeof(msgid)) 769 if (m->friend_message)
770 (*m->friend_message)(m, i, message, message_length, m->friend_message_userdata);
771
698 break; 772 break;
699 memcpy(&msgid, data, sizeof(msgid)); 773 }
700 msgid = ntohl(msgid); 774
701 if (m->read_receipt) 775 case PACKET_ID_ACTION: {
702 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata); 776 if (m->friend_action)
703 break; 777 (*m->friend_action)(m, i, data, data_length, m->friend_action_userdata);
704 } 778
779 break;
780 }
781
782 case PACKET_ID_RECEIPT: {
783 uint32_t msgid;
784
785 if (data_length < sizeof(msgid))
786 break;
787
788 memcpy(&msgid, data, sizeof(msgid));
789 msgid = ntohl(msgid);
790
791 if (m->read_receipt)
792 (*m->read_receipt)(m, i, msgid, m->read_receipt_userdata);
793
794 break;
795 }
705 } 796 }
706 } else { 797 } else {
707 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ 798 if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
@@ -709,6 +800,7 @@ void doFriends(Messenger *m)
709 m->friendlist[i].crypt_connection_id = -1; 800 m->friendlist[i].crypt_connection_id = -1;
710 set_friend_status(m, i, FRIEND_CONFIRMED); 801 set_friend_status(m, i, FRIEND_CONFIRMED);
711 } 802 }
803
712 break; 804 break;
713 } 805 }
714 } 806 }
@@ -721,8 +813,10 @@ void doInbound(Messenger *m)
721 uint8_t public_key[crypto_box_PUBLICKEYBYTES]; 813 uint8_t public_key[crypto_box_PUBLICKEYBYTES];
722 uint8_t session_key[crypto_box_PUBLICKEYBYTES]; 814 uint8_t session_key[crypto_box_PUBLICKEYBYTES];
723 int inconnection = crypto_inbound(public_key, secret_nonce, session_key); 815 int inconnection = crypto_inbound(public_key, secret_nonce, session_key);
816
724 if (inconnection != -1) { 817 if (inconnection != -1) {
725 int friend_id = getfriend_id(m, public_key); 818 int friend_id = getfriend_id(m, public_key);
819
726 if (friend_id != -1) { 820 if (friend_id != -1) {
727 crypto_kill(m->friendlist[friend_id].crypt_connection_id); 821 crypto_kill(m->friendlist[friend_id].crypt_connection_id);
728 m->friendlist[friend_id].crypt_connection_id = 822 m->friendlist[friend_id].crypt_connection_id =
@@ -775,12 +869,14 @@ void Messenger_save(Messenger *m, uint8_t *data)
775} 869}
776 870
777/* load the messenger from data of size length. */ 871/* load the messenger from data of size length. */
778int Messenger_load(Messenger *m, uint8_t * data, uint32_t length) 872int Messenger_load(Messenger *m, uint8_t *data, uint32_t length)
779{ 873{
780 if (length == ~0) 874 if (length == ~0)
781 return -1; 875 return -1;
876
782 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3) 877 if (length < crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3)
783 return -1; 878 return -1;
879
784 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3; 880 length -= crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES + sizeof(uint32_t) * 3;
785 load_keys(data); 881 load_keys(data);
786 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; 882 data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES;
@@ -794,23 +890,28 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
794 890
795 if (length < size) 891 if (length < size)
796 return -1; 892 return -1;
893
797 length -= size; 894 length -= size;
895
798 if (DHT_load(data, size) == -1) 896 if (DHT_load(data, size) == -1)
799 return -1; 897 return -1;
898
800 data += size; 899 data += size;
801 memcpy(&size, data, sizeof(size)); 900 memcpy(&size, data, sizeof(size));
802 data += sizeof(size); 901 data += sizeof(size);
902
803 if (length != size || length % sizeof(Friend) != 0) 903 if (length != size || length % sizeof(Friend) != 0)
804 return -1; 904 return -1;
805 905
806 Friend * temp = malloc(size); 906 Friend *temp = malloc(size);
807 memcpy(temp, data, size); 907 memcpy(temp, data, size);
808 908
809 uint16_t num = size / sizeof(Friend); 909 uint16_t num = size / sizeof(Friend);
810 910
811 uint32_t i; 911 uint32_t i;
912
812 for (i = 0; i < num; ++i) { 913 for (i = 0; i < num; ++i) {
813 if(temp[i].status >= 3) { 914 if (temp[i].status >= 3) {
814 int fnum = m_addfriend_norequest(m, temp[i].client_id); 915 int fnum = m_addfriend_norequest(m, temp[i].client_id);
815 setfriendname(m, fnum, temp[i].name); 916 setfriendname(m, fnum, temp[i].name);
816 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ 917 /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */
@@ -824,6 +925,7 @@ int Messenger_load(Messenger *m, uint8_t * data, uint32_t length)
824 m_addfriend(m, address, temp[i].info, temp[i].info_size); 925 m_addfriend(m, address, temp[i].info, temp[i].info_size);
825 } 926 }
826 } 927 }
928
827 free(temp); 929 free(temp);
828 return 0; 930 return 0;
829} 931}