diff options
-rw-r--r-- | core/Messenger.c | 112 |
1 files changed, 51 insertions, 61 deletions
diff --git a/core/Messenger.c b/core/Messenger.c index 00f54cfa..5f33886f 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -47,8 +47,9 @@ uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | |||
47 | static uint8_t self_name[MAX_NAME_LENGTH]; | 47 | static uint8_t self_name[MAX_NAME_LENGTH]; |
48 | static uint16_t self_name_length; | 48 | static uint16_t self_name_length; |
49 | 49 | ||
50 | static uint8_t *self_statusmessage; | 50 | static uint8_t self_statusmessage[MAX_STATUSMESSAGE_LENGTH]; |
51 | static uint16_t self_statusmessage_len; | 51 | static uint16_t self_statusmessage_length; |
52 | |||
52 | static USERSTATUS self_userstatus; | 53 | static USERSTATUS self_userstatus; |
53 | 54 | ||
54 | static Friend *friendlist; | 55 | static Friend *friendlist; |
@@ -56,6 +57,7 @@ static uint32_t numfriends; | |||
56 | 57 | ||
57 | 58 | ||
58 | static void set_friend_status(int friendnumber, uint8_t status); | 59 | static void set_friend_status(int friendnumber, uint8_t status); |
60 | static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); | ||
59 | 61 | ||
60 | /* 1 if we are online | 62 | /* 1 if we are online |
61 | 0 if we are offline | 63 | 0 if we are offline |
@@ -234,17 +236,13 @@ uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | |||
234 | 236 | ||
235 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) | 237 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) |
236 | { | 238 | { |
237 | if (friendnumber < 0 || friendnumber >= numfriends) | 239 | if (length >= (MAX_DATA_SIZE - sizeof(theid))) |
238 | return 0; | ||
239 | if (length >= (MAX_DATA_SIZE - sizeof(theid)) || friendlist[friendnumber].status != FRIEND_ONLINE) | ||
240 | /* this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. */ | ||
241 | return 0; | 240 | return 0; |
242 | uint8_t temp[MAX_DATA_SIZE]; | 241 | uint8_t temp[MAX_DATA_SIZE]; |
243 | temp[0] = PACKET_ID_MESSAGE; | ||
244 | theid = htonl(theid); | 242 | theid = htonl(theid); |
245 | memcpy(temp + 1, &theid, sizeof(theid)); | 243 | memcpy(temp, &theid, sizeof(theid)); |
246 | memcpy(temp + 1 + sizeof(theid), message, length); | 244 | memcpy(temp + sizeof(theid), message, length); |
247 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1 + sizeof(theid)); | 245 | return write_cryptpacket_id(friendnumber, PACKET_ID_MESSAGE, temp, length + sizeof(theid)); |
248 | } | 246 | } |
249 | 247 | ||
250 | /* send an action to an online friend | 248 | /* send an action to an online friend |
@@ -252,14 +250,7 @@ uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message | |||
252 | return 0 if it was not */ | 250 | return 0 if it was not */ |
253 | int m_sendaction(int friendnumber, uint8_t *action, uint32_t length) | 251 | int m_sendaction(int friendnumber, uint8_t *action, uint32_t length) |
254 | { | 252 | { |
255 | if (friendnumber < 0 || friendnumber >= numfriends) | 253 | return write_cryptpacket_id(friendnumber, PACKET_ID_ACTION, action, length); |
256 | return 0; | ||
257 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) | ||
258 | return 0; | ||
259 | uint8_t temp[MAX_DATA_SIZE]; | ||
260 | temp[0] = PACKET_ID_ACTION; | ||
261 | memcpy(temp + 1, action, length); | ||
262 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); | ||
263 | } | 254 | } |
264 | 255 | ||
265 | /* send a name packet to friendnumber | 256 | /* send a name packet to friendnumber |
@@ -268,10 +259,7 @@ static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) | |||
268 | { | 259 | { |
269 | if(length > MAX_NAME_LENGTH || length == 0) | 260 | if(length > MAX_NAME_LENGTH || length == 0) |
270 | return 0; | 261 | return 0; |
271 | uint8_t temp[MAX_NAME_LENGTH + 1]; | 262 | return write_cryptpacket_id(friendnumber, PACKET_ID_NICKNAME, name, length); |
272 | memcpy(temp + 1, name, length); | ||
273 | temp[0] = PACKET_ID_NICKNAME; | ||
274 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); | ||
275 | } | 263 | } |
276 | 264 | ||
277 | /* set the name of a friend | 265 | /* set the name of a friend |
@@ -330,11 +318,8 @@ int m_set_statusmessage(uint8_t *status, uint16_t length) | |||
330 | { | 318 | { |
331 | if (length > MAX_STATUSMESSAGE_LENGTH) | 319 | if (length > MAX_STATUSMESSAGE_LENGTH) |
332 | return -1; | 320 | return -1; |
333 | uint8_t *newstatus = calloc(length, 1); | 321 | memcpy(self_statusmessage, status, length); |
334 | memcpy(newstatus, status, length); | 322 | self_statusmessage_length = length; |
335 | free(self_statusmessage); | ||
336 | self_statusmessage = newstatus; | ||
337 | self_statusmessage_len = length; | ||
338 | 323 | ||
339 | uint32_t i; | 324 | uint32_t i; |
340 | for (i = 0; i < numfriends; ++i) | 325 | for (i = 0; i < numfriends; ++i) |
@@ -399,22 +384,12 @@ USERSTATUS m_get_self_userstatus(void) | |||
399 | 384 | ||
400 | static int send_statusmessage(int friendnumber, uint8_t * status, uint16_t length) | 385 | static int send_statusmessage(int friendnumber, uint8_t * status, uint16_t length) |
401 | { | 386 | { |
402 | uint8_t *thepacket = malloc(length + 1); | 387 | return write_cryptpacket_id(friendnumber, PACKET_ID_STATUSMESSAGE, status, length); |
403 | memcpy(thepacket + 1, status, length); | ||
404 | thepacket[0] = PACKET_ID_STATUSMESSAGE; | ||
405 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, length + 1); | ||
406 | free(thepacket); | ||
407 | return written; | ||
408 | } | 388 | } |
409 | 389 | ||
410 | static int send_userstatus(int friendnumber, USERSTATUS status) | 390 | static int send_userstatus(int friendnumber, USERSTATUS status) |
411 | { | 391 | { |
412 | uint8_t *thepacket = malloc(1 + 1); | 392 | return write_cryptpacket_id(friendnumber, PACKET_ID_USERSTATUS, (uint8_t*)&status, sizeof(USERSTATUS)); |
413 | memcpy(thepacket + 1, &status, 1); | ||
414 | thepacket[0] = PACKET_ID_USERSTATUS; | ||
415 | int written = write_cryptpacket(friendlist[friendnumber].crypt_connection_id, thepacket, 1 + 1); | ||
416 | free(thepacket); | ||
417 | return written; | ||
418 | } | 393 | } |
419 | 394 | ||
420 | static int set_friend_statusmessage(int friendnumber, uint8_t * status, uint16_t length) | 395 | static int set_friend_statusmessage(int friendnumber, uint8_t * status, uint16_t length) |
@@ -517,6 +492,18 @@ static void set_friend_status(int friendnumber, uint8_t status) | |||
517 | friendlist[friendnumber].status = status; | 492 | friendlist[friendnumber].status = status; |
518 | } | 493 | } |
519 | 494 | ||
495 | static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) | ||
496 | { | ||
497 | if (friendnumber < 0 || friendnumber >= numfriends) | ||
498 | return 0; | ||
499 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) | ||
500 | return 0; | ||
501 | uint8_t packet[length + 1]; | ||
502 | packet[0] = packet_id; | ||
503 | memcpy(packet + 1, data, length); | ||
504 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, packet, length + 1); | ||
505 | } | ||
506 | |||
520 | #define PORT 33445 | 507 | #define PORT 33445 |
521 | /* run this at startup */ | 508 | /* run this at startup */ |
522 | int initMessenger(void) | 509 | int initMessenger(void) |
@@ -578,7 +565,7 @@ static void doFriends(void) | |||
578 | friendlist[i].name_sent = 1; | 565 | friendlist[i].name_sent = 1; |
579 | } | 566 | } |
580 | if (friendlist[i].statusmessage_sent == 0) { | 567 | if (friendlist[i].statusmessage_sent == 0) { |
581 | if (send_statusmessage(i, self_statusmessage, self_statusmessage_len)) | 568 | if (send_statusmessage(i, self_statusmessage, self_statusmessage_length)) |
582 | friendlist[i].statusmessage_sent = 1; | 569 | friendlist[i].statusmessage_sent = 1; |
583 | } | 570 | } |
584 | if (friendlist[i].userstatus_sent == 0) { | 571 | if (friendlist[i].userstatus_sent == 0) { |
@@ -586,59 +573,62 @@ static void doFriends(void) | |||
586 | friendlist[i].userstatus_sent = 1; | 573 | friendlist[i].userstatus_sent = 1; |
587 | } | 574 | } |
588 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); | 575 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); |
576 | uint8_t packet_id = temp[0]; | ||
577 | uint8_t* data = temp + 1; | ||
578 | int data_length = len - 1; | ||
589 | if (len > 0) { | 579 | if (len > 0) { |
590 | switch (temp[0]) { | 580 | switch (packet_id) { |
591 | case PACKET_ID_NICKNAME: { | 581 | case PACKET_ID_NICKNAME: { |
592 | if (len >= MAX_NAME_LENGTH + 1 || len == 1) | 582 | if (data_length >= MAX_NAME_LENGTH || data_length == 0) |
593 | break; | 583 | break; |
594 | if(friend_namechange_isset) | 584 | if(friend_namechange_isset) |
595 | friend_namechange(i, temp + 1, len - 1); | 585 | friend_namechange(i, data, data_length); |
596 | memcpy(friendlist[i].name, temp + 1, len - 1); | 586 | memcpy(friendlist[i].name, data, data_length); |
597 | friendlist[i].name[len - 2] = 0; /* make sure the NULL terminator is present. */ | 587 | friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ |
598 | break; | 588 | break; |
599 | } | 589 | } |
600 | case PACKET_ID_STATUSMESSAGE: { | 590 | case PACKET_ID_STATUSMESSAGE: { |
601 | if (len < 2) | 591 | if (data_length == 0) |
602 | break; | 592 | break; |
603 | uint8_t *status = calloc(MIN(len - 1, MAX_STATUSMESSAGE_LENGTH), 1); | 593 | uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); |
604 | memcpy(status, temp + 1, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH)); | 594 | memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
605 | if (friend_statusmessagechange_isset) | 595 | if (friend_statusmessagechange_isset) |
606 | friend_statusmessagechange(i, status, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH)); | 596 | friend_statusmessagechange(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
607 | set_friend_statusmessage(i, status, MIN(len - 1, MAX_STATUSMESSAGE_LENGTH)); | 597 | set_friend_statusmessage(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
608 | free(status); | 598 | free(status); |
609 | break; | 599 | break; |
610 | } | 600 | } |
611 | case PACKET_ID_USERSTATUS: { | 601 | case PACKET_ID_USERSTATUS: { |
612 | if (len != 2) | 602 | if (data_length != 1) |
613 | break; | 603 | break; |
614 | USERSTATUS status = temp[1]; | 604 | USERSTATUS status = data[0]; |
615 | if (friend_userstatuschange_isset) | 605 | if (friend_userstatuschange_isset) |
616 | friend_userstatuschange(i, status); | 606 | friend_userstatuschange(i, status); |
617 | set_friend_userstatus(i, status); | 607 | set_friend_userstatus(i, status); |
618 | break; | 608 | break; |
619 | } | 609 | } |
620 | case PACKET_ID_MESSAGE: { | 610 | case PACKET_ID_MESSAGE: { |
611 | uint8_t *message_id = data; | ||
612 | uint8_t message_id_length = 4; | ||
613 | uint8_t *message = data + message_id_length; | ||
614 | uint16_t message_length = data_length - message_id_length; | ||
621 | if (friendlist[i].receives_read_receipts) { | 615 | if (friendlist[i].receives_read_receipts) { |
622 | uint8_t *thepacket = malloc(5); | 616 | write_cryptpacket_id(i, PACKET_ID_RECEIPT, message_id, message_id_length); |
623 | thepacket[0] = PACKET_ID_RECEIPT; | ||
624 | memcpy(thepacket + 1, temp + 1, 4); | ||
625 | write_cryptpacket(friendlist[i].crypt_connection_id, thepacket, 5); | ||
626 | free(thepacket); | ||
627 | } | 617 | } |
628 | if (friend_message_isset) | 618 | if (friend_message_isset) |
629 | (*friend_message)(i, temp + 5, len - 5); | 619 | (*friend_message)(i, message, message_length); |
630 | break; | 620 | break; |
631 | } | 621 | } |
632 | case PACKET_ID_ACTION: { | 622 | case PACKET_ID_ACTION: { |
633 | if (friend_action_isset) | 623 | if (friend_action_isset) |
634 | (*friend_action)(i, temp + 1, len - 1); | 624 | (*friend_action)(i, data, data_length); |
635 | break; | 625 | break; |
636 | } | 626 | } |
637 | case PACKET_ID_RECEIPT: { | 627 | case PACKET_ID_RECEIPT: { |
638 | uint32_t msgid; | 628 | uint32_t msgid; |
639 | if (len < 1 + sizeof(msgid)) | 629 | if (data_length < sizeof(msgid)) |
640 | break; | 630 | break; |
641 | memcpy(&msgid, temp + 1, sizeof(msgid)); | 631 | memcpy(&msgid, data, sizeof(msgid)); |
642 | msgid = ntohl(msgid); | 632 | msgid = ntohl(msgid); |
643 | if (read_receipt_isset) | 633 | if (read_receipt_isset) |
644 | (*read_receipt)(i, msgid); | 634 | (*read_receipt)(i, msgid); |