Merge remote-tracking branch 'upstream/master' into MessengerLoadSave

This commit is contained in:
Coren[m] 2013-09-13 18:43:04 +02:00
commit d2603cf169
15 changed files with 385 additions and 25 deletions

View File

@ -31,6 +31,7 @@
#endif
#include "../toxcore/DHT.h"
#include "../toxcore/LAN_discovery.h"
#include "../toxcore/friend_requests.h"
#include "../testing/misc_tools.c"
@ -123,6 +124,9 @@ int main(int argc, char *argv[])
int is_waiting_for_dht_connection = 1;
uint64_t last_LANdiscovery = 0;
LANdiscovery_init(dht);
while (1) {
if (is_waiting_for_dht_connection && DHT_isconnected(dht)) {
printf("Connected to other bootstrap server successfully.\n");
@ -130,6 +134,10 @@ int main(int argc, char *argv[])
}
do_DHT(dht);
if (last_LANdiscovery + (is_waiting_for_dht_connection ? 5 : LAN_DISCOVERY_INTERVAL) < unix_time()) {
send_LANdiscovery(htons(PORT), dht->c);
last_LANdiscovery = unix_time();
}
networking_poll(dht->c->lossless_udp->net);

View File

@ -348,13 +348,34 @@ void line_eval(Tox *m, char *line)
do_refresh();
} else if (inpt_command == 'h') { //help
new_lines(help);
} else if (inpt_command == 'i') { //info
} else if (inpt_command == 'x') { //info
char idstring[200];
get_id(m, idstring);
new_lines(idstring);
}
} else if (inpt_command == 'g') { //create new group chat
char msg[256];
sprintf(msg, "[g] Created new group chat with number: %u", tox_add_groupchat(m));
new_lines(msg);
} else if (inpt_command == 'i') { //invite friendnum to groupnum
char *posi[1];
int friendnumber = strtoul(line + prompt_offset, posi, 0);
int groupnumber = strtoul(*posi + 1, NULL, 0);
char msg[256];
sprintf(msg, "[g] Invited friend number %u to group number %u, returned: %u (0 means success)", friendnumber,
groupnumber, tox_invite_friend(m, friendnumber, groupnumber));
new_lines(msg);
} else if (inpt_command == 'z') { //send message to groupnum
char *posi[1];
int groupnumber = strtoul(line + prompt_offset, posi, 0);
else if (inpt_command == 'q') { //exit
if (**posi != 0) {
char msg[256 + 1024];
sprintf(msg, "[g] sent message: %s to group num: %u returned: %u (0 means success)", *posi + 1, groupnumber,
tox_group_message_send(m, groupnumber, (uint8_t *)*posi + 1, strlen(*posi + 1) + 1));
new_lines(msg);
}
} else if (inpt_command == 'q') { //exit
endwin();
exit(EXIT_SUCCESS);
} else {
@ -535,6 +556,22 @@ void print_help(void)
puts("\t-f\t-\tSpecify a keyfile to read (or write to) from.");
}
void print_invite(Tox *m, int friendnumber, uint8_t *group_public_key, void *userdata)
{
char msg[256];
sprintf(msg, "[i] recieved group chat invite from: %u, auto accepting and joining. group number: %u", friendnumber,
tox_join_groupchat(m, friendnumber, group_public_key));
new_lines(msg);
}
void print_groupmessage(Tox *m, int groupnumber, uint8_t *message, uint16_t length, void *userdata)
{
char msg[256 + length];
sprintf(msg, "[g] %u: %s", groupnumber, message);
new_lines(msg);
}
int main(int argc, char *argv[])
{
int on = 0;
@ -579,6 +616,8 @@ int main(int argc, char *argv[])
tox_callback_friendmessage(m, print_message, NULL);
tox_callback_namechange(m, print_nickchange, NULL);
tox_callback_statusmessage(m, print_statuschange, NULL);
tox_callback_group_invite(m, print_invite, NULL);
tox_callback_group_message(m, print_groupmessage, NULL);
initscr();
noecho();

View File

@ -31,7 +31,6 @@
#include <ctype.h>
#include "../toxcore/tox.h"
#define STRING_LENGTH 256
#define HISTORY 50
#define PUB_KEY_BYTES 32

View File

@ -498,7 +498,7 @@ static int getnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cli
uint8_t plain[sizeof(ping_id) + CLIENT_ID_SIZE];
uint8_t encrypt[sizeof(ping_id) + CLIENT_ID_SIZE + ENCRYPTION_PADDING];
uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce);
new_nonce(nonce);
memcpy(plain, &ping_id, sizeof(ping_id));
memcpy(plain + sizeof(ping_id), client_id, CLIENT_ID_SIZE);
@ -540,7 +540,7 @@ static int sendnodes(DHT *dht, IP_Port ip_port, uint8_t *public_key, uint8_t *cl
uint8_t plain[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES];
uint8_t encrypt[sizeof(ping_id) + sizeof(Node_format) * MAX_SENT_NODES + ENCRYPTION_PADDING];
uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce);
new_nonce(nonce);
memcpy(plain, &ping_id, sizeof(ping_id));
memcpy(plain + sizeof(ping_id), nodes_list, num_nodes * sizeof(Node_format));

View File

@ -35,6 +35,8 @@
#include <linux/netdevice.h>
#endif
/* Interval in seconds between LAN discovery packet sending. */
#define LAN_DISCOVERY_INTERVAL 60
/* Send a LAN discovery pcaket to the broadcast address with port port. */
int send_LANdiscovery(uint16_t port, Net_Crypto *c);

View File

@ -673,6 +673,40 @@ static int group_num(Messenger *m, uint8_t *group_public_key)
return -1;
}
/* Set the callback for group invites.
*
* Function(Messenger *m, int friendnumber, uint8_t *group_public_key, void *userdata)
*/
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, void *), void *userdata)
{
m->group_invite = function;
m->group_invite_userdata = userdata;
}
/* Set the callback for group messages.
*
* Function(Messenger *m, int groupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata)
{
m->group_message = function;
m->group_message_userdata = userdata;
}
static void group_message_function(Group_Chat *chat, int peer_number, uint8_t *message, uint16_t length, void *userdata)
{
Messenger *m = userdata;
uint32_t i;
for (i = 0; i < m->numchats; ++i) { //TODO: remove this
if (m->chats[i] == chat)
break;
}
if (m->group_message)
(*m->group_message)(m, i, message, length, m->group_invite_userdata);
}
/* Creates a new groupchat and puts it in the chats array.
*
* return group number on success.
@ -689,6 +723,7 @@ int add_groupchat(Messenger *m)
if (newchat == NULL)
return -1;
callback_groupmessage(newchat, &group_message_function, m);
m->chats[i] = newchat;
return i;
}
@ -705,6 +740,8 @@ int add_groupchat(Messenger *m)
if (temp[m->numchats] == NULL)
return -1;
m->chats = temp;
callback_groupmessage(temp[m->numchats], &group_message_function, m);
++m->numchats;
return (m->numchats - 1);
}
@ -714,7 +751,7 @@ int add_groupchat(Messenger *m)
* return 0 on success.
* return -1 if failure.
*/
static int del_groupchat(Messenger *m, int groupnumber)
int del_groupchat(Messenger *m, int groupnumber)
{
if ((unsigned int)groupnumber >= m->numchats)
return -1;
@ -748,9 +785,42 @@ static int del_groupchat(Messenger *m, int groupnumber)
return 0;
}
/* return 1 if that friend was invited to the group
* return 0 if the friend was not or error.
*/
static uint8_t group_invited(Messenger *m, int friendnumber, int groupnumber)
{
//TODO: this function;
return 1;
}
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int invite_friend(Messenger *m, int friendnumber, int groupnumber)
{
if (friend_not_valid(m, friendnumber) || (unsigned int)groupnumber >= m->numchats)
return -1;
if (m->chats == NULL)
return -1;
if (m->friendlist[friendnumber].status == NOFRIEND || m->chats[groupnumber] == NULL)
return -1;
//TODO: store invited friends.
if (write_cryptpacket_id(m, friendnumber, PACKET_ID_INVITE_GROUPCHAT, m->chats[groupnumber]->self_public_key,
crypto_box_PUBLICKEYBYTES) == 0)
return -1;
return 0;
}
/* Join a group (you need to have been invited first.)
*
* returns 0 on success
* returns group number on success
* returns -1 on failure.
*/
int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_key)
@ -770,12 +840,34 @@ int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_
if (write_cryptpacket_id(m, friendnumber, PACKET_ID_JOIN_GROUPCHAT, data, sizeof(data))) {
chat_bootstrap_nonlazy(m->chats[groupnum], get_friend_ipport(m, friendnumber),
friend_group_public_key); //TODO: check if ip returned is zero?
return 0;
return groupnum;
}
return -1;
}
/* send a group message
* return 0 on success
* return -1 on failure
*/
int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length)
{
if ((unsigned int)groupnumber >= m->numchats)
return -1;
if (m->chats == NULL)
return -1;
if (m->chats[groupnumber] == NULL)
return -1;
if (group_sendmessage(m->chats[groupnumber], message, length) > 0)
return 0;
return -1;
}
static int handle_group(void *object, IP_Port source, uint8_t *packet, uint32_t length)
{
Messenger *m = object;
@ -809,8 +901,6 @@ static void do_allgroupchats(Messenger *m)
/*********************************/
/* Interval in seconds between LAN discovery packet sending. */
#define LAN_DISCOVERY_INTERVAL 60
#define PORT 33445
/* Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds. */
@ -1064,6 +1154,29 @@ void doFriends(Messenger *m)
break;
}
case PACKET_ID_INVITE_GROUPCHAT: {
if (data_length != crypto_box_PUBLICKEYBYTES)
break;
if (m->group_invite)
(*m->group_invite)(m, i, data, m->group_invite_userdata);
}
case PACKET_ID_JOIN_GROUPCHAT: {
if (data_length != crypto_box_PUBLICKEYBYTES * 2)
break;
int groupnum = group_num(m, data);
if (groupnum == -1)
break;
if (!group_invited(m, i, groupnum))
break;
group_newpeer(m->chats[groupnum], data + crypto_box_PUBLICKEYBYTES);
}
}
} else {
if (is_cryptoconnected(m->net_crypto,

View File

@ -157,7 +157,10 @@ typedef struct Messenger {
void *friend_statuschange_userdata;
void (*friend_connectionstatuschange)(struct Messenger *m, int, uint8_t, void *);
void *friend_connectionstatuschange_userdata;
void (*group_invite)(struct Messenger *m, int, uint8_t *, void *);
void *group_invite_userdata;
void (*group_message)(struct Messenger *m, int, uint8_t *, uint16_t, void *);
void *group_message_userdata;
} Messenger;
@ -369,6 +372,57 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, u
*/
void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t, void *), void *userdata);
/**********GROUP CHATS************/
/* Set the callback for group invites.
*
* Function(Messenger *m, int friendnumber, uint8_t *group_public_key, void *userdata)
*/
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, void *), void *userdata);
/* Set the callback for group messages.
*
* Function(Messenger *m, int groupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t, void *),
void *userdata);
/* Creates a new groupchat and puts it in the chats array.
*
* return group number on success.
* return -1 on failure.
*/
int add_groupchat(Messenger *m);
/* Delete a groupchat from the chats array.
*
* return 0 on success.
* return -1 if failure.
*/
int del_groupchat(Messenger *m, int groupnumber);
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int invite_friend(Messenger *m, int friendnumber, int groupnumber);
/* Join a group (you need to have been invited first.)
*
* returns group number on success
* returns -1 on failure.
*/
int join_groupchat(Messenger *m, int friendnumber, uint8_t *friend_group_public_key);
/* send a group message
* return 0 on success
* return -1 on failure
*/
int group_message_send(Messenger *m, int groupnumber, uint8_t *message, uint32_t length);
/*********************************/
/* Run this at startup.
* return allocated instance of Messenger on success.
* return 0 if there are problems.

View File

@ -77,6 +77,7 @@ void callback_groupmessage(Group_Chat *chat, void (*function)(Group_Chat *chat,
/*
* Send a message to the group.
*
* returns the number of peers it has sent it to.
*/
uint32_t group_sendmessage(Group_Chat *chat, uint8_t *message, uint32_t length);

View File

@ -145,14 +145,26 @@ static void increment_nonce(uint8_t *nonce)
/* Fill the given nonce with random bytes. */
void random_nonce(uint8_t *nonce)
{
uint32_t i, temp;
for (i = 0; i < crypto_box_NONCEBYTES / 4; ++i) {
temp = random_int();
memcpy(nonce + 4 * i, &temp, 4);
}
randombytes(nonce, crypto_box_NONCEBYTES);
}
static uint8_t base_nonce[crypto_box_NONCEBYTES];
static uint8_t nonce_set = 0;
/*Gives a nonce guaranteed to be different from previous ones.*/
void new_nonce(uint8_t *nonce)
{
if (nonce_set == 0) {
random_nonce(base_nonce);
nonce_set = 1;
}
increment_nonce(base_nonce);
memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
}
/* return 0 if there is no received data in the buffer.
* return -1 if the packet was discarded.
* return length of received data if successful.
@ -237,7 +249,7 @@ int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *
uint8_t temp[MAX_DATA_SIZE];
memcpy(temp + 1, data, length);
temp[0] = request_id;
random_nonce(nonce);
new_nonce(nonce);
int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
@ -336,7 +348,7 @@ static int send_cryptohandshake(Net_Crypto *c, int connection_id, uint8_t *publi
uint8_t temp[crypto_box_NONCEBYTES + crypto_box_PUBLICKEYBYTES];
uint8_t nonce[crypto_box_NONCEBYTES];
random_nonce(nonce);
new_nonce(nonce);
memcpy(temp, secret_nonce, crypto_box_NONCEBYTES);
memcpy(temp + crypto_box_NONCEBYTES, session_key, crypto_box_PUBLICKEYBYTES);

View File

@ -115,6 +115,9 @@ int decrypt_data_fast(uint8_t *enc_key, uint8_t *nonce,
/* Fill the given nonce with random bytes. */
void random_nonce(uint8_t *nonce);
/*Gives a nonce guaranteed to be different from previous ones.*/
void new_nonce(uint8_t *nonce);
/* return 0 if there is no received data in the buffer.
* return -1 if the packet was discarded.
* return length of received data if successful.

View File

@ -49,7 +49,6 @@ uint64_t current_time(void)
}
/* return a random number.
* NOTE: This function should probably not be used where cryptographic randomness is absolutely necessary.
*/
uint32_t random_int(void)
{
@ -57,7 +56,9 @@ uint32_t random_int(void)
/* NOTE: this function comes from libsodium. */
return randombytes_random();
#else
return random();
uint32_t randnum;
randombytes((uint8_t *)&randnum , sizeof(randnum));
return randnum;
#endif
}

View File

@ -57,6 +57,7 @@
#include <sodium.h>
#else
#include <crypto_box.h>
#include <randombytes.h>
#define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
#endif
@ -130,7 +131,6 @@ typedef struct {
uint64_t current_time(void);
/* return a random number.
* NOTE: this function should probably not be used where cryptographic randomness is absolutely necessary.
*/
uint32_t random_int(void);

View File

@ -135,7 +135,7 @@ int send_ping_request(void *ping, Net_Crypto *c, IP_Port ipp, uint8_t *client_id
pk[0] = NET_PACKET_PING_REQUEST;
id_cpy(pk + 1, c->self_public_key); // Our pubkey
random_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate random nonce
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
// Encrypt ping_id using recipient privkey
rc = encrypt_data(client_id,
@ -160,7 +160,7 @@ int send_ping_response(Net_Crypto *c, IP_Port ipp, uint8_t *client_id, uint64_t
pk[0] = NET_PACKET_PING_RESPONSE;
id_cpy(pk + 1, c->self_public_key); // Our pubkey
random_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate random nonce
new_nonce(pk + 1 + CLIENT_ID_SIZE); // Generate new nonce
// Encrypt ping_id using recipient privkey
rc = encrypt_data(client_id,

View File

@ -366,6 +366,81 @@ void tox_callback_connectionstatus(void *tox, void (*function)(Messenger *tox, i
m_callback_connectionstatus(m, function, userdata);
}
/**********GROUP CHAT FUNCTIONS: WARNING WILL BREAK A LOT************/
/* Set the callback for group invites.
*
* Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata)
*/
void tox_callback_group_invite(void *tox, void (*function)(Messenger *tox, int, uint8_t *, void *), void *userdata)
{
Messenger *m = tox;
m_callback_group_invite(m, function, userdata);
}
/* Set the callback for group messages.
*
* Function(Tox *tox, int groupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void tox_callback_group_message(void *tox, void (*function)(Messenger *tox, int, uint8_t *, uint16_t, void *),
void *userdata)
{
Messenger *m = tox;
m_callback_group_message(m, function, userdata);
}
/* Creates a new groupchat and puts it in the chats array.
*
* return group number on success.
* return -1 on failure.
*/
int tox_add_groupchat(void *tox)
{
Messenger *m = tox;
return add_groupchat(m);
}
/* Delete a groupchat from the chats array.
*
* return 0 on success.
* return -1 if failure.
*/
int tox_del_groupchat(void *tox, int groupnumber)
{
Messenger *m = tox;
return del_groupchat(m, groupnumber);
}
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int tox_invite_friend(void *tox, int friendnumber, int groupnumber)
{
Messenger *m = tox;
return invite_friend(m, friendnumber, groupnumber);
}
/* Join a group (you need to have been invited first.)
*
* returns group number on success
* returns -1 on failure.
*/
int tox_join_groupchat(void *tox, int friendnumber, uint8_t *friend_group_public_key)
{
Messenger *m = tox;
return join_groupchat(m, friendnumber, friend_group_public_key);
}
/* send a group message
* return 0 on success
* return -1 on failure
*/
int tox_group_message_send(void *tox, int groupnumber, uint8_t *message, uint32_t length)
{
Messenger *m = tox;
return group_message_send(m, groupnumber, message, length);
}
/******************END OF GROUP CHAT FUNCTIONS************************/
/* Use this function to bootstrap the client.
* Sends a get nodes request to the given node with ip port and public_key.
*/

View File

@ -289,6 +289,59 @@ void tox_callback_read_receipt(Tox *tox, void (*function)(Tox *tox, int, uint32_
*/
void tox_callback_connectionstatus(Tox *tox, void (*function)(Tox *tox, int, uint8_t, void *), void *userdata);
/**********GROUP CHAT FUNCTIONS: WARNING WILL BREAK A LOT************/
/* Set the callback for group invites.
*
* Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata)
*/
void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, void *), void *userdata);
/* Set the callback for group messages.
*
* Function(Tox *tox, int groupnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, uint8_t *, uint16_t, void *),
void *userdata);
/* Creates a new groupchat and puts it in the chats array.
*
* return group number on success.
* return -1 on failure.
*/
int tox_add_groupchat(Tox *tox);
/* Delete a groupchat from the chats array.
*
* return 0 on success.
* return -1 if failure.
*/
int tox_del_groupchat(Tox *tox, int groupnumber);
/* invite friendnumber to groupnumber
* return 0 on success
* return -1 on failure
*/
int tox_invite_friend(Tox *tox, int friendnumber, int groupnumber);
/* Join a group (you need to have been invited first.)
*
* returns group number on success
* returns -1 on failure.
*/
int tox_join_groupchat(Tox *tox, int friendnumber, uint8_t *friend_group_public_key);
/* send a group message
* return 0 on success
* return -1 on failure
*/
int tox_group_message_send(Tox *tox, int groupnumber, uint8_t *message, uint32_t length);
/******************END OF GROUP CHAT FUNCTIONS************************/
/* Use this function to bootstrap the client.
* Sends a get nodes request to the given node with ip port and public_key.
*/