summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2013-08-19 07:00:59 -0400
committerirungentoo <irungentoo@gmail.com>2013-08-19 07:00:59 -0400
commit88986f793a02921e8a23e540a80275e91c87a82a (patch)
tree800cc1fe691e6ff86fcd33ed38ad7a12a1ebe66b
parentb8bf05250c8ed0de4b555963df5f7ef3887aa1dd (diff)
Prevented possible MITM attack.
Friends must now send to themselves at least one encrypted ping packet every 5 seconds. If no encrypted ping packets are recieved from a friend within 10 seconds the connection is killed.
-rw-r--r--core/Messenger.c33
-rw-r--r--core/Messenger.h9
2 files changed, 39 insertions, 3 deletions
diff --git a/core/Messenger.c b/core/Messenger.c
index 66ae4f41..7fd6a569 100644
--- a/core/Messenger.c
+++ b/core/Messenger.c
@@ -482,6 +482,12 @@ static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status)
482 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); 482 return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat));
483} 483}
484 484
485static int send_ping(Messenger *m, int friendnumber)
486{
487 m->friendlist[friendnumber].ping_lastsent = unix_time();
488 return write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0);
489}
490
485static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length) 491static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length)
486{ 492{
487 if (friendnumber >= m->numfriends || friendnumber < 0) 493 if (friendnumber >= m->numfriends || friendnumber < 0)
@@ -596,7 +602,10 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint
596 602
597 uint8_t packet[length + 1]; 603 uint8_t packet[length + 1];
598 packet[0] = packet_id; 604 packet[0] = packet_id;
599 memcpy(packet + 1, data, length); 605
606 if (length != 0)
607 memcpy(packet + 1, data, length);
608
600 return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); 609 return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1);
601} 610}
602 611
@@ -659,6 +668,7 @@ void doFriends(Messenger *m)
659 uint32_t i; 668 uint32_t i;
660 int len; 669 int len;
661 uint8_t temp[MAX_DATA_SIZE]; 670 uint8_t temp[MAX_DATA_SIZE];
671 uint64_t temp_time = unix_time();
662 672
663 for (i = 0; i < m->numfriends; ++i) { 673 for (i = 0; i < m->numfriends; ++i) {
664 if (m->friendlist[i].status == FRIEND_ADDED) { 674 if (m->friendlist[i].status == FRIEND_ADDED) {
@@ -667,7 +677,7 @@ void doFriends(Messenger *m)
667 677
668 if (fr >= 0) { 678 if (fr >= 0) {
669 set_friend_status(m, i, FRIEND_REQUESTED); 679 set_friend_status(m, i, FRIEND_REQUESTED);
670 m->friendlist[i].friendrequest_lastsent = unix_time(); 680 m->friendlist[i].friendrequest_lastsent = temp_time;
671 } 681 }
672 } 682 }
673 683
@@ -676,7 +686,7 @@ void doFriends(Messenger *m)
676 if (m->friendlist[i].status == FRIEND_REQUESTED) { 686 if (m->friendlist[i].status == FRIEND_REQUESTED) {
677 /* If we didn't connect to friend after successfully sending him a friend request the request is deemed 687 /* If we didn't connect to friend after successfully sending him a friend request the request is deemed
678 unsuccessful so we set the status back to FRIEND_ADDED and try again.*/ 688 unsuccessful so we set the status back to FRIEND_ADDED and try again.*/
679 if (m->friendlist[i].friendrequest_lastsent + m->friendlist[i].friendrequest_timeout < unix_time()) { 689 if (m->friendlist[i].friendrequest_lastsent + m->friendlist[i].friendrequest_timeout < temp_time) {
680 set_friend_status(m, i, FRIEND_ADDED); 690 set_friend_status(m, i, FRIEND_ADDED);
681 /* Double the default timeout everytime if friendrequest is assumed to have been 691 /* Double the default timeout everytime if friendrequest is assumed to have been
682 sent unsuccessfully. */ 692 sent unsuccessfully. */
@@ -698,6 +708,7 @@ void doFriends(Messenger *m)
698 m->friendlist[i].name_sent = 0; 708 m->friendlist[i].name_sent = 0;
699 m->friendlist[i].userstatus_sent = 0; 709 m->friendlist[i].userstatus_sent = 0;
700 m->friendlist[i].statusmessage_sent = 0; 710 m->friendlist[i].statusmessage_sent = 0;
711 m->friendlist[i].ping_lastrecv = temp_time;
701 break; 712 break;
702 713
703 case 4: 714 case 4:
@@ -726,6 +737,10 @@ void doFriends(Messenger *m)
726 m->friendlist[i].userstatus_sent = 1; 737 m->friendlist[i].userstatus_sent = 1;
727 } 738 }
728 739
740 if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) {
741 send_ping(m, i);
742 }
743
729 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); 744 len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp);
730 uint8_t packet_id = temp[0]; 745 uint8_t packet_id = temp[0];
731 uint8_t *data = temp + 1; 746 uint8_t *data = temp + 1;
@@ -733,6 +748,11 @@ void doFriends(Messenger *m)
733 748
734 if (len > 0) { 749 if (len > 0) {
735 switch (packet_id) { 750 switch (packet_id) {
751 case PACKET_ID_PING: {
752 m->friendlist[i].ping_lastrecv = temp_time;
753 break;
754 }
755
736 case PACKET_ID_NICKNAME: { 756 case PACKET_ID_NICKNAME: {
737 if (data_length >= MAX_NAME_LENGTH || data_length == 0) 757 if (data_length >= MAX_NAME_LENGTH || data_length == 0)
738 break; 758 break;
@@ -821,6 +841,13 @@ void doFriends(Messenger *m)
821 841
822 break; 842 break;
823 } 843 }
844
845 if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) {
846 /* if we stopped recieving ping packets kill it */
847 crypto_kill(m->friendlist[i].crypt_connection_id);
848 m->friendlist[i].crypt_connection_id = -1;
849 set_friend_status(m, i, FRIEND_CONFIRMED);
850 }
824 } 851 }
825 } 852 }
826} 853}
diff --git a/core/Messenger.h b/core/Messenger.h
index 20ea33fb..9016be93 100644
--- a/core/Messenger.h
+++ b/core/Messenger.h
@@ -40,6 +40,7 @@ extern "C" {
40 40
41#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) 41#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
42 42
43#define PACKET_ID_PING 0
43#define PACKET_ID_NICKNAME 48 44#define PACKET_ID_NICKNAME 48
44#define PACKET_ID_STATUSMESSAGE 49 45#define PACKET_ID_STATUSMESSAGE 49
45#define PACKET_ID_USERSTATUS 50 46#define PACKET_ID_USERSTATUS 50
@@ -71,6 +72,12 @@ extern "C" {
71/* Default start timeout in seconds between friend requests */ 72/* Default start timeout in seconds between friend requests */
72#define FRIENDREQUEST_TIMEOUT 5; 73#define FRIENDREQUEST_TIMEOUT 5;
73 74
75/* interval between the sending of ping packets.*/
76#define FRIEND_PING_INTERVAL 5
77
78/* If no packets are recieved from friend in this time interval, kill the connection.*/
79#define FRIEND_CONNECTION_TIMEOUT (FRIEND_PING_INTERVAL * 2)
80
74/* USERSTATUS 81/* USERSTATUS
75 * Represents userstatuses someone can have. */ 82 * Represents userstatuses someone can have. */
76 83
@@ -100,6 +107,8 @@ typedef struct {
100 uint32_t message_id; /* a semi-unique id used in read receipts */ 107 uint32_t message_id; /* a semi-unique id used in read receipts */
101 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */ 108 uint8_t receives_read_receipts; /* shall we send read receipts to this person? */
102 uint32_t friendrequest_nospam; /*The nospam number used in the friend request*/ 109 uint32_t friendrequest_nospam; /*The nospam number used in the friend request*/
110 uint64_t ping_lastrecv;
111 uint64_t ping_lastsent;
103} Friend; 112} Friend;
104 113
105typedef struct Messenger { 114typedef struct Messenger {