From 88986f793a02921e8a23e540a80275e91c87a82a Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 19 Aug 2013 07:00:59 -0400 Subject: 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. --- core/Messenger.c | 33 ++++++++++++++++++++++++++++++--- core/Messenger.h | 9 +++++++++ 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) return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); } +static int send_ping(Messenger *m, int friendnumber) +{ + m->friendlist[friendnumber].ping_lastsent = unix_time(); + return write_cryptpacket_id(m, friendnumber, PACKET_ID_PING, 0, 0); +} + static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t *status, uint16_t length) { if (friendnumber >= m->numfriends || friendnumber < 0) @@ -596,7 +602,10 @@ int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint uint8_t packet[length + 1]; packet[0] = packet_id; - memcpy(packet + 1, data, length); + + if (length != 0) + memcpy(packet + 1, data, length); + return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); } @@ -659,6 +668,7 @@ void doFriends(Messenger *m) uint32_t i; int len; uint8_t temp[MAX_DATA_SIZE]; + uint64_t temp_time = unix_time(); for (i = 0; i < m->numfriends; ++i) { if (m->friendlist[i].status == FRIEND_ADDED) { @@ -667,7 +677,7 @@ void doFriends(Messenger *m) if (fr >= 0) { set_friend_status(m, i, FRIEND_REQUESTED); - m->friendlist[i].friendrequest_lastsent = unix_time(); + m->friendlist[i].friendrequest_lastsent = temp_time; } } @@ -676,7 +686,7 @@ void doFriends(Messenger *m) if (m->friendlist[i].status == FRIEND_REQUESTED) { /* If we didn't connect to friend after successfully sending him a friend request the request is deemed unsuccessful so we set the status back to FRIEND_ADDED and try again.*/ - if (m->friendlist[i].friendrequest_lastsent + m->friendlist[i].friendrequest_timeout < unix_time()) { + if (m->friendlist[i].friendrequest_lastsent + m->friendlist[i].friendrequest_timeout < temp_time) { set_friend_status(m, i, FRIEND_ADDED); /* Double the default timeout everytime if friendrequest is assumed to have been sent unsuccessfully. */ @@ -698,6 +708,7 @@ void doFriends(Messenger *m) m->friendlist[i].name_sent = 0; m->friendlist[i].userstatus_sent = 0; m->friendlist[i].statusmessage_sent = 0; + m->friendlist[i].ping_lastrecv = temp_time; break; case 4: @@ -726,6 +737,10 @@ void doFriends(Messenger *m) m->friendlist[i].userstatus_sent = 1; } + if (m->friendlist[i].ping_lastsent + FRIEND_PING_INTERVAL < temp_time) { + send_ping(m, i); + } + len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); uint8_t packet_id = temp[0]; uint8_t *data = temp + 1; @@ -733,6 +748,11 @@ void doFriends(Messenger *m) if (len > 0) { switch (packet_id) { + case PACKET_ID_PING: { + m->friendlist[i].ping_lastrecv = temp_time; + break; + } + case PACKET_ID_NICKNAME: { if (data_length >= MAX_NAME_LENGTH || data_length == 0) break; @@ -821,6 +841,13 @@ void doFriends(Messenger *m) break; } + + if (m->friendlist[i].ping_lastrecv + FRIEND_CONNECTION_TIMEOUT < temp_time) { + /* if we stopped recieving ping packets kill it */ + crypto_kill(m->friendlist[i].crypt_connection_id); + m->friendlist[i].crypt_connection_id = -1; + set_friend_status(m, i, FRIEND_CONFIRMED); + } } } } 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" { #define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) +#define PACKET_ID_PING 0 #define PACKET_ID_NICKNAME 48 #define PACKET_ID_STATUSMESSAGE 49 #define PACKET_ID_USERSTATUS 50 @@ -71,6 +72,12 @@ extern "C" { /* Default start timeout in seconds between friend requests */ #define FRIENDREQUEST_TIMEOUT 5; +/* interval between the sending of ping packets.*/ +#define FRIEND_PING_INTERVAL 5 + +/* If no packets are recieved from friend in this time interval, kill the connection.*/ +#define FRIEND_CONNECTION_TIMEOUT (FRIEND_PING_INTERVAL * 2) + /* USERSTATUS * Represents userstatuses someone can have. */ @@ -100,6 +107,8 @@ typedef struct { uint32_t message_id; /* a semi-unique id used in read receipts */ uint8_t receives_read_receipts; /* shall we send read receipts to this person? */ uint32_t friendrequest_nospam; /*The nospam number used in the friend request*/ + uint64_t ping_lastrecv; + uint64_t ping_lastsent; } Friend; typedef struct Messenger { -- cgit v1.2.3