diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index e5298b3163..863259acb5 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -39,7 +39,6 @@ static void set_friend_status(Messenger *m, int32_t friendnumber, uint8_t status); static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_t packet_id, const uint8_t *data, uint32_t length, uint8_t congestion_control); -static int send_avatar_data_control(const Messenger *m, const uint32_t friendnumber, uint8_t op); // friend_not_valid determines if the friendnumber passed is valid in the Messenger object static uint8_t friend_not_valid(const Messenger *m, int32_t friendnumber) @@ -208,10 +207,6 @@ static int32_t init_new_friend(Messenger *m, const uint8_t *real_pk, uint8_t sta id_copy(m->friendlist[i].real_pk, real_pk); m->friendlist[i].statusmessage_length = 0; m->friendlist[i].userstatus = USERSTATUS_NONE; - m->friendlist[i].avatar_info_sent = 0; - m->friendlist[i].avatar_recv_data = NULL; - m->friendlist[i].avatar_send_data.bytes_sent = 0; - m->friendlist[i].avatar_send_data.last_reset = 0; m->friendlist[i].is_typing = 0; m->friendlist[i].message_id = 0; friend_connection_callbacks(m->fr_c, friendcon_id, MESSENGER_CALLBACK_INDEX, &handle_status, &handle_packet, @@ -397,7 +392,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber) if (m->friendlist[friendnumber].status == FRIEND_ONLINE) remove_online_friend(m, friendnumber); - free(m->friendlist[friendnumber].avatar_recv_data); clear_receipts(m, friendnumber); remove_request_received(&(m->fr), m->friendlist[friendnumber].real_pk); friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, 0, 0, 0, 0, 0); @@ -656,149 +650,6 @@ int m_set_userstatus(Messenger *m, uint8_t status) return 0; } -int m_unset_avatar(Messenger *m) -{ - if (m->avatar_data != NULL) - free(m->avatar_data); - - m->avatar_data = NULL; - m->avatar_data_length = 0; - m->avatar_format = AVATAR_FORMAT_NONE; - memset(m->avatar_hash, 0, AVATAR_HASH_LENGTH); - - uint32_t i; - - for (i = 0; i < m->numfriends; ++i) - m->friendlist[i].avatar_info_sent = 0; - - return 0; -} - -int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length) -{ - if (format == AVATAR_FORMAT_NONE) { - m_unset_avatar(m); - return 0; - } - - if (length > AVATAR_MAX_DATA_LENGTH || length == 0) - return -1; - - if (data == NULL) - return -1; - - uint8_t *tmp = realloc(m->avatar_data, length); - - if (tmp == NULL) - return -1; - - m->avatar_format = format; - m->avatar_data = tmp; - m->avatar_data_length = length; - memcpy(m->avatar_data, data, length); - - m_avatar_hash(m->avatar_hash, m->avatar_data, m->avatar_data_length); - - uint32_t i; - - for (i = 0; i < m->numfriends; ++i) - m->friendlist[i].avatar_info_sent = 0; - - return 0; -} - -int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, - uint8_t *hash) -{ - if (format) - *format = m->avatar_format; - - if (length) - *length = m->avatar_data_length; - - if (hash) - memcpy(hash, m->avatar_hash, AVATAR_HASH_LENGTH); - - if (buf != NULL && maxlen > 0) { - if (m->avatar_data_length <= maxlen) - memcpy(buf, m->avatar_data, m->avatar_data_length); - else - return -1; - } - - return 0; -} - -int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) -{ - if (hash == NULL) - return -1; - - return crypto_hash_sha256(hash, data, datalen); -} - -int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen) -{ - return m_hash(hash, data, datalen); -} - -int m_request_avatar_info(const Messenger *m, const int32_t friendnumber) -{ - if (friend_not_valid(m, friendnumber)) - return -1; - - if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO_REQ, 0, 0, 0)) - return 0; - else - return -1; -} - -int m_send_avatar_info(const Messenger *m, const int32_t friendnumber) -{ - if (friend_not_valid(m, friendnumber)) - return -1; - - uint8_t data[sizeof(uint8_t) + AVATAR_HASH_LENGTH]; - data[0] = m->avatar_format; - memcpy(data + 1, m->avatar_hash, AVATAR_HASH_LENGTH); - - if (write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_INFO, data, sizeof(data), 0)) - return 0; - else - return -1; -} - -int m_request_avatar_data(const Messenger *m, const int32_t friendnumber) -{ - if (friend_not_valid(m, friendnumber)) - return -1; - - AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; - - if (avrd == NULL) { - avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1); - - if (avrd == NULL) - return -1; - - avrd->started = 0; - m->friendlist[friendnumber].avatar_recv_data = avrd; - } - - if (avrd->started) { - LOGGER_DEBUG("Resetting already started data request. " - "friendnumber == %u", friendnumber); - } - - avrd->started = 0; - avrd->bytes_received = 0; - avrd->total_length = 0; - avrd->format = AVATAR_FORMAT_NONE; - - return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ); -} - - /* return the size of friendnumber's user status. * Guaranteed to be at most MAX_STATUSMESSAGE_LENGTH. */ @@ -1021,20 +872,6 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess m->friend_connectionstatuschange_internal_userdata = userdata; } -void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, void *), - void *userdata) -{ - m->avatar_info_recv = function; - m->avatar_info_recv_userdata = userdata; -} - -void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *, - uint32_t, void *), void *userdata) -{ - m->avatar_data_recv = function; - m->avatar_data_recv_userdata = userdata; -} - static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber) { int last_connection_udp_tcp = m->friendlist[friendnumber].last_connection_udp_tcp; @@ -1646,9 +1483,6 @@ Messenger *new_messenger(Messenger_Options *options) m->net = new_networking(ip, TOX_PORT_DEFAULT); } - m->avatar_format = AVATAR_FORMAT_NONE; - m->avatar_data = NULL; - if (m->net == NULL) { free(m); return NULL; @@ -1714,11 +1548,9 @@ void kill_messenger(Messenger *m) kill_networking(m->net); for (i = 0; i < m->numfriends; ++i) { - free(m->friendlist[i].avatar_recv_data); clear_receipts(m, i); } - free(m->avatar_data); free(m->friendlist); free(m); } @@ -1752,293 +1584,16 @@ static int handle_status(void *object, int i, uint8_t status) m->friendlist[i].userstatus_sent = 0; m->friendlist[i].statusmessage_sent = 0; m->friendlist[i].user_istyping_sent = 0; - m->friendlist[i].avatar_info_sent = 0; m->friendlist[i].ping_lastrecv = temp_time; } else { /* Went offline. */ if (m->friendlist[i].status == FRIEND_ONLINE) { set_friend_status(m, i, FRIEND_CONFIRMED); } - - /* Clear avatar transfer state */ - if (m->friendlist[i].avatar_recv_data) { - free(m->friendlist[i].avatar_recv_data); - m->friendlist[i].avatar_recv_data = NULL; - } - } - - return 0; -} - - -/* Sends an avatar data control packet to the peer. Usually to return status - * values or request data. - */ -static int send_avatar_data_control(const Messenger *m, const uint32_t friendnumber, - uint8_t op) -{ - int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_DATA_CONTROL, - &op, sizeof(op), 0); - LOGGER_DEBUG("friendnumber = %u, op = %u, ret = %d", - friendnumber, op, ret); - return ret ? 0 : -1; -} - - -static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber, - uint8_t *data, uint32_t data_length) -{ - if (data_length != 1) { - LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad " - "data_length = %u, friendnumber = %u", - data_length, friendnumber); - send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); - return -1; /* Error */ - } - - LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]); - - switch (data[0]) { - case AVATAR_DATACONTROL_REQ: { - - /* Check data transfer limits for this friend */ - AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data); - - if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) { - /* User reached data limit. Check timeout */ - uint64_t now = unix_time(); - - if (avsd->last_reset > 0 - && (avsd->last_reset + AVATAR_DATA_TRANSFER_TIMEOUT < now)) { - avsd->bytes_sent = 0; - avsd->last_reset = now; - } else { - /* Friend still rate-limitted. Send an error and stops. */ - LOGGER_DEBUG("Avatar data transfer limit reached. " - "friendnumber = %u", friendnumber); - send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); - return 0; - } - } - - /* Start the transmission with a DATA_START message. Format: - * uint8_t format - * uint8_t hash[AVATAR_HASH_LENGTH] - * uint32_t total_length - */ - LOGGER_DEBUG("Sending start msg to friend number %u. " - "m->avatar_format = %u, m->avatar_data_length = %u", - friendnumber, m->avatar_format, m->avatar_data_length); - uint8_t start_data[1 + AVATAR_HASH_LENGTH + sizeof(uint32_t)]; - uint32_t avatar_len = htonl(m->avatar_data_length); - - start_data[0] = m->avatar_format; - memcpy(start_data + 1, m->avatar_hash, AVATAR_HASH_LENGTH); - memcpy(start_data + 1 + AVATAR_HASH_LENGTH, &avatar_len, sizeof(uint32_t)); - - avsd->bytes_sent += sizeof(start_data); /* For rate limit */ - - int ret = write_cryptpacket_id(m, friendnumber, PACKET_ID_AVATAR_DATA_START, - start_data, sizeof(start_data), 0); - - if (!ret) { - /* Something went wrong, try to signal the error so the friend - * can clear up the state. */ - send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); - return 0; - } - - /* User have no avatar data, nothing more to do. */ - if (m->avatar_format == AVATAR_FORMAT_NONE) - return 0; - - /* Send the actual avatar data. */ - uint32_t offset = 0; - - while (offset < m->avatar_data_length) { - uint32_t chunk_len = m->avatar_data_length - offset; - - if (chunk_len > AVATAR_DATA_MAX_CHUNK_SIZE) - chunk_len = AVATAR_DATA_MAX_CHUNK_SIZE; - - uint8_t chunk[AVATAR_DATA_MAX_CHUNK_SIZE]; - memcpy(chunk, m->avatar_data + offset, chunk_len); - offset += chunk_len; - avsd->bytes_sent += chunk_len; /* For rate limit */ - - int ret = write_cryptpacket_id(m, friendnumber, - PACKET_ID_AVATAR_DATA_PUSH, - chunk, chunk_len, 0); - - if (!ret) { - LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, " - "friendnumber = %u, offset = %u", - ret, friendnumber, offset); - send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR); - return -1; - } - } - - return 0; - } - - case AVATAR_DATACONTROL_ERROR: { - if (m->friendlist[friendnumber].avatar_recv_data) { - /* We were receiving the data, sender detected an error - (eg. changing avatar) and asked us to stop. */ - free(m->friendlist[friendnumber].avatar_recv_data); - m->friendlist[friendnumber].avatar_recv_data = NULL; - } - - return 0; - } - } - - return -1; -} - - -static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber, - uint8_t *data, uint32_t data_length) -{ - LOGGER_DEBUG("data_length = %u, friendnumber = %u", data_length, friendnumber); - - if (data_length != 1 + AVATAR_HASH_LENGTH + sizeof(uint32_t)) { - LOGGER_DEBUG("Invalid msg length = %u, friendnumber = %u", - data_length, friendnumber); - return -1; } - AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; - - if (avrd == NULL) { - LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u", - friendnumber); - return -1; - } - - if (avrd->started) { - /* Already receiving data from this friend. Must be an error - * or an malicious request, because we zeroed the started bit - * when we requested the data. */ - LOGGER_DEBUG("Received an unrequested duplicated DATA_START, " - "friendnumber = %u", friendnumber); - return -1; - } - - /* Copy data from message to our control structure */ - avrd->started = 1; - avrd->format = data[0]; - memcpy(avrd->hash, data + 1, AVATAR_HASH_LENGTH); - uint32_t tmp_len; - memcpy(&tmp_len, data + 1 + AVATAR_HASH_LENGTH, sizeof(uint32_t)); - avrd->total_length = ntohl(tmp_len); - avrd->bytes_received = 0; - - LOGGER_DEBUG("friendnumber = %u, avrd->format = %u, " - "avrd->total_length = %u, avrd->bytes_received = %u", - friendnumber, avrd->format, avrd->total_length, - avrd->bytes_received); - - if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) { - /* Invalid data length. Stops. */ - LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, " - "friendnumber = %u", friendnumber); - free(avrd); - avrd = NULL; - m->friendlist[friendnumber].avatar_recv_data = NULL; - return 0; - } - - if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) { - /* No real data to receive. Run callback function and finish. */ - LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber); - - if (m->avatar_data_recv) { - memset(avrd->hash, 0, AVATAR_HASH_LENGTH); - (m->avatar_data_recv)(m, friendnumber, avrd->format, avrd->hash, - NULL, 0, m->avatar_data_recv_userdata); - } - - free(avrd); - avrd = NULL; - m->friendlist[friendnumber].avatar_recv_data = NULL; - return 0; - } - - /* Waits for more data to be received */ - return 0; -} - - -static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber, - uint8_t *data, uint32_t data_length) -{ - LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length); - - AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data; - - if (avrd == NULL) { - /* No active transfer. It must be an error or a malicious request, - * because we set the avatar_recv_data on the first DATA_START. */ - LOGGER_DEBUG("Error: avrd == NULL, friendnumber = %u", friendnumber); - return -1; /* Error */ - } - - if (avrd->started == 0) { - /* Receiving data for a non-started request. Must be an error - * or an malicious request. */ - LOGGER_DEBUG("Received an data push for a yet non started data " - "request. friendnumber = %u", friendnumber); - return -1; /* Error */ - } - - uint32_t new_length = avrd->bytes_received + data_length; - - if (new_length > avrd->total_length - || new_length >= AVATAR_MAX_DATA_LENGTH) { - /* Invalid data length due to error or malice. Stops. */ - LOGGER_DEBUG("Invalid data length. friendnumber = %u, " - "new_length = %u, avrd->total_length = %u", - friendnumber, new_length, avrd->total_length); - free(avrd); - m->friendlist[friendnumber].avatar_recv_data = NULL; - return 0; - } - - memcpy(avrd->data + avrd->bytes_received, data, data_length); - avrd->bytes_received += data_length; - - if (avrd->bytes_received == avrd->total_length) { - LOGGER_DEBUG("All data received. friendnumber = %u", friendnumber); - - /* All data was received. Check if the hashes match. It the - * requester's responsability to do this. The sender may have done - * anything with its avatar data between the DATA_START and now. - */ - uint8_t cur_hash[AVATAR_HASH_LENGTH]; - m_avatar_hash(cur_hash, avrd->data, avrd->bytes_received); - - if (memcmp(cur_hash, avrd->hash, AVATAR_HASH_LENGTH) == 0) { - /* Avatar successfuly received! */ - if (m->avatar_data_recv) { - (m->avatar_data_recv)(m, friendnumber, avrd->format, cur_hash, - avrd->data, avrd->bytes_received, m->avatar_data_recv_userdata); - } - } else { - LOGGER_DEBUG("Avatar hash error. friendnumber = %u", friendnumber); - } - - free(avrd); - m->friendlist[friendnumber].avatar_recv_data = NULL; - return 0; - } - - /* Waits for more data to be received */ return 0; } - - static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) { if (len == 0) @@ -2178,42 +1733,6 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len) break; } - case PACKET_ID_AVATAR_INFO_REQ: { - /* Send our avatar information */ - m_send_avatar_info(m, i); - break; - } - - case PACKET_ID_AVATAR_INFO: { - if (m->avatar_info_recv) { - /* - * A malicious user may send an incomplete avatar info message. - * Check if it have the correct size for the format: - * [1 uint8_t: avatar format] [32 uint8_t: hash] - */ - if (data_length == AVATAR_HASH_LENGTH + 1) { - (m->avatar_info_recv)(m, i, data[0], data + 1, m->avatar_info_recv_userdata); - } - } - - break; - } - - case PACKET_ID_AVATAR_DATA_CONTROL: { - handle_avatar_data_control(m, i, data, data_length); - break; - } - - case PACKET_ID_AVATAR_DATA_START: { - handle_avatar_data_start(m, i, data, data_length); - break; - } - - case PACKET_ID_AVATAR_DATA_PUSH: { - handle_avatar_data_push(m, i, data, data_length); - break; - } - case PACKET_ID_INVITE_GROUPCHAT: { if (data_length == 0) break; @@ -2362,11 +1881,6 @@ void do_friends(Messenger *m) m->friendlist[i].userstatus_sent = 1; } - if (m->friendlist[i].avatar_info_sent == 0) { - if (m_send_avatar_info(m, i) == 0) - m->friendlist[i].avatar_info_sent = 1; - } - if (m->friendlist[i].user_istyping_sent == 0) { if (send_user_istyping(m, i, m->friendlist[i].user_istyping)) m->friendlist[i].user_istyping_sent = 1; diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 4e011a57d4..4823590070 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -33,8 +33,6 @@ #define MAX_NAME_LENGTH 128 /* TODO: this must depend on other variable. */ #define MAX_STATUSMESSAGE_LENGTH 1007 -#define AVATAR_MAX_DATA_LENGTH 16384 -#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES #define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t)) @@ -47,11 +45,6 @@ #define PACKET_ID_STATUSMESSAGE 49 #define PACKET_ID_USERSTATUS 50 #define PACKET_ID_TYPING 51 -#define PACKET_ID_AVATAR_INFO_REQ 52 -#define PACKET_ID_AVATAR_INFO 53 -#define PACKET_ID_AVATAR_DATA_CONTROL 54 -#define PACKET_ID_AVATAR_DATA_START 55 -#define PACKET_ID_AVATAR_DATA_PUSH 56 #define PACKET_ID_MESSAGE 64 #define PACKET_ID_ACTION 65 #define PACKET_ID_MSI 69 @@ -112,14 +105,6 @@ enum { /* Interval between the sending of tcp relay information */ #define FRIEND_SHARE_RELAYS_INTERVAL (5 * 60) -/* Must be < MAX_CRYPTO_DATA_SIZE */ -#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1) - -/* Per-friend data limit for avatar data requests */ -#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH) -#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */ - - enum { CONNECTION_NONE, CONNECTION_TCP, @@ -138,42 +123,6 @@ typedef enum { } USERSTATUS; -/* AVATAR_FORMAT - - * Data formats for user avatar images - */ -typedef enum { - AVATAR_FORMAT_NONE = 0, - AVATAR_FORMAT_PNG -} -AVATAR_FORMAT; - -/* AVATAR_DATACONTROL - * To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL) - */ -typedef enum { - AVATAR_DATACONTROL_REQ, - AVATAR_DATACONTROL_ERROR -} -AVATAR_DATACONTROL; - -typedef struct { - uint8_t started; - AVATAR_FORMAT format; - uint8_t hash[AVATAR_HASH_LENGTH]; - uint32_t total_length; - uint32_t bytes_received; - uint8_t data[AVATAR_MAX_DATA_LENGTH]; -} -AVATAR_RECEIVEDATA; - -typedef struct { - /* Fields only used to limit the network usage from a given friend */ - uint32_t bytes_sent; /* Total bytes send to this user */ - uint64_t last_reset; /* Time the data counter was last reset */ -} -AVATAR_SENDDATA; - - struct File_Transfers { uint64_t size; uint64_t transferred; @@ -217,7 +166,6 @@ typedef struct { uint8_t statusmessage_sent; USERSTATUS userstatus; uint8_t userstatus_sent; - uint8_t avatar_info_sent; uint8_t user_istyping; uint8_t user_istyping_sent; uint8_t is_typing; @@ -230,9 +178,6 @@ typedef struct { struct File_Transfers file_sending[MAX_CONCURRENT_FILE_PIPES]; struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; - AVATAR_SENDDATA avatar_send_data; - AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend. - struct { int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint32_t len, void *object); void *object; @@ -269,11 +214,6 @@ struct Messenger { USERSTATUS userstatus; - AVATAR_FORMAT avatar_format; - uint8_t *avatar_data; - uint32_t avatar_data_length; - uint8_t avatar_hash[AVATAR_HASH_LENGTH]; - Friend *friendlist; uint32_t numfriends; @@ -305,10 +245,6 @@ struct Messenger { void *friend_connectionstatuschange_userdata; void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *); void *friend_connectionstatuschange_internal_userdata; - void *avatar_info_recv_userdata; - void (*avatar_info_recv)(struct Messenger *m, uint32_t, uint8_t, uint8_t *, void *); - void *avatar_data_recv_userdata; - void (*avatar_data_recv)(struct Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, void *); void *group_chat_object; /* Set by new_groupchats()*/ void (*group_invite)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t); @@ -503,113 +439,6 @@ uint8_t m_get_userstatus(const Messenger *m, int32_t friendnumber); uint8_t m_get_self_userstatus(const Messenger *m); -/* Set the user avatar image data. - * This should be made before connecting, so we will not announce that the user have no avatar - * before setting and announcing a new one, forcing the peers to re-download it. - * - * Notice that the library treats the image as raw data and does not interpret it by any way. - * - * Arguments: - * format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT); - * data - pointer to the avatar data (may be NULL it the format is NONE); - * length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH. - * - * returns 0 on success - * returns -1 on failure. - */ -int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length); - -/* Unsets the user avatar. - - returns 0 on success (currently always returns 0) */ -int m_unset_avatar(Messenger *m); - -/* Get avatar data from the current user. - * Copies the current user avatar data to the destination buffer and sets the image format - * accordingly. - * - * If the avatar format is NONE, the buffer 'buf' isleft uninitialized, 'hash' is zeroed, and - * 'length' is set to zero. - * - * If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored. - * - * Arguments: - * format - destination pointer to the avatar image format (see AVATAR_FORMAT); - * buf - destination buffer to the image data. Must have at least 'maxlen' bytes; - * length - destination pointer to the image data length; - * maxlen - length of the destination buffer 'buf'; - * hash - destination pointer to the avatar hash (it must be exactly AVATAR_HASH_LENGTH bytes long). - * - * returns 0 on success; - * returns -1 on failure. - * - */ -int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen, - uint8_t *hash); - -/* Generates a cryptographic hash of the given data. - * This function may be used by clients for any purpose, but is provided primarily for - * validating cached avatars. - * This function is a wrapper to internal message-digest functions. - * - * Arguments: - * hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long. - * data - data to be hashed; - * datalen - length of the data; - * - * returns 0 on success - * returns -1 on failure. - */ -int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); - -/* Generates a cryptographic hash of the given avatar data. - * This function is a wrapper to m_hash and specifically provided - * to generate hashes from user avatars that may be memcmp()ed with the values returned by the - * other avatar functions. It is specially important to validate cached avatars. - * - * Arguments: - * hash - destination buffer for the hash data, it must be exactly AVATAR_HASH_LENGTH bytes long. - * data - avatar image data; - * datalen - length of the avatar image data; it must be <= MAX_AVATAR_DATA_LENGTH. - * - * returns 0 on success - * returns -1 on failure. - */ -int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen); - -/* Request avatar information from a friend. - * Asks a friend to provide their avatar information (image format and hash). The friend may - * or may not answer this request and, if answered, the information will be provided through - * the callback 'avatar_info'. - * - * returns 0 on success - * returns -1 on failure. - */ -int m_request_avatar_info(const Messenger *m, const int32_t friendnumber); - -/* Send an unrequested avatar information to a friend. - * Sends our avatar format and hash to a friend; he/she can use this information to validate - * an avatar from the cache and may (or not) reply with an avatar data request. - * - * Notice: it is NOT necessary to send these notification after changing the avatar or - * connecting. The library already does this. - * - * returns 0 on success - * returns -1 on failure. - */ -int m_send_avatar_info(const Messenger *m, const int32_t friendnumber); - - -/* Request the avatar data from a friend. - * Ask a friend to send their avatar data. The friend may or may not answer this request and, - * if answered, the information will be provided in callback 'avatar_data'. - * - * returns 0 on sucess - * returns -1 on failure. - */ -int m_request_avatar_data(const Messenger *m, const int32_t friendnumber); - - /* returns timestamp of last time friendnumber was seen online, or 0 if never seen. * returns -1 on error. */ @@ -702,48 +531,6 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess void *userdata); -/* Set the callback function for avatar information. - * This callback will be called when avatar information are received from friends. These events - * can arrive at anytime, but are usually received uppon connection and in reply of avatar - * information requests. - * - * Function format is: - * function(Tox *tox, uint32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata) - * - * where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of - * the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the - * image format is NONE, the hash is zeroed. - * - */ -void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, void *), - void *userdata); - - -/* Set the callback function for avatar data. - * This callback will be called when the complete avatar data was correctly received from a - * friend. This only happens in reply of a avatar data request (see tox_request_avatar_data); - * - * Function format is: - * function(Tox *tox, uint32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata) - * - * where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the - * locally-calculated cryptographic hash of the avatar data and it is exactly - * AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length - * of such data. - * - * If format is NONE, 'data' is NULL, 'datalen' is zero, and the hash is zeroed. The hash is - * always validated locally with the function tox_avatar_hash and ensured to match the image - * data, so this value can be safely used to compare with cached avatars. - * - * WARNING: users MUST treat all avatar image data received from another peer as untrusted and - * potentially malicious. The library only ensures that the data which arrived is the same the - * other user sent, and does not interpret or validate any image data. - */ -void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, uint8_t *, uint8_t *, - uint32_t, void *), void *userdata); - - - /**********GROUP CHATS************/ /* Set the callback for group invites.