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.
This commit is contained in:
irungentoo 2013-08-19 07:00:59 -04:00
parent b8bf05250c
commit 88986f793a
2 changed files with 39 additions and 3 deletions

View File

@ -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);
}
}
}
}

View File

@ -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 {